xref: /freebsd-src/contrib/netbsd-tests/kernel/arch/amd64/t_ptrace_wait.c (revision f467f63cbb5063ff62496d79752f7563db42e02a)
1 /*	$NetBSD: t_ptrace_wait.c,v 1.9 2017/01/13 21:30:41 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2016 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __RCSID("$NetBSD: t_ptrace_wait.c,v 1.9 2017/01/13 21:30:41 christos Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/types.h>
34 #include <sys/ptrace.h>
35 #include <sys/resource.h>
36 #include <sys/stat.h>
37 #include <sys/sysctl.h>
38 #include <sys/wait.h>
39 #include <machine/reg.h>
40 #include <x86/dbregs.h>
41 #include <err.h>
42 #include <errno.h>
43 #include <sched.h>
44 #include <signal.h>
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <strings.h>
49 #include <unistd.h>
50 
51 #include <atf-c.h>
52 
53 #include "h_macros.h"
54 
55 #include "../../t_ptrace_wait.h"
56 
57 
58 #if defined(HAVE_GPREGS)
59 ATF_TC(regs1);
60 ATF_TC_HEAD(regs1, tc)
61 {
62 	atf_tc_set_md_var(tc, "descr",
63 	    "Call PT_GETREGS and iterate over General Purpose registers");
64 }
65 
66 ATF_TC_BODY(regs1, tc)
67 {
68 	const int exitval = 5;
69 	const int sigval = SIGSTOP;
70 	pid_t child, wpid;
71 #if defined(TWAIT_HAVE_STATUS)
72 	int status;
73 #endif
74 	struct reg r;
75 
76 	printf("Before forking process PID=%d\n", getpid());
77 	ATF_REQUIRE((child = fork()) != -1);
78 	if (child == 0) {
79 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
80 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
81 
82 		printf("Before raising %s from child\n", strsignal(sigval));
83 		FORKEE_ASSERT(raise(sigval) == 0);
84 
85 		printf("Before exiting of the child process\n");
86 		_exit(exitval);
87 	}
88 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
89 
90 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
91 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
92 
93 	validate_status_stopped(status, sigval);
94 
95 	printf("Call GETREGS for the child process\n");
96 	ATF_REQUIRE(ptrace(PT_GETREGS, child, &r, 0) != -1);
97 
98 	printf("RAX=%#" PRIxREGISTER "\n", r.regs[_REG_RAX]);
99 	printf("RBX=%#" PRIxREGISTER "\n", r.regs[_REG_RBX]);
100 	printf("RCX=%#" PRIxREGISTER "\n", r.regs[_REG_RCX]);
101 	printf("RDX=%#" PRIxREGISTER "\n", r.regs[_REG_RDX]);
102 
103 	printf("RDI=%#" PRIxREGISTER "\n", r.regs[_REG_RDI]);
104 	printf("RSI=%#" PRIxREGISTER "\n", r.regs[_REG_RSI]);
105 
106 	printf("GS=%#" PRIxREGISTER "\n", r.regs[_REG_GS]);
107 	printf("FS=%#" PRIxREGISTER "\n", r.regs[_REG_FS]);
108 	printf("ES=%#" PRIxREGISTER "\n", r.regs[_REG_ES]);
109 	printf("DS=%#" PRIxREGISTER "\n", r.regs[_REG_DS]);
110 	printf("CS=%#" PRIxREGISTER "\n", r.regs[_REG_CS]);
111 	printf("SS=%#" PRIxREGISTER "\n", r.regs[_REG_SS]);
112 
113 	printf("RSP=%#" PRIxREGISTER "\n", r.regs[_REG_RSP]);
114 	printf("RIP=%#" PRIxREGISTER "\n", r.regs[_REG_RIP]);
115 
116 	printf("RFLAGS=%#" PRIxREGISTER "\n", r.regs[_REG_RFLAGS]);
117 
118 	printf("R8=%#" PRIxREGISTER "\n", r.regs[_REG_R8]);
119 	printf("R9=%#" PRIxREGISTER "\n", r.regs[_REG_R9]);
120 	printf("R10=%#" PRIxREGISTER "\n", r.regs[_REG_R10]);
121 	printf("R11=%#" PRIxREGISTER "\n", r.regs[_REG_R11]);
122 	printf("R12=%#" PRIxREGISTER "\n", r.regs[_REG_R12]);
123 	printf("R13=%#" PRIxREGISTER "\n", r.regs[_REG_R13]);
124 	printf("R14=%#" PRIxREGISTER "\n", r.regs[_REG_R14]);
125 	printf("R15=%#" PRIxREGISTER "\n", r.regs[_REG_R15]);
126 
127 	printf("Before resuming the child process where it left off and "
128 	    "without signal to be sent\n");
129 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
130 
131 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
132 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
133 
134 	validate_status_exited(status, exitval);
135 
136 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
137 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
138 }
139 #endif
140 
141 #if defined(__HAVE_PTRACE_WATCHPOINTS)
142 ATF_TC(watchpoint_count);
143 ATF_TC_HEAD(watchpoint_count, tc)
144 {
145 	atf_tc_set_md_var(tc, "descr",
146 	    "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints");
147 }
148 
149 ATF_TC_BODY(watchpoint_count, tc)
150 {
151 	const int exitval = 5;
152 	const int sigval = SIGSTOP;
153 	pid_t child, wpid;
154 #if defined(TWAIT_HAVE_STATUS)
155 	int status;
156 #endif
157 	int N;
158 
159 	printf("Before forking process PID=%d\n", getpid());
160 	ATF_REQUIRE((child = fork()) != -1);
161 	if (child == 0) {
162 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
163 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
164 
165 		printf("Before raising %s from child\n", strsignal(sigval));
166 		FORKEE_ASSERT(raise(sigval) == 0);
167 
168 		printf("Before exiting of the child process\n");
169 		_exit(exitval);
170 	}
171 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
172 
173 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
174 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
175 
176 	validate_status_stopped(status, sigval);
177 
178 	printf("Call GETREGS for the child process\n");
179 	ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
180 	printf("Reported %d watchpoints\n", N);
181 
182 	ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
183 
184 	printf("Before resuming the child process where it left off and "
185 	    "without signal to be sent\n");
186 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
187 
188 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
189 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
190 
191 	validate_status_exited(status, exitval);
192 
193 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
194 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
195 }
196 #endif
197 
198 #if defined(__HAVE_PTRACE_WATCHPOINTS)
199 ATF_TC(watchpoint_read);
200 ATF_TC_HEAD(watchpoint_read, tc)
201 {
202 	atf_tc_set_md_var(tc, "descr",
203 	    "Call PT_COUNT_WATCHPOINTS and assert four available watchpoints");
204 }
205 
206 ATF_TC_BODY(watchpoint_read, tc)
207 {
208 	const int exitval = 5;
209 	const int sigval = SIGSTOP;
210 	pid_t child, wpid;
211 #if defined(TWAIT_HAVE_STATUS)
212 	int status;
213 #endif
214 	int i, N;
215 	struct ptrace_watchpoint pw;
216 	int len = sizeof(pw);
217 
218 	printf("Before forking process PID=%d\n", getpid());
219 	ATF_REQUIRE((child = fork()) != -1);
220 	if (child == 0) {
221 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
222 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
223 
224 		printf("Before raising %s from child\n", strsignal(sigval));
225 		FORKEE_ASSERT(raise(sigval) == 0);
226 
227 		printf("Before exiting of the child process\n");
228 		_exit(exitval);
229 	}
230 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
231 
232 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
233 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
234 
235 	validate_status_stopped(status, sigval);
236 
237 	printf("Call GETREGS for the child process\n");
238 	ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
239 
240 	ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
241 
242 	for (i = 0; i < N; i++) {
243 		printf("Before reading watchpoint %d\n", i);
244 		pw.pw_index = i;
245 		ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1);
246 
247 		printf("struct ptrace {\n");
248 		printf("\t.pw_index=%d\n", pw.pw_index);
249 		printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
250 		printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
251 		printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
252 		printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
253 		printf("}\n");
254 	}
255 
256 	printf("Before resuming the child process where it left off and "
257 	    "without signal to be sent\n");
258 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
259 
260 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
261 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
262 
263 	validate_status_exited(status, exitval);
264 
265 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
266 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
267 }
268 #endif
269 
270 #if defined(__HAVE_PTRACE_WATCHPOINTS)
271 ATF_TC(watchpoint_write_unmodified);
272 ATF_TC_HEAD(watchpoint_write_unmodified, tc)
273 {
274 	atf_tc_set_md_var(tc, "descr",
275 	    "Call PT_COUNT_WATCHPOINTS and assert functional write of "
276 	    "unmodified data");
277 }
278 
279 ATF_TC_BODY(watchpoint_write_unmodified, tc)
280 {
281 	const int exitval = 5;
282 	const int sigval = SIGSTOP;
283 	pid_t child, wpid;
284 #if defined(TWAIT_HAVE_STATUS)
285 	int status;
286 #endif
287 	int i, N;
288 	struct ptrace_watchpoint pw;
289 	int len = sizeof(pw);
290 
291 	printf("Before forking process PID=%d\n", getpid());
292 	ATF_REQUIRE((child = fork()) != -1);
293 	if (child == 0) {
294 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
295 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
296 
297 		printf("Before raising %s from child\n", strsignal(sigval));
298 		FORKEE_ASSERT(raise(sigval) == 0);
299 
300 		printf("Before exiting of the child process\n");
301 		_exit(exitval);
302 	}
303 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
304 
305 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
306 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
307 
308 	validate_status_stopped(status, sigval);
309 
310 	printf("Call GETREGS for the child process\n");
311 	ATF_REQUIRE((N = ptrace(PT_COUNT_WATCHPOINTS, child, NULL, 0)) != -1);
312 
313 	ATF_REQUIRE_EQ_MSG(N, 4, "Expected 4 hw watchpoints - got %d", N);
314 
315 	for (i = 0; i < N; i++) {
316 		printf("Before reading watchpoint %d\n", i);
317 		pw.pw_index = i;
318 		ATF_REQUIRE(ptrace(PT_READ_WATCHPOINT, child, &pw, len) != -1);
319 
320 		printf("struct ptrace {\n");
321 		printf("\t.pw_index=%d\n", pw.pw_index);
322 		printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
323 		printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
324 		printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
325 		printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
326 		printf("}\n");
327 
328 		printf("Before writing watchpoint %d (unmodified)\n", i);
329 		ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len)
330 		    != -1);
331 	}
332 
333 	printf("Before resuming the child process where it left off and "
334 	    "without signal to be sent\n");
335 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
336 
337 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
338 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
339 
340 	validate_status_exited(status, exitval);
341 
342 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
343 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
344 }
345 #endif
346 
347 #if defined(__HAVE_PTRACE_WATCHPOINTS)
348 ATF_TC(watchpoint_trap_code0);
349 ATF_TC_HEAD(watchpoint_trap_code0, tc)
350 {
351 	atf_tc_set_md_var(tc, "descr",
352 	    "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 0");
353 }
354 
355 ATF_TC_BODY(watchpoint_trap_code0, tc)
356 {
357 	const int exitval = 5;
358 	const int sigval = SIGSTOP;
359 	pid_t child, wpid;
360 #if defined(TWAIT_HAVE_STATUS)
361 	int status;
362 #endif
363 	const int i = 0;
364 	struct ptrace_watchpoint pw;
365 	int len = sizeof(pw);
366 	int watchme = 1234;
367 
368 	printf("Before forking process PID=%d\n", getpid());
369 	ATF_REQUIRE((child = fork()) != -1);
370 	if (child == 0) {
371 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
372 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
373 
374 		printf("Before raising %s from child\n", strsignal(sigval));
375 		FORKEE_ASSERT(raise(sigval) == 0);
376 
377 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
378 
379 		printf("Before exiting of the child process\n");
380 		_exit(exitval);
381 	}
382 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
383 
384 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
385 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
386 
387 	validate_status_stopped(status, sigval);
388 
389 	printf("Preparing code watchpoint trap %d\n", i);
390 
391 	pw.pw_index = i;
392 	pw.pw_lwpid = 0;
393 	pw.pw_md.md_address = (void *)check_happy;
394 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
395 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
396 
397 	printf("struct ptrace {\n");
398 	printf("\t.pw_index=%d\n", pw.pw_index);
399 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
400 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
401 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
402 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
403 	printf("}\n");
404 
405 	printf("Before writing watchpoint %d\n", i);
406 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
407 
408 	printf("Before resuming the child process where it left off "
409 	    "and without signal to be sent\n");
410 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
411 
412 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
413 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
414 
415 	validate_status_stopped(status, SIGTRAP);
416 
417 	pw.pw_md.md_address = NULL;
418 	printf("Before writing watchpoint %d (disable it)\n", i);
419 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
420 
421 	printf("Before resuming the child process where it left off and "
422 	    "without signal to be sent\n");
423 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
424 
425 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
426 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
427 
428 	validate_status_exited(status, exitval);
429 
430 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
431 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
432 }
433 #endif
434 
435 #if defined(__HAVE_PTRACE_WATCHPOINTS)
436 ATF_TC(watchpoint_trap_code1);
437 ATF_TC_HEAD(watchpoint_trap_code1, tc)
438 {
439 	atf_tc_set_md_var(tc, "descr",
440 	    "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 1");
441 }
442 
443 ATF_TC_BODY(watchpoint_trap_code1, tc)
444 {
445 	const int exitval = 5;
446 	const int sigval = SIGSTOP;
447 	pid_t child, wpid;
448 #if defined(TWAIT_HAVE_STATUS)
449 	int status;
450 #endif
451 	const int i = 1;
452 	struct ptrace_watchpoint pw;
453 	int len = sizeof(pw);
454 	int watchme = 1234;
455 
456 	printf("Before forking process PID=%d\n", getpid());
457 	ATF_REQUIRE((child = fork()) != -1);
458 	if (child == 0) {
459 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
460 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
461 
462 		printf("Before raising %s from child\n", strsignal(sigval));
463 		FORKEE_ASSERT(raise(sigval) == 0);
464 
465 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
466 
467 		printf("Before exiting of the child process\n");
468 		_exit(exitval);
469 	}
470 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
471 
472 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
473 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
474 
475 	validate_status_stopped(status, sigval);
476 
477 	printf("Preparing code watchpoint trap %d\n", i);
478 
479 	pw.pw_index = i;
480 	pw.pw_lwpid = 0;
481 	pw.pw_md.md_address = (void *)check_happy;
482 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
483 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
484 
485 	printf("struct ptrace {\n");
486 	printf("\t.pw_index=%d\n", pw.pw_index);
487 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
488 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
489 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
490 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
491 	printf("}\n");
492 
493 	printf("Before writing watchpoint %d\n", i);
494 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
495 
496 	printf("Before resuming the child process where it left off "
497 	    "and without signal to be sent\n");
498 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
499 
500 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
501 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
502 
503 	validate_status_stopped(status, SIGTRAP);
504 
505 	pw.pw_md.md_address = NULL;
506 	printf("Before writing watchpoint %d (disable it)\n", i);
507 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
508 
509 	printf("Before resuming the child process where it left off and "
510 	    "without signal to be sent\n");
511 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
512 
513 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
514 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
515 
516 	validate_status_exited(status, exitval);
517 
518 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
519 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
520 }
521 #endif
522 
523 #if defined(__HAVE_PTRACE_WATCHPOINTS)
524 ATF_TC(watchpoint_trap_code2);
525 ATF_TC_HEAD(watchpoint_trap_code2, tc)
526 {
527 	atf_tc_set_md_var(tc, "descr",
528 	    "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 2");
529 }
530 
531 ATF_TC_BODY(watchpoint_trap_code2, tc)
532 {
533 	const int exitval = 5;
534 	const int sigval = SIGSTOP;
535 	pid_t child, wpid;
536 #if defined(TWAIT_HAVE_STATUS)
537 	int status;
538 #endif
539 	const int i = 2;
540 	struct ptrace_watchpoint pw;
541 	int len = sizeof(pw);
542 	int watchme = 1234;
543 
544 	printf("Before forking process PID=%d\n", getpid());
545 	ATF_REQUIRE((child = fork()) != -1);
546 	if (child == 0) {
547 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
548 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
549 
550 		printf("Before raising %s from child\n", strsignal(sigval));
551 		FORKEE_ASSERT(raise(sigval) == 0);
552 
553 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
554 
555 		printf("Before exiting of the child process\n");
556 		_exit(exitval);
557 	}
558 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
559 
560 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
561 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
562 
563 	validate_status_stopped(status, sigval);
564 
565 	printf("Preparing code watchpoint trap %d\n", i);
566 
567 	pw.pw_index = i;
568 	pw.pw_lwpid = 0;
569 	pw.pw_md.md_address = (void *)check_happy;
570 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
571 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
572 
573 	printf("struct ptrace {\n");
574 	printf("\t.pw_index=%d\n", pw.pw_index);
575 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
576 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
577 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
578 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
579 	printf("}\n");
580 
581 	printf("Before writing watchpoint %d\n", i);
582 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
583 
584 	printf("Before resuming the child process where it left off "
585 	    "and without signal to be sent\n");
586 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
587 
588 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
589 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
590 
591 	validate_status_stopped(status, SIGTRAP);
592 
593 	pw.pw_md.md_address = NULL;
594 	printf("Before writing watchpoint %d (disable it)\n", i);
595 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
596 
597 	printf("Before resuming the child process where it left off and "
598 	    "without signal to be sent\n");
599 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
600 
601 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
602 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
603 
604 	validate_status_exited(status, exitval);
605 
606 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
607 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
608 }
609 #endif
610 
611 #if defined(__HAVE_PTRACE_WATCHPOINTS)
612 ATF_TC(watchpoint_trap_code3);
613 ATF_TC_HEAD(watchpoint_trap_code3, tc)
614 {
615 	atf_tc_set_md_var(tc, "descr",
616 	    "Call PT_COUNT_WATCHPOINTS and test code trap with watchpoint 3");
617 }
618 
619 ATF_TC_BODY(watchpoint_trap_code3, tc)
620 {
621 	const int exitval = 5;
622 	const int sigval = SIGSTOP;
623 	pid_t child, wpid;
624 #if defined(TWAIT_HAVE_STATUS)
625 	int status;
626 #endif
627 	const int i = 3;
628 	struct ptrace_watchpoint pw;
629 	int len = sizeof(pw);
630 	int watchme = 1234;
631 
632 	printf("Before forking process PID=%d\n", getpid());
633 	ATF_REQUIRE((child = fork()) != -1);
634 	if (child == 0) {
635 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
636 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
637 
638 		printf("Before raising %s from child\n", strsignal(sigval));
639 		FORKEE_ASSERT(raise(sigval) == 0);
640 
641 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
642 
643 		printf("Before exiting of the child process\n");
644 		_exit(exitval);
645 	}
646 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
647 
648 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
649 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
650 
651 	validate_status_stopped(status, sigval);
652 
653 	printf("Preparing code watchpoint trap %d\n", i);
654 
655 	pw.pw_index = i;
656 	pw.pw_lwpid = 0;
657 	pw.pw_md.md_address = (void *)check_happy;
658 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_EXECUTION;
659 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
660 
661 	printf("struct ptrace {\n");
662 	printf("\t.pw_index=%d\n", pw.pw_index);
663 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
664 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
665 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
666 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
667 	printf("}\n");
668 
669 	printf("Before writing watchpoint %d\n", i);
670 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
671 
672 	printf("Before resuming the child process where it left off "
673 	    "and without signal to be sent\n");
674 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
675 
676 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
677 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
678 
679 	validate_status_stopped(status, SIGTRAP);
680 
681 	pw.pw_md.md_address = NULL;
682 	printf("Before writing watchpoint %d (disable it)\n", i);
683 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
684 
685 	printf("Before resuming the child process where it left off and "
686 	    "without signal to be sent\n");
687 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
688 
689 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
690 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
691 
692 	validate_status_exited(status, exitval);
693 
694 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
695 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
696 }
697 #endif
698 
699 #if defined(__HAVE_PTRACE_WATCHPOINTS)
700 ATF_TC(watchpoint_trap_data_write0);
701 ATF_TC_HEAD(watchpoint_trap_data_write0, tc)
702 {
703 	atf_tc_set_md_var(tc, "descr",
704 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0");
705 }
706 
707 ATF_TC_BODY(watchpoint_trap_data_write0, tc)
708 {
709 	const int exitval = 5;
710 	const int sigval = SIGSTOP;
711 	pid_t child, wpid;
712 #if defined(TWAIT_HAVE_STATUS)
713 	int status;
714 #endif
715 	const int i = 0;
716 	struct ptrace_watchpoint pw;
717 	int len = sizeof(pw);
718 	int watchme = 1234;
719 
720 	printf("Before forking process PID=%d\n", getpid());
721 	ATF_REQUIRE((child = fork()) != -1);
722 	if (child == 0) {
723 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
724 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
725 
726 		printf("Before raising %s from child\n", strsignal(sigval));
727 		FORKEE_ASSERT(raise(sigval) == 0);
728 
729 		++watchme;
730 
731 		printf("Before exiting of the child process\n");
732 		_exit(exitval);
733 	}
734 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
735 
736 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
737 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
738 
739 	validate_status_stopped(status, sigval);
740 
741 	printf("Preparing code watchpoint trap %d\n", i);
742 
743 	pw.pw_index = 0;
744 	pw.pw_md.md_address = &watchme;
745 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
746 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
747 
748 	printf("struct ptrace {\n");
749 	printf("\t.pw_index=%d\n", pw.pw_index);
750 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
751 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
752 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
753 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
754 	printf("}\n");
755 
756 	printf("Before writing watchpoint %d\n", i);
757 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
758 
759 	printf("Before resuming the child process where it left off "
760 	    "and without signal to be sent\n");
761 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
762 
763 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
764 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
765 
766 	validate_status_stopped(status, SIGTRAP);
767 
768 	printf("Before resuming the child process where it left off and "
769 	    "without signal to be sent\n");
770 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
771 
772 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
773 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
774 
775 	validate_status_exited(status, exitval);
776 
777 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
778 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
779 }
780 #endif
781 
782 #if defined(__HAVE_PTRACE_WATCHPOINTS)
783 ATF_TC(watchpoint_trap_data_write1);
784 ATF_TC_HEAD(watchpoint_trap_data_write1, tc)
785 {
786 	atf_tc_set_md_var(tc, "descr",
787 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1");
788 }
789 
790 ATF_TC_BODY(watchpoint_trap_data_write1, tc)
791 {
792 	const int exitval = 5;
793 	const int sigval = SIGSTOP;
794 	pid_t child, wpid;
795 #if defined(TWAIT_HAVE_STATUS)
796 	int status;
797 #endif
798 	const int i = 1;
799 	struct ptrace_watchpoint pw;
800 	int len = sizeof(pw);
801 	int watchme = 1234;
802 
803 	printf("Before forking process PID=%d\n", getpid());
804 	ATF_REQUIRE((child = fork()) != -1);
805 	if (child == 0) {
806 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
807 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
808 
809 		printf("Before raising %s from child\n", strsignal(sigval));
810 		FORKEE_ASSERT(raise(sigval) == 0);
811 
812 		++watchme;
813 
814 		printf("Before exiting of the child process\n");
815 		_exit(exitval);
816 	}
817 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
818 
819 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
820 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
821 
822 	validate_status_stopped(status, sigval);
823 
824 	printf("Preparing code watchpoint trap %d\n", i);
825 
826 	pw.pw_index = i;
827 	pw.pw_md.md_address = &watchme;
828 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
829 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
830 
831 	printf("struct ptrace {\n");
832 	printf("\t.pw_index=%d\n", pw.pw_index);
833 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
834 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
835 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
836 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
837 	printf("}\n");
838 
839 	printf("Before writing watchpoint %d\n", i);
840 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
841 
842 	printf("Before resuming the child process where it left off "
843 	    "and without signal to be sent\n");
844 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
845 
846 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
847 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
848 
849 	validate_status_stopped(status, SIGTRAP);
850 
851 	printf("Before resuming the child process where it left off and "
852 	    "without signal to be sent\n");
853 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
854 
855 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
856 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
857 
858 	validate_status_exited(status, exitval);
859 
860 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
861 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
862 }
863 #endif
864 
865 #if defined(__HAVE_PTRACE_WATCHPOINTS)
866 ATF_TC(watchpoint_trap_data_write2);
867 ATF_TC_HEAD(watchpoint_trap_data_write2, tc)
868 {
869 	atf_tc_set_md_var(tc, "descr",
870 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2");
871 }
872 
873 ATF_TC_BODY(watchpoint_trap_data_write2, tc)
874 {
875 	const int exitval = 5;
876 	const int sigval = SIGSTOP;
877 	pid_t child, wpid;
878 #if defined(TWAIT_HAVE_STATUS)
879 	int status;
880 #endif
881 	const int i = 2;
882 	struct ptrace_watchpoint pw;
883 	int len = sizeof(pw);
884 	int watchme = 1234;
885 
886 	printf("Before forking process PID=%d\n", getpid());
887 	ATF_REQUIRE((child = fork()) != -1);
888 	if (child == 0) {
889 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
890 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
891 
892 		printf("Before raising %s from child\n", strsignal(sigval));
893 		FORKEE_ASSERT(raise(sigval) == 0);
894 
895 		++watchme;
896 
897 		printf("Before exiting of the child process\n");
898 		_exit(exitval);
899 	}
900 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
901 
902 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
903 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
904 
905 	validate_status_stopped(status, sigval);
906 
907 	printf("Preparing code watchpoint trap %d\n", i);
908 
909 	pw.pw_index = i;
910 	pw.pw_md.md_address = &watchme;
911 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
912 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
913 
914 	printf("struct ptrace {\n");
915 	printf("\t.pw_index=%d\n", pw.pw_index);
916 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
917 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
918 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
919 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
920 	printf("}\n");
921 
922 	printf("Before writing watchpoint %d\n", i);
923 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
924 
925 	printf("Before resuming the child process where it left off "
926 	    "and without signal to be sent\n");
927 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
928 
929 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
930 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
931 
932 	validate_status_stopped(status, SIGTRAP);
933 
934 	printf("Before resuming the child process where it left off and "
935 	    "without signal to be sent\n");
936 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
937 
938 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
939 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
940 
941 	validate_status_exited(status, exitval);
942 
943 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
944 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
945 }
946 #endif
947 
948 
949 #if defined(__HAVE_PTRACE_WATCHPOINTS)
950 ATF_TC(watchpoint_trap_data_write3);
951 ATF_TC_HEAD(watchpoint_trap_data_write3, tc)
952 {
953 	atf_tc_set_md_var(tc, "descr",
954 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3");
955 }
956 
957 ATF_TC_BODY(watchpoint_trap_data_write3, tc)
958 {
959 	const int exitval = 5;
960 	const int sigval = SIGSTOP;
961 	pid_t child, wpid;
962 #if defined(TWAIT_HAVE_STATUS)
963 	int status;
964 #endif
965 	const int i = 3;
966 	struct ptrace_watchpoint pw;
967 	int len = sizeof(pw);
968 	int watchme = 1234;
969 
970 	printf("Before forking process PID=%d\n", getpid());
971 	ATF_REQUIRE((child = fork()) != -1);
972 	if (child == 0) {
973 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
974 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
975 
976 		printf("Before raising %s from child\n", strsignal(sigval));
977 		FORKEE_ASSERT(raise(sigval) == 0);
978 
979 		++watchme;
980 
981 		printf("Before exiting of the child process\n");
982 		_exit(exitval);
983 	}
984 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
985 
986 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
987 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
988 
989 	validate_status_stopped(status, sigval);
990 
991 	printf("Preparing code watchpoint trap %d\n", i);
992 
993 	pw.pw_index = i;
994 	pw.pw_md.md_address = &watchme;
995 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_WRITE;
996 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
997 
998 	printf("struct ptrace {\n");
999 	printf("\t.pw_index=%d\n", pw.pw_index);
1000 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1001 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1002 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1003 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1004 	printf("}\n");
1005 
1006 	printf("Before writing watchpoint %d\n", i);
1007 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1008 
1009 	printf("Before resuming the child process where it left off "
1010 	    "and without signal to be sent\n");
1011 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1012 
1013 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1014 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1015 
1016 	validate_status_stopped(status, SIGTRAP);
1017 
1018 	printf("Before resuming the child process where it left off and "
1019 	    "without signal to be sent\n");
1020 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1021 
1022 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1023 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1024 
1025 	validate_status_exited(status, exitval);
1026 
1027 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1028 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1029 }
1030 #endif
1031 
1032 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1033 ATF_TC(watchpoint_trap_data_rw0);
1034 ATF_TC_HEAD(watchpoint_trap_data_rw0, tc)
1035 {
1036 	atf_tc_set_md_var(tc, "descr",
1037 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 0");
1038 }
1039 
1040 ATF_TC_BODY(watchpoint_trap_data_rw0, tc)
1041 {
1042 	const int exitval = 5;
1043 	const int sigval = SIGSTOP;
1044 	pid_t child, wpid;
1045 #if defined(TWAIT_HAVE_STATUS)
1046 	int status;
1047 #endif
1048 	const int i = 0;
1049 	struct ptrace_watchpoint pw;
1050 	int len = sizeof(pw);
1051 	int watchme = 1234;
1052 
1053 	printf("Before forking process PID=%d\n", getpid());
1054 	ATF_REQUIRE((child = fork()) != -1);
1055 	if (child == 0) {
1056 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1057 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1058 
1059 		printf("Before raising %s from child\n", strsignal(sigval));
1060 		FORKEE_ASSERT(raise(sigval) == 0);
1061 
1062 		printf("watchme=%d\n", watchme);
1063 
1064 		printf("Before exiting of the child process\n");
1065 		_exit(exitval);
1066 	}
1067 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1068 
1069 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1070 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1071 
1072 	validate_status_stopped(status, sigval);
1073 
1074 	printf("Preparing code watchpoint trap %d\n", i);
1075 
1076 	pw.pw_index = i;
1077 	pw.pw_md.md_address = &watchme;
1078 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1079 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1080 
1081 	printf("struct ptrace {\n");
1082 	printf("\t.pw_index=%d\n", pw.pw_index);
1083 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1084 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1085 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1086 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1087 	printf("}\n");
1088 
1089 	printf("Before writing watchpoint %d\n", i);
1090 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1091 
1092 	printf("Before resuming the child process where it left off "
1093 	    "and without signal to be sent\n");
1094 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1095 
1096 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1097 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1098 
1099 	validate_status_stopped(status, SIGTRAP);
1100 
1101 	printf("Before resuming the child process where it left off and "
1102 	    "without signal to be sent\n");
1103 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1104 
1105 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1106 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1107 
1108 	validate_status_exited(status, exitval);
1109 
1110 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1111 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1112 }
1113 #endif
1114 
1115 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1116 ATF_TC(watchpoint_trap_data_rw1);
1117 ATF_TC_HEAD(watchpoint_trap_data_rw1, tc)
1118 {
1119 	atf_tc_set_md_var(tc, "descr",
1120 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 1");
1121 }
1122 
1123 ATF_TC_BODY(watchpoint_trap_data_rw1, tc)
1124 {
1125 	const int exitval = 5;
1126 	const int sigval = SIGSTOP;
1127 	pid_t child, wpid;
1128 #if defined(TWAIT_HAVE_STATUS)
1129 	int status;
1130 #endif
1131 	const int i = 1;
1132 	struct ptrace_watchpoint pw;
1133 	int len = sizeof(pw);
1134 	int watchme = 1234;
1135 
1136 	printf("Before forking process PID=%d\n", getpid());
1137 	ATF_REQUIRE((child = fork()) != -1);
1138 	if (child == 0) {
1139 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1140 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1141 
1142 		printf("Before raising %s from child\n", strsignal(sigval));
1143 		FORKEE_ASSERT(raise(sigval) == 0);
1144 
1145 		printf("watchme=%d\n", watchme);
1146 
1147 		printf("Before exiting of the child process\n");
1148 		_exit(exitval);
1149 	}
1150 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1151 
1152 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1153 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1154 
1155 	validate_status_stopped(status, sigval);
1156 
1157 	printf("Preparing code watchpoint trap %d\n", i);
1158 
1159 	pw.pw_index = i;
1160 	pw.pw_md.md_address = &watchme;
1161 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1162 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1163 
1164 	printf("struct ptrace {\n");
1165 	printf("\t.pw_index=%d\n", pw.pw_index);
1166 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1167 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1168 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1169 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1170 	printf("}\n");
1171 
1172 	printf("Before writing watchpoint %d\n", i);
1173 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1174 
1175 	printf("Before resuming the child process where it left off "
1176 	    "and without signal to be sent\n");
1177 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1178 
1179 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1180 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1181 
1182 	validate_status_stopped(status, SIGTRAP);
1183 
1184 	printf("Before resuming the child process where it left off and "
1185 	    "without signal to be sent\n");
1186 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1187 
1188 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1189 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1190 
1191 	validate_status_exited(status, exitval);
1192 
1193 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1194 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1195 }
1196 #endif
1197 
1198 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1199 ATF_TC(watchpoint_trap_data_rw2);
1200 ATF_TC_HEAD(watchpoint_trap_data_rw2, tc)
1201 {
1202 	atf_tc_set_md_var(tc, "descr",
1203 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 2");
1204 }
1205 
1206 ATF_TC_BODY(watchpoint_trap_data_rw2, tc)
1207 {
1208 	const int exitval = 5;
1209 	const int sigval = SIGSTOP;
1210 	pid_t child, wpid;
1211 #if defined(TWAIT_HAVE_STATUS)
1212 	int status;
1213 #endif
1214 	const int i = 2;
1215 	struct ptrace_watchpoint pw;
1216 	int len = sizeof(pw);
1217 	int watchme = 1234;
1218 
1219 	printf("Before forking process PID=%d\n", getpid());
1220 	ATF_REQUIRE((child = fork()) != -1);
1221 	if (child == 0) {
1222 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1223 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1224 
1225 		printf("Before raising %s from child\n", strsignal(sigval));
1226 		FORKEE_ASSERT(raise(sigval) == 0);
1227 
1228 		printf("watchme=%d\n", watchme);
1229 
1230 		printf("Before exiting of the child process\n");
1231 		_exit(exitval);
1232 	}
1233 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1234 
1235 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1236 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1237 
1238 	validate_status_stopped(status, sigval);
1239 
1240 	printf("Preparing code watchpoint trap %d\n", i);
1241 
1242 	pw.pw_index = i;
1243 	pw.pw_md.md_address = &watchme;
1244 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1245 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1246 
1247 	printf("struct ptrace {\n");
1248 	printf("\t.pw_index=%d\n", pw.pw_index);
1249 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1250 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1251 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1252 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1253 	printf("}\n");
1254 
1255 	printf("Before writing watchpoint %d\n", i);
1256 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1257 
1258 	printf("Before resuming the child process where it left off "
1259 	    "and without signal to be sent\n");
1260 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1261 
1262 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1263 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1264 
1265 	validate_status_stopped(status, SIGTRAP);
1266 
1267 	printf("Before resuming the child process where it left off and "
1268 	    "without signal to be sent\n");
1269 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1270 
1271 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1272 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1273 
1274 	validate_status_exited(status, exitval);
1275 
1276 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1277 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1278 }
1279 #endif
1280 
1281 #if defined(__HAVE_PTRACE_WATCHPOINTS)
1282 ATF_TC(watchpoint_trap_data_rw3);
1283 ATF_TC_HEAD(watchpoint_trap_data_rw3, tc)
1284 {
1285 	atf_tc_set_md_var(tc, "descr",
1286 	    "Call PT_COUNT_WATCHPOINTS and test write trap with watchpoint 3");
1287 }
1288 
1289 ATF_TC_BODY(watchpoint_trap_data_rw3, tc)
1290 {
1291 	const int exitval = 5;
1292 	const int sigval = SIGSTOP;
1293 	pid_t child, wpid;
1294 #if defined(TWAIT_HAVE_STATUS)
1295 	int status;
1296 #endif
1297 	const int i = 3;
1298 	struct ptrace_watchpoint pw;
1299 	int len = sizeof(pw);
1300 	int watchme = 1234;
1301 
1302 	printf("Before forking process PID=%d\n", getpid());
1303 	ATF_REQUIRE((child = fork()) != -1);
1304 	if (child == 0) {
1305 		printf("Before calling PT_TRACE_ME from child %d\n", getpid());
1306 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1307 
1308 		printf("Before raising %s from child\n", strsignal(sigval));
1309 		FORKEE_ASSERT(raise(sigval) == 0);
1310 
1311 		printf("watchme=%d\n", watchme);
1312 
1313 		printf("Before exiting of the child process\n");
1314 		_exit(exitval);
1315 	}
1316 	printf("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1317 
1318 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1319 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1320 
1321 	validate_status_stopped(status, sigval);
1322 
1323 	printf("Preparing code watchpoint trap %d\n", i);
1324 
1325 	pw.pw_index = i;
1326 	pw.pw_md.md_address = &watchme;
1327 	pw.pw_md.md_condition = X86_HW_WATCHPOINT_DR7_CONDITION_DATA_READWRITE;
1328 	pw.pw_md.md_length = X86_HW_WATCHPOINT_DR7_LENGTH_BYTE;
1329 
1330 	printf("struct ptrace {\n");
1331 	printf("\t.pw_index=%d\n", pw.pw_index);
1332 	printf("\t.pw_lwpid=%d\n", pw.pw_lwpid);
1333 	printf("\t.pw_md.md_address=%p\n", pw.pw_md.md_address);
1334 	printf("\t.pw_md.md_condition=%#x\n", pw.pw_md.md_condition);
1335 	printf("\t.pw_md.md_length=%#x\n", pw.pw_md.md_length);
1336 	printf("}\n");
1337 
1338 	printf("Before writing watchpoint %d\n", i);
1339 	ATF_REQUIRE(ptrace(PT_WRITE_WATCHPOINT, child, &pw, len) != -1);
1340 
1341 	printf("Before resuming the child process where it left off "
1342 	    "and without signal to be sent\n");
1343 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1344 
1345 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1346 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1347 
1348 	validate_status_stopped(status, SIGTRAP);
1349 
1350 	printf("Before resuming the child process where it left off and "
1351 	    "without signal to be sent\n");
1352 	ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1353 
1354 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1355 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1356 
1357 	validate_status_exited(status, exitval);
1358 
1359 	printf("Before calling %s() for the child\n", TWAIT_FNAME);
1360 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1361 }
1362 #endif
1363 
1364 ATF_TP_ADD_TCS(tp)
1365 {
1366 	setvbuf(stdout, NULL, _IONBF, 0);
1367 	setvbuf(stderr, NULL, _IONBF, 0);
1368 
1369 	ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1);
1370 
1371 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_count);
1372 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_read);
1373 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_write_unmodified);
1374 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code0);
1375 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code1);
1376 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code2);
1377 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_code3);
1378 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write0);
1379 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write1);
1380 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write2);
1381 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_write3);
1382 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw0);
1383 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw1);
1384 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw2);
1385 	ATF_TP_ADD_TC_HAVE_PTRACE_WATCHPOINTS(tp, watchpoint_trap_data_rw3);
1386 
1387 	return atf_no_error();
1388 }
1389