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