t_ptrace_x86_wait.h revision 1.5 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