xref: /netbsd-src/tests/lib/libc/sys/t_ptrace_x86_wait.h (revision c38e7cc395b1472a774ff828e46123de44c628e9)
1 /*	$NetBSD: t_ptrace_x86_wait.h,v 1.5 2018/04/08 17:20:18 kamil 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 #if defined(__i386__) || defined(__x86_64__)
30 union u {
31 	unsigned long raw;
32 	struct {
33 		unsigned long local_dr0_breakpoint : 1;		/* 0 */
34 		unsigned long global_dr0_breakpoint : 1;	/* 1 */
35 		unsigned long local_dr1_breakpoint : 1;		/* 2 */
36 		unsigned long global_dr1_breakpoint : 1;	/* 3 */
37 		unsigned long local_dr2_breakpoint : 1;		/* 4 */
38 		unsigned long global_dr2_breakpoint : 1;	/* 5 */
39 		unsigned long local_dr3_breakpoint : 1;		/* 6 */
40 		unsigned long global_dr3_breakpoint : 1;	/* 7 */
41 		unsigned long local_exact_breakpt : 1;		/* 8 */
42 		unsigned long global_exact_breakpt : 1;		/* 9 */
43 		unsigned long reserved_10 : 1;			/* 10 */
44 		unsigned long rest_trans_memory : 1;		/* 11 */
45 		unsigned long reserved_12 : 1;			/* 12 */
46 		unsigned long general_detect_enable : 1;	/* 13 */
47 		unsigned long reserved_14 : 1;			/* 14 */
48 		unsigned long reserved_15 : 1;			/* 15 */
49 		unsigned long condition_dr0 : 2;		/* 16-17 */
50 		unsigned long len_dr0 : 2;			/* 18-19 */
51 		unsigned long condition_dr1 : 2;		/* 20-21 */
52 		unsigned long len_dr1 : 2;			/* 22-23 */
53 		unsigned long condition_dr2 : 2;		/* 24-25 */
54 		unsigned long len_dr2 : 2;			/* 26-27 */
55 		unsigned long condition_dr3 : 2;		/* 28-29 */
56 		unsigned long len_dr3 : 2;			/* 30-31 */
57 	} bits;
58 };
59 
60 static bool
61 can_we_set_dbregs(void)
62 {
63 	static long euid = -1;
64 	static int user_set_dbregs  = -1;
65 	size_t user_set_dbregs_len = sizeof(user_set_dbregs);
66 
67 	if (euid == -1)
68 		euid = geteuid();
69 
70 	if (euid == 0)
71 		return true;
72 
73 	if (user_set_dbregs == -1) {
74 		if (sysctlbyname("security.models.extensions.user_set_dbregs",
75 			&user_set_dbregs, &user_set_dbregs_len, NULL, 0)
76 			== -1) {
77 			return false;
78 		}
79 	}
80 
81 	if (user_set_dbregs > 0)
82 		return true;
83 	else
84 		return false;
85 }
86 
87 ATF_TC(dbregs_print);
88 ATF_TC_HEAD(dbregs_print, tc)
89 {
90 	atf_tc_set_md_var(tc, "descr",
91 	    "Verify plain PT_GETDBREGS with printing Debug Registers");
92 }
93 
94 ATF_TC_BODY(dbregs_print, tc)
95 {
96 	const int exitval = 5;
97 	const int sigval = SIGSTOP;
98 	pid_t child, wpid;
99 #if defined(TWAIT_HAVE_STATUS)
100 	int status;
101 #endif
102 	struct dbreg r;
103 	size_t i;
104 
105 	DPRINTF("Before forking process PID=%d\n", getpid());
106 	SYSCALL_REQUIRE((child = fork()) != -1);
107 	if (child == 0) {
108 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
109 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
110 
111 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
112 		FORKEE_ASSERT(raise(sigval) == 0);
113 
114 		DPRINTF("Before exiting of the child process\n");
115 		_exit(exitval);
116 	}
117 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
118 
119 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
120 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
121 
122 	validate_status_stopped(status, sigval);
123 
124 	DPRINTF("Call GETDBREGS for the child process\n");
125 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, 0) != -1);
126 
127 	DPRINTF("State of the debug registers:\n");
128 	for (i = 0; i < __arraycount(r.dr); i++)
129 		DPRINTF("r[%zu]=%" PRIxREGISTER "\n", i, r.dr[i]);
130 
131 	DPRINTF("Before resuming the child process where it left off and "
132 	    "without signal to be sent\n");
133 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
134 
135 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
136 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
137 
138 	validate_status_exited(status, exitval);
139 
140 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
141 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
142 }
143 
144 
145 enum dbreg_preserve_mode {
146 	dbreg_preserve_mode_none,
147 	dbreg_preserve_mode_yield,
148 	dbreg_preserve_mode_continued
149 };
150 
151 static void
152 dbreg_preserve(int reg, enum dbreg_preserve_mode mode)
153 {
154 	const int exitval = 5;
155 	const int sigval = SIGSTOP;
156 	pid_t child, wpid;
157 #if defined(TWAIT_HAVE_STATUS)
158 	int status;
159 #endif
160 	struct dbreg r1;
161 	struct dbreg r2;
162 	size_t i;
163 	int watchme;
164 
165 	if (!can_we_set_dbregs()) {
166 		atf_tc_skip("Either run this test as root or set sysctl(3) "
167 		            "security.models.extensions.user_set_dbregs to 1");
168 	}
169 
170 	DPRINTF("Before forking process PID=%d\n", getpid());
171 	SYSCALL_REQUIRE((child = fork()) != -1);
172 	if (child == 0) {
173 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
174 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
175 
176 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
177 		FORKEE_ASSERT(raise(sigval) == 0);
178 
179 		if (mode == dbreg_preserve_mode_continued) {
180 			DPRINTF("Before raising %s from child\n",
181 			       strsignal(sigval));
182 			FORKEE_ASSERT(raise(sigval) == 0);
183 		}
184 
185 		DPRINTF("Before exiting of the child process\n");
186 		_exit(exitval);
187 	}
188 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
189 
190 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
191 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
192 
193 	validate_status_stopped(status, sigval);
194 
195 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
196 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
197 
198 	DPRINTF("State of the debug registers (r1):\n");
199 	for (i = 0; i < __arraycount(r1.dr); i++)
200 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
201 
202 	r1.dr[reg] = (long)(intptr_t)&watchme;
203 	DPRINTF("Set DR0 (r1.dr[%d]) to new value %" PRIxREGISTER "\n",
204 	    reg, r1.dr[reg]);
205 
206 	DPRINTF("New state of the debug registers (r1):\n");
207 	for (i = 0; i < __arraycount(r1.dr); i++)
208 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
209 
210 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
211 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
212 
213 	switch (mode) {
214 	case dbreg_preserve_mode_none:
215 		break;
216 	case dbreg_preserve_mode_yield:
217 		DPRINTF("Yields a processor voluntarily and gives other "
218 		       "threads a chance to run without waiting for an "
219 		       "involuntary preemptive switch\n");
220 		sched_yield();
221 		break;
222 	case dbreg_preserve_mode_continued:
223 		DPRINTF("Call CONTINUE for the child process\n");
224 	        SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
225 
226 		DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
227 		TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
228 
229 		validate_status_stopped(status, sigval);
230 		break;
231 	}
232 
233 	DPRINTF("Call GETDBREGS for the child process (r2)\n");
234 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1);
235 
236 	DPRINTF("Assert that (r1) and (r2) are the same\n");
237 	SYSCALL_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) == 0);
238 
239 	DPRINTF("Before resuming the child process where it left off and "
240 	    "without signal to be sent\n");
241 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
242 
243 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
244 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
245 
246 	validate_status_exited(status, exitval);
247 
248 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
249 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
250 }
251 
252 
253 ATF_TC(dbregs_preserve_dr0);
254 ATF_TC_HEAD(dbregs_preserve_dr0, tc)
255 {
256 	atf_tc_set_md_var(tc, "descr",
257 	    "Verify that setting DR0 is preserved across ptrace(2) calls");
258 }
259 
260 ATF_TC_BODY(dbregs_preserve_dr0, tc)
261 {
262 	dbreg_preserve(0, dbreg_preserve_mode_none);
263 }
264 
265 ATF_TC(dbregs_preserve_dr1);
266 ATF_TC_HEAD(dbregs_preserve_dr1, tc)
267 {
268 	atf_tc_set_md_var(tc, "descr",
269 	    "Verify that setting DR1 is preserved across ptrace(2) calls");
270 }
271 
272 ATF_TC_BODY(dbregs_preserve_dr1, tc)
273 {
274 	dbreg_preserve(1, dbreg_preserve_mode_none);
275 }
276 
277 ATF_TC(dbregs_preserve_dr2);
278 ATF_TC_HEAD(dbregs_preserve_dr2, tc)
279 {
280 	atf_tc_set_md_var(tc, "descr",
281 	    "Verify that setting DR2 is preserved across ptrace(2) calls");
282 }
283 
284 ATF_TC_BODY(dbregs_preserve_dr2, tc)
285 {
286 	dbreg_preserve(2, dbreg_preserve_mode_none);
287 }
288 
289 ATF_TC(dbregs_preserve_dr3);
290 ATF_TC_HEAD(dbregs_preserve_dr3, tc)
291 {
292 	atf_tc_set_md_var(tc, "descr",
293 	    "Verify that setting DR3 is preserved across ptrace(2) calls");
294 }
295 
296 ATF_TC_BODY(dbregs_preserve_dr3, tc)
297 {
298 	dbreg_preserve(3, dbreg_preserve_mode_none);
299 }
300 
301 ATF_TC(dbregs_preserve_dr0_yield);
302 ATF_TC_HEAD(dbregs_preserve_dr0_yield, tc)
303 {
304 	atf_tc_set_md_var(tc, "descr",
305 	    "Verify that setting DR0 is preserved across ptrace(2) calls with "
306 	    "scheduler yield");
307 }
308 
309 ATF_TC_BODY(dbregs_preserve_dr0_yield, tc)
310 {
311 	dbreg_preserve(0, dbreg_preserve_mode_yield);
312 }
313 
314 ATF_TC(dbregs_preserve_dr1_yield);
315 ATF_TC_HEAD(dbregs_preserve_dr1_yield, tc)
316 {
317 	atf_tc_set_md_var(tc, "descr",
318 	    "Verify that setting DR1 is preserved across ptrace(2) calls with "
319 	    "scheduler yield");
320 }
321 
322 ATF_TC_BODY(dbregs_preserve_dr1_yield, tc)
323 {
324 	dbreg_preserve(0, dbreg_preserve_mode_yield);
325 }
326 
327 ATF_TC(dbregs_preserve_dr2_yield);
328 ATF_TC_HEAD(dbregs_preserve_dr2_yield, tc)
329 {
330 	atf_tc_set_md_var(tc, "descr",
331 	    "Verify that setting DR2 is preserved across ptrace(2) calls with "
332 	    "scheduler yield");
333 }
334 
335 ATF_TC_BODY(dbregs_preserve_dr2_yield, tc)
336 {
337 	dbreg_preserve(0, dbreg_preserve_mode_yield);
338 }
339 
340 
341 ATF_TC(dbregs_preserve_dr3_yield);
342 ATF_TC_HEAD(dbregs_preserve_dr3_yield, tc)
343 {
344 	atf_tc_set_md_var(tc, "descr",
345 	    "Verify that setting DR3 is preserved across ptrace(2) calls with "
346 	    "scheduler yield");
347 }
348 
349 ATF_TC_BODY(dbregs_preserve_dr3_yield, tc)
350 {
351 	dbreg_preserve(3, dbreg_preserve_mode_yield);
352 }
353 
354 ATF_TC(dbregs_preserve_dr0_continued);
355 ATF_TC_HEAD(dbregs_preserve_dr0_continued, tc)
356 {
357 	atf_tc_set_md_var(tc, "descr",
358 	    "Verify that setting DR0 is preserved across ptrace(2) calls and "
359 	    "with continued child");
360 }
361 
362 ATF_TC_BODY(dbregs_preserve_dr0_continued, tc)
363 {
364 	dbreg_preserve(0, dbreg_preserve_mode_continued);
365 }
366 
367 ATF_TC(dbregs_preserve_dr1_continued);
368 ATF_TC_HEAD(dbregs_preserve_dr1_continued, tc)
369 {
370 	atf_tc_set_md_var(tc, "descr",
371 	    "Verify that setting DR1 is preserved across ptrace(2) calls and "
372 	    "with continued child");
373 }
374 
375 ATF_TC_BODY(dbregs_preserve_dr1_continued, tc)
376 {
377 	dbreg_preserve(1, dbreg_preserve_mode_continued);
378 }
379 
380 ATF_TC(dbregs_preserve_dr2_continued);
381 ATF_TC_HEAD(dbregs_preserve_dr2_continued, tc)
382 {
383 	atf_tc_set_md_var(tc, "descr",
384 	    "Verify that setting DR2 is preserved across ptrace(2) calls and "
385 	    "with continued child");
386 }
387 
388 ATF_TC_BODY(dbregs_preserve_dr2_continued, tc)
389 {
390 	dbreg_preserve(2, dbreg_preserve_mode_continued);
391 }
392 
393 ATF_TC(dbregs_preserve_dr3_continued);
394 ATF_TC_HEAD(dbregs_preserve_dr3_continued, tc)
395 {
396 	atf_tc_set_md_var(tc, "descr",
397 	    "Verify that setting DR3 is preserved across ptrace(2) calls and "
398 	    "with continued child");
399 }
400 
401 ATF_TC_BODY(dbregs_preserve_dr3_continued, tc)
402 {
403 	dbreg_preserve(3, dbreg_preserve_mode_continued);
404 }
405 
406 
407 static void
408 dbregs_trap_variable(int reg, int cond, int len, bool write)
409 {
410 	const int exitval = 5;
411 	const int sigval = SIGSTOP;
412 	pid_t child, wpid;
413 #if defined(TWAIT_HAVE_STATUS)
414 	int status;
415 #endif
416 	struct dbreg r1;
417 	size_t i;
418 	volatile int watchme = 0;
419 	union u dr7;
420 
421 	struct ptrace_siginfo info;
422 	memset(&info, 0, sizeof(info));
423 
424 	if (!can_we_set_dbregs()) {
425 		atf_tc_skip("Either run this test as root or set sysctl(3) "
426 		            "security.models.extensions.user_set_dbregs to 1");
427 	}
428 
429 	dr7.raw = 0;
430 	switch (reg) {
431 	case 0:
432 		dr7.bits.global_dr0_breakpoint = 1;
433 		dr7.bits.condition_dr0 = cond;
434 		dr7.bits.len_dr0 = len;
435 	case 1:
436 		dr7.bits.global_dr1_breakpoint = 1;
437 		dr7.bits.condition_dr1 = cond;
438 		dr7.bits.len_dr1 = len;
439 	case 2:
440 		dr7.bits.global_dr2_breakpoint = 1;
441 		dr7.bits.condition_dr2 = cond;
442 		dr7.bits.len_dr2 = len;
443 	case 3:
444 		dr7.bits.global_dr3_breakpoint = 1;
445 		dr7.bits.condition_dr3 = cond;
446 		dr7.bits.len_dr3 = len;
447 		break;
448 	}
449 
450 	DPRINTF("Before forking process PID=%d\n", getpid());
451 	SYSCALL_REQUIRE((child = fork()) != -1);
452 	if (child == 0) {
453 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
454 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
455 
456 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
457 		FORKEE_ASSERT(raise(sigval) == 0);
458 
459 		if (write)
460 			watchme = 1;
461 		else
462 			printf("watchme=%d\n", watchme);
463 
464 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
465 		FORKEE_ASSERT(raise(sigval) == 0);
466 
467 		DPRINTF("Before exiting of the child process\n");
468 		_exit(exitval);
469 	}
470 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
471 
472 	DPRINTF("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 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
478 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
479 
480 	DPRINTF("State of the debug registers (r1):\n");
481 	for (i = 0; i < __arraycount(r1.dr); i++)
482 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
483 
484 	r1.dr[reg] = (long)(intptr_t)&watchme;
485 	DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n",
486 	    reg, reg, r1.dr[reg]);
487 
488 	r1.dr[7] = dr7.raw;
489 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
490 	    r1.dr[7]);
491 
492 	DPRINTF("New state of the debug registers (r1):\n");
493 	for (i = 0; i < __arraycount(r1.dr); i++)
494 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
495 
496 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
497 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
498 
499 	DPRINTF("Call CONTINUE for the child process\n");
500 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
501 
502 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
503 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
504 
505 	validate_status_stopped(status, SIGTRAP);
506 
507 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
508 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
509 
510 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
511 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
512 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
513 	    info.psi_siginfo.si_errno);
514 
515 	DPRINTF("Before checking siginfo_t\n");
516 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
517 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG);
518 
519 	DPRINTF("Call CONTINUE for the child process\n");
520 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
521 
522 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
523 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
524 
525 	validate_status_stopped(status, sigval);
526 
527 	DPRINTF("Before resuming the child process where it left off and "
528 	    "without signal to be sent\n");
529 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
530 
531 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
532 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
533 
534 	validate_status_exited(status, exitval);
535 
536 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
537 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
538 }
539 
540 ATF_TC(dbregs_dr0_trap_variable_writeonly_byte);
541 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_byte, tc)
542 {
543 	atf_tc_set_md_var(tc, "descr",
544 	    "Verify that setting trap with DR0 triggers SIGTRAP "
545 	    "(break on data writes only and 1 byte mode)");
546 }
547 
548 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_byte, tc)
549 {
550 	/* 0b01 -- break on data write only */
551 	/* 0b00 -- 1 byte */
552 
553 	dbregs_trap_variable(0, 1, 0, true);
554 }
555 
556 ATF_TC(dbregs_dr1_trap_variable_writeonly_byte);
557 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_byte, tc)
558 {
559 	atf_tc_set_md_var(tc, "descr",
560 	    "Verify that setting trap with DR1 triggers SIGTRAP "
561 	    "(break on data writes only and 1 byte mode)");
562 }
563 
564 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_byte, tc)
565 {
566 	/* 0b01 -- break on data write only */
567 	/* 0b00 -- 1 byte */
568 
569 	dbregs_trap_variable(1, 1, 0, true);
570 }
571 
572 ATF_TC(dbregs_dr2_trap_variable_writeonly_byte);
573 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_byte, tc)
574 {
575 	atf_tc_set_md_var(tc, "descr",
576 	    "Verify that setting trap with DR2 triggers SIGTRAP "
577 	    "(break on data writes only and 1 byte mode)");
578 }
579 
580 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_byte, tc)
581 {
582 	/* 0b01 -- break on data write only */
583 	/* 0b00 -- 1 byte */
584 
585 	dbregs_trap_variable(2, 1, 0, true);
586 }
587 
588 ATF_TC(dbregs_dr3_trap_variable_writeonly_byte);
589 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_byte, tc)
590 {
591 	atf_tc_set_md_var(tc, "descr",
592 	    "Verify that setting trap with DR3 triggers SIGTRAP "
593 	    "(break on data writes only and 1 byte mode)");
594 }
595 
596 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_byte, tc)
597 {
598 	/* 0b01 -- break on data write only */
599 	/* 0b00 -- 1 byte */
600 
601 	dbregs_trap_variable(3, 1, 0, true);
602 }
603 
604 ATF_TC(dbregs_dr0_trap_variable_writeonly_2bytes);
605 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_2bytes, tc)
606 {
607 	atf_tc_set_md_var(tc, "descr",
608 	    "Verify that setting trap with DR0 triggers SIGTRAP "
609 	    "(break on data writes only and 2 bytes mode)");
610 }
611 
612 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_2bytes, tc)
613 {
614 	/* 0b01 -- break on data write only */
615 	/* 0b01 -- 2 bytes */
616 
617 	dbregs_trap_variable(0, 1, 1, true);
618 }
619 
620 ATF_TC(dbregs_dr1_trap_variable_writeonly_2bytes);
621 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_2bytes, tc)
622 {
623 	atf_tc_set_md_var(tc, "descr",
624 	    "Verify that setting trap with DR1 triggers SIGTRAP "
625 	    "(break on data writes only and 2 bytes mode)");
626 }
627 
628 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_2bytes, tc)
629 {
630 	/* 0b01 -- break on data write only */
631 	/* 0b01 -- 2 bytes */
632 
633 	dbregs_trap_variable(1, 1, 1, true);
634 }
635 
636 ATF_TC(dbregs_dr2_trap_variable_writeonly_2bytes);
637 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_2bytes, tc)
638 {
639 	atf_tc_set_md_var(tc, "descr",
640 	    "Verify that setting trap with DR2 triggers SIGTRAP "
641 	    "(break on data writes only and 2 bytes mode)");
642 }
643 
644 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_2bytes, tc)
645 {
646 	/* 0b01 -- break on data write only */
647 	/* 0b01 -- 2 bytes */
648 
649 	dbregs_trap_variable(2, 1, 1, true);
650 }
651 
652 ATF_TC(dbregs_dr3_trap_variable_writeonly_2bytes);
653 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_2bytes, tc)
654 {
655 	atf_tc_set_md_var(tc, "descr",
656 	    "Verify that setting trap with DR3 triggers SIGTRAP "
657 	    "(break on data writes only and 2 bytes mode)");
658 }
659 
660 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_2bytes, tc)
661 {
662 	/* 0b01 -- break on data write only */
663 	/* 0b01 -- 2 bytes */
664 
665 	dbregs_trap_variable(3, 1, 1, true);
666 }
667 
668 ATF_TC(dbregs_dr0_trap_variable_writeonly_4bytes);
669 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_4bytes, tc)
670 {
671 	atf_tc_set_md_var(tc, "descr",
672 	    "Verify that setting trap with DR0 triggers SIGTRAP "
673 	    "(break on data writes only and 4 bytes mode)");
674 }
675 
676 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_4bytes, tc)
677 {
678 	/* 0b01 -- break on data write only */
679 	/* 0b11 -- 4 bytes */
680 
681 	dbregs_trap_variable(0, 1, 3, true);
682 }
683 
684 ATF_TC(dbregs_dr1_trap_variable_writeonly_4bytes);
685 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_4bytes, tc)
686 {
687 	atf_tc_set_md_var(tc, "descr",
688 	    "Verify that setting trap with DR1 triggers SIGTRAP "
689 	    "(break on data writes only and 4 bytes mode)");
690 }
691 
692 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_4bytes, tc)
693 {
694 	/* 0b01 -- break on data write only */
695 	/* 0b11 -- 4 bytes */
696 
697 	dbregs_trap_variable(1, 1, 3, true);
698 }
699 
700 ATF_TC(dbregs_dr2_trap_variable_writeonly_4bytes);
701 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_4bytes, tc)
702 {
703 	atf_tc_set_md_var(tc, "descr",
704 	    "Verify that setting trap with DR2 triggers SIGTRAP "
705 	    "(break on data writes only and 4 bytes mode)");
706 }
707 
708 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_4bytes, tc)
709 {
710 	/* 0b01 -- break on data write only */
711 	/* 0b11 -- 4 bytes */
712 
713 	dbregs_trap_variable(2, 1, 3, true);
714 }
715 
716 ATF_TC(dbregs_dr3_trap_variable_writeonly_4bytes);
717 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_4bytes, tc)
718 {
719 	atf_tc_set_md_var(tc, "descr",
720 	    "Verify that setting trap with DR3 triggers SIGTRAP "
721 	    "(break on data writes only and 4 bytes mode)");
722 }
723 
724 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_4bytes, tc)
725 {
726 	/* 0b01 -- break on data write only */
727 	/* 0b11 -- 4 bytes */
728 
729 	dbregs_trap_variable(3, 1, 3, true);
730 }
731 
732 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_byte);
733 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_byte, tc)
734 {
735 	atf_tc_set_md_var(tc, "descr",
736 	    "Verify that setting trap with DR0 triggers SIGTRAP "
737 	    "(break on data read/write trap in read 1 byte mode)");
738 }
739 
740 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_byte, tc)
741 {
742 	/* 0b11 -- break on data write&read */
743 	/* 0b00 -- 1 byte */
744 
745 	dbregs_trap_variable(0, 3, 0, true);
746 }
747 
748 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_byte);
749 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_byte, tc)
750 {
751 	atf_tc_set_md_var(tc, "descr",
752 	    "Verify that setting trap with DR1 triggers SIGTRAP "
753 	    "(break on data read/write trap in read 1 byte mode)");
754 }
755 
756 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_byte, tc)
757 {
758 	/* 0b11 -- break on data write&read */
759 	/* 0b00 -- 1 byte */
760 
761 	dbregs_trap_variable(1, 3, 0, true);
762 }
763 
764 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_byte);
765 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_byte, tc)
766 {
767 	atf_tc_set_md_var(tc, "descr",
768 	    "Verify that setting trap with DR2 triggers SIGTRAP "
769 	    "(break on data read/write trap in read 1 byte mode)");
770 }
771 
772 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_byte, tc)
773 {
774 	/* 0b11 -- break on data write&read */
775 	/* 0b00 -- 1 byte */
776 
777 	dbregs_trap_variable(2, 3, 0, true);
778 }
779 
780 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_byte);
781 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_byte, tc)
782 {
783 	atf_tc_set_md_var(tc, "descr",
784 	    "Verify that setting trap with DR3 triggers SIGTRAP "
785 	    "(break on data read/write trap in read 1 byte mode)");
786 }
787 
788 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_byte, tc)
789 {
790 	/* 0b11 -- break on data write&read */
791 	/* 0b00 -- 1 byte */
792 
793 	dbregs_trap_variable(3, 3, 0, true);
794 }
795 
796 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_2bytes);
797 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc)
798 {
799 	atf_tc_set_md_var(tc, "descr",
800 	    "Verify that setting trap with DR0 triggers SIGTRAP "
801 	    "(break on data read/write trap in read 2 bytes mode)");
802 }
803 
804 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc)
805 {
806 	/* 0b11 -- break on data write&read */
807 	/* 0b01 -- 2 bytes */
808 
809 	dbregs_trap_variable(0, 3, 1, true);
810 }
811 
812 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_2bytes);
813 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc)
814 {
815 	atf_tc_set_md_var(tc, "descr",
816 	    "Verify that setting trap with DR1 triggers SIGTRAP "
817 	    "(break on data read/write trap in read 2 bytes mode)");
818 }
819 
820 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc)
821 {
822 	/* 0b11 -- break on data write&read */
823 	/* 0b01 -- 2 bytes */
824 
825 	dbregs_trap_variable(1, 3, 1, true);
826 }
827 
828 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_2bytes);
829 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc)
830 {
831 	atf_tc_set_md_var(tc, "descr",
832 	    "Verify that setting trap with DR2 triggers SIGTRAP "
833 	    "(break on data read/write trap in read 2 bytes mode)");
834 }
835 
836 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc)
837 {
838 	/* 0b11 -- break on data write&read */
839 	/* 0b01 -- 2 bytes */
840 
841 	dbregs_trap_variable(2, 3, 1, true);
842 }
843 
844 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_2bytes);
845 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc)
846 {
847 	atf_tc_set_md_var(tc, "descr",
848 	    "Verify that setting trap with DR3 triggers SIGTRAP "
849 	    "(break on data read/write trap in read 2 bytes mode)");
850 }
851 
852 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc)
853 {
854 	/* 0b11 -- break on data write&read */
855 	/* 0b01 -- 2 bytes */
856 
857 	dbregs_trap_variable(3, 3, 1, true);
858 }
859 
860 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_4bytes);
861 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc)
862 {
863 	atf_tc_set_md_var(tc, "descr",
864 	    "Verify that setting trap with DR0 triggers SIGTRAP "
865 	    "(break on data read/write trap in read 4 bytes mode)");
866 }
867 
868 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc)
869 {
870 	/* 0b11 -- break on data write&read */
871 	/* 0b11 -- 4 bytes */
872 
873 	dbregs_trap_variable(0, 3, 3, true);
874 }
875 
876 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_4bytes);
877 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc)
878 {
879 	atf_tc_set_md_var(tc, "descr",
880 	    "Verify that setting trap with DR1 triggers SIGTRAP "
881 	    "(break on data read/write trap in read 4 bytes mode)");
882 }
883 
884 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc)
885 {
886 	/* 0b11 -- break on data write&read */
887 	/* 0b11 -- 4 bytes */
888 
889 	dbregs_trap_variable(1, 3, 3, true);
890 }
891 
892 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_4bytes);
893 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc)
894 {
895 	atf_tc_set_md_var(tc, "descr",
896 	    "Verify that setting trap with DR2 triggers SIGTRAP "
897 	    "(break on data read/write trap in read 4 bytes mode)");
898 }
899 
900 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc)
901 {
902 	/* 0b11 -- break on data write&read */
903 	/* 0b11 -- 4 bytes */
904 
905 	dbregs_trap_variable(2, 3, 3, true);
906 }
907 
908 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_4bytes);
909 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc)
910 {
911 	atf_tc_set_md_var(tc, "descr",
912 	    "Verify that setting trap with DR3 triggers SIGTRAP "
913 	    "(break on data read/write trap in read 4 bytes mode)");
914 }
915 
916 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc)
917 {
918 	/* 0b11 -- break on data write&read */
919 	/* 0b11 -- 4 bytes */
920 
921 	dbregs_trap_variable(3, 3, 3, true);
922 }
923 
924 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_byte);
925 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_byte, tc)
926 {
927 	atf_tc_set_md_var(tc, "descr",
928 	    "Verify that setting trap with DR0 triggers SIGTRAP "
929 	    "(break on data read/write trap in write 1 byte mode)");
930 }
931 
932 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_byte, tc)
933 {
934 	/* 0b11 -- break on data write&read */
935 	/* 0b00 -- 1 byte */
936 
937 	dbregs_trap_variable(0, 3, 0, false);
938 }
939 
940 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_byte);
941 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_byte, tc)
942 {
943 	atf_tc_set_md_var(tc, "descr",
944 	    "Verify that setting trap with DR1 triggers SIGTRAP "
945 	    "(break on data read/write trap in write 1 byte mode)");
946 }
947 
948 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_byte, tc)
949 {
950 	/* 0b11 -- break on data write&read */
951 	/* 0b00 -- 1 byte */
952 
953 	dbregs_trap_variable(1, 3, 0, false);
954 }
955 
956 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_byte);
957 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_byte, tc)
958 {
959 	atf_tc_set_md_var(tc, "descr",
960 	    "Verify that setting trap with DR2 triggers SIGTRAP "
961 	    "(break on data read/write trap in write 1 byte mode)");
962 }
963 
964 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_byte, tc)
965 {
966 	/* 0b11 -- break on data write&read */
967 	/* 0b00 -- 1 byte */
968 
969 	dbregs_trap_variable(2, 3, 0, false);
970 }
971 
972 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_byte);
973 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_byte, tc)
974 {
975 	atf_tc_set_md_var(tc, "descr",
976 	    "Verify that setting trap with DR3 triggers SIGTRAP "
977 	    "(break on data read/write trap in write 1 byte mode)");
978 }
979 
980 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_byte, tc)
981 {
982 	/* 0b11 -- break on data write&read */
983 	/* 0b00 -- 1 byte */
984 
985 	dbregs_trap_variable(3, 3, 0, false);
986 }
987 
988 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_2bytes);
989 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc)
990 {
991 	atf_tc_set_md_var(tc, "descr",
992 	    "Verify that setting trap with DR0 triggers SIGTRAP "
993 	    "(break on data read/write trap in write 2 bytes mode)");
994 }
995 
996 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc)
997 {
998 	/* 0b11 -- break on data write&read */
999 	/* 0b01 -- 2 bytes */
1000 
1001 	dbregs_trap_variable(0, 3, 1, false);
1002 }
1003 
1004 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_2bytes);
1005 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc)
1006 {
1007 	atf_tc_set_md_var(tc, "descr",
1008 	    "Verify that setting trap with DR1 triggers SIGTRAP "
1009 	    "(break on data read/write trap in write 2 bytes mode)");
1010 }
1011 
1012 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc)
1013 {
1014 	/* 0b11 -- break on data write&read */
1015 	/* 0b01 -- 2 bytes */
1016 
1017 	dbregs_trap_variable(1, 3, 1, false);
1018 }
1019 
1020 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_2bytes);
1021 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc)
1022 {
1023 	atf_tc_set_md_var(tc, "descr",
1024 	    "Verify that setting trap with DR2 triggers SIGTRAP "
1025 	    "(break on data read/write trap in write 2 bytes mode)");
1026 }
1027 
1028 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc)
1029 {
1030 	/* 0b11 -- break on data write&read */
1031 	/* 0b01 -- 2 bytes */
1032 
1033 	dbregs_trap_variable(2, 3, 1, false);
1034 }
1035 
1036 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_2bytes);
1037 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc)
1038 {
1039 	atf_tc_set_md_var(tc, "descr",
1040 	    "Verify that setting trap with DR3 triggers SIGTRAP "
1041 	    "(break on data read/write trap in write 2 bytes mode)");
1042 }
1043 
1044 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc)
1045 {
1046 	/* 0b11 -- break on data write&read */
1047 	/* 0b01 -- 2 bytes */
1048 
1049 	dbregs_trap_variable(3, 3, 1, false);
1050 }
1051 
1052 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_4bytes);
1053 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc)
1054 {
1055 	atf_tc_set_md_var(tc, "descr",
1056 	    "Verify that setting trap with DR0 triggers SIGTRAP "
1057 	    "(break on data read/write trap in write 4 bytes mode)");
1058 }
1059 
1060 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc)
1061 {
1062 	/* 0b11 -- break on data write&read */
1063 	/* 0b11 -- 4 bytes */
1064 
1065 	dbregs_trap_variable(0, 3, 3, false);
1066 }
1067 
1068 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_4bytes);
1069 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc)
1070 {
1071 	atf_tc_set_md_var(tc, "descr",
1072 	    "Verify that setting trap with DR1 triggers SIGTRAP "
1073 	    "(break on data read/write trap in write 4 bytes mode)");
1074 }
1075 
1076 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc)
1077 {
1078 	/* 0b11 -- break on data write&read */
1079 	/* 0b11 -- 4 bytes */
1080 
1081 	dbregs_trap_variable(1, 3, 3, false);
1082 }
1083 
1084 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_4bytes);
1085 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc)
1086 {
1087 	atf_tc_set_md_var(tc, "descr",
1088 	    "Verify that setting trap with DR2 triggers SIGTRAP "
1089 	    "(break on data read/write trap in write 4 bytes mode)");
1090 }
1091 
1092 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc)
1093 {
1094 	/* 0b11 -- break on data write&read */
1095 	/* 0b11 -- 4 bytes */
1096 
1097 	dbregs_trap_variable(2, 3, 3, false);
1098 }
1099 
1100 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_4bytes);
1101 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc)
1102 {
1103 	atf_tc_set_md_var(tc, "descr",
1104 	    "Verify that setting trap with DR3 triggers SIGTRAP "
1105 	    "(break on data read/write trap in write 4 bytes mode)");
1106 }
1107 
1108 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc)
1109 {
1110 	/* 0b11 -- break on data write&read */
1111 	/* 0b11 -- 4 bytes */
1112 
1113 	dbregs_trap_variable(3, 3, 3, false);
1114 }
1115 
1116 #if defined(HAVE_DBREGS)
1117 ATF_TC(dbregs_dr0_trap_code);
1118 ATF_TC_HEAD(dbregs_dr0_trap_code, tc)
1119 {
1120 	atf_tc_set_md_var(tc, "descr",
1121 	    "Verify that setting trap with DR0 triggers SIGTRAP "
1122 	    "(break on code execution trap)");
1123 }
1124 
1125 ATF_TC_BODY(dbregs_dr0_trap_code, tc)
1126 {
1127 	const int exitval = 5;
1128 	const int sigval = SIGSTOP;
1129 	pid_t child, wpid;
1130 #if defined(TWAIT_HAVE_STATUS)
1131 	int status;
1132 #endif
1133 	struct dbreg r1;
1134 	size_t i;
1135 	volatile int watchme = 1;
1136 	union u dr7;
1137 
1138 	struct ptrace_siginfo info;
1139 	memset(&info, 0, sizeof(info));
1140 
1141 	if (!can_we_set_dbregs()) {
1142 		atf_tc_skip("Either run this test as root or set sysctl(3) "
1143 		            "security.models.extensions.user_set_dbregs to 1");
1144 	}
1145 
1146 	dr7.raw = 0;
1147 	dr7.bits.global_dr0_breakpoint = 1;
1148 	dr7.bits.condition_dr0 = 0;	/* 0b00 -- break on code execution */
1149 	dr7.bits.len_dr0 = 0;		/* 0b00 -- 1 byte */
1150 
1151 	DPRINTF("Before forking process PID=%d\n", getpid());
1152 	SYSCALL_REQUIRE((child = fork()) != -1);
1153 	if (child == 0) {
1154 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1155 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1156 
1157 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1158 		FORKEE_ASSERT(raise(sigval) == 0);
1159 
1160 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
1161 
1162 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1163 		FORKEE_ASSERT(raise(sigval) == 0);
1164 
1165 		DPRINTF("Before exiting of the child process\n");
1166 		_exit(exitval);
1167 	}
1168 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1169 
1170 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1171 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1172 
1173 	validate_status_stopped(status, sigval);
1174 
1175 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
1176 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
1177 
1178 	DPRINTF("State of the debug registers (r1):\n");
1179 	for (i = 0; i < __arraycount(r1.dr); i++)
1180 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1181 
1182 	r1.dr[0] = (long)(intptr_t)check_happy;
1183 	DPRINTF("Set DR0 (r1.dr[0]) to new value %" PRIxREGISTER "\n",
1184 	    r1.dr[0]);
1185 
1186 	r1.dr[7] = dr7.raw;
1187 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1188 	    r1.dr[7]);
1189 
1190 	DPRINTF("New state of the debug registers (r1):\n");
1191 	for (i = 0; i < __arraycount(r1.dr); i++)
1192 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1193 
1194 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1195 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1196 
1197 	DPRINTF("Call CONTINUE for the child process\n");
1198 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1199 
1200 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1201 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1202 
1203 	validate_status_stopped(status, SIGTRAP);
1204 
1205 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1206 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1207 
1208 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1209 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1210 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1211 	    info.psi_siginfo.si_errno);
1212 
1213 	DPRINTF("Before checking siginfo_t\n");
1214 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1215 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG);
1216 
1217 	DPRINTF("Remove code trap from check_happy=%p\n", check_happy);
1218 	dr7.bits.global_dr0_breakpoint = 0;
1219 	r1.dr[7] = dr7.raw;
1220 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1221 	    r1.dr[7]);
1222 
1223 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1224 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1225 
1226 	DPRINTF("Call CONTINUE for the child process\n");
1227 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1228 
1229 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1230 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1231 
1232 	validate_status_stopped(status, sigval);
1233 
1234 	DPRINTF("Before resuming the child process where it left off and "
1235 	    "without signal to be sent\n");
1236 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1237 
1238 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1239 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1240 
1241 	validate_status_exited(status, exitval);
1242 
1243 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1244 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1245 }
1246 #endif
1247 
1248 #if defined(HAVE_DBREGS)
1249 ATF_TC(dbregs_dr1_trap_code);
1250 ATF_TC_HEAD(dbregs_dr1_trap_code, tc)
1251 {
1252 	atf_tc_set_md_var(tc, "descr",
1253 	    "Verify that setting trap with DR1 triggers SIGTRAP "
1254 	    "(break on code execution trap)");
1255 }
1256 
1257 ATF_TC_BODY(dbregs_dr1_trap_code, tc)
1258 {
1259 	const int exitval = 5;
1260 	const int sigval = SIGSTOP;
1261 	pid_t child, wpid;
1262 #if defined(TWAIT_HAVE_STATUS)
1263 	int status;
1264 #endif
1265 	struct dbreg r1;
1266 	size_t i;
1267 	volatile int watchme = 1;
1268 	union u dr7;
1269 
1270 	struct ptrace_siginfo info;
1271 	memset(&info, 0, sizeof(info));
1272 
1273 	if (!can_we_set_dbregs()) {
1274 		atf_tc_skip("Either run this test as root or set sysctl(3) "
1275 		            "security.models.extensions.user_set_dbregs to 1");
1276 	}
1277 
1278 	dr7.raw = 0;
1279 	dr7.bits.global_dr1_breakpoint = 1;
1280 	dr7.bits.condition_dr1 = 0;	/* 0b00 -- break on code execution */
1281 	dr7.bits.len_dr1 = 0;		/* 0b00 -- 1 byte */
1282 
1283 	DPRINTF("Before forking process PID=%d\n", getpid());
1284 	SYSCALL_REQUIRE((child = fork()) != -1);
1285 	if (child == 0) {
1286 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1287 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1288 
1289 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1290 		FORKEE_ASSERT(raise(sigval) == 0);
1291 
1292 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
1293 
1294 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1295 		FORKEE_ASSERT(raise(sigval) == 0);
1296 
1297 		DPRINTF("Before exiting of the child process\n");
1298 		_exit(exitval);
1299 	}
1300 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1301 
1302 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1303 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1304 
1305 	validate_status_stopped(status, sigval);
1306 
1307 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
1308 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
1309 
1310 	DPRINTF("State of the debug registers (r1):\n");
1311 	for (i = 0; i < __arraycount(r1.dr); i++)
1312 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1313 
1314 	r1.dr[1] = (long)(intptr_t)check_happy;
1315 	DPRINTF("Set DR1 (r1.dr[1]) to new value %" PRIxREGISTER "\n",
1316 	    r1.dr[1]);
1317 
1318 	r1.dr[7] = dr7.raw;
1319 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1320 	    r1.dr[7]);
1321 
1322 	DPRINTF("New state of the debug registers (r1):\n");
1323 	for (i = 0; i < __arraycount(r1.dr); i++)
1324 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1325 
1326 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1327 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1328 
1329 	DPRINTF("Call CONTINUE for the child process\n");
1330 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1331 
1332 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1333 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1334 
1335 	validate_status_stopped(status, SIGTRAP);
1336 
1337 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1338 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1339 
1340 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1341 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1342 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1343 	    info.psi_siginfo.si_errno);
1344 
1345 	DPRINTF("Before checking siginfo_t\n");
1346 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1347 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG);
1348 
1349 	DPRINTF("Remove code trap from check_happy=%p\n", check_happy);
1350 	dr7.bits.global_dr1_breakpoint = 0;
1351 	r1.dr[7] = dr7.raw;
1352 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1353 	    r1.dr[7]);
1354 
1355 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1356 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1357 
1358 	DPRINTF("Call CONTINUE for the child process\n");
1359 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1360 
1361 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1362 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1363 
1364 	validate_status_stopped(status, sigval);
1365 
1366 	DPRINTF("Before resuming the child process where it left off and "
1367 	    "without signal to be sent\n");
1368 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1369 
1370 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1371 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1372 
1373 	validate_status_exited(status, exitval);
1374 
1375 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1376 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1377 }
1378 #endif
1379 
1380 #if defined(HAVE_DBREGS)
1381 ATF_TC(dbregs_dr2_trap_code);
1382 ATF_TC_HEAD(dbregs_dr2_trap_code, tc)
1383 {
1384 	atf_tc_set_md_var(tc, "descr",
1385 	    "Verify that setting trap with DR2 triggers SIGTRAP "
1386 	    "(break on code execution trap)");
1387 }
1388 
1389 ATF_TC_BODY(dbregs_dr2_trap_code, tc)
1390 {
1391 	const int exitval = 5;
1392 	const int sigval = SIGSTOP;
1393 	pid_t child, wpid;
1394 #if defined(TWAIT_HAVE_STATUS)
1395 	int status;
1396 #endif
1397 	struct dbreg r1;
1398 	size_t i;
1399 	volatile int watchme = 1;
1400 	union u dr7;
1401 
1402 	struct ptrace_siginfo info;
1403 	memset(&info, 0, sizeof(info));
1404 
1405 	if (!can_we_set_dbregs()) {
1406 		atf_tc_skip("Either run this test as root or set sysctl(3) "
1407 		            "security.models.extensions.user_set_dbregs to 1");
1408 	}
1409 
1410 	dr7.raw = 0;
1411 	dr7.bits.global_dr2_breakpoint = 1;
1412 	dr7.bits.condition_dr2 = 0;	/* 0b00 -- break on code execution */
1413 	dr7.bits.len_dr2 = 0;		/* 0b00 -- 1 byte */
1414 
1415 	DPRINTF("Before forking process PID=%d\n", getpid());
1416 	SYSCALL_REQUIRE((child = fork()) != -1);
1417 	if (child == 0) {
1418 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1419 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1420 
1421 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1422 		FORKEE_ASSERT(raise(sigval) == 0);
1423 
1424 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
1425 
1426 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1427 		FORKEE_ASSERT(raise(sigval) == 0);
1428 
1429 		DPRINTF("Before exiting of the child process\n");
1430 		_exit(exitval);
1431 	}
1432 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1433 
1434 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1435 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1436 
1437 	validate_status_stopped(status, sigval);
1438 
1439 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
1440 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
1441 
1442 	DPRINTF("State of the debug registers (r1):\n");
1443 	for (i = 0; i < __arraycount(r1.dr); i++)
1444 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1445 
1446 	r1.dr[2] = (long)(intptr_t)check_happy;
1447 	DPRINTF("Set DR2 (r1.dr[2]) to new value %" PRIxREGISTER "\n",
1448 	    r1.dr[2]);
1449 
1450 	r1.dr[7] = dr7.raw;
1451 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1452 	    r1.dr[7]);
1453 
1454 	DPRINTF("New state of the debug registers (r1):\n");
1455 	for (i = 0; i < __arraycount(r1.dr); i++)
1456 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1457 
1458 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1459 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1460 
1461 	DPRINTF("Call CONTINUE for the child process\n");
1462 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1463 
1464 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1465 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1466 
1467 	validate_status_stopped(status, SIGTRAP);
1468 
1469 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1470 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1471 
1472 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1473 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1474 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1475 	    info.psi_siginfo.si_errno);
1476 
1477 	DPRINTF("Before checking siginfo_t\n");
1478 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1479 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG);
1480 
1481 	DPRINTF("Remove code trap from check_happy=%p\n", check_happy);
1482 	dr7.bits.global_dr2_breakpoint = 0;
1483 	r1.dr[7] = dr7.raw;
1484 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1485 	    r1.dr[7]);
1486 
1487 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1488 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1489 
1490 	DPRINTF("Call CONTINUE for the child process\n");
1491 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1492 
1493 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1494 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1495 
1496 	validate_status_stopped(status, sigval);
1497 
1498 	DPRINTF("Before resuming the child process where it left off and "
1499 	    "without signal to be sent\n");
1500 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1501 
1502 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1503 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1504 
1505 	validate_status_exited(status, exitval);
1506 
1507 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1508 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1509 }
1510 #endif
1511 
1512 #if defined(HAVE_DBREGS)
1513 ATF_TC(dbregs_dr3_trap_code);
1514 ATF_TC_HEAD(dbregs_dr3_trap_code, tc)
1515 {
1516 	atf_tc_set_md_var(tc, "descr",
1517 	    "Verify that setting trap with DR3 triggers SIGTRAP "
1518 	    "(break on code execution trap)");
1519 }
1520 
1521 ATF_TC_BODY(dbregs_dr3_trap_code, tc)
1522 {
1523 	const int exitval = 5;
1524 	const int sigval = SIGSTOP;
1525 	pid_t child, wpid;
1526 #if defined(TWAIT_HAVE_STATUS)
1527 	int status;
1528 #endif
1529 	struct dbreg r1;
1530 	size_t i;
1531 	volatile int watchme = 1;
1532 	union u dr7;
1533 
1534 	struct ptrace_siginfo info;
1535 	memset(&info, 0, sizeof(info));
1536 
1537 	if (!can_we_set_dbregs()) {
1538 		atf_tc_skip("Either run this test as root or set sysctl(3) "
1539 		            "security.models.extensions.user_set_dbregs to 1");
1540 	}
1541 
1542 	dr7.raw = 0;
1543 	dr7.bits.global_dr3_breakpoint = 1;
1544 	dr7.bits.condition_dr3 = 0;	/* 0b00 -- break on code execution */
1545 	dr7.bits.len_dr3 = 0;		/* 0b00 -- 1 byte */
1546 
1547 	DPRINTF("Before forking process PID=%d\n", getpid());
1548 	SYSCALL_REQUIRE((child = fork()) != -1);
1549 	if (child == 0) {
1550 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1551 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1552 
1553 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1554 		FORKEE_ASSERT(raise(sigval) == 0);
1555 
1556 		printf("check_happy(%d)=%d\n", watchme, check_happy(watchme));
1557 
1558 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1559 		FORKEE_ASSERT(raise(sigval) == 0);
1560 
1561 		DPRINTF("Before exiting of the child process\n");
1562 		_exit(exitval);
1563 	}
1564 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1565 
1566 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1567 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1568 
1569 	validate_status_stopped(status, sigval);
1570 
1571 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
1572 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
1573 
1574 	DPRINTF("State of the debug registers (r1):\n");
1575 	for (i = 0; i < __arraycount(r1.dr); i++)
1576 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1577 
1578 	r1.dr[3] = (long)(intptr_t)check_happy;
1579 	DPRINTF("Set DR3 (r1.dr[3]) to new value %" PRIxREGISTER "\n",
1580 	    r1.dr[3]);
1581 
1582 	r1.dr[7] = dr7.raw;
1583 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1584 	    r1.dr[7]);
1585 
1586 	DPRINTF("New state of the debug registers (r1):\n");
1587 	for (i = 0; i < __arraycount(r1.dr); i++)
1588 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1589 
1590 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1591 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1592 
1593 	DPRINTF("Call CONTINUE for the child process\n");
1594 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1595 
1596 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1597 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1598 
1599 	validate_status_stopped(status, SIGTRAP);
1600 
1601 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1602 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1603 
1604 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1605 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1606 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1607 	    info.psi_siginfo.si_errno);
1608 
1609 	DPRINTF("Before checking siginfo_t\n");
1610 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP);
1611 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG);
1612 
1613 	DPRINTF("Remove code trap from check_happy=%p\n", check_happy);
1614 	dr7.bits.global_dr3_breakpoint = 0;
1615 	r1.dr[7] = dr7.raw;
1616 	DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n",
1617 	    r1.dr[7]);
1618 
1619 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1620 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1621 
1622 	DPRINTF("Call CONTINUE for the child process\n");
1623 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1624 
1625 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1626 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1627 
1628 	validate_status_stopped(status, sigval);
1629 
1630 	DPRINTF("Before resuming the child process where it left off and "
1631 	    "without signal to be sent\n");
1632 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1633 
1634 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1635 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1636 
1637 	validate_status_exited(status, exitval);
1638 
1639 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1640 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1641 }
1642 #endif
1643 
1644 volatile lwpid_t x86_the_lwp_id = 0;
1645 
1646 static void __used
1647 x86_lwp_main_func(void *arg)
1648 {
1649 	x86_the_lwp_id = _lwp_self();
1650 	_lwp_exit();
1651 }
1652 
1653 static void
1654 dbregs_dont_inherit_lwp(int reg)
1655 {
1656 	const int exitval = 5;
1657 	const int sigval = SIGSTOP;
1658 	pid_t child, wpid;
1659 #if defined(TWAIT_HAVE_STATUS)
1660 	int status;
1661 #endif
1662 	ptrace_state_t state;
1663 	const int slen = sizeof(state);
1664 	ptrace_event_t event;
1665 	const int elen = sizeof(event);
1666 	ucontext_t uc;
1667 	lwpid_t lid;
1668 	static const size_t ssize = 16*1024;
1669 	void *stack;
1670 	size_t i;
1671 	struct dbreg r1;
1672 	struct dbreg r2;
1673 
1674 	if (!can_we_set_dbregs()) {
1675 		atf_tc_skip("Either run this test as root or set sysctl(3) "
1676 		            "security.models.extensions.user_set_dbregs to 1");
1677 	}
1678 
1679 	DPRINTF("Before forking process PID=%d\n", getpid());
1680 	SYSCALL_REQUIRE((child = fork()) != -1);
1681 	if (child == 0) {
1682 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1683 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1684 
1685 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1686 		FORKEE_ASSERT(raise(sigval) == 0);
1687 
1688 		DPRINTF("Before allocating memory for stack in child\n");
1689 		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
1690 
1691 		DPRINTF("Before making context for new lwp in child\n");
1692 		_lwp_makecontext(&uc, x86_lwp_main_func, NULL, NULL, stack,
1693 		    ssize);
1694 
1695 		DPRINTF("Before creating new in child\n");
1696 		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
1697 
1698 		DPRINTF("Before waiting for lwp %d to exit\n", lid);
1699 		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
1700 
1701 		DPRINTF("Before verifying that reported %d and running lid %d "
1702 		    "are the same\n", lid, x86_the_lwp_id);
1703 		FORKEE_ASSERT_EQ(lid, x86_the_lwp_id);
1704 
1705 		DPRINTF("Before exiting of the child process\n");
1706 		_exit(exitval);
1707 	}
1708 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1709 
1710 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1711 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1712 
1713 	validate_status_stopped(status, sigval);
1714 
1715 	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
1716 	event.pe_set_event = PTRACE_LWP_CREATE;
1717 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
1718 
1719 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
1720 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
1721 
1722 	DPRINTF("State of the debug registers (r1):\n");
1723 	for (i = 0; i < __arraycount(r1.dr); i++)
1724 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1725 
1726 	r1.dr[reg] = (long)(intptr_t)check_happy;
1727 	DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n",
1728 	    reg, reg, r1.dr[0]);
1729 
1730 	DPRINTF("New state of the debug registers (r1):\n");
1731 	for (i = 0; i < __arraycount(r1.dr); i++)
1732 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1733 
1734 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1735 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1736 
1737 	DPRINTF("Before resuming the child process where it left off and "
1738 	    "without signal to be sent\n");
1739 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1740 
1741 	DPRINTF("Before calling %s() for the child - expected stopped "
1742 	    "SIGTRAP\n", TWAIT_FNAME);
1743 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1744 
1745 	validate_status_stopped(status, SIGTRAP);
1746 
1747 	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
1748 
1749 	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
1750 
1751 	lid = state.pe_lwp;
1752 	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
1753 
1754 	DPRINTF("Call GETDBREGS for the child process new lwp (r2)\n");
1755 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, lid) != -1);
1756 
1757 	DPRINTF("State of the debug registers (r2):\n");
1758 	for (i = 0; i < __arraycount(r2.dr); i++)
1759 		DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]);
1760 
1761 	DPRINTF("Assert that (r1) and (r2) are not the same\n");
1762 	ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0);
1763 
1764 	DPRINTF("Before resuming the child process where it left off and "
1765 	    "without signal to be sent\n");
1766 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1767 
1768 	DPRINTF("Before calling %s() for the child - expected exited\n",
1769 	    TWAIT_FNAME);
1770 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1771 
1772 	validate_status_exited(status, exitval);
1773 
1774 	DPRINTF("Before calling %s() for the child - expected no process\n",
1775 	    TWAIT_FNAME);
1776 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1777 }
1778 
1779 ATF_TC(dbregs_dr0_dont_inherit_lwp);
1780 ATF_TC_HEAD(dbregs_dr0_dont_inherit_lwp, tc)
1781 {
1782 	atf_tc_set_md_var(tc, "descr",
1783 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
1784 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 0 from "
1785 	    "the forker thread is not inherited");
1786 }
1787 
1788 ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc)
1789 {
1790 	dbregs_dont_inherit_lwp(0);
1791 }
1792 
1793 ATF_TC(dbregs_dr1_dont_inherit_lwp);
1794 ATF_TC_HEAD(dbregs_dr1_dont_inherit_lwp, tc)
1795 {
1796 	atf_tc_set_md_var(tc, "descr",
1797 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
1798 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 1 from "
1799 	    "the forker thread is not inherited");
1800 }
1801 
1802 ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc)
1803 {
1804 	dbregs_dont_inherit_lwp(1);
1805 }
1806 
1807 ATF_TC(dbregs_dr2_dont_inherit_lwp);
1808 ATF_TC_HEAD(dbregs_dr2_dont_inherit_lwp, tc)
1809 {
1810 	atf_tc_set_md_var(tc, "descr",
1811 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
1812 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 2 from "
1813 	    "the forker thread is not inherited");
1814 }
1815 
1816 ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc)
1817 {
1818 	dbregs_dont_inherit_lwp(2);
1819 }
1820 
1821 ATF_TC(dbregs_dr3_dont_inherit_lwp);
1822 ATF_TC_HEAD(dbregs_dr3_dont_inherit_lwp, tc)
1823 {
1824 	atf_tc_set_md_var(tc, "descr",
1825 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
1826 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 3 from "
1827 	    "the forker thread is not inherited");
1828 }
1829 
1830 ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc)
1831 {
1832 	dbregs_dont_inherit_lwp(3);
1833 }
1834 
1835 static void
1836 dbregs_dont_inherit_execve(int reg)
1837 {
1838 	const int sigval = SIGTRAP;
1839 	pid_t child, wpid;
1840 #if defined(TWAIT_HAVE_STATUS)
1841 	int status;
1842 #endif
1843 	size_t i;
1844 	struct dbreg r1;
1845 	struct dbreg r2;
1846 
1847 	struct ptrace_siginfo info;
1848 	memset(&info, 0, sizeof(info));
1849 
1850 	if (!can_we_set_dbregs()) {
1851 		atf_tc_skip("Either run this test as root or set sysctl(3) "
1852 		            "security.models.extensions.user_set_dbregs to 1");
1853 	}
1854 
1855 	DPRINTF("Before forking process PID=%d\n", getpid());
1856 	SYSCALL_REQUIRE((child = fork()) != -1);
1857 	if (child == 0) {
1858 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
1859 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
1860 
1861 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
1862 		FORKEE_ASSERT(raise(sigval) == 0);
1863 
1864 		DPRINTF("Before calling execve(2) from child\n");
1865 		execlp("/bin/echo", "/bin/echo", NULL);
1866 
1867 		FORKEE_ASSERT(0 && "Not reached");
1868 	}
1869 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
1870 
1871 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1872 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1873 
1874 	validate_status_stopped(status, sigval);
1875 
1876 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
1877 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
1878 
1879 	DPRINTF("State of the debug registers (r1):\n");
1880 	for (i = 0; i < __arraycount(r1.dr); i++)
1881 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1882 
1883 	r1.dr[reg] = (long)(intptr_t)check_happy;
1884 	DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n",
1885 	    reg, reg, r1.dr[reg]);
1886 
1887 	DPRINTF("New state of the debug registers (r1):\n");
1888 	for (i = 0; i < __arraycount(r1.dr); i++)
1889 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
1890 
1891 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
1892 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
1893 
1894 	DPRINTF("Before resuming the child process where it left off and "
1895 	    "without signal to be sent\n");
1896 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1897 
1898 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1899 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1900 
1901 	validate_status_stopped(status, sigval);
1902 
1903 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
1904 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
1905 
1906 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
1907 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
1908 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
1909 	    info.psi_siginfo.si_errno);
1910 
1911 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
1912 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
1913 
1914 	DPRINTF("Call GETDBREGS for the child process after execve(2)\n");
1915 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1);
1916 
1917 	DPRINTF("State of the debug registers (r2):\n");
1918 	for (i = 0; i < __arraycount(r2.dr); i++)
1919 		DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]);
1920 
1921 	DPRINTF("Assert that (r1) and (r2) are not the same\n");
1922 	ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0);
1923 
1924 	DPRINTF("Before resuming the child process where it left off and "
1925 	    "without signal to be sent\n");
1926 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
1927 
1928 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1929 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
1930 
1931 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
1932 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
1933 }
1934 
1935 ATF_TC(dbregs_dr0_dont_inherit_execve);
1936 ATF_TC_HEAD(dbregs_dr0_dont_inherit_execve, tc)
1937 {
1938 	atf_tc_set_md_var(tc, "descr",
1939 	    "Verify that execve(2) is intercepted by tracer and Debug "
1940 	    "Register 0 is reset");
1941 }
1942 
1943 ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc)
1944 {
1945 	dbregs_dont_inherit_execve(0);
1946 }
1947 
1948 ATF_TC(dbregs_dr1_dont_inherit_execve);
1949 ATF_TC_HEAD(dbregs_dr1_dont_inherit_execve, tc)
1950 {
1951 	atf_tc_set_md_var(tc, "descr",
1952 	    "Verify that execve(2) is intercepted by tracer and Debug "
1953 	    "Register 1 is reset");
1954 }
1955 
1956 ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc)
1957 {
1958 	dbregs_dont_inherit_execve(1);
1959 }
1960 
1961 ATF_TC(dbregs_dr2_dont_inherit_execve);
1962 ATF_TC_HEAD(dbregs_dr2_dont_inherit_execve, tc)
1963 {
1964 	atf_tc_set_md_var(tc, "descr",
1965 	    "Verify that execve(2) is intercepted by tracer and Debug "
1966 	    "Register 2 is reset");
1967 }
1968 
1969 ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc)
1970 {
1971 	dbregs_dont_inherit_execve(2);
1972 }
1973 
1974 ATF_TC(dbregs_dr3_dont_inherit_execve);
1975 ATF_TC_HEAD(dbregs_dr3_dont_inherit_execve, tc)
1976 {
1977 	atf_tc_set_md_var(tc, "descr",
1978 	    "Verify that execve(2) is intercepted by tracer and Debug "
1979 	    "Register 3 is reset");
1980 }
1981 
1982 ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc)
1983 {
1984 	dbregs_dont_inherit_execve(3);
1985 }
1986 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \
1987 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \
1988 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \
1989 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \
1990 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \
1991 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \
1992 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \
1993 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \
1994 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \
1995 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \
1996 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \
1997 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \
1998 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \
1999 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \
2000 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \
2001 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \
2002 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \
2003 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \
2004 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \
2005 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \
2006 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \
2007 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \
2008 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \
2009 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \
2010 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \
2011 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \
2012 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \
2013 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \
2014 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \
2015 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \
2016 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \
2017 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \
2018 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \
2019 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \
2020 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \
2021 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \
2022 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \
2023 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \
2024 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \
2025 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \
2026 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \
2027 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \
2028 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \
2029 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \
2030 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \
2031 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \
2032 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \
2033 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \
2034 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \
2035 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \
2036 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \
2037 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \
2038 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \
2039 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \
2040 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \
2041 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \
2042 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \
2043 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \
2044 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \
2045 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \
2046 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \
2047 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve);
2048 #else
2049 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86()
2050 #endif
2051