1 /* $NetBSD: t_ptrace_x86_wait.h,v 1.27 2020/10/09 17:43:30 mgorny Exp $ */ 2 3 /*- 4 * Copyright (c) 2016, 2017, 2018, 2019 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 DPRINTF("Before forking process PID=%d\n", getpid()); 79 SYSCALL_REQUIRE((child = fork()) != -1); 80 if (child == 0) { 81 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 82 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 83 84 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 85 FORKEE_ASSERT(raise(sigval) == 0); 86 87 DPRINTF("Before exiting of the child process\n"); 88 _exit(exitval); 89 } 90 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 91 92 DPRINTF("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 DPRINTF("Call GETDBREGS for the child process\n"); 98 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, 0) != -1); 99 100 DPRINTF("State of the debug registers:\n"); 101 for (i = 0; i < __arraycount(r.dr); i++) 102 DPRINTF("r[%zu]=%" PRIxREGISTER "\n", i, r.dr[i]); 103 104 DPRINTF("Before resuming the child process where it left off and " 105 "without signal to be sent\n"); 106 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 107 108 DPRINTF("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 DPRINTF("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 if (!can_we_set_dbregs()) { 139 atf_tc_skip("Either run this test as root or set sysctl(3) " 140 "security.models.extensions.user_set_dbregs to 1"); 141 } 142 143 DPRINTF("Before forking process PID=%d\n", getpid()); 144 SYSCALL_REQUIRE((child = fork()) != -1); 145 if (child == 0) { 146 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 147 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 148 149 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 150 FORKEE_ASSERT(raise(sigval) == 0); 151 152 if (mode == dbreg_preserve_mode_continued) { 153 DPRINTF("Before raising %s from child\n", 154 strsignal(sigval)); 155 FORKEE_ASSERT(raise(sigval) == 0); 156 } 157 158 DPRINTF("Before exiting of the child process\n"); 159 _exit(exitval); 160 } 161 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 162 163 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 164 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 165 166 validate_status_stopped(status, sigval); 167 168 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 169 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 170 171 DPRINTF("State of the debug registers (r1):\n"); 172 for (i = 0; i < __arraycount(r1.dr); i++) 173 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 174 175 r1.dr[reg] = (long)(intptr_t)&watchme; 176 DPRINTF("Set DR0 (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 177 reg, r1.dr[reg]); 178 179 DPRINTF("New state of the debug registers (r1):\n"); 180 for (i = 0; i < __arraycount(r1.dr); i++) 181 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 182 183 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 184 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 185 186 switch (mode) { 187 case dbreg_preserve_mode_none: 188 break; 189 case dbreg_preserve_mode_yield: 190 DPRINTF("Yields a processor voluntarily and gives other " 191 "threads a chance to run without waiting for an " 192 "involuntary preemptive switch\n"); 193 sched_yield(); 194 break; 195 case dbreg_preserve_mode_continued: 196 DPRINTF("Call CONTINUE for the child process\n"); 197 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 198 199 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 200 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 201 202 validate_status_stopped(status, sigval); 203 break; 204 } 205 206 DPRINTF("Call GETDBREGS for the child process (r2)\n"); 207 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1); 208 209 DPRINTF("Assert that (r1) and (r2) are the same\n"); 210 SYSCALL_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) == 0); 211 212 DPRINTF("Before resuming the child process where it left off and " 213 "without signal to be sent\n"); 214 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 215 216 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 217 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 218 219 validate_status_exited(status, exitval); 220 221 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 222 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 223 } 224 225 226 ATF_TC(dbregs_preserve_dr0); 227 ATF_TC_HEAD(dbregs_preserve_dr0, tc) 228 { 229 atf_tc_set_md_var(tc, "descr", 230 "Verify that setting DR0 is preserved across ptrace(2) calls"); 231 } 232 233 ATF_TC_BODY(dbregs_preserve_dr0, tc) 234 { 235 dbreg_preserve(0, dbreg_preserve_mode_none); 236 } 237 238 ATF_TC(dbregs_preserve_dr1); 239 ATF_TC_HEAD(dbregs_preserve_dr1, tc) 240 { 241 atf_tc_set_md_var(tc, "descr", 242 "Verify that setting DR1 is preserved across ptrace(2) calls"); 243 } 244 245 ATF_TC_BODY(dbregs_preserve_dr1, tc) 246 { 247 dbreg_preserve(1, dbreg_preserve_mode_none); 248 } 249 250 ATF_TC(dbregs_preserve_dr2); 251 ATF_TC_HEAD(dbregs_preserve_dr2, tc) 252 { 253 atf_tc_set_md_var(tc, "descr", 254 "Verify that setting DR2 is preserved across ptrace(2) calls"); 255 } 256 257 ATF_TC_BODY(dbregs_preserve_dr2, tc) 258 { 259 dbreg_preserve(2, dbreg_preserve_mode_none); 260 } 261 262 ATF_TC(dbregs_preserve_dr3); 263 ATF_TC_HEAD(dbregs_preserve_dr3, tc) 264 { 265 atf_tc_set_md_var(tc, "descr", 266 "Verify that setting DR3 is preserved across ptrace(2) calls"); 267 } 268 269 ATF_TC_BODY(dbregs_preserve_dr3, tc) 270 { 271 dbreg_preserve(3, dbreg_preserve_mode_none); 272 } 273 274 ATF_TC(dbregs_preserve_dr0_yield); 275 ATF_TC_HEAD(dbregs_preserve_dr0_yield, tc) 276 { 277 atf_tc_set_md_var(tc, "descr", 278 "Verify that setting DR0 is preserved across ptrace(2) calls with " 279 "scheduler yield"); 280 } 281 282 ATF_TC_BODY(dbregs_preserve_dr0_yield, tc) 283 { 284 dbreg_preserve(0, dbreg_preserve_mode_yield); 285 } 286 287 ATF_TC(dbregs_preserve_dr1_yield); 288 ATF_TC_HEAD(dbregs_preserve_dr1_yield, tc) 289 { 290 atf_tc_set_md_var(tc, "descr", 291 "Verify that setting DR1 is preserved across ptrace(2) calls with " 292 "scheduler yield"); 293 } 294 295 ATF_TC_BODY(dbregs_preserve_dr1_yield, tc) 296 { 297 dbreg_preserve(0, dbreg_preserve_mode_yield); 298 } 299 300 ATF_TC(dbregs_preserve_dr2_yield); 301 ATF_TC_HEAD(dbregs_preserve_dr2_yield, tc) 302 { 303 atf_tc_set_md_var(tc, "descr", 304 "Verify that setting DR2 is preserved across ptrace(2) calls with " 305 "scheduler yield"); 306 } 307 308 ATF_TC_BODY(dbregs_preserve_dr2_yield, tc) 309 { 310 dbreg_preserve(0, dbreg_preserve_mode_yield); 311 } 312 313 314 ATF_TC(dbregs_preserve_dr3_yield); 315 ATF_TC_HEAD(dbregs_preserve_dr3_yield, tc) 316 { 317 atf_tc_set_md_var(tc, "descr", 318 "Verify that setting DR3 is preserved across ptrace(2) calls with " 319 "scheduler yield"); 320 } 321 322 ATF_TC_BODY(dbregs_preserve_dr3_yield, tc) 323 { 324 dbreg_preserve(3, dbreg_preserve_mode_yield); 325 } 326 327 ATF_TC(dbregs_preserve_dr0_continued); 328 ATF_TC_HEAD(dbregs_preserve_dr0_continued, tc) 329 { 330 atf_tc_set_md_var(tc, "descr", 331 "Verify that setting DR0 is preserved across ptrace(2) calls and " 332 "with continued child"); 333 } 334 335 ATF_TC_BODY(dbregs_preserve_dr0_continued, tc) 336 { 337 dbreg_preserve(0, dbreg_preserve_mode_continued); 338 } 339 340 ATF_TC(dbregs_preserve_dr1_continued); 341 ATF_TC_HEAD(dbregs_preserve_dr1_continued, tc) 342 { 343 atf_tc_set_md_var(tc, "descr", 344 "Verify that setting DR1 is preserved across ptrace(2) calls and " 345 "with continued child"); 346 } 347 348 ATF_TC_BODY(dbregs_preserve_dr1_continued, tc) 349 { 350 dbreg_preserve(1, dbreg_preserve_mode_continued); 351 } 352 353 ATF_TC(dbregs_preserve_dr2_continued); 354 ATF_TC_HEAD(dbregs_preserve_dr2_continued, tc) 355 { 356 atf_tc_set_md_var(tc, "descr", 357 "Verify that setting DR2 is preserved across ptrace(2) calls and " 358 "with continued child"); 359 } 360 361 ATF_TC_BODY(dbregs_preserve_dr2_continued, tc) 362 { 363 dbreg_preserve(2, dbreg_preserve_mode_continued); 364 } 365 366 ATF_TC(dbregs_preserve_dr3_continued); 367 ATF_TC_HEAD(dbregs_preserve_dr3_continued, tc) 368 { 369 atf_tc_set_md_var(tc, "descr", 370 "Verify that setting DR3 is preserved across ptrace(2) calls and " 371 "with continued child"); 372 } 373 374 ATF_TC_BODY(dbregs_preserve_dr3_continued, tc) 375 { 376 dbreg_preserve(3, dbreg_preserve_mode_continued); 377 } 378 379 380 static void 381 dbregs_trap_variable(int reg, int cond, int len, bool write) 382 { 383 const int exitval = 5; 384 const int sigval = SIGSTOP; 385 pid_t child, wpid; 386 #if defined(TWAIT_HAVE_STATUS) 387 int status; 388 #endif 389 struct dbreg r1; 390 size_t i; 391 volatile int watchme = 0; 392 union u dr7; 393 394 struct ptrace_siginfo info; 395 memset(&info, 0, sizeof(info)); 396 397 if (!can_we_set_dbregs()) { 398 atf_tc_skip("Either run this test as root or set sysctl(3) " 399 "security.models.extensions.user_set_dbregs to 1"); 400 } 401 402 dr7.raw = 0; 403 switch (reg) { 404 case 0: 405 dr7.bits.global_dr0_breakpoint = 1; 406 dr7.bits.condition_dr0 = cond; 407 dr7.bits.len_dr0 = len; 408 break; 409 case 1: 410 dr7.bits.global_dr1_breakpoint = 1; 411 dr7.bits.condition_dr1 = cond; 412 dr7.bits.len_dr1 = len; 413 break; 414 case 2: 415 dr7.bits.global_dr2_breakpoint = 1; 416 dr7.bits.condition_dr2 = cond; 417 dr7.bits.len_dr2 = len; 418 break; 419 case 3: 420 dr7.bits.global_dr3_breakpoint = 1; 421 dr7.bits.condition_dr3 = cond; 422 dr7.bits.len_dr3 = len; 423 break; 424 } 425 426 DPRINTF("Before forking process PID=%d\n", getpid()); 427 SYSCALL_REQUIRE((child = fork()) != -1); 428 if (child == 0) { 429 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 430 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 431 432 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 433 FORKEE_ASSERT(raise(sigval) == 0); 434 435 if (write) 436 watchme = 1; 437 else 438 printf("watchme=%d\n", watchme); 439 440 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 441 FORKEE_ASSERT(raise(sigval) == 0); 442 443 DPRINTF("Before exiting of the child process\n"); 444 _exit(exitval); 445 } 446 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 447 448 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 449 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 450 451 validate_status_stopped(status, sigval); 452 453 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 454 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 455 456 DPRINTF("State of the debug registers (r1):\n"); 457 for (i = 0; i < __arraycount(r1.dr); i++) 458 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 459 460 r1.dr[reg] = (long)(intptr_t)&watchme; 461 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 462 reg, reg, r1.dr[reg]); 463 464 r1.dr[7] = dr7.raw; 465 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 466 r1.dr[7]); 467 468 DPRINTF("New state of the debug registers (r1):\n"); 469 for (i = 0; i < __arraycount(r1.dr); i++) 470 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 471 472 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 473 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 474 475 DPRINTF("Call CONTINUE for the child process\n"); 476 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 477 478 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 479 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 480 481 validate_status_stopped(status, SIGTRAP); 482 483 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 484 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 485 486 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 487 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 488 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 489 info.psi_siginfo.si_errno); 490 491 DPRINTF("Before checking siginfo_t\n"); 492 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 493 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 494 495 DPRINTF("Call CONTINUE for the child process\n"); 496 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 497 498 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 499 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 500 501 validate_status_stopped(status, sigval); 502 503 DPRINTF("Before resuming the child process where it left off and " 504 "without signal to be sent\n"); 505 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 506 507 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 508 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 509 510 validate_status_exited(status, exitval); 511 512 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 513 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 514 } 515 516 ATF_TC(dbregs_dr0_trap_variable_writeonly_byte); 517 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_byte, tc) 518 { 519 atf_tc_set_md_var(tc, "descr", 520 "Verify that setting trap with DR0 triggers SIGTRAP " 521 "(break on data writes only and 1 byte mode)"); 522 } 523 524 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_byte, tc) 525 { 526 /* 0b01 -- break on data write only */ 527 /* 0b00 -- 1 byte */ 528 529 dbregs_trap_variable(0, 1, 0, true); 530 } 531 532 ATF_TC(dbregs_dr1_trap_variable_writeonly_byte); 533 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_byte, tc) 534 { 535 atf_tc_set_md_var(tc, "descr", 536 "Verify that setting trap with DR1 triggers SIGTRAP " 537 "(break on data writes only and 1 byte mode)"); 538 } 539 540 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_byte, tc) 541 { 542 /* 0b01 -- break on data write only */ 543 /* 0b00 -- 1 byte */ 544 545 dbregs_trap_variable(1, 1, 0, true); 546 } 547 548 ATF_TC(dbregs_dr2_trap_variable_writeonly_byte); 549 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_byte, tc) 550 { 551 atf_tc_set_md_var(tc, "descr", 552 "Verify that setting trap with DR2 triggers SIGTRAP " 553 "(break on data writes only and 1 byte mode)"); 554 } 555 556 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_byte, tc) 557 { 558 /* 0b01 -- break on data write only */ 559 /* 0b00 -- 1 byte */ 560 561 dbregs_trap_variable(2, 1, 0, true); 562 } 563 564 ATF_TC(dbregs_dr3_trap_variable_writeonly_byte); 565 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_byte, tc) 566 { 567 atf_tc_set_md_var(tc, "descr", 568 "Verify that setting trap with DR3 triggers SIGTRAP " 569 "(break on data writes only and 1 byte mode)"); 570 } 571 572 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_byte, tc) 573 { 574 /* 0b01 -- break on data write only */ 575 /* 0b00 -- 1 byte */ 576 577 dbregs_trap_variable(3, 1, 0, true); 578 } 579 580 ATF_TC(dbregs_dr0_trap_variable_writeonly_2bytes); 581 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_2bytes, tc) 582 { 583 atf_tc_set_md_var(tc, "descr", 584 "Verify that setting trap with DR0 triggers SIGTRAP " 585 "(break on data writes only and 2 bytes mode)"); 586 } 587 588 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_2bytes, tc) 589 { 590 /* 0b01 -- break on data write only */ 591 /* 0b01 -- 2 bytes */ 592 593 dbregs_trap_variable(0, 1, 1, true); 594 } 595 596 ATF_TC(dbregs_dr1_trap_variable_writeonly_2bytes); 597 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_2bytes, tc) 598 { 599 atf_tc_set_md_var(tc, "descr", 600 "Verify that setting trap with DR1 triggers SIGTRAP " 601 "(break on data writes only and 2 bytes mode)"); 602 } 603 604 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_2bytes, tc) 605 { 606 /* 0b01 -- break on data write only */ 607 /* 0b01 -- 2 bytes */ 608 609 dbregs_trap_variable(1, 1, 1, true); 610 } 611 612 ATF_TC(dbregs_dr2_trap_variable_writeonly_2bytes); 613 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_2bytes, tc) 614 { 615 atf_tc_set_md_var(tc, "descr", 616 "Verify that setting trap with DR2 triggers SIGTRAP " 617 "(break on data writes only and 2 bytes mode)"); 618 } 619 620 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_2bytes, tc) 621 { 622 /* 0b01 -- break on data write only */ 623 /* 0b01 -- 2 bytes */ 624 625 dbregs_trap_variable(2, 1, 1, true); 626 } 627 628 ATF_TC(dbregs_dr3_trap_variable_writeonly_2bytes); 629 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_2bytes, tc) 630 { 631 atf_tc_set_md_var(tc, "descr", 632 "Verify that setting trap with DR3 triggers SIGTRAP " 633 "(break on data writes only and 2 bytes mode)"); 634 } 635 636 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_2bytes, tc) 637 { 638 /* 0b01 -- break on data write only */ 639 /* 0b01 -- 2 bytes */ 640 641 dbregs_trap_variable(3, 1, 1, true); 642 } 643 644 ATF_TC(dbregs_dr0_trap_variable_writeonly_4bytes); 645 ATF_TC_HEAD(dbregs_dr0_trap_variable_writeonly_4bytes, tc) 646 { 647 atf_tc_set_md_var(tc, "descr", 648 "Verify that setting trap with DR0 triggers SIGTRAP " 649 "(break on data writes only and 4 bytes mode)"); 650 } 651 652 ATF_TC_BODY(dbregs_dr0_trap_variable_writeonly_4bytes, tc) 653 { 654 /* 0b01 -- break on data write only */ 655 /* 0b11 -- 4 bytes */ 656 657 dbregs_trap_variable(0, 1, 3, true); 658 } 659 660 ATF_TC(dbregs_dr1_trap_variable_writeonly_4bytes); 661 ATF_TC_HEAD(dbregs_dr1_trap_variable_writeonly_4bytes, tc) 662 { 663 atf_tc_set_md_var(tc, "descr", 664 "Verify that setting trap with DR1 triggers SIGTRAP " 665 "(break on data writes only and 4 bytes mode)"); 666 } 667 668 ATF_TC_BODY(dbregs_dr1_trap_variable_writeonly_4bytes, tc) 669 { 670 /* 0b01 -- break on data write only */ 671 /* 0b11 -- 4 bytes */ 672 673 dbregs_trap_variable(1, 1, 3, true); 674 } 675 676 ATF_TC(dbregs_dr2_trap_variable_writeonly_4bytes); 677 ATF_TC_HEAD(dbregs_dr2_trap_variable_writeonly_4bytes, tc) 678 { 679 atf_tc_set_md_var(tc, "descr", 680 "Verify that setting trap with DR2 triggers SIGTRAP " 681 "(break on data writes only and 4 bytes mode)"); 682 } 683 684 ATF_TC_BODY(dbregs_dr2_trap_variable_writeonly_4bytes, tc) 685 { 686 /* 0b01 -- break on data write only */ 687 /* 0b11 -- 4 bytes */ 688 689 dbregs_trap_variable(2, 1, 3, true); 690 } 691 692 ATF_TC(dbregs_dr3_trap_variable_writeonly_4bytes); 693 ATF_TC_HEAD(dbregs_dr3_trap_variable_writeonly_4bytes, tc) 694 { 695 atf_tc_set_md_var(tc, "descr", 696 "Verify that setting trap with DR3 triggers SIGTRAP " 697 "(break on data writes only and 4 bytes mode)"); 698 } 699 700 ATF_TC_BODY(dbregs_dr3_trap_variable_writeonly_4bytes, tc) 701 { 702 /* 0b01 -- break on data write only */ 703 /* 0b11 -- 4 bytes */ 704 705 dbregs_trap_variable(3, 1, 3, true); 706 } 707 708 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_byte); 709 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_byte, tc) 710 { 711 atf_tc_set_md_var(tc, "descr", 712 "Verify that setting trap with DR0 triggers SIGTRAP " 713 "(break on data read/write trap in read 1 byte mode)"); 714 } 715 716 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_byte, tc) 717 { 718 /* 0b11 -- break on data write&read */ 719 /* 0b00 -- 1 byte */ 720 721 dbregs_trap_variable(0, 3, 0, true); 722 } 723 724 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_byte); 725 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_byte, tc) 726 { 727 atf_tc_set_md_var(tc, "descr", 728 "Verify that setting trap with DR1 triggers SIGTRAP " 729 "(break on data read/write trap in read 1 byte mode)"); 730 } 731 732 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_byte, tc) 733 { 734 /* 0b11 -- break on data write&read */ 735 /* 0b00 -- 1 byte */ 736 737 dbregs_trap_variable(1, 3, 0, true); 738 } 739 740 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_byte); 741 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_byte, tc) 742 { 743 atf_tc_set_md_var(tc, "descr", 744 "Verify that setting trap with DR2 triggers SIGTRAP " 745 "(break on data read/write trap in read 1 byte mode)"); 746 } 747 748 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_byte, tc) 749 { 750 /* 0b11 -- break on data write&read */ 751 /* 0b00 -- 1 byte */ 752 753 dbregs_trap_variable(2, 3, 0, true); 754 } 755 756 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_byte); 757 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_byte, tc) 758 { 759 atf_tc_set_md_var(tc, "descr", 760 "Verify that setting trap with DR3 triggers SIGTRAP " 761 "(break on data read/write trap in read 1 byte mode)"); 762 } 763 764 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_byte, tc) 765 { 766 /* 0b11 -- break on data write&read */ 767 /* 0b00 -- 1 byte */ 768 769 dbregs_trap_variable(3, 3, 0, true); 770 } 771 772 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_2bytes); 773 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc) 774 { 775 atf_tc_set_md_var(tc, "descr", 776 "Verify that setting trap with DR0 triggers SIGTRAP " 777 "(break on data read/write trap in read 2 bytes mode)"); 778 } 779 780 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_2bytes, tc) 781 { 782 /* 0b11 -- break on data write&read */ 783 /* 0b01 -- 2 bytes */ 784 785 dbregs_trap_variable(0, 3, 1, true); 786 } 787 788 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_2bytes); 789 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc) 790 { 791 atf_tc_set_md_var(tc, "descr", 792 "Verify that setting trap with DR1 triggers SIGTRAP " 793 "(break on data read/write trap in read 2 bytes mode)"); 794 } 795 796 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_2bytes, tc) 797 { 798 /* 0b11 -- break on data write&read */ 799 /* 0b01 -- 2 bytes */ 800 801 dbregs_trap_variable(1, 3, 1, true); 802 } 803 804 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_2bytes); 805 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc) 806 { 807 atf_tc_set_md_var(tc, "descr", 808 "Verify that setting trap with DR2 triggers SIGTRAP " 809 "(break on data read/write trap in read 2 bytes mode)"); 810 } 811 812 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_2bytes, tc) 813 { 814 /* 0b11 -- break on data write&read */ 815 /* 0b01 -- 2 bytes */ 816 817 dbregs_trap_variable(2, 3, 1, true); 818 } 819 820 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_2bytes); 821 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc) 822 { 823 atf_tc_set_md_var(tc, "descr", 824 "Verify that setting trap with DR3 triggers SIGTRAP " 825 "(break on data read/write trap in read 2 bytes mode)"); 826 } 827 828 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_2bytes, tc) 829 { 830 /* 0b11 -- break on data write&read */ 831 /* 0b01 -- 2 bytes */ 832 833 dbregs_trap_variable(3, 3, 1, true); 834 } 835 836 ATF_TC(dbregs_dr0_trap_variable_readwrite_write_4bytes); 837 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc) 838 { 839 atf_tc_set_md_var(tc, "descr", 840 "Verify that setting trap with DR0 triggers SIGTRAP " 841 "(break on data read/write trap in read 4 bytes mode)"); 842 } 843 844 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_write_4bytes, tc) 845 { 846 /* 0b11 -- break on data write&read */ 847 /* 0b11 -- 4 bytes */ 848 849 dbregs_trap_variable(0, 3, 3, true); 850 } 851 852 ATF_TC(dbregs_dr1_trap_variable_readwrite_write_4bytes); 853 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc) 854 { 855 atf_tc_set_md_var(tc, "descr", 856 "Verify that setting trap with DR1 triggers SIGTRAP " 857 "(break on data read/write trap in read 4 bytes mode)"); 858 } 859 860 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_write_4bytes, tc) 861 { 862 /* 0b11 -- break on data write&read */ 863 /* 0b11 -- 4 bytes */ 864 865 dbregs_trap_variable(1, 3, 3, true); 866 } 867 868 ATF_TC(dbregs_dr2_trap_variable_readwrite_write_4bytes); 869 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc) 870 { 871 atf_tc_set_md_var(tc, "descr", 872 "Verify that setting trap with DR2 triggers SIGTRAP " 873 "(break on data read/write trap in read 4 bytes mode)"); 874 } 875 876 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_write_4bytes, tc) 877 { 878 /* 0b11 -- break on data write&read */ 879 /* 0b11 -- 4 bytes */ 880 881 dbregs_trap_variable(2, 3, 3, true); 882 } 883 884 ATF_TC(dbregs_dr3_trap_variable_readwrite_write_4bytes); 885 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc) 886 { 887 atf_tc_set_md_var(tc, "descr", 888 "Verify that setting trap with DR3 triggers SIGTRAP " 889 "(break on data read/write trap in read 4 bytes mode)"); 890 } 891 892 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_write_4bytes, tc) 893 { 894 /* 0b11 -- break on data write&read */ 895 /* 0b11 -- 4 bytes */ 896 897 dbregs_trap_variable(3, 3, 3, true); 898 } 899 900 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_byte); 901 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_byte, tc) 902 { 903 atf_tc_set_md_var(tc, "descr", 904 "Verify that setting trap with DR0 triggers SIGTRAP " 905 "(break on data read/write trap in write 1 byte mode)"); 906 } 907 908 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_byte, tc) 909 { 910 /* 0b11 -- break on data write&read */ 911 /* 0b00 -- 1 byte */ 912 913 dbregs_trap_variable(0, 3, 0, false); 914 } 915 916 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_byte); 917 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_byte, tc) 918 { 919 atf_tc_set_md_var(tc, "descr", 920 "Verify that setting trap with DR1 triggers SIGTRAP " 921 "(break on data read/write trap in write 1 byte mode)"); 922 } 923 924 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_byte, tc) 925 { 926 /* 0b11 -- break on data write&read */ 927 /* 0b00 -- 1 byte */ 928 929 dbregs_trap_variable(1, 3, 0, false); 930 } 931 932 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_byte); 933 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_byte, tc) 934 { 935 atf_tc_set_md_var(tc, "descr", 936 "Verify that setting trap with DR2 triggers SIGTRAP " 937 "(break on data read/write trap in write 1 byte mode)"); 938 } 939 940 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_byte, tc) 941 { 942 /* 0b11 -- break on data write&read */ 943 /* 0b00 -- 1 byte */ 944 945 dbregs_trap_variable(2, 3, 0, false); 946 } 947 948 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_byte); 949 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_byte, tc) 950 { 951 atf_tc_set_md_var(tc, "descr", 952 "Verify that setting trap with DR3 triggers SIGTRAP " 953 "(break on data read/write trap in write 1 byte mode)"); 954 } 955 956 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_byte, tc) 957 { 958 /* 0b11 -- break on data write&read */ 959 /* 0b00 -- 1 byte */ 960 961 dbregs_trap_variable(3, 3, 0, false); 962 } 963 964 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_2bytes); 965 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc) 966 { 967 atf_tc_set_md_var(tc, "descr", 968 "Verify that setting trap with DR0 triggers SIGTRAP " 969 "(break on data read/write trap in write 2 bytes mode)"); 970 } 971 972 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_2bytes, tc) 973 { 974 /* 0b11 -- break on data write&read */ 975 /* 0b01 -- 2 bytes */ 976 977 dbregs_trap_variable(0, 3, 1, false); 978 } 979 980 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_2bytes); 981 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc) 982 { 983 atf_tc_set_md_var(tc, "descr", 984 "Verify that setting trap with DR1 triggers SIGTRAP " 985 "(break on data read/write trap in write 2 bytes mode)"); 986 } 987 988 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_2bytes, tc) 989 { 990 /* 0b11 -- break on data write&read */ 991 /* 0b01 -- 2 bytes */ 992 993 dbregs_trap_variable(1, 3, 1, false); 994 } 995 996 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_2bytes); 997 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc) 998 { 999 atf_tc_set_md_var(tc, "descr", 1000 "Verify that setting trap with DR2 triggers SIGTRAP " 1001 "(break on data read/write trap in write 2 bytes mode)"); 1002 } 1003 1004 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_2bytes, tc) 1005 { 1006 /* 0b11 -- break on data write&read */ 1007 /* 0b01 -- 2 bytes */ 1008 1009 dbregs_trap_variable(2, 3, 1, false); 1010 } 1011 1012 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_2bytes); 1013 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc) 1014 { 1015 atf_tc_set_md_var(tc, "descr", 1016 "Verify that setting trap with DR3 triggers SIGTRAP " 1017 "(break on data read/write trap in write 2 bytes mode)"); 1018 } 1019 1020 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_2bytes, tc) 1021 { 1022 /* 0b11 -- break on data write&read */ 1023 /* 0b01 -- 2 bytes */ 1024 1025 dbregs_trap_variable(3, 3, 1, false); 1026 } 1027 1028 ATF_TC(dbregs_dr0_trap_variable_readwrite_read_4bytes); 1029 ATF_TC_HEAD(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc) 1030 { 1031 atf_tc_set_md_var(tc, "descr", 1032 "Verify that setting trap with DR0 triggers SIGTRAP " 1033 "(break on data read/write trap in write 4 bytes mode)"); 1034 } 1035 1036 ATF_TC_BODY(dbregs_dr0_trap_variable_readwrite_read_4bytes, tc) 1037 { 1038 /* 0b11 -- break on data write&read */ 1039 /* 0b11 -- 4 bytes */ 1040 1041 dbregs_trap_variable(0, 3, 3, false); 1042 } 1043 1044 ATF_TC(dbregs_dr1_trap_variable_readwrite_read_4bytes); 1045 ATF_TC_HEAD(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc) 1046 { 1047 atf_tc_set_md_var(tc, "descr", 1048 "Verify that setting trap with DR1 triggers SIGTRAP " 1049 "(break on data read/write trap in write 4 bytes mode)"); 1050 } 1051 1052 ATF_TC_BODY(dbregs_dr1_trap_variable_readwrite_read_4bytes, tc) 1053 { 1054 /* 0b11 -- break on data write&read */ 1055 /* 0b11 -- 4 bytes */ 1056 1057 dbregs_trap_variable(1, 3, 3, false); 1058 } 1059 1060 ATF_TC(dbregs_dr2_trap_variable_readwrite_read_4bytes); 1061 ATF_TC_HEAD(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc) 1062 { 1063 atf_tc_set_md_var(tc, "descr", 1064 "Verify that setting trap with DR2 triggers SIGTRAP " 1065 "(break on data read/write trap in write 4 bytes mode)"); 1066 } 1067 1068 ATF_TC_BODY(dbregs_dr2_trap_variable_readwrite_read_4bytes, tc) 1069 { 1070 /* 0b11 -- break on data write&read */ 1071 /* 0b11 -- 4 bytes */ 1072 1073 dbregs_trap_variable(2, 3, 3, false); 1074 } 1075 1076 ATF_TC(dbregs_dr3_trap_variable_readwrite_read_4bytes); 1077 ATF_TC_HEAD(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc) 1078 { 1079 atf_tc_set_md_var(tc, "descr", 1080 "Verify that setting trap with DR3 triggers SIGTRAP " 1081 "(break on data read/write trap in write 4 bytes mode)"); 1082 } 1083 1084 ATF_TC_BODY(dbregs_dr3_trap_variable_readwrite_read_4bytes, tc) 1085 { 1086 /* 0b11 -- break on data write&read */ 1087 /* 0b11 -- 4 bytes */ 1088 1089 dbregs_trap_variable(3, 3, 3, false); 1090 } 1091 1092 #if defined(HAVE_DBREGS) 1093 ATF_TC(dbregs_dr0_trap_code); 1094 ATF_TC_HEAD(dbregs_dr0_trap_code, tc) 1095 { 1096 atf_tc_set_md_var(tc, "descr", 1097 "Verify that setting trap with DR0 triggers SIGTRAP " 1098 "(break on code execution trap)"); 1099 } 1100 1101 ATF_TC_BODY(dbregs_dr0_trap_code, tc) 1102 { 1103 const int exitval = 5; 1104 const int sigval = SIGSTOP; 1105 pid_t child, wpid; 1106 #if defined(TWAIT_HAVE_STATUS) 1107 int status; 1108 #endif 1109 struct dbreg r1; 1110 size_t i; 1111 volatile int watchme = 1; 1112 union u dr7; 1113 1114 struct ptrace_siginfo info; 1115 memset(&info, 0, sizeof(info)); 1116 1117 if (!can_we_set_dbregs()) { 1118 atf_tc_skip("Either run this test as root or set sysctl(3) " 1119 "security.models.extensions.user_set_dbregs to 1"); 1120 } 1121 1122 dr7.raw = 0; 1123 dr7.bits.global_dr0_breakpoint = 1; 1124 dr7.bits.condition_dr0 = 0; /* 0b00 -- break on code execution */ 1125 dr7.bits.len_dr0 = 0; /* 0b00 -- 1 byte */ 1126 1127 DPRINTF("Before forking process PID=%d\n", getpid()); 1128 SYSCALL_REQUIRE((child = fork()) != -1); 1129 if (child == 0) { 1130 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1131 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1132 1133 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1134 FORKEE_ASSERT(raise(sigval) == 0); 1135 1136 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1137 1138 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1139 FORKEE_ASSERT(raise(sigval) == 0); 1140 1141 DPRINTF("Before exiting of the child process\n"); 1142 _exit(exitval); 1143 } 1144 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1145 1146 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1147 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1148 1149 validate_status_stopped(status, sigval); 1150 1151 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1152 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1153 1154 DPRINTF("State of the debug registers (r1):\n"); 1155 for (i = 0; i < __arraycount(r1.dr); i++) 1156 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1157 1158 r1.dr[0] = (long)(intptr_t)check_happy; 1159 DPRINTF("Set DR0 (r1.dr[0]) to new value %" PRIxREGISTER "\n", 1160 r1.dr[0]); 1161 1162 r1.dr[7] = dr7.raw; 1163 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1164 r1.dr[7]); 1165 1166 DPRINTF("New state of the debug registers (r1):\n"); 1167 for (i = 0; i < __arraycount(r1.dr); i++) 1168 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1169 1170 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1171 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1172 1173 DPRINTF("Call CONTINUE for the child process\n"); 1174 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1175 1176 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1177 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1178 1179 validate_status_stopped(status, SIGTRAP); 1180 1181 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1182 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1183 1184 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1185 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1186 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1187 info.psi_siginfo.si_errno); 1188 1189 DPRINTF("Before checking siginfo_t\n"); 1190 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1191 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1192 1193 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1194 dr7.bits.global_dr0_breakpoint = 0; 1195 r1.dr[7] = dr7.raw; 1196 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1197 r1.dr[7]); 1198 1199 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1200 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1201 1202 DPRINTF("Call CONTINUE for the child process\n"); 1203 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1204 1205 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1206 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1207 1208 validate_status_stopped(status, sigval); 1209 1210 DPRINTF("Before resuming the child process where it left off and " 1211 "without signal to be sent\n"); 1212 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1213 1214 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1215 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1216 1217 validate_status_exited(status, exitval); 1218 1219 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1220 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1221 } 1222 #endif 1223 1224 #if defined(HAVE_DBREGS) 1225 ATF_TC(dbregs_dr1_trap_code); 1226 ATF_TC_HEAD(dbregs_dr1_trap_code, tc) 1227 { 1228 atf_tc_set_md_var(tc, "descr", 1229 "Verify that setting trap with DR1 triggers SIGTRAP " 1230 "(break on code execution trap)"); 1231 } 1232 1233 ATF_TC_BODY(dbregs_dr1_trap_code, tc) 1234 { 1235 const int exitval = 5; 1236 const int sigval = SIGSTOP; 1237 pid_t child, wpid; 1238 #if defined(TWAIT_HAVE_STATUS) 1239 int status; 1240 #endif 1241 struct dbreg r1; 1242 size_t i; 1243 volatile int watchme = 1; 1244 union u dr7; 1245 1246 struct ptrace_siginfo info; 1247 memset(&info, 0, sizeof(info)); 1248 1249 if (!can_we_set_dbregs()) { 1250 atf_tc_skip("Either run this test as root or set sysctl(3) " 1251 "security.models.extensions.user_set_dbregs to 1"); 1252 } 1253 1254 dr7.raw = 0; 1255 dr7.bits.global_dr1_breakpoint = 1; 1256 dr7.bits.condition_dr1 = 0; /* 0b00 -- break on code execution */ 1257 dr7.bits.len_dr1 = 0; /* 0b00 -- 1 byte */ 1258 1259 DPRINTF("Before forking process PID=%d\n", getpid()); 1260 SYSCALL_REQUIRE((child = fork()) != -1); 1261 if (child == 0) { 1262 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1263 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1264 1265 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1266 FORKEE_ASSERT(raise(sigval) == 0); 1267 1268 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1269 1270 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1271 FORKEE_ASSERT(raise(sigval) == 0); 1272 1273 DPRINTF("Before exiting of the child process\n"); 1274 _exit(exitval); 1275 } 1276 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1277 1278 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1279 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1280 1281 validate_status_stopped(status, sigval); 1282 1283 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1284 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1285 1286 DPRINTF("State of the debug registers (r1):\n"); 1287 for (i = 0; i < __arraycount(r1.dr); i++) 1288 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1289 1290 r1.dr[1] = (long)(intptr_t)check_happy; 1291 DPRINTF("Set DR1 (r1.dr[1]) to new value %" PRIxREGISTER "\n", 1292 r1.dr[1]); 1293 1294 r1.dr[7] = dr7.raw; 1295 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1296 r1.dr[7]); 1297 1298 DPRINTF("New state of the debug registers (r1):\n"); 1299 for (i = 0; i < __arraycount(r1.dr); i++) 1300 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1301 1302 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1303 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1304 1305 DPRINTF("Call CONTINUE for the child process\n"); 1306 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1307 1308 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1309 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1310 1311 validate_status_stopped(status, SIGTRAP); 1312 1313 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1314 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1315 1316 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1317 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1318 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1319 info.psi_siginfo.si_errno); 1320 1321 DPRINTF("Before checking siginfo_t\n"); 1322 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1323 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1324 1325 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1326 dr7.bits.global_dr1_breakpoint = 0; 1327 r1.dr[7] = dr7.raw; 1328 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1329 r1.dr[7]); 1330 1331 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1332 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1333 1334 DPRINTF("Call CONTINUE for the child process\n"); 1335 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1336 1337 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1338 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1339 1340 validate_status_stopped(status, sigval); 1341 1342 DPRINTF("Before resuming the child process where it left off and " 1343 "without signal to be sent\n"); 1344 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1345 1346 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1347 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1348 1349 validate_status_exited(status, exitval); 1350 1351 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1352 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1353 } 1354 #endif 1355 1356 #if defined(HAVE_DBREGS) 1357 ATF_TC(dbregs_dr2_trap_code); 1358 ATF_TC_HEAD(dbregs_dr2_trap_code, tc) 1359 { 1360 atf_tc_set_md_var(tc, "descr", 1361 "Verify that setting trap with DR2 triggers SIGTRAP " 1362 "(break on code execution trap)"); 1363 } 1364 1365 ATF_TC_BODY(dbregs_dr2_trap_code, tc) 1366 { 1367 const int exitval = 5; 1368 const int sigval = SIGSTOP; 1369 pid_t child, wpid; 1370 #if defined(TWAIT_HAVE_STATUS) 1371 int status; 1372 #endif 1373 struct dbreg r1; 1374 size_t i; 1375 volatile int watchme = 1; 1376 union u dr7; 1377 1378 struct ptrace_siginfo info; 1379 memset(&info, 0, sizeof(info)); 1380 1381 if (!can_we_set_dbregs()) { 1382 atf_tc_skip("Either run this test as root or set sysctl(3) " 1383 "security.models.extensions.user_set_dbregs to 1"); 1384 } 1385 1386 dr7.raw = 0; 1387 dr7.bits.global_dr2_breakpoint = 1; 1388 dr7.bits.condition_dr2 = 0; /* 0b00 -- break on code execution */ 1389 dr7.bits.len_dr2 = 0; /* 0b00 -- 1 byte */ 1390 1391 DPRINTF("Before forking process PID=%d\n", getpid()); 1392 SYSCALL_REQUIRE((child = fork()) != -1); 1393 if (child == 0) { 1394 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1395 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1396 1397 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1398 FORKEE_ASSERT(raise(sigval) == 0); 1399 1400 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1401 1402 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1403 FORKEE_ASSERT(raise(sigval) == 0); 1404 1405 DPRINTF("Before exiting of the child process\n"); 1406 _exit(exitval); 1407 } 1408 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1409 1410 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1411 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1412 1413 validate_status_stopped(status, sigval); 1414 1415 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1416 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1417 1418 DPRINTF("State of the debug registers (r1):\n"); 1419 for (i = 0; i < __arraycount(r1.dr); i++) 1420 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1421 1422 r1.dr[2] = (long)(intptr_t)check_happy; 1423 DPRINTF("Set DR2 (r1.dr[2]) to new value %" PRIxREGISTER "\n", 1424 r1.dr[2]); 1425 1426 r1.dr[7] = dr7.raw; 1427 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1428 r1.dr[7]); 1429 1430 DPRINTF("New state of the debug registers (r1):\n"); 1431 for (i = 0; i < __arraycount(r1.dr); i++) 1432 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1433 1434 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1435 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1436 1437 DPRINTF("Call CONTINUE for the child process\n"); 1438 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1439 1440 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1441 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1442 1443 validate_status_stopped(status, SIGTRAP); 1444 1445 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1446 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1447 1448 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1449 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1450 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1451 info.psi_siginfo.si_errno); 1452 1453 DPRINTF("Before checking siginfo_t\n"); 1454 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1455 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1456 1457 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1458 dr7.bits.global_dr2_breakpoint = 0; 1459 r1.dr[7] = dr7.raw; 1460 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1461 r1.dr[7]); 1462 1463 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1464 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1465 1466 DPRINTF("Call CONTINUE for the child process\n"); 1467 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1468 1469 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1470 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1471 1472 validate_status_stopped(status, sigval); 1473 1474 DPRINTF("Before resuming the child process where it left off and " 1475 "without signal to be sent\n"); 1476 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1477 1478 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1479 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1480 1481 validate_status_exited(status, exitval); 1482 1483 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1484 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1485 } 1486 #endif 1487 1488 #if defined(HAVE_DBREGS) 1489 ATF_TC(dbregs_dr3_trap_code); 1490 ATF_TC_HEAD(dbregs_dr3_trap_code, tc) 1491 { 1492 atf_tc_set_md_var(tc, "descr", 1493 "Verify that setting trap with DR3 triggers SIGTRAP " 1494 "(break on code execution trap)"); 1495 } 1496 1497 ATF_TC_BODY(dbregs_dr3_trap_code, tc) 1498 { 1499 const int exitval = 5; 1500 const int sigval = SIGSTOP; 1501 pid_t child, wpid; 1502 #if defined(TWAIT_HAVE_STATUS) 1503 int status; 1504 #endif 1505 struct dbreg r1; 1506 size_t i; 1507 volatile int watchme = 1; 1508 union u dr7; 1509 1510 struct ptrace_siginfo info; 1511 memset(&info, 0, sizeof(info)); 1512 1513 if (!can_we_set_dbregs()) { 1514 atf_tc_skip("Either run this test as root or set sysctl(3) " 1515 "security.models.extensions.user_set_dbregs to 1"); 1516 } 1517 1518 dr7.raw = 0; 1519 dr7.bits.global_dr3_breakpoint = 1; 1520 dr7.bits.condition_dr3 = 0; /* 0b00 -- break on code execution */ 1521 dr7.bits.len_dr3 = 0; /* 0b00 -- 1 byte */ 1522 1523 DPRINTF("Before forking process PID=%d\n", getpid()); 1524 SYSCALL_REQUIRE((child = fork()) != -1); 1525 if (child == 0) { 1526 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1527 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1528 1529 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1530 FORKEE_ASSERT(raise(sigval) == 0); 1531 1532 printf("check_happy(%d)=%d\n", watchme, check_happy(watchme)); 1533 1534 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1535 FORKEE_ASSERT(raise(sigval) == 0); 1536 1537 DPRINTF("Before exiting of the child process\n"); 1538 _exit(exitval); 1539 } 1540 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1541 1542 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1543 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1544 1545 validate_status_stopped(status, sigval); 1546 1547 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1548 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1549 1550 DPRINTF("State of the debug registers (r1):\n"); 1551 for (i = 0; i < __arraycount(r1.dr); i++) 1552 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1553 1554 r1.dr[3] = (long)(intptr_t)check_happy; 1555 DPRINTF("Set DR3 (r1.dr[3]) to new value %" PRIxREGISTER "\n", 1556 r1.dr[3]); 1557 1558 r1.dr[7] = dr7.raw; 1559 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1560 r1.dr[7]); 1561 1562 DPRINTF("New state of the debug registers (r1):\n"); 1563 for (i = 0; i < __arraycount(r1.dr); i++) 1564 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1565 1566 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1567 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1568 1569 DPRINTF("Call CONTINUE for the child process\n"); 1570 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1571 1572 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1573 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1574 1575 validate_status_stopped(status, SIGTRAP); 1576 1577 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1578 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1579 1580 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1581 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1582 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1583 info.psi_siginfo.si_errno); 1584 1585 DPRINTF("Before checking siginfo_t\n"); 1586 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); 1587 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_DBREG); 1588 1589 DPRINTF("Remove code trap from check_happy=%p\n", check_happy); 1590 dr7.bits.global_dr3_breakpoint = 0; 1591 r1.dr[7] = dr7.raw; 1592 DPRINTF("Set DR7 (r1.dr[7]) to new value %" PRIxREGISTER "\n", 1593 r1.dr[7]); 1594 1595 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1596 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1597 1598 DPRINTF("Call CONTINUE for the child process\n"); 1599 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1600 1601 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1602 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1603 1604 validate_status_stopped(status, sigval); 1605 1606 DPRINTF("Before resuming the child process where it left off and " 1607 "without signal to be sent\n"); 1608 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1609 1610 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1611 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1612 1613 validate_status_exited(status, exitval); 1614 1615 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1616 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1617 } 1618 #endif 1619 1620 static void * __used 1621 x86_main_func(void *arg) 1622 { 1623 1624 return arg; 1625 } 1626 1627 static void 1628 dbregs_dont_inherit_lwp(int reg) 1629 { 1630 const int exitval = 5; 1631 const int sigval = SIGSTOP; 1632 pid_t child, wpid; 1633 #if defined(TWAIT_HAVE_STATUS) 1634 int status; 1635 #endif 1636 ptrace_state_t state; 1637 const int slen = sizeof(state); 1638 ptrace_event_t event; 1639 const int elen = sizeof(event); 1640 pthread_t t; 1641 lwpid_t lid; 1642 size_t i; 1643 struct dbreg r1; 1644 struct dbreg r2; 1645 1646 if (!can_we_set_dbregs()) { 1647 atf_tc_skip("Either run this test as root or set sysctl(3) " 1648 "security.models.extensions.user_set_dbregs to 1"); 1649 } 1650 1651 DPRINTF("Before forking process PID=%d\n", getpid()); 1652 SYSCALL_REQUIRE((child = fork()) != -1); 1653 if (child == 0) { 1654 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1655 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1656 1657 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1658 FORKEE_ASSERT(raise(sigval) == 0); 1659 1660 FORKEE_ASSERT(!pthread_create(&t, NULL, x86_main_func, NULL)); 1661 1662 DPRINTF("Before waiting for thread to exit\n"); 1663 FORKEE_ASSERT(!pthread_join(t, NULL)); 1664 1665 DPRINTF("Before exiting of the child process\n"); 1666 _exit(exitval); 1667 } 1668 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1669 1670 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1671 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1672 1673 validate_status_stopped(status, sigval); 1674 1675 DPRINTF("Set empty EVENT_MASK for the child %d\n", child); 1676 event.pe_set_event = PTRACE_LWP_CREATE; 1677 SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); 1678 1679 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1680 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1681 1682 DPRINTF("State of the debug registers (r1):\n"); 1683 for (i = 0; i < __arraycount(r1.dr); i++) 1684 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1685 1686 r1.dr[reg] = (long)(intptr_t)check_happy; 1687 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1688 reg, reg, r1.dr[0]); 1689 1690 DPRINTF("New state of the debug registers (r1):\n"); 1691 for (i = 0; i < __arraycount(r1.dr); i++) 1692 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1693 1694 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1695 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1696 1697 DPRINTF("Before resuming the child process where it left off and " 1698 "without signal to be sent\n"); 1699 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1700 1701 DPRINTF("Before calling %s() for the child - expected stopped " 1702 "SIGTRAP\n", TWAIT_FNAME); 1703 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1704 1705 validate_status_stopped(status, SIGTRAP); 1706 1707 SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); 1708 1709 ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); 1710 1711 lid = state.pe_lwp; 1712 DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); 1713 1714 DPRINTF("Call GETDBREGS for the child process new lwp (r2)\n"); 1715 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, lid) != -1); 1716 1717 DPRINTF("State of the debug registers (r2):\n"); 1718 for (i = 0; i < __arraycount(r2.dr); i++) 1719 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1720 1721 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1722 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1723 1724 DPRINTF("Before resuming the child process where it left off and " 1725 "without signal to be sent\n"); 1726 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1727 1728 DPRINTF("Before calling %s() for the child - expected exited\n", 1729 TWAIT_FNAME); 1730 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1731 1732 validate_status_exited(status, exitval); 1733 1734 DPRINTF("Before calling %s() for the child - expected no process\n", 1735 TWAIT_FNAME); 1736 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1737 } 1738 1739 ATF_TC(dbregs_dr0_dont_inherit_lwp); 1740 ATF_TC_HEAD(dbregs_dr0_dont_inherit_lwp, tc) 1741 { 1742 atf_tc_set_md_var(tc, "descr", 1743 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1744 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 0 from " 1745 "the forker thread is not inherited"); 1746 } 1747 1748 ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc) 1749 { 1750 dbregs_dont_inherit_lwp(0); 1751 } 1752 1753 ATF_TC(dbregs_dr1_dont_inherit_lwp); 1754 ATF_TC_HEAD(dbregs_dr1_dont_inherit_lwp, tc) 1755 { 1756 atf_tc_set_md_var(tc, "descr", 1757 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1758 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 1 from " 1759 "the forker thread is not inherited"); 1760 } 1761 1762 ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc) 1763 { 1764 dbregs_dont_inherit_lwp(1); 1765 } 1766 1767 ATF_TC(dbregs_dr2_dont_inherit_lwp); 1768 ATF_TC_HEAD(dbregs_dr2_dont_inherit_lwp, tc) 1769 { 1770 atf_tc_set_md_var(tc, "descr", 1771 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1772 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 2 from " 1773 "the forker thread is not inherited"); 1774 } 1775 1776 ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc) 1777 { 1778 dbregs_dont_inherit_lwp(2); 1779 } 1780 1781 ATF_TC(dbregs_dr3_dont_inherit_lwp); 1782 ATF_TC_HEAD(dbregs_dr3_dont_inherit_lwp, tc) 1783 { 1784 atf_tc_set_md_var(tc, "descr", 1785 "Verify that 1 LWP creation is intercepted by ptrace(2) with " 1786 "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 3 from " 1787 "the forker thread is not inherited"); 1788 } 1789 1790 ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc) 1791 { 1792 dbregs_dont_inherit_lwp(3); 1793 } 1794 1795 static void 1796 dbregs_dont_inherit_execve(int reg) 1797 { 1798 const int sigval = SIGTRAP; 1799 pid_t child, wpid; 1800 #if defined(TWAIT_HAVE_STATUS) 1801 int status; 1802 #endif 1803 size_t i; 1804 struct dbreg r1; 1805 struct dbreg r2; 1806 1807 struct ptrace_siginfo info; 1808 memset(&info, 0, sizeof(info)); 1809 1810 if (!can_we_set_dbregs()) { 1811 atf_tc_skip("Either run this test as root or set sysctl(3) " 1812 "security.models.extensions.user_set_dbregs to 1"); 1813 } 1814 1815 DPRINTF("Before forking process PID=%d\n", getpid()); 1816 SYSCALL_REQUIRE((child = fork()) != -1); 1817 if (child == 0) { 1818 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 1819 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 1820 1821 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 1822 FORKEE_ASSERT(raise(sigval) == 0); 1823 1824 DPRINTF("Before calling execve(2) from child\n"); 1825 execlp("/bin/echo", "/bin/echo", NULL); 1826 1827 FORKEE_ASSERT(0 && "Not reached"); 1828 } 1829 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 1830 1831 DPRINTF("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 DPRINTF("Call GETDBREGS for the child process (r1)\n"); 1837 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1); 1838 1839 DPRINTF("State of the debug registers (r1):\n"); 1840 for (i = 0; i < __arraycount(r1.dr); i++) 1841 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1842 1843 r1.dr[reg] = (long)(intptr_t)check_happy; 1844 DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n", 1845 reg, reg, r1.dr[reg]); 1846 1847 DPRINTF("New state of the debug registers (r1):\n"); 1848 for (i = 0; i < __arraycount(r1.dr); i++) 1849 DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]); 1850 1851 DPRINTF("Call SETDBREGS for the child process (r1)\n"); 1852 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1); 1853 1854 DPRINTF("Before resuming the child process where it left off and " 1855 "without signal to be sent\n"); 1856 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1857 1858 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1859 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1860 1861 validate_status_stopped(status, sigval); 1862 1863 DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); 1864 SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); 1865 1866 DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid); 1867 DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", 1868 info.psi_siginfo.si_signo, info.psi_siginfo.si_code, 1869 info.psi_siginfo.si_errno); 1870 1871 ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); 1872 ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); 1873 1874 DPRINTF("Call GETDBREGS for the child process after execve(2)\n"); 1875 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1); 1876 1877 DPRINTF("State of the debug registers (r2):\n"); 1878 for (i = 0; i < __arraycount(r2.dr); i++) 1879 DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]); 1880 1881 DPRINTF("Assert that (r1) and (r2) are not the same\n"); 1882 ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0); 1883 1884 DPRINTF("Before resuming the child process where it left off and " 1885 "without signal to be sent\n"); 1886 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 1887 1888 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1889 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 1890 1891 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 1892 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 1893 } 1894 1895 ATF_TC(dbregs_dr0_dont_inherit_execve); 1896 ATF_TC_HEAD(dbregs_dr0_dont_inherit_execve, tc) 1897 { 1898 atf_tc_set_md_var(tc, "descr", 1899 "Verify that execve(2) is intercepted by tracer and Debug " 1900 "Register 0 is reset"); 1901 } 1902 1903 ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc) 1904 { 1905 dbregs_dont_inherit_execve(0); 1906 } 1907 1908 ATF_TC(dbregs_dr1_dont_inherit_execve); 1909 ATF_TC_HEAD(dbregs_dr1_dont_inherit_execve, tc) 1910 { 1911 atf_tc_set_md_var(tc, "descr", 1912 "Verify that execve(2) is intercepted by tracer and Debug " 1913 "Register 1 is reset"); 1914 } 1915 1916 ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc) 1917 { 1918 dbregs_dont_inherit_execve(1); 1919 } 1920 1921 ATF_TC(dbregs_dr2_dont_inherit_execve); 1922 ATF_TC_HEAD(dbregs_dr2_dont_inherit_execve, tc) 1923 { 1924 atf_tc_set_md_var(tc, "descr", 1925 "Verify that execve(2) is intercepted by tracer and Debug " 1926 "Register 2 is reset"); 1927 } 1928 1929 ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc) 1930 { 1931 dbregs_dont_inherit_execve(2); 1932 } 1933 1934 ATF_TC(dbregs_dr3_dont_inherit_execve); 1935 ATF_TC_HEAD(dbregs_dr3_dont_inherit_execve, tc) 1936 { 1937 atf_tc_set_md_var(tc, "descr", 1938 "Verify that execve(2) is intercepted by tracer and Debug " 1939 "Register 3 is reset"); 1940 } 1941 1942 ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc) 1943 { 1944 dbregs_dont_inherit_execve(3); 1945 } 1946 1947 /// ---------------------------------------------------------------------------- 1948 1949 ATF_TC(x86_cve_2018_8897); 1950 ATF_TC_HEAD(x86_cve_2018_8897, tc) 1951 { 1952 atf_tc_set_md_var(tc, "descr", 1953 "Verify mitigation for CVE-2018-8897 (POP SS debug exception)"); 1954 } 1955 1956 #define X86_CVE_2018_8897_PAGE 0x5000 /* page addressable by 32-bit registers */ 1957 1958 static void 1959 x86_cve_2018_8897_trigger(void) 1960 { 1961 /* 1962 * A function to trigger the POP SS (CVE-2018-8897) vulnerability 1963 * 1964 * ifdef __x86_64__ 1965 * 1966 * We need to switch to 32-bit mode execution on 64-bit kernel. 1967 * This is achieved with far jump instruction and GDT descriptor 1968 * set to 32-bit CS selector. The 32-bit CS selector is kernel 1969 * specific, in the NetBSD case registered as GUCODE32_SEL 1970 * that is equal to (14 (decimal) << 3) with GDT and user 1971 * privilege level (this makes it 0x73). 1972 * 1973 * In UNIX as(1) assembly x86_64 far jump is coded as ljmp. 1974 * amd64 ljmp requires an indirect address with cs:RIP. 1975 * 1976 * When we are running in 32-bit mode, it's similar to the 1977 * mode as if the binary had been launched in netbsd32. 1978 * 1979 * There are two versions of this exploit, one with RIP 1980 * relative code and the other with static addresses. 1981 * The first one is PIE code aware, the other no-PIE one. 1982 * 1983 * 1984 * After switching to the 32-bit mode we can move on to the remaining 1985 * part of the exploit. 1986 * 1987 * endif // __x86_64__ 1988 * 1989 * Set the stack pointer to the page we allocated earlier. Remember 1990 * that we put an SS selector exactly at this address, so we can pop. 1991 * 1992 * movl $0x5000,%esp 1993 * 1994 * Pop the SS selector off the stack. This reloads the SS selector, 1995 * which is fine. Remember that we set DR0 at address 0x5000, which 1996 * we are now reading. Therefore, on this instruction, the CPU will 1997 * raise a #DB exception. 1998 * 1999 * But the "pop %ss" instruction is special: it blocks exceptions 2000 * until the next instruction is executed. So the #DB that we just 2001 * raised is actually blocked. 2002 * 2003 * pop %ss 2004 * 2005 * We are still here, and didn't receive the #DB. After we execute 2006 * this instruction, the effect of "pop %ss" will disappear, and 2007 * we will receive the #DB for real. 2008 * 2009 * int $4 2010 * 2011 * Here the bug happens. We executed "int $4", so we entered the 2012 * kernel, with interrupts disabled. The #DB that was pending is 2013 * received. But, it is received immediately in kernel mode, and is 2014 * _NOT_ received when interrupts are enabled again. 2015 * 2016 * It means that, in the first instruction of the $4 handler, we 2017 * think we are safe with interrupts disabled. But we aren't, and 2018 * just got interrupted. 2019 * 2020 * The new interrupt handler doesn't handle this particular context: 2021 * we are entered in kernel mode, the previous context was kernel 2022 * mode too but it still had the user context loaded. 2023 * 2024 * We find ourselves not doing a 'swapgs'. At the end of the day, it 2025 * means that we call trap() with a curcpu() that is fully 2026 * controllable by userland. From then on, it is easy to escalate 2027 * privileges. 2028 * 2029 * With SVS it also means we don't switch CR3, so this results in a 2030 * triple fault, which this time cannot be turned to a privilege 2031 * escalation. 2032 */ 2033 2034 #if __x86_64__ 2035 #if __PIE__ 2036 void *csRIP; 2037 2038 csRIP = malloc(sizeof(int) + sizeof(short)); 2039 FORKEE_ASSERT(csRIP != NULL); 2040 2041 __asm__ __volatile__( 2042 " leal 24(%%eip), %%eax\n\t" 2043 " movq %0, %%rdx\n\t" 2044 " movl %%eax, (%%rdx)\n\t" 2045 " movw $0x73, 4(%%rdx)\n\t" 2046 " movq %1, %%rax\n\t" 2047 " ljmp *(%%rax)\n\t" 2048 " .code32\n\t" 2049 " movl $0x5000, %%esp\n\t" 2050 " pop %%ss\n\t" 2051 " int $4\n\t" 2052 " .code64\n\t" 2053 : "=m"(csRIP) 2054 : "m"(csRIP) 2055 : "%rax", "%rdx", "%rsp" 2056 ); 2057 #else /* !__PIE__ */ 2058 __asm__ __volatile__( 2059 " movq $farjmp32%=, %%rax\n\t" 2060 " ljmp *(%%rax)\n\t" 2061 "farjmp32%=:\n\t" 2062 " .long trigger32%=\n\t" 2063 " .word 0x73\n\t" 2064 " .code32\n\t" 2065 "trigger32%=:\n\t" 2066 " movl $0x5000, %%esp\n\t" 2067 " pop %%ss\n\t" 2068 " int $4\n\t" 2069 " .code64\n\t" 2070 : 2071 : 2072 : "%rax", "%rsp" 2073 ); 2074 #endif 2075 #elif __i386__ 2076 __asm__ __volatile__( 2077 "movl $0x5000, %%esp\n\t" 2078 "pop %%ss\n\t" 2079 "int $4\n\t" 2080 : 2081 : 2082 : "%esp" 2083 ); 2084 #endif 2085 } 2086 2087 ATF_TC_BODY(x86_cve_2018_8897, tc) 2088 { 2089 const int sigval = SIGSTOP; 2090 pid_t child, wpid; 2091 #if defined(TWAIT_HAVE_STATUS) 2092 int status; 2093 #endif 2094 char *trap_page; 2095 struct dbreg db; 2096 2097 2098 if (!can_we_set_dbregs()) { 2099 atf_tc_skip("Either run this test as root or set sysctl(3) " 2100 "security.models.extensions.user_set_dbregs to 1"); 2101 } 2102 2103 DPRINTF("Before forking process PID=%d\n", getpid()); 2104 SYSCALL_REQUIRE((child = fork()) != -1); 2105 if (child == 0) { 2106 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2107 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2108 2109 trap_page = mmap((void *)X86_CVE_2018_8897_PAGE, 2110 sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE, 2111 MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0); 2112 2113 /* trigger page fault */ 2114 memset(trap_page, 0, sysconf(_SC_PAGESIZE)); 2115 2116 // kernel GDT 2117 #if __x86_64__ 2118 /* SS selector (descriptor 9 (0x4f >> 3)) */ 2119 *trap_page = 0x4f; 2120 #elif __i386__ 2121 /* SS selector (descriptor 4 (0x23 >> 3)) */ 2122 *trap_page = 0x23; 2123 #endif 2124 2125 DPRINTF("Before raising %s from child\n", strsignal(sigval)); 2126 FORKEE_ASSERT(raise(sigval) == 0); 2127 2128 x86_cve_2018_8897_trigger(); 2129 2130 /* NOTREACHED */ 2131 FORKEE_ASSERTX(0 && "This shall not be reached"); 2132 } 2133 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 2134 2135 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2136 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2137 2138 validate_status_stopped(status, sigval); 2139 2140 DPRINTF("Call GETDBREGS for the child process\n"); 2141 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &db, 0) != -1); 2142 2143 /* 2144 * Set up the dbregs. We put the 0x5000 address in DR0. 2145 * It means that, the first time we touch this, the CPU will trigger a 2146 * #DB exception. 2147 */ 2148 db.dr[0] = X86_CVE_2018_8897_PAGE; 2149 db.dr[7] = 0x30003; 2150 2151 DPRINTF("Call SETDBREGS for the child process\n"); 2152 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &db, 0) != -1); 2153 2154 DPRINTF("Before resuming the child process where it left off and " 2155 "without signal to be sent\n"); 2156 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 2157 2158 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2159 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2160 2161 // In this test we receive SIGFPE, is this appropriate? 2162 // validate_status_stopped(status, SIGFPE); 2163 2164 DPRINTF("Kill the child process\n"); 2165 SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1); 2166 2167 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2168 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 2169 2170 validate_status_signaled(status, SIGKILL, 0); 2171 2172 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 2173 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 2174 } 2175 2176 /// ---------------------------------------------------------------------------- 2177 2178 union x86_test_register { 2179 struct { 2180 uint64_t a, b, c, d; 2181 } ymm; 2182 struct { 2183 uint64_t a, b; 2184 } xmm; 2185 uint64_t u64; 2186 uint32_t u32; 2187 }; 2188 2189 struct x86_test_fpu_registers { 2190 struct { 2191 uint64_t mantissa; 2192 uint16_t sign_exp; 2193 } __aligned(16) st[8]; 2194 2195 uint16_t cw; 2196 uint16_t sw; 2197 uint16_t tw; 2198 uint8_t tw_abridged; 2199 uint16_t opcode; 2200 union fp_addr ip; 2201 union fp_addr dp; 2202 }; 2203 2204 enum x86_test_regset { 2205 TEST_GPREGS, 2206 TEST_FPREGS, 2207 TEST_XMMREGS, 2208 TEST_XSTATE 2209 }; 2210 2211 /* Please keep them grouped by acceptable x86_test_regset. */ 2212 enum x86_test_registers { 2213 /* TEST_GPREGS */ 2214 GPREGS_32, 2215 GPREGS_32_EBP_ESP, 2216 GPREGS_64, 2217 GPREGS_64_R8, 2218 /* TEST_FPREGS/TEST_XMMREGS */ 2219 FPREGS_FPU, 2220 FPREGS_MM, 2221 FPREGS_XMM, 2222 /* TEST_XSTATE */ 2223 FPREGS_YMM 2224 }; 2225 2226 enum x86_test_regmode { 2227 TEST_GETREGS, 2228 TEST_SETREGS, 2229 TEST_COREDUMP 2230 }; 2231 2232 static __inline void get_gp32_regs(union x86_test_register out[]) 2233 { 2234 #if defined(__i386__) 2235 const uint32_t fill = 0x0F0F0F0F; 2236 2237 __asm__ __volatile__( 2238 /* fill registers with clobber pattern */ 2239 "movl %6, %%eax\n\t" 2240 "movl %6, %%ebx\n\t" 2241 "movl %6, %%ecx\n\t" 2242 "movl %6, %%edx\n\t" 2243 "movl %6, %%esi\n\t" 2244 "movl %6, %%edi\n\t" 2245 "\n\t" 2246 "int3\n\t" 2247 : "=a"(out[0].u32), "=b"(out[1].u32), "=c"(out[2].u32), 2248 "=d"(out[3].u32), "=S"(out[4].u32), "=D"(out[5].u32) 2249 : "g"(fill) 2250 ); 2251 #else 2252 __unreachable(); 2253 #endif 2254 } 2255 2256 static __inline void set_gp32_regs(const union x86_test_register data[]) 2257 { 2258 #if defined(__i386__) 2259 __asm__ __volatile__( 2260 "int3\n\t" 2261 : 2262 : "a"(data[0].u32), "b"(data[1].u32), "c"(data[2].u32), 2263 "d"(data[3].u32), "S"(data[4].u32), "D"(data[5].u32) 2264 : 2265 ); 2266 #else 2267 __unreachable(); 2268 #endif 2269 } 2270 2271 static __inline void get_gp32_ebp_esp_regs(union x86_test_register out[]) 2272 { 2273 #if defined(__i386__) 2274 const uint32_t fill = 0x0F0F0F0F; 2275 2276 __asm__ __volatile__( 2277 /* save original ebp & esp using our output registers */ 2278 "movl %%esp, %0\n\t" 2279 "movl %%ebp, %1\n\t" 2280 /* fill them with clobber pattern */ 2281 "movl %2, %%esp\n\t" 2282 "movl %2, %%ebp\n\t" 2283 "\n\t" 2284 "int3\n\t" 2285 "\n\t" 2286 /* restore ebp & esp, and save the result */ 2287 "xchgl %%esp, %0\n\t" 2288 "xchgl %%ebp, %1\n\t" 2289 : "=r"(out[0].u32), "=r"(out[1].u32) 2290 : "g"(fill) 2291 : 2292 ); 2293 #else 2294 __unreachable(); 2295 #endif 2296 } 2297 2298 static __inline void set_gp32_ebp_esp_regs(const union x86_test_register data[]) 2299 { 2300 #if defined(__i386__) 2301 __asm__ __volatile__( 2302 /* ebp & ebp are a bit tricky, we must not clobber them */ 2303 "movl %%esp, %%eax\n\t" 2304 "movl %%ebp, %%ebx\n\t" 2305 "movl %0, %%esp\n\t" 2306 "movl %1, %%ebp\n\t" 2307 "\n\t" 2308 "int3\n\t" 2309 "\n\t" 2310 "movl %%eax, %%esp\n\t" 2311 "movl %%ebx, %%ebp\n\t" 2312 : 2313 : "ri"(data[0].u32), "ri"(data[1].u32) 2314 : "%eax", "%ebx" 2315 ); 2316 #else 2317 __unreachable(); 2318 #endif 2319 } 2320 2321 static __inline void get_gp64_regs(union x86_test_register out[]) 2322 { 2323 #if defined(__x86_64__) 2324 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2325 2326 __asm__ __volatile__( 2327 /* save rsp & rbp */ 2328 "movq %%rsp, %6\n\t" 2329 "movq %%rbp, %7\n\t" 2330 "\n\t" 2331 /* fill registers with clobber pattern */ 2332 "movq %8, %%rax\n\t" 2333 "movq %8, %%rbx\n\t" 2334 "movq %8, %%rcx\n\t" 2335 "movq %8, %%rdx\n\t" 2336 "movq %8, %%rsp\n\t" 2337 "movq %8, %%rbp\n\t" 2338 "movq %8, %%rsi\n\t" 2339 "movq %8, %%rdi\n\t" 2340 "\n\t" 2341 "int3\n\t" 2342 "\n\t" 2343 /* swap saved & current rsp & rbp */ 2344 "xchgq %%rsp, %6\n\t" 2345 "xchgq %%rbp, %7\n\t" 2346 : "=a"(out[0].u64), "=b"(out[1].u64), "=c"(out[2].u64), 2347 "=d"(out[3].u64), "=S"(out[4].u64), "=D"(out[5].u64), 2348 "=r"(out[6].u64), "=r"(out[7].u64) 2349 : "g"(fill) 2350 ); 2351 #else 2352 __unreachable(); 2353 #endif 2354 } 2355 2356 static __inline void set_gp64_regs(const union x86_test_register data[]) 2357 { 2358 #if defined(__x86_64__) 2359 __asm__ __volatile__( 2360 /* rbp & rbp are a bit tricky, we must not clobber them */ 2361 "movq %%rsp, %%r8\n\t" 2362 "movq %%rbp, %%r9\n\t" 2363 "movq %6, %%rsp\n\t" 2364 "movq %7, %%rbp\n\t" 2365 "\n\t" 2366 "int3\n\t" 2367 "\n\t" 2368 "movq %%r8, %%rsp\n\t" 2369 "movq %%r9, %%rbp\n\t" 2370 : 2371 : "a"(data[0].u64), "b"(data[1].u64), "c"(data[2].u64), 2372 "d"(data[3].u64), "S"(data[4].u64), "D"(data[5].u64), 2373 "r"(data[6].u64), "r"(data[7].u64) 2374 : "%r8", "%r9" 2375 ); 2376 #else 2377 __unreachable(); 2378 #endif 2379 } 2380 2381 static __inline void get_gp64_r8_regs(union x86_test_register out[]) 2382 { 2383 #if defined(__x86_64__) 2384 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2385 2386 __asm__ __volatile__( 2387 /* fill registers with clobber pattern */ 2388 "movq %1, %%r8\n\t" 2389 "movq %1, %%r9\n\t" 2390 "movq %1, %%r10\n\t" 2391 "movq %1, %%r11\n\t" 2392 "movq %1, %%r12\n\t" 2393 "movq %1, %%r13\n\t" 2394 "movq %1, %%r14\n\t" 2395 "movq %1, %%r15\n\t" 2396 "\n\t" 2397 "int3\n\t" 2398 "\n\t" 2399 "movq %%r8, 0x00(%0)\n\t" 2400 "movq %%r9, 0x20(%0)\n\t" 2401 "movq %%r10, 0x40(%0)\n\t" 2402 "movq %%r11, 0x60(%0)\n\t" 2403 "movq %%r12, 0x80(%0)\n\t" 2404 "movq %%r13, 0xA0(%0)\n\t" 2405 "movq %%r14, 0xC0(%0)\n\t" 2406 "movq %%r15, 0xE0(%0)\n\t" 2407 : 2408 : "a"(out), "m"(fill) 2409 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2410 ); 2411 #else 2412 __unreachable(); 2413 #endif 2414 } 2415 2416 static __inline void set_gp64_r8_regs(const union x86_test_register data[]) 2417 { 2418 #if defined(__x86_64__) 2419 __asm__ __volatile__( 2420 "movq 0x00(%0), %%r8\n\t" 2421 "movq 0x20(%0), %%r9\n\t" 2422 "movq 0x40(%0), %%r10\n\t" 2423 "movq 0x60(%0), %%r11\n\t" 2424 "movq 0x80(%0), %%r12\n\t" 2425 "movq 0xA0(%0), %%r13\n\t" 2426 "movq 0xC0(%0), %%r14\n\t" 2427 "movq 0xE0(%0), %%r15\n\t" 2428 "int3\n\t" 2429 : 2430 : "b"(data) 2431 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2432 ); 2433 #else 2434 __unreachable(); 2435 #endif 2436 } 2437 2438 static __inline void get_fpu_regs(struct x86_test_fpu_registers *out) 2439 { 2440 struct save87 fsave; 2441 struct fxsave fxsave; 2442 2443 __CTASSERT(sizeof(out->st[0]) == 16); 2444 2445 __asm__ __volatile__( 2446 "finit\n\t" 2447 "int3\n\t" 2448 #if defined(__x86_64__) 2449 "fxsave64 %2\n\t" 2450 #else 2451 "fxsave %2\n\t" 2452 #endif 2453 "fnstenv %1\n\t" 2454 "fnclex\n\t" 2455 "fstpt 0x00(%0)\n\t" 2456 "fstpt 0x10(%0)\n\t" 2457 "fstpt 0x20(%0)\n\t" 2458 "fstpt 0x30(%0)\n\t" 2459 "fstpt 0x40(%0)\n\t" 2460 "fstpt 0x50(%0)\n\t" 2461 "fstpt 0x60(%0)\n\t" 2462 "fstpt 0x70(%0)\n\t" 2463 : 2464 : "a"(out->st), "m"(fsave), "m"(fxsave) 2465 : "st", "memory" 2466 ); 2467 2468 FORKEE_ASSERT(fsave.s87_cw == fxsave.fx_cw); 2469 FORKEE_ASSERT(fsave.s87_sw == fxsave.fx_sw); 2470 2471 /* fsave contains full tw */ 2472 out->cw = fsave.s87_cw; 2473 out->sw = fsave.s87_sw; 2474 out->tw = fsave.s87_tw; 2475 out->tw_abridged = fxsave.fx_tw; 2476 out->opcode = fxsave.fx_opcode; 2477 out->ip = fxsave.fx_ip; 2478 out->dp = fxsave.fx_dp; 2479 } 2480 2481 /* used as single-precision float */ 2482 uint32_t x86_test_zero = 0; 2483 2484 static __inline void set_fpu_regs(const struct x86_test_fpu_registers *data) 2485 { 2486 __CTASSERT(sizeof(data->st[0]) == 16); 2487 2488 __asm__ __volatile__( 2489 "finit\n\t" 2490 "fldcw %1\n\t" 2491 /* load on stack in reverse order to make it easier to read */ 2492 "fldt 0x70(%0)\n\t" 2493 "fldt 0x60(%0)\n\t" 2494 "fldt 0x50(%0)\n\t" 2495 "fldt 0x40(%0)\n\t" 2496 "fldt 0x30(%0)\n\t" 2497 "fldt 0x20(%0)\n\t" 2498 "fldt 0x10(%0)\n\t" 2499 "fldt 0x00(%0)\n\t" 2500 /* free st7 */ 2501 "ffree %%st(7)\n\t" 2502 /* this should trigger a divide-by-zero */ 2503 "fdivs (%2)\n\t" 2504 "int3\n\t" 2505 : 2506 : "a"(&data->st), "m"(data->cw), "b"(&x86_test_zero) 2507 : "st" 2508 ); 2509 } 2510 2511 __attribute__((target("mmx"))) 2512 static __inline void get_mm_regs(union x86_test_register out[]) 2513 { 2514 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2515 2516 __asm__ __volatile__( 2517 /* fill registers with clobber pattern */ 2518 "movq %1, %%mm0\n\t" 2519 "movq %1, %%mm1\n\t" 2520 "movq %1, %%mm2\n\t" 2521 "movq %1, %%mm3\n\t" 2522 "movq %1, %%mm4\n\t" 2523 "movq %1, %%mm5\n\t" 2524 "movq %1, %%mm6\n\t" 2525 "movq %1, %%mm7\n\t" 2526 "\n\t" 2527 "int3\n\t" 2528 "\n\t" 2529 "movq %%mm0, 0x00(%0)\n\t" 2530 "movq %%mm1, 0x20(%0)\n\t" 2531 "movq %%mm2, 0x40(%0)\n\t" 2532 "movq %%mm3, 0x60(%0)\n\t" 2533 "movq %%mm4, 0x80(%0)\n\t" 2534 "movq %%mm5, 0xA0(%0)\n\t" 2535 "movq %%mm6, 0xC0(%0)\n\t" 2536 "movq %%mm7, 0xE0(%0)\n\t" 2537 : 2538 : "a"(out), "m"(fill) 2539 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2540 ); 2541 } 2542 2543 __attribute__((target("mmx"))) 2544 static __inline void set_mm_regs(const union x86_test_register data[]) 2545 { 2546 __asm__ __volatile__( 2547 "movq 0x00(%0), %%mm0\n\t" 2548 "movq 0x20(%0), %%mm1\n\t" 2549 "movq 0x40(%0), %%mm2\n\t" 2550 "movq 0x60(%0), %%mm3\n\t" 2551 "movq 0x80(%0), %%mm4\n\t" 2552 "movq 0xA0(%0), %%mm5\n\t" 2553 "movq 0xC0(%0), %%mm6\n\t" 2554 "movq 0xE0(%0), %%mm7\n\t" 2555 "int3\n\t" 2556 : 2557 : "b"(data) 2558 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2559 ); 2560 } 2561 2562 __attribute__((target("sse"))) 2563 static __inline void get_xmm_regs(union x86_test_register out[]) 2564 { 2565 union x86_test_register fill __aligned(32) = { 2566 .xmm={ 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2567 }; 2568 2569 __asm__ __volatile__( 2570 /* fill registers with clobber pattern */ 2571 "movaps %1, %%xmm0\n\t" 2572 "movaps %1, %%xmm1\n\t" 2573 "movaps %1, %%xmm2\n\t" 2574 "movaps %1, %%xmm3\n\t" 2575 "movaps %1, %%xmm4\n\t" 2576 "movaps %1, %%xmm5\n\t" 2577 "movaps %1, %%xmm6\n\t" 2578 "movaps %1, %%xmm7\n\t" 2579 #if defined(__x86_64__) 2580 "movaps %1, %%xmm8\n\t" 2581 "movaps %1, %%xmm9\n\t" 2582 "movaps %1, %%xmm10\n\t" 2583 "movaps %1, %%xmm11\n\t" 2584 "movaps %1, %%xmm12\n\t" 2585 "movaps %1, %%xmm13\n\t" 2586 "movaps %1, %%xmm14\n\t" 2587 "movaps %1, %%xmm15\n\t" 2588 #endif 2589 "\n\t" 2590 "int3\n\t" 2591 "\n\t" 2592 "movaps %%xmm0, 0x000(%0)\n\t" 2593 "movaps %%xmm1, 0x020(%0)\n\t" 2594 "movaps %%xmm2, 0x040(%0)\n\t" 2595 "movaps %%xmm3, 0x060(%0)\n\t" 2596 "movaps %%xmm4, 0x080(%0)\n\t" 2597 "movaps %%xmm5, 0x0A0(%0)\n\t" 2598 "movaps %%xmm6, 0x0C0(%0)\n\t" 2599 "movaps %%xmm7, 0x0E0(%0)\n\t" 2600 #if defined(__x86_64__) 2601 "movaps %%xmm8, 0x100(%0)\n\t" 2602 "movaps %%xmm9, 0x120(%0)\n\t" 2603 "movaps %%xmm10, 0x140(%0)\n\t" 2604 "movaps %%xmm11, 0x160(%0)\n\t" 2605 "movaps %%xmm12, 0x180(%0)\n\t" 2606 "movaps %%xmm13, 0x1A0(%0)\n\t" 2607 "movaps %%xmm14, 0x1C0(%0)\n\t" 2608 "movaps %%xmm15, 0x1E0(%0)\n\t" 2609 #endif 2610 : 2611 : "a"(out), "m"(fill) 2612 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" 2613 #if defined(__x86_64__) 2614 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", 2615 "%xmm15" 2616 #endif 2617 ); 2618 } 2619 2620 __attribute__((target("sse"))) 2621 static __inline void set_xmm_regs(const union x86_test_register data[]) 2622 { 2623 __asm__ __volatile__( 2624 "movaps 0x000(%0), %%xmm0\n\t" 2625 "movaps 0x020(%0), %%xmm1\n\t" 2626 "movaps 0x040(%0), %%xmm2\n\t" 2627 "movaps 0x060(%0), %%xmm3\n\t" 2628 "movaps 0x080(%0), %%xmm4\n\t" 2629 "movaps 0x0A0(%0), %%xmm5\n\t" 2630 "movaps 0x0C0(%0), %%xmm6\n\t" 2631 "movaps 0x0E0(%0), %%xmm7\n\t" 2632 #if defined(__x86_64__) 2633 "movaps 0x100(%0), %%xmm8\n\t" 2634 "movaps 0x120(%0), %%xmm9\n\t" 2635 "movaps 0x140(%0), %%xmm10\n\t" 2636 "movaps 0x160(%0), %%xmm11\n\t" 2637 "movaps 0x180(%0), %%xmm12\n\t" 2638 "movaps 0x1A0(%0), %%xmm13\n\t" 2639 "movaps 0x1C0(%0), %%xmm14\n\t" 2640 "movaps 0x1E0(%0), %%xmm15\n\t" 2641 #endif 2642 "int3\n\t" 2643 : 2644 : "b"(data) 2645 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", 2646 "%xmm7" 2647 #if defined(__x86_64__) 2648 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", 2649 "%xmm14", "%xmm15" 2650 #endif 2651 ); 2652 } 2653 2654 __attribute__((target("avx"))) 2655 static __inline void get_ymm_regs(union x86_test_register out[]) 2656 { 2657 union x86_test_register fill __aligned(32) = { 2658 { 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2659 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2660 }; 2661 2662 __asm__ __volatile__( 2663 /* fill registers with clobber pattern */ 2664 "vmovaps %1, %%ymm0\n\t" 2665 "vmovaps %1, %%ymm1\n\t" 2666 "vmovaps %1, %%ymm2\n\t" 2667 "vmovaps %1, %%ymm3\n\t" 2668 "vmovaps %1, %%ymm4\n\t" 2669 "vmovaps %1, %%ymm5\n\t" 2670 "vmovaps %1, %%ymm6\n\t" 2671 "vmovaps %1, %%ymm7\n\t" 2672 #if defined(__x86_64__) 2673 "vmovaps %1, %%ymm8\n\t" 2674 "vmovaps %1, %%ymm9\n\t" 2675 "vmovaps %1, %%ymm10\n\t" 2676 "vmovaps %1, %%ymm11\n\t" 2677 "vmovaps %1, %%ymm12\n\t" 2678 "vmovaps %1, %%ymm13\n\t" 2679 "vmovaps %1, %%ymm14\n\t" 2680 "vmovaps %1, %%ymm15\n\t" 2681 #endif 2682 "\n\t" 2683 "int3\n\t" 2684 "\n\t" 2685 "vmovaps %%ymm0, 0x000(%0)\n\t" 2686 "vmovaps %%ymm1, 0x020(%0)\n\t" 2687 "vmovaps %%ymm2, 0x040(%0)\n\t" 2688 "vmovaps %%ymm3, 0x060(%0)\n\t" 2689 "vmovaps %%ymm4, 0x080(%0)\n\t" 2690 "vmovaps %%ymm5, 0x0A0(%0)\n\t" 2691 "vmovaps %%ymm6, 0x0C0(%0)\n\t" 2692 "vmovaps %%ymm7, 0x0E0(%0)\n\t" 2693 #if defined(__x86_64__) 2694 "vmovaps %%ymm8, 0x100(%0)\n\t" 2695 "vmovaps %%ymm9, 0x120(%0)\n\t" 2696 "vmovaps %%ymm10, 0x140(%0)\n\t" 2697 "vmovaps %%ymm11, 0x160(%0)\n\t" 2698 "vmovaps %%ymm12, 0x180(%0)\n\t" 2699 "vmovaps %%ymm13, 0x1A0(%0)\n\t" 2700 "vmovaps %%ymm14, 0x1C0(%0)\n\t" 2701 "vmovaps %%ymm15, 0x1E0(%0)\n\t" 2702 #endif 2703 : 2704 : "a"(out), "m"(fill) 2705 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7" 2706 #if defined(__x86_64__) 2707 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", 2708 "%ymm15" 2709 #endif 2710 ); 2711 } 2712 2713 __attribute__((target("avx"))) 2714 static __inline void set_ymm_regs(const union x86_test_register data[]) 2715 { 2716 __asm__ __volatile__( 2717 "vmovaps 0x000(%0), %%ymm0\n\t" 2718 "vmovaps 0x020(%0), %%ymm1\n\t" 2719 "vmovaps 0x040(%0), %%ymm2\n\t" 2720 "vmovaps 0x060(%0), %%ymm3\n\t" 2721 "vmovaps 0x080(%0), %%ymm4\n\t" 2722 "vmovaps 0x0A0(%0), %%ymm5\n\t" 2723 "vmovaps 0x0C0(%0), %%ymm6\n\t" 2724 "vmovaps 0x0E0(%0), %%ymm7\n\t" 2725 #if defined(__x86_64__) 2726 "vmovaps 0x100(%0), %%ymm8\n\t" 2727 "vmovaps 0x120(%0), %%ymm9\n\t" 2728 "vmovaps 0x140(%0), %%ymm10\n\t" 2729 "vmovaps 0x160(%0), %%ymm11\n\t" 2730 "vmovaps 0x180(%0), %%ymm12\n\t" 2731 "vmovaps 0x1A0(%0), %%ymm13\n\t" 2732 "vmovaps 0x1C0(%0), %%ymm14\n\t" 2733 "vmovaps 0x1E0(%0), %%ymm15\n\t" 2734 #endif 2735 "int3\n\t" 2736 : 2737 : "b"(data) 2738 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", 2739 "%ymm7" 2740 #if defined(__x86_64__) 2741 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", 2742 "%ymm14", "%ymm15" 2743 #endif 2744 ); 2745 } 2746 2747 static void 2748 x86_register_test(enum x86_test_regset regset, enum x86_test_registers regs, 2749 enum x86_test_regmode regmode) 2750 { 2751 const int exitval = 5; 2752 pid_t child, wpid; 2753 #if defined(TWAIT_HAVE_STATUS) 2754 const int sigval = SIGTRAP; 2755 int status; 2756 #endif 2757 struct reg gpr; 2758 struct fpreg fpr; 2759 #if defined(__i386__) 2760 struct xmmregs xmm; 2761 #endif 2762 struct xstate xst; 2763 struct iovec iov; 2764 struct fxsave* fxs = NULL; 2765 uint64_t xst_flags = 0; 2766 char core_path[] = "/tmp/core.XXXXXX"; 2767 int core_fd; 2768 2769 const union x86_test_register expected[] __aligned(32) = { 2770 {{ 0x0706050403020100, 0x0F0E0D0C0B0A0908, 2771 0x1716151413121110, 0x1F1E1D1C1B1A1918, }}, 2772 {{ 0x0807060504030201, 0x100F0E0D0C0B0A09, 2773 0x1817161514131211, 0x201F1E1D1C1B1A19, }}, 2774 {{ 0x0908070605040302, 0x11100F0E0D0C0B0A, 2775 0x1918171615141312, 0x21201F1E1D1C1B1A, }}, 2776 {{ 0x0A09080706050403, 0x1211100F0E0D0C0B, 2777 0x1A19181716151413, 0x2221201F1E1D1C1B, }}, 2778 {{ 0x0B0A090807060504, 0x131211100F0E0D0C, 2779 0x1B1A191817161514, 0x232221201F1E1D1C, }}, 2780 {{ 0x0C0B0A0908070605, 0x14131211100F0E0D, 2781 0x1C1B1A1918171615, 0x24232221201F1E1D, }}, 2782 {{ 0x0D0C0B0A09080706, 0x1514131211100F0E, 2783 0x1D1C1B1A19181716, 0x2524232221201F1E, }}, 2784 {{ 0x0E0D0C0B0A090807, 0x161514131211100F, 2785 0x1E1D1C1B1A191817, 0x262524232221201F, }}, 2786 {{ 0x0F0E0D0C0B0A0908, 0x1716151413121110, 2787 0x1F1E1D1C1B1A1918, 0x2726252423222120, }}, 2788 {{ 0x100F0E0D0C0B0A09, 0x1817161514131211, 2789 0x201F1E1D1C1B1A19, 0x2827262524232221, }}, 2790 {{ 0x11100F0E0D0C0B0A, 0x1918171615141312, 2791 0x21201F1E1D1C1B1A, 0x2928272625242322, }}, 2792 {{ 0x1211100F0E0D0C0B, 0x1A19181716151413, 2793 0x2221201F1E1D1C1B, 0x2A29282726252423, }}, 2794 {{ 0x131211100F0E0D0C, 0x1B1A191817161514, 2795 0x232221201F1E1D1C, 0x2B2A292827262524, }}, 2796 {{ 0x14131211100F0E0D, 0x1C1B1A1918171615, 2797 0x24232221201F1E1D, 0x2C2B2A2928272625, }}, 2798 {{ 0x1514131211100F0E, 0x1D1C1B1A19181716, 2799 0x2524232221201F1E, 0x2D2C2B2A29282726, }}, 2800 {{ 0x161514131211100F, 0x1E1D1C1B1A191817, 2801 0x262524232221201F, 0x2E2D2C2B2A292827, }}, 2802 }; 2803 2804 const struct x86_test_fpu_registers expected_fpu = { 2805 .st = { 2806 {0x8000000000000000, 0x4000}, /* +2.0 */ 2807 {0x3f00000000000000, 0x0000}, /* 1.654785e-4932 */ 2808 {0x0000000000000000, 0x0000}, /* +0 */ 2809 {0x0000000000000000, 0x8000}, /* -0 */ 2810 {0x8000000000000000, 0x7fff}, /* +inf */ 2811 {0x8000000000000000, 0xffff}, /* -inf */ 2812 {0xc000000000000000, 0xffff}, /* nan */ 2813 /* st(7) will be freed to test tag word better */ 2814 {0x0000000000000000, 0x0000}, /* +0 */ 2815 }, 2816 /* 0000 0011 0111 1011 2817 * PU OZDI -- unmask divide-by-zero exc. 2818 * RR --------- reserved 2819 * PC ------------ 64-bit precision 2820 * RC -------------- round to nearest 2821 * I ----------------- allow interrupts (unused) 2822 */ 2823 .cw = 0x037b, 2824 /* 1000 0000 1000 0100 2825 * SPU OZDI -- divide-by-zero exception 2826 * I ---------- interrupt (exception handling) 2827 * C CCC ------------ condition codes 2828 * TO P --------------- top register is 0 2829 * B -------------------- FPU is busy 2830 */ 2831 .sw = 0x8084, 2832 /* 1110 1010 0101 1000 2833 * R7R6 R5R4 R3R2 R1R0 2834 * nz -- non-zero (+2.0) 2835 * sp ---- special (denormal) 2836 * zrzr ------- zeroes 2837 * sp spsp ------------ specials (NaN + infinities) 2838 * em ------------------- empty register 2839 */ 2840 .tw = 0xea58, 2841 /* 0111 1111 -- registers 0 to 6 are used */ 2842 .tw_abridged = 0x7f, 2843 /* FDIV */ 2844 .opcode = 0x0033, 2845 /* random bits for IP/DP write test 2846 * keep it below 48 bits since it can be truncated 2847 */ 2848 .ip = {.fa_64 = 0x00000a9876543210}, 2849 .dp = {.fa_64 = 0x0000056789abcdef}, 2850 }; 2851 2852 bool need_32 = false, need_64 = false, need_cpuid = false; 2853 2854 switch (regs) { 2855 case GPREGS_32: 2856 case GPREGS_32_EBP_ESP: 2857 need_32 = true; 2858 break; 2859 case GPREGS_64: 2860 case GPREGS_64_R8: 2861 need_64 = true; 2862 break; 2863 case FPREGS_FPU: 2864 break; 2865 case FPREGS_MM: 2866 case FPREGS_XMM: 2867 case FPREGS_YMM: 2868 need_cpuid = true; 2869 break; 2870 } 2871 2872 if (need_32) { 2873 #if defined(__x86_64__) 2874 atf_tc_skip("Test requires 32-bit mode"); 2875 #endif 2876 } 2877 if (need_64) { 2878 #if defined(__i386__) 2879 atf_tc_skip("Test requires 64-bit mode"); 2880 #endif 2881 } 2882 2883 if (need_cpuid) { 2884 /* verify whether needed instruction sets are supported here */ 2885 unsigned int eax, ebx, ecx, edx; 2886 2887 DPRINTF("Before invoking cpuid\n"); 2888 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) 2889 atf_tc_skip("CPUID is not supported by the CPU"); 2890 2891 DPRINTF("cpuid: ECX = %08x, EDX = %08xd\n", ecx, edx); 2892 2893 switch (regs) { 2894 case FPREGS_YMM: 2895 if (!(ecx & bit_AVX)) 2896 atf_tc_skip("AVX is not supported by the CPU"); 2897 /*FALLTHROUGH*/ 2898 case FPREGS_XMM: 2899 if (!(edx & bit_SSE)) 2900 atf_tc_skip("SSE is not supported by the CPU"); 2901 break; 2902 case FPREGS_MM: 2903 if (!(edx & bit_MMX)) 2904 atf_tc_skip("MMX is not supported by the CPU"); 2905 break; 2906 case GPREGS_32: 2907 case GPREGS_32_EBP_ESP: 2908 case GPREGS_64: 2909 case GPREGS_64_R8: 2910 case FPREGS_FPU: 2911 __unreachable(); 2912 } 2913 } 2914 2915 DPRINTF("Before forking process PID=%d\n", getpid()); 2916 SYSCALL_REQUIRE((child = fork()) != -1); 2917 if (child == 0) { 2918 union x86_test_register vals[16] __aligned(32); 2919 struct x86_test_fpu_registers vals_fpu; 2920 2921 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 2922 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 2923 2924 DPRINTF("Before running assembly from child\n"); 2925 switch (regmode) { 2926 case TEST_GETREGS: 2927 case TEST_COREDUMP: 2928 switch (regs) { 2929 case GPREGS_32: 2930 set_gp32_regs(expected); 2931 break; 2932 case GPREGS_32_EBP_ESP: 2933 set_gp32_ebp_esp_regs(expected); 2934 break; 2935 case GPREGS_64: 2936 set_gp64_regs(expected); 2937 break; 2938 case GPREGS_64_R8: 2939 set_gp64_r8_regs(expected); 2940 break; 2941 case FPREGS_FPU: 2942 set_fpu_regs(&expected_fpu); 2943 break; 2944 case FPREGS_MM: 2945 set_mm_regs(expected); 2946 break; 2947 case FPREGS_XMM: 2948 set_xmm_regs(expected); 2949 break; 2950 case FPREGS_YMM: 2951 set_ymm_regs(expected); 2952 break; 2953 } 2954 break; 2955 case TEST_SETREGS: 2956 switch (regs) { 2957 case GPREGS_32: 2958 get_gp32_regs(vals); 2959 break; 2960 case GPREGS_32_EBP_ESP: 2961 get_gp32_ebp_esp_regs(vals); 2962 break; 2963 case GPREGS_64: 2964 get_gp64_regs(vals); 2965 break; 2966 case GPREGS_64_R8: 2967 get_gp64_r8_regs(vals); 2968 break; 2969 case FPREGS_FPU: 2970 get_fpu_regs(&vals_fpu); 2971 break; 2972 case FPREGS_MM: 2973 get_mm_regs(vals); 2974 break; 2975 case FPREGS_XMM: 2976 get_xmm_regs(vals); 2977 break; 2978 case FPREGS_YMM: 2979 get_ymm_regs(vals); 2980 break; 2981 } 2982 2983 DPRINTF("Before comparing results\n"); 2984 switch (regs) { 2985 case GPREGS_32: 2986 FORKEE_ASSERT(!memcmp(&vals[5].u32, 2987 &expected[5].u32, sizeof(vals->u32))); 2988 FORKEE_ASSERT(!memcmp(&vals[4].u32, 2989 &expected[4].u32, sizeof(vals->u32))); 2990 FORKEE_ASSERT(!memcmp(&vals[3].u32, 2991 &expected[3].u32, sizeof(vals->u32))); 2992 FORKEE_ASSERT(!memcmp(&vals[2].u32, 2993 &expected[2].u32, sizeof(vals->u32))); 2994 /*FALLTHROUGH*/ 2995 case GPREGS_32_EBP_ESP: 2996 FORKEE_ASSERT(!memcmp(&vals[1].u32, 2997 &expected[1].u32, sizeof(vals->u32))); 2998 FORKEE_ASSERT(!memcmp(&vals[0].u32, 2999 &expected[0].u32, sizeof(vals->u32))); 3000 break; 3001 case GPREGS_64: 3002 case GPREGS_64_R8: 3003 case FPREGS_MM: 3004 FORKEE_ASSERT(!memcmp(&vals[0].u64, 3005 &expected[0].u64, sizeof(vals->u64))); 3006 FORKEE_ASSERT(!memcmp(&vals[1].u64, 3007 &expected[1].u64, sizeof(vals->u64))); 3008 FORKEE_ASSERT(!memcmp(&vals[2].u64, 3009 &expected[2].u64, sizeof(vals->u64))); 3010 FORKEE_ASSERT(!memcmp(&vals[3].u64, 3011 &expected[3].u64, sizeof(vals->u64))); 3012 FORKEE_ASSERT(!memcmp(&vals[4].u64, 3013 &expected[4].u64, sizeof(vals->u64))); 3014 FORKEE_ASSERT(!memcmp(&vals[5].u64, 3015 &expected[5].u64, sizeof(vals->u64))); 3016 FORKEE_ASSERT(!memcmp(&vals[6].u64, 3017 &expected[6].u64, sizeof(vals->u64))); 3018 FORKEE_ASSERT(!memcmp(&vals[7].u64, 3019 &expected[7].u64, sizeof(vals->u64))); 3020 break; 3021 case FPREGS_FPU: 3022 FORKEE_ASSERT(vals_fpu.cw == expected_fpu.cw); 3023 FORKEE_ASSERT(vals_fpu.sw == expected_fpu.sw); 3024 FORKEE_ASSERT(vals_fpu.tw == expected_fpu.tw); 3025 FORKEE_ASSERT(vals_fpu.tw_abridged 3026 == expected_fpu.tw_abridged); 3027 FORKEE_ASSERT(vals_fpu.ip.fa_64 3028 == expected_fpu.ip.fa_64); 3029 FORKEE_ASSERT(vals_fpu.dp.fa_64 3030 == expected_fpu.dp.fa_64); 3031 3032 FORKEE_ASSERT(vals_fpu.st[0].sign_exp 3033 == expected_fpu.st[0].sign_exp); 3034 FORKEE_ASSERT(vals_fpu.st[0].mantissa 3035 == expected_fpu.st[0].mantissa); 3036 FORKEE_ASSERT(vals_fpu.st[1].sign_exp 3037 == expected_fpu.st[1].sign_exp); 3038 FORKEE_ASSERT(vals_fpu.st[1].mantissa 3039 == expected_fpu.st[1].mantissa); 3040 FORKEE_ASSERT(vals_fpu.st[2].sign_exp 3041 == expected_fpu.st[2].sign_exp); 3042 FORKEE_ASSERT(vals_fpu.st[2].mantissa 3043 == expected_fpu.st[2].mantissa); 3044 FORKEE_ASSERT(vals_fpu.st[3].sign_exp 3045 == expected_fpu.st[3].sign_exp); 3046 FORKEE_ASSERT(vals_fpu.st[3].mantissa 3047 == expected_fpu.st[3].mantissa); 3048 FORKEE_ASSERT(vals_fpu.st[4].sign_exp 3049 == expected_fpu.st[4].sign_exp); 3050 FORKEE_ASSERT(vals_fpu.st[4].mantissa 3051 == expected_fpu.st[4].mantissa); 3052 FORKEE_ASSERT(vals_fpu.st[5].sign_exp 3053 == expected_fpu.st[5].sign_exp); 3054 FORKEE_ASSERT(vals_fpu.st[5].mantissa 3055 == expected_fpu.st[5].mantissa); 3056 FORKEE_ASSERT(vals_fpu.st[6].sign_exp 3057 == expected_fpu.st[6].sign_exp); 3058 FORKEE_ASSERT(vals_fpu.st[6].mantissa 3059 == expected_fpu.st[6].mantissa); 3060 /* st(7) is left empty == undefined */ 3061 break; 3062 case FPREGS_XMM: 3063 FORKEE_ASSERT(!memcmp(&vals[0].xmm, 3064 &expected[0].xmm, sizeof(vals->xmm))); 3065 FORKEE_ASSERT(!memcmp(&vals[1].xmm, 3066 &expected[1].xmm, sizeof(vals->xmm))); 3067 FORKEE_ASSERT(!memcmp(&vals[2].xmm, 3068 &expected[2].xmm, sizeof(vals->xmm))); 3069 FORKEE_ASSERT(!memcmp(&vals[3].xmm, 3070 &expected[3].xmm, sizeof(vals->xmm))); 3071 FORKEE_ASSERT(!memcmp(&vals[4].xmm, 3072 &expected[4].xmm, sizeof(vals->xmm))); 3073 FORKEE_ASSERT(!memcmp(&vals[5].xmm, 3074 &expected[5].xmm, sizeof(vals->xmm))); 3075 FORKEE_ASSERT(!memcmp(&vals[6].xmm, 3076 &expected[6].xmm, sizeof(vals->xmm))); 3077 FORKEE_ASSERT(!memcmp(&vals[7].xmm, 3078 &expected[7].xmm, sizeof(vals->xmm))); 3079 #if defined(__x86_64__) 3080 FORKEE_ASSERT(!memcmp(&vals[8].xmm, 3081 &expected[8].xmm, sizeof(vals->xmm))); 3082 FORKEE_ASSERT(!memcmp(&vals[9].xmm, 3083 &expected[9].xmm, sizeof(vals->xmm))); 3084 FORKEE_ASSERT(!memcmp(&vals[10].xmm, 3085 &expected[10].xmm, sizeof(vals->xmm))); 3086 FORKEE_ASSERT(!memcmp(&vals[11].xmm, 3087 &expected[11].xmm, sizeof(vals->xmm))); 3088 FORKEE_ASSERT(!memcmp(&vals[12].xmm, 3089 &expected[12].xmm, sizeof(vals->xmm))); 3090 FORKEE_ASSERT(!memcmp(&vals[13].xmm, 3091 &expected[13].xmm, sizeof(vals->xmm))); 3092 FORKEE_ASSERT(!memcmp(&vals[14].xmm, 3093 &expected[14].xmm, sizeof(vals->xmm))); 3094 FORKEE_ASSERT(!memcmp(&vals[15].xmm, 3095 &expected[15].xmm, sizeof(vals->xmm))); 3096 #endif 3097 break; 3098 case FPREGS_YMM: 3099 FORKEE_ASSERT(!memcmp(&vals[0].ymm, 3100 &expected[0].ymm, sizeof(vals->ymm))); 3101 FORKEE_ASSERT(!memcmp(&vals[1].ymm, 3102 &expected[1].ymm, sizeof(vals->ymm))); 3103 FORKEE_ASSERT(!memcmp(&vals[2].ymm, 3104 &expected[2].ymm, sizeof(vals->ymm))); 3105 FORKEE_ASSERT(!memcmp(&vals[3].ymm, 3106 &expected[3].ymm, sizeof(vals->ymm))); 3107 FORKEE_ASSERT(!memcmp(&vals[4].ymm, 3108 &expected[4].ymm, sizeof(vals->ymm))); 3109 FORKEE_ASSERT(!memcmp(&vals[5].ymm, 3110 &expected[5].ymm, sizeof(vals->ymm))); 3111 FORKEE_ASSERT(!memcmp(&vals[6].ymm, 3112 &expected[6].ymm, sizeof(vals->ymm))); 3113 FORKEE_ASSERT(!memcmp(&vals[7].ymm, 3114 &expected[7].ymm, sizeof(vals->ymm))); 3115 #if defined(__x86_64__) 3116 FORKEE_ASSERT(!memcmp(&vals[8].ymm, 3117 &expected[8].ymm, sizeof(vals->ymm))); 3118 FORKEE_ASSERT(!memcmp(&vals[9].ymm, 3119 &expected[9].ymm, sizeof(vals->ymm))); 3120 FORKEE_ASSERT(!memcmp(&vals[10].ymm, 3121 &expected[10].ymm, sizeof(vals->ymm))); 3122 FORKEE_ASSERT(!memcmp(&vals[11].ymm, 3123 &expected[11].ymm, sizeof(vals->ymm))); 3124 FORKEE_ASSERT(!memcmp(&vals[12].ymm, 3125 &expected[12].ymm, sizeof(vals->ymm))); 3126 FORKEE_ASSERT(!memcmp(&vals[13].ymm, 3127 &expected[13].ymm, sizeof(vals->ymm))); 3128 FORKEE_ASSERT(!memcmp(&vals[14].ymm, 3129 &expected[14].ymm, sizeof(vals->ymm))); 3130 FORKEE_ASSERT(!memcmp(&vals[15].ymm, 3131 &expected[15].ymm, sizeof(vals->ymm))); 3132 #endif 3133 break; 3134 } 3135 break; 3136 } 3137 3138 DPRINTF("Before exiting of the child process\n"); 3139 _exit(exitval); 3140 } 3141 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3142 3143 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3144 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3145 3146 validate_status_stopped(status, sigval); 3147 3148 if (regset == TEST_XSTATE) { 3149 switch (regs) { 3150 case FPREGS_FPU: 3151 case FPREGS_MM: 3152 xst_flags |= XCR0_X87; 3153 break; 3154 case FPREGS_YMM: 3155 xst_flags |= XCR0_YMM_Hi128; 3156 /*FALLTHROUGH*/ 3157 case FPREGS_XMM: 3158 xst_flags |= XCR0_SSE; 3159 break; 3160 case GPREGS_32: 3161 case GPREGS_32_EBP_ESP: 3162 case GPREGS_64: 3163 case GPREGS_64_R8: 3164 __unreachable(); 3165 break; 3166 } 3167 } 3168 3169 switch (regmode) { 3170 case TEST_GETREGS: 3171 case TEST_SETREGS: 3172 if (regset == TEST_GPREGS || regs == FPREGS_FPU) { 3173 DPRINTF("Call GETREGS for the child process\n"); 3174 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) 3175 != -1); 3176 } 3177 3178 switch (regset) { 3179 case TEST_GPREGS: 3180 /* already handled above */ 3181 break; 3182 case TEST_XMMREGS: 3183 #if defined(__i386__) 3184 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3185 DPRINTF("Call GETXMMREGS for the child process\n"); 3186 SYSCALL_REQUIRE(ptrace(PT_GETXMMREGS, child, &xmm, 0) 3187 != -1); 3188 fxs = &xmm.fxstate; 3189 break; 3190 #else 3191 /*FALLTHROUGH*/ 3192 #endif 3193 case TEST_FPREGS: 3194 #if defined(__x86_64__) 3195 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3196 fxs = &fpr.fxstate; 3197 #else 3198 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_XMM); 3199 #endif 3200 DPRINTF("Call GETFPREGS for the child process\n"); 3201 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) 3202 != -1); 3203 break; 3204 case TEST_XSTATE: 3205 ATF_REQUIRE(regs >= FPREGS_FPU); 3206 iov.iov_base = &xst; 3207 iov.iov_len = sizeof(xst); 3208 3209 DPRINTF("Call GETXSTATE for the child process\n"); 3210 SYSCALL_REQUIRE(ptrace(PT_GETXSTATE, child, &iov, 0) 3211 != -1); 3212 3213 ATF_REQUIRE((xst.xs_rfbm & xst_flags) == xst_flags); 3214 switch (regmode) { 3215 case TEST_SETREGS: 3216 xst.xs_rfbm = xst_flags; 3217 xst.xs_xstate_bv = xst_flags; 3218 break; 3219 case TEST_GETREGS: 3220 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3221 == xst_flags); 3222 break; 3223 case TEST_COREDUMP: 3224 __unreachable(); 3225 break; 3226 } 3227 3228 fxs = &xst.xs_fxsave; 3229 break; 3230 } 3231 break; 3232 case TEST_COREDUMP: 3233 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 3234 close(core_fd); 3235 3236 DPRINTF("Call DUMPCORE for the child process\n"); 3237 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, 3238 strlen(core_path)) != -1); 3239 3240 if (regset == TEST_GPREGS || regs == FPREGS_FPU) { 3241 DPRINTF("Parse core file for PT_GETREGS\n"); 3242 ATF_REQUIRE_EQ(core_find_note(core_path, 3243 "NetBSD-CORE@*", PT_GETREGS, &gpr, sizeof(gpr)), 3244 sizeof(gpr)); 3245 } 3246 3247 switch (regset) { 3248 case TEST_GPREGS: 3249 /* handled above */ 3250 break; 3251 case TEST_XMMREGS: 3252 #if defined(__i386__) 3253 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3254 unlink(core_path); 3255 atf_tc_skip("XMMREGS not supported in core dumps"); 3256 break; 3257 #else 3258 /*FALLTHROUGH*/ 3259 #endif 3260 case TEST_FPREGS: 3261 #if defined(__x86_64__) 3262 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3263 fxs = &fpr.fxstate; 3264 #else 3265 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_XMM); 3266 #endif 3267 DPRINTF("Parse core file for PT_GETFPREGS\n"); 3268 ATF_REQUIRE_EQ(core_find_note(core_path, 3269 "NetBSD-CORE@*", PT_GETFPREGS, &fpr, sizeof(fpr)), 3270 sizeof(fpr)); 3271 break; 3272 case TEST_XSTATE: 3273 ATF_REQUIRE(regs >= FPREGS_FPU); 3274 DPRINTF("Parse core file for PT_GETXSTATE\n"); 3275 ATF_REQUIRE_EQ(core_find_note(core_path, 3276 "NetBSD-CORE@*", PT_GETXSTATE, &xst, sizeof(xst)), 3277 sizeof(xst)); 3278 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3279 == xst_flags); 3280 fxs = &xst.xs_fxsave; 3281 break; 3282 } 3283 unlink(core_path); 3284 } 3285 3286 #if defined(__x86_64__) 3287 #define ST_EXP(n) fxs->fx_87_ac[n].r.f87_exp_sign 3288 #define ST_MAN(n) fxs->fx_87_ac[n].r.f87_mantissa 3289 #else 3290 #define ST_EXP(n) *( \ 3291 regset == TEST_FPREGS \ 3292 ? &fpr.fstate.s87_ac[n].f87_exp_sign \ 3293 : &fxs->fx_87_ac[n].r.f87_exp_sign \ 3294 ) 3295 #define ST_MAN(n) *( \ 3296 regset == TEST_FPREGS \ 3297 ? &fpr.fstate.s87_ac[n].f87_mantissa \ 3298 : &fxs->fx_87_ac[n].r.f87_mantissa \ 3299 ) 3300 #endif 3301 3302 switch (regmode) { 3303 case TEST_GETREGS: 3304 case TEST_COREDUMP: 3305 switch (regs) { 3306 case GPREGS_32: 3307 #if defined(__i386__) 3308 ATF_CHECK_EQ((uint32_t)gpr.r_eax, expected[0].u32); 3309 ATF_CHECK_EQ((uint32_t)gpr.r_ebx, expected[1].u32); 3310 ATF_CHECK_EQ((uint32_t)gpr.r_ecx, expected[2].u32); 3311 ATF_CHECK_EQ((uint32_t)gpr.r_edx, expected[3].u32); 3312 ATF_CHECK_EQ((uint32_t)gpr.r_esi, expected[4].u32); 3313 ATF_CHECK_EQ((uint32_t)gpr.r_edi, expected[5].u32); 3314 #endif 3315 break; 3316 case GPREGS_32_EBP_ESP: 3317 #if defined(__i386__) 3318 ATF_CHECK_EQ((uint32_t)gpr.r_esp, expected[0].u32); 3319 ATF_CHECK_EQ((uint32_t)gpr.r_ebp, expected[1].u32); 3320 #endif 3321 break; 3322 case GPREGS_64: 3323 #if defined(__x86_64__) 3324 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RAX], 3325 expected[0].u64); 3326 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBX], 3327 expected[1].u64); 3328 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RCX], 3329 expected[2].u64); 3330 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDX], 3331 expected[3].u64); 3332 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSI], 3333 expected[4].u64); 3334 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDI], 3335 expected[5].u64); 3336 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSP], 3337 expected[6].u64); 3338 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBP], 3339 expected[7].u64); 3340 #endif 3341 break; 3342 case GPREGS_64_R8: 3343 #if defined(__x86_64__) 3344 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R8], 3345 expected[0].u64); 3346 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R9], 3347 expected[1].u64); 3348 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R10], 3349 expected[2].u64); 3350 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R11], 3351 expected[3].u64); 3352 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R12], 3353 expected[4].u64); 3354 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R13], 3355 expected[5].u64); 3356 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R14], 3357 expected[6].u64); 3358 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R15], 3359 expected[7].u64); 3360 #endif 3361 break; 3362 case FPREGS_FPU: 3363 #if defined(__i386__) 3364 if (regset == TEST_FPREGS) { 3365 /* GETFPREGS on i386 */ 3366 ATF_CHECK_EQ(fpr.fstate.s87_cw, 3367 expected_fpu.cw); 3368 ATF_CHECK_EQ(fpr.fstate.s87_sw, 3369 expected_fpu.sw); 3370 #if 0 /* TODO: translation from FXSAVE is broken */ 3371 ATF_CHECK_EQ(fpr.fstate.s87_tw, 3372 expected_fpu.tw); 3373 #endif 3374 ATF_CHECK_EQ(fpr.fstate.s87_opcode, 3375 expected_fpu.opcode); 3376 ATF_CHECK_EQ(fpr.fstate.s87_ip.fa_32.fa_off, 3377 (uint32_t)gpr.r_eip - 3); 3378 ATF_CHECK_EQ(fpr.fstate.s87_dp.fa_32.fa_off, 3379 (uint32_t)&x86_test_zero); 3380 /* note: fa_seg is missing on newer CPUs */ 3381 } else 3382 #endif 3383 { 3384 /* amd64 or GETXSTATE on i386 */ 3385 ATF_CHECK_EQ(fxs->fx_cw, expected_fpu.cw); 3386 ATF_CHECK_EQ(fxs->fx_sw, expected_fpu.sw); 3387 ATF_CHECK_EQ(fxs->fx_tw, 3388 expected_fpu.tw_abridged); 3389 ATF_CHECK_EQ(fxs->fx_opcode, 3390 expected_fpu.opcode); 3391 #if defined(__x86_64__) 3392 #if 0 /* TODO: kernel needs patching to call *XSAVE64 */ 3393 ATF_CHECK_EQ(fxs->fx_ip.fa_64, 3394 ((uint64_t)gpr.regs[_REG_RIP]) - 3); 3395 ATF_CHECK_EQ(fxs->fx_dp.fa_64, 3396 (uint64_t)&x86_test_zero); 3397 #endif 3398 #else 3399 ATF_CHECK_EQ(fxs->fx_ip.fa_32.fa_off, 3400 (uint32_t)gpr.r_eip - 3); 3401 ATF_CHECK_EQ(fxs->fx_dp.fa_32.fa_off, 3402 (uint32_t)&x86_test_zero); 3403 /* note: fa_seg is missing on newer CPUs */ 3404 #endif 3405 } 3406 3407 ATF_CHECK_EQ(ST_EXP(0), expected_fpu.st[0].sign_exp); 3408 ATF_CHECK_EQ(ST_MAN(0), expected_fpu.st[0].mantissa); 3409 ATF_CHECK_EQ(ST_EXP(1), expected_fpu.st[1].sign_exp); 3410 ATF_CHECK_EQ(ST_MAN(1), expected_fpu.st[1].mantissa); 3411 ATF_CHECK_EQ(ST_EXP(2), expected_fpu.st[2].sign_exp); 3412 ATF_CHECK_EQ(ST_MAN(2), expected_fpu.st[2].mantissa); 3413 ATF_CHECK_EQ(ST_EXP(3), expected_fpu.st[3].sign_exp); 3414 ATF_CHECK_EQ(ST_MAN(3), expected_fpu.st[3].mantissa); 3415 ATF_CHECK_EQ(ST_EXP(4), expected_fpu.st[4].sign_exp); 3416 ATF_CHECK_EQ(ST_MAN(4), expected_fpu.st[4].mantissa); 3417 ATF_CHECK_EQ(ST_EXP(5), expected_fpu.st[5].sign_exp); 3418 ATF_CHECK_EQ(ST_MAN(5), expected_fpu.st[5].mantissa); 3419 ATF_CHECK_EQ(ST_EXP(6), expected_fpu.st[6].sign_exp); 3420 ATF_CHECK_EQ(ST_MAN(6), expected_fpu.st[6].mantissa); 3421 ATF_CHECK_EQ(ST_EXP(7), expected_fpu.st[7].sign_exp); 3422 ATF_CHECK_EQ(ST_MAN(7), expected_fpu.st[7].mantissa); 3423 break; 3424 case FPREGS_MM: 3425 ATF_CHECK_EQ(ST_MAN(0), expected[0].u64); 3426 ATF_CHECK_EQ(ST_MAN(1), expected[1].u64); 3427 ATF_CHECK_EQ(ST_MAN(2), expected[2].u64); 3428 ATF_CHECK_EQ(ST_MAN(3), expected[3].u64); 3429 ATF_CHECK_EQ(ST_MAN(4), expected[4].u64); 3430 ATF_CHECK_EQ(ST_MAN(5), expected[5].u64); 3431 ATF_CHECK_EQ(ST_MAN(6), expected[6].u64); 3432 ATF_CHECK_EQ(ST_MAN(7), expected[7].u64); 3433 break; 3434 case FPREGS_YMM: 3435 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[0], 3436 &expected[0].ymm.c, sizeof(expected->ymm)/2)); 3437 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[1], 3438 &expected[1].ymm.c, sizeof(expected->ymm)/2)); 3439 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[2], 3440 &expected[2].ymm.c, sizeof(expected->ymm)/2)); 3441 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[3], 3442 &expected[3].ymm.c, sizeof(expected->ymm)/2)); 3443 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[4], 3444 &expected[4].ymm.c, sizeof(expected->ymm)/2)); 3445 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[5], 3446 &expected[5].ymm.c, sizeof(expected->ymm)/2)); 3447 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[6], 3448 &expected[6].ymm.c, sizeof(expected->ymm)/2)); 3449 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[7], 3450 &expected[7].ymm.c, sizeof(expected->ymm)/2)); 3451 #if defined(__x86_64__) 3452 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[8], 3453 &expected[8].ymm.c, sizeof(expected->ymm)/2)); 3454 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[9], 3455 &expected[9].ymm.c, sizeof(expected->ymm)/2)); 3456 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[10], 3457 &expected[10].ymm.c, sizeof(expected->ymm)/2)); 3458 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[11], 3459 &expected[11].ymm.c, sizeof(expected->ymm)/2)); 3460 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[12], 3461 &expected[12].ymm.c, sizeof(expected->ymm)/2)); 3462 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[13], 3463 &expected[13].ymm.c, sizeof(expected->ymm)/2)); 3464 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[14], 3465 &expected[14].ymm.c, sizeof(expected->ymm)/2)); 3466 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[15], 3467 &expected[15].ymm.c, sizeof(expected->ymm)/2)); 3468 #endif 3469 /*FALLTHROUGH*/ 3470 case FPREGS_XMM: 3471 ATF_CHECK(!memcmp(&fxs->fx_xmm[0], &expected[0].ymm.a, 3472 sizeof(expected->ymm)/2)); 3473 ATF_CHECK(!memcmp(&fxs->fx_xmm[1], &expected[1].ymm.a, 3474 sizeof(expected->ymm)/2)); 3475 ATF_CHECK(!memcmp(&fxs->fx_xmm[2], &expected[2].ymm.a, 3476 sizeof(expected->ymm)/2)); 3477 ATF_CHECK(!memcmp(&fxs->fx_xmm[3], &expected[3].ymm.a, 3478 sizeof(expected->ymm)/2)); 3479 ATF_CHECK(!memcmp(&fxs->fx_xmm[4], &expected[4].ymm.a, 3480 sizeof(expected->ymm)/2)); 3481 ATF_CHECK(!memcmp(&fxs->fx_xmm[5], &expected[5].ymm.a, 3482 sizeof(expected->ymm)/2)); 3483 ATF_CHECK(!memcmp(&fxs->fx_xmm[6], &expected[6].ymm.a, 3484 sizeof(expected->ymm)/2)); 3485 ATF_CHECK(!memcmp(&fxs->fx_xmm[7], &expected[7].ymm.a, 3486 sizeof(expected->ymm)/2)); 3487 #if defined(__x86_64__) 3488 ATF_CHECK(!memcmp(&fxs->fx_xmm[8], &expected[8].ymm.a, 3489 sizeof(expected->ymm)/2)); 3490 ATF_CHECK(!memcmp(&fxs->fx_xmm[9], &expected[9].ymm.a, 3491 sizeof(expected->ymm)/2)); 3492 ATF_CHECK(!memcmp(&fxs->fx_xmm[10], &expected[10].ymm.a, 3493 sizeof(expected->ymm)/2)); 3494 ATF_CHECK(!memcmp(&fxs->fx_xmm[11], &expected[11].ymm.a, 3495 sizeof(expected->ymm)/2)); 3496 ATF_CHECK(!memcmp(&fxs->fx_xmm[12], &expected[12].ymm.a, 3497 sizeof(expected->ymm)/2)); 3498 ATF_CHECK(!memcmp(&fxs->fx_xmm[13], &expected[13].ymm.a, 3499 sizeof(expected->ymm)/2)); 3500 ATF_CHECK(!memcmp(&fxs->fx_xmm[14], &expected[14].ymm.a, 3501 sizeof(expected->ymm)/2)); 3502 ATF_CHECK(!memcmp(&fxs->fx_xmm[15], &expected[15].ymm.a, 3503 sizeof(expected->ymm)/2)); 3504 #endif 3505 break; 3506 } 3507 break; 3508 case TEST_SETREGS: 3509 switch (regs) { 3510 case GPREGS_32: 3511 #if defined(__i386__) 3512 gpr.r_eax = expected[0].u32; 3513 gpr.r_ebx = expected[1].u32; 3514 gpr.r_ecx = expected[2].u32; 3515 gpr.r_edx = expected[3].u32; 3516 gpr.r_esi = expected[4].u32; 3517 gpr.r_edi = expected[5].u32; 3518 #endif 3519 break; 3520 case GPREGS_32_EBP_ESP: 3521 #if defined(__i386__) 3522 gpr.r_esp = expected[0].u32; 3523 gpr.r_ebp = expected[1].u32; 3524 #endif 3525 break; 3526 case GPREGS_64: 3527 #if defined(__x86_64__) 3528 gpr.regs[_REG_RAX] = expected[0].u64; 3529 gpr.regs[_REG_RBX] = expected[1].u64; 3530 gpr.regs[_REG_RCX] = expected[2].u64; 3531 gpr.regs[_REG_RDX] = expected[3].u64; 3532 gpr.regs[_REG_RSI] = expected[4].u64; 3533 gpr.regs[_REG_RDI] = expected[5].u64; 3534 gpr.regs[_REG_RSP] = expected[6].u64; 3535 gpr.regs[_REG_RBP] = expected[7].u64; 3536 #endif 3537 break; 3538 case GPREGS_64_R8: 3539 #if defined(__x86_64__) 3540 gpr.regs[_REG_R8] = expected[0].u64; 3541 gpr.regs[_REG_R9] = expected[1].u64; 3542 gpr.regs[_REG_R10] = expected[2].u64; 3543 gpr.regs[_REG_R11] = expected[3].u64; 3544 gpr.regs[_REG_R12] = expected[4].u64; 3545 gpr.regs[_REG_R13] = expected[5].u64; 3546 gpr.regs[_REG_R14] = expected[6].u64; 3547 gpr.regs[_REG_R15] = expected[7].u64; 3548 #endif 3549 break; 3550 case FPREGS_FPU: 3551 #if defined(__i386__) 3552 if (regset == TEST_FPREGS) { 3553 /* SETFPREGS on i386 */ 3554 fpr.fstate.s87_cw = expected_fpu.cw; 3555 fpr.fstate.s87_sw = expected_fpu.sw; 3556 //#if 0 /* TODO: translation from FXSAVE is broken */ 3557 fpr.fstate.s87_tw = expected_fpu.tw; 3558 //#endif 3559 fpr.fstate.s87_opcode = expected_fpu.opcode; 3560 fpr.fstate.s87_ip = expected_fpu.ip; 3561 fpr.fstate.s87_dp = expected_fpu.dp; 3562 } else 3563 #endif /*defined(__i386__)*/ 3564 { 3565 /* amd64 or SETXSTATE on i386 */ 3566 fxs->fx_cw = expected_fpu.cw; 3567 fxs->fx_sw = expected_fpu.sw; 3568 fxs->fx_tw = expected_fpu.tw_abridged; 3569 fxs->fx_opcode = expected_fpu.opcode; 3570 fxs->fx_ip = expected_fpu.ip; 3571 fxs->fx_dp = expected_fpu.dp; 3572 } 3573 3574 ST_EXP(0) = expected_fpu.st[0].sign_exp; 3575 ST_MAN(0) = expected_fpu.st[0].mantissa; 3576 ST_EXP(1) = expected_fpu.st[1].sign_exp; 3577 ST_MAN(1) = expected_fpu.st[1].mantissa; 3578 ST_EXP(2) = expected_fpu.st[2].sign_exp; 3579 ST_MAN(2) = expected_fpu.st[2].mantissa; 3580 ST_EXP(3) = expected_fpu.st[3].sign_exp; 3581 ST_MAN(3) = expected_fpu.st[3].mantissa; 3582 ST_EXP(4) = expected_fpu.st[4].sign_exp; 3583 ST_MAN(4) = expected_fpu.st[4].mantissa; 3584 ST_EXP(5) = expected_fpu.st[5].sign_exp; 3585 ST_MAN(5) = expected_fpu.st[5].mantissa; 3586 ST_EXP(6) = expected_fpu.st[6].sign_exp; 3587 ST_MAN(6) = expected_fpu.st[6].mantissa; 3588 ST_EXP(7) = expected_fpu.st[7].sign_exp; 3589 ST_MAN(7) = expected_fpu.st[7].mantissa; 3590 break; 3591 case FPREGS_MM: 3592 ST_MAN(0) = expected[0].u64; 3593 ST_MAN(1) = expected[1].u64; 3594 ST_MAN(2) = expected[2].u64; 3595 ST_MAN(3) = expected[3].u64; 3596 ST_MAN(4) = expected[4].u64; 3597 ST_MAN(5) = expected[5].u64; 3598 ST_MAN(6) = expected[6].u64; 3599 ST_MAN(7) = expected[7].u64; 3600 break; 3601 case FPREGS_YMM: 3602 memcpy(&xst.xs_ymm_hi128.xs_ymm[0], 3603 &expected[0].ymm.c, sizeof(expected->ymm)/2); 3604 memcpy(&xst.xs_ymm_hi128.xs_ymm[1], 3605 &expected[1].ymm.c, sizeof(expected->ymm)/2); 3606 memcpy(&xst.xs_ymm_hi128.xs_ymm[2], 3607 &expected[2].ymm.c, sizeof(expected->ymm)/2); 3608 memcpy(&xst.xs_ymm_hi128.xs_ymm[3], 3609 &expected[3].ymm.c, sizeof(expected->ymm)/2); 3610 memcpy(&xst.xs_ymm_hi128.xs_ymm[4], 3611 &expected[4].ymm.c, sizeof(expected->ymm)/2); 3612 memcpy(&xst.xs_ymm_hi128.xs_ymm[5], 3613 &expected[5].ymm.c, sizeof(expected->ymm)/2); 3614 memcpy(&xst.xs_ymm_hi128.xs_ymm[6], 3615 &expected[6].ymm.c, sizeof(expected->ymm)/2); 3616 memcpy(&xst.xs_ymm_hi128.xs_ymm[7], 3617 &expected[7].ymm.c, sizeof(expected->ymm)/2); 3618 #if defined(__x86_64__) 3619 memcpy(&xst.xs_ymm_hi128.xs_ymm[8], 3620 &expected[8].ymm.c, sizeof(expected->ymm)/2); 3621 memcpy(&xst.xs_ymm_hi128.xs_ymm[9], 3622 &expected[9].ymm.c, sizeof(expected->ymm)/2); 3623 memcpy(&xst.xs_ymm_hi128.xs_ymm[10], 3624 &expected[10].ymm.c, sizeof(expected->ymm)/2); 3625 memcpy(&xst.xs_ymm_hi128.xs_ymm[11], 3626 &expected[11].ymm.c, sizeof(expected->ymm)/2); 3627 memcpy(&xst.xs_ymm_hi128.xs_ymm[12], 3628 &expected[12].ymm.c, sizeof(expected->ymm)/2); 3629 memcpy(&xst.xs_ymm_hi128.xs_ymm[13], 3630 &expected[13].ymm.c, sizeof(expected->ymm)/2); 3631 memcpy(&xst.xs_ymm_hi128.xs_ymm[14], 3632 &expected[14].ymm.c, sizeof(expected->ymm)/2); 3633 memcpy(&xst.xs_ymm_hi128.xs_ymm[15], 3634 &expected[15].ymm.c, sizeof(expected->ymm)/2); 3635 #endif 3636 /*FALLTHROUGH*/ 3637 case FPREGS_XMM: 3638 memcpy(&fxs->fx_xmm[0], &expected[0].ymm.a, 3639 sizeof(expected->ymm)/2); 3640 memcpy(&fxs->fx_xmm[1], &expected[1].ymm.a, 3641 sizeof(expected->ymm)/2); 3642 memcpy(&fxs->fx_xmm[2], &expected[2].ymm.a, 3643 sizeof(expected->ymm)/2); 3644 memcpy(&fxs->fx_xmm[3], &expected[3].ymm.a, 3645 sizeof(expected->ymm)/2); 3646 memcpy(&fxs->fx_xmm[4], &expected[4].ymm.a, 3647 sizeof(expected->ymm)/2); 3648 memcpy(&fxs->fx_xmm[5], &expected[5].ymm.a, 3649 sizeof(expected->ymm)/2); 3650 memcpy(&fxs->fx_xmm[6], &expected[6].ymm.a, 3651 sizeof(expected->ymm)/2); 3652 memcpy(&fxs->fx_xmm[7], &expected[7].ymm.a, 3653 sizeof(expected->ymm)/2); 3654 #if defined(__x86_64__) 3655 memcpy(&fxs->fx_xmm[8], &expected[8].ymm.a, 3656 sizeof(expected->ymm)/2); 3657 memcpy(&fxs->fx_xmm[9], &expected[9].ymm.a, 3658 sizeof(expected->ymm)/2); 3659 memcpy(&fxs->fx_xmm[10], &expected[10].ymm.a, 3660 sizeof(expected->ymm)/2); 3661 memcpy(&fxs->fx_xmm[11], &expected[11].ymm.a, 3662 sizeof(expected->ymm)/2); 3663 memcpy(&fxs->fx_xmm[12], &expected[12].ymm.a, 3664 sizeof(expected->ymm)/2); 3665 memcpy(&fxs->fx_xmm[13], &expected[13].ymm.a, 3666 sizeof(expected->ymm)/2); 3667 memcpy(&fxs->fx_xmm[14], &expected[14].ymm.a, 3668 sizeof(expected->ymm)/2); 3669 memcpy(&fxs->fx_xmm[15], &expected[15].ymm.a, 3670 sizeof(expected->ymm)/2); 3671 #endif 3672 break; 3673 } 3674 3675 switch (regset) { 3676 case TEST_GPREGS: 3677 DPRINTF("Call SETREGS for the child process\n"); 3678 SYSCALL_REQUIRE(ptrace(PT_SETREGS, child, &gpr, 0) 3679 != -1); 3680 break; 3681 case TEST_XMMREGS: 3682 #if defined(__i386__) 3683 DPRINTF("Call SETXMMREGS for the child process\n"); 3684 SYSCALL_REQUIRE(ptrace(PT_SETXMMREGS, child, &xmm, 0) 3685 != -1); 3686 break; 3687 #else 3688 /*FALLTHROUGH*/ 3689 #endif 3690 case TEST_FPREGS: 3691 DPRINTF("Call SETFPREGS for the child process\n"); 3692 SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &fpr, 0) 3693 != -1); 3694 break; 3695 case TEST_XSTATE: 3696 DPRINTF("Call SETXSTATE for the child process\n"); 3697 SYSCALL_REQUIRE(ptrace(PT_SETXSTATE, child, &iov, 0) 3698 != -1); 3699 break; 3700 } 3701 break; 3702 } 3703 3704 #undef ST_EXP 3705 #undef ST_MAN 3706 3707 DPRINTF("Before resuming the child process where it left off and " 3708 "without signal to be sent\n"); 3709 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 3710 3711 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3712 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3713 3714 validate_status_exited(status, exitval); 3715 3716 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3717 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 3718 } 3719 3720 #define X86_REGISTER_TEST(test, regset, regs, regmode, descr) \ 3721 ATF_TC(test); \ 3722 ATF_TC_HEAD(test, tc) \ 3723 { \ 3724 atf_tc_set_md_var(tc, "descr", descr); \ 3725 } \ 3726 \ 3727 ATF_TC_BODY(test, tc) \ 3728 { \ 3729 x86_register_test(regset, regs, regmode); \ 3730 } 3731 3732 X86_REGISTER_TEST(x86_gpregs32_read, TEST_GPREGS, GPREGS_32, TEST_GETREGS, 3733 "Test reading basic 32-bit gp registers from debugged program " 3734 "via PT_GETREGS."); 3735 X86_REGISTER_TEST(x86_gpregs32_write, TEST_GPREGS, GPREGS_32, TEST_SETREGS, 3736 "Test writing basic 32-bit gp registers into debugged program " 3737 "via PT_SETREGS."); 3738 X86_REGISTER_TEST(x86_gpregs32_core, TEST_GPREGS, GPREGS_32, TEST_COREDUMP, 3739 "Test reading basic 32-bit gp registers from core dump."); 3740 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_read, TEST_GPREGS, GPREGS_32_EBP_ESP, 3741 TEST_GETREGS, "Test reading ebp & esp registers from debugged program " 3742 "via PT_GETREGS."); 3743 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_write, TEST_GPREGS, GPREGS_32_EBP_ESP, 3744 TEST_SETREGS, "Test writing ebp & esp registers into debugged program " 3745 "via PT_SETREGS."); 3746 X86_REGISTER_TEST(x86_gpregs32_ebp_esp_core, TEST_GPREGS, GPREGS_32_EBP_ESP, 3747 TEST_COREDUMP, "Test reading ebp & esp registers from core dump."); 3748 3749 X86_REGISTER_TEST(x86_gpregs64_read, TEST_GPREGS, GPREGS_64, TEST_GETREGS, 3750 "Test reading basic 64-bit gp registers from debugged program " 3751 "via PT_GETREGS."); 3752 X86_REGISTER_TEST(x86_gpregs64_write, TEST_GPREGS, GPREGS_64, TEST_SETREGS, 3753 "Test writing basic 64-bit gp registers into debugged program " 3754 "via PT_SETREGS."); 3755 X86_REGISTER_TEST(x86_gpregs64_core, TEST_GPREGS, GPREGS_64, TEST_COREDUMP, 3756 "Test reading basic 64-bit gp registers from core dump."); 3757 X86_REGISTER_TEST(x86_gpregs64_r8_read, TEST_GPREGS, GPREGS_64_R8, TEST_GETREGS, 3758 "Test reading r8..r15 registers from debugged program via PT_GETREGS."); 3759 X86_REGISTER_TEST(x86_gpregs64_r8_write, TEST_GPREGS, GPREGS_64_R8, 3760 TEST_SETREGS, "Test writing r8..r15 registers into debugged program " 3761 "via PT_SETREGS."); 3762 X86_REGISTER_TEST(x86_gpregs64_r8_core, TEST_GPREGS, GPREGS_64_R8, 3763 TEST_COREDUMP, "Test reading r8..r15 registers from core dump."); 3764 3765 X86_REGISTER_TEST(x86_fpregs_fpu_read, TEST_FPREGS, FPREGS_FPU, TEST_GETREGS, 3766 "Test reading base FPU registers from debugged program via PT_GETFPREGS."); 3767 X86_REGISTER_TEST(x86_fpregs_fpu_write, TEST_FPREGS, FPREGS_FPU, TEST_SETREGS, 3768 "Test writing base FPU registers into debugged program via PT_SETFPREGS."); 3769 X86_REGISTER_TEST(x86_fpregs_fpu_core, TEST_FPREGS, FPREGS_FPU, TEST_COREDUMP, 3770 "Test reading base FPU registers from coredump."); 3771 X86_REGISTER_TEST(x86_fpregs_mm_read, TEST_FPREGS, FPREGS_MM, TEST_GETREGS, 3772 "Test reading mm0..mm7 registers from debugged program " 3773 "via PT_GETFPREGS."); 3774 X86_REGISTER_TEST(x86_fpregs_mm_write, TEST_FPREGS, FPREGS_MM, TEST_SETREGS, 3775 "Test writing mm0..mm7 registers into debugged program " 3776 "via PT_SETFPREGS."); 3777 X86_REGISTER_TEST(x86_fpregs_mm_core, TEST_FPREGS, FPREGS_MM, TEST_COREDUMP, 3778 "Test reading mm0..mm7 registers from coredump."); 3779 X86_REGISTER_TEST(x86_fpregs_xmm_read, TEST_XMMREGS, FPREGS_XMM, TEST_GETREGS, 3780 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 3781 "via PT_GETFPREGS (PT_GETXMMREGS on i386)."); 3782 X86_REGISTER_TEST(x86_fpregs_xmm_write, TEST_XMMREGS, FPREGS_XMM, TEST_SETREGS, 3783 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 3784 "via PT_SETFPREGS (PT_SETXMMREGS on i386)."); 3785 X86_REGISTER_TEST(x86_fpregs_xmm_core, TEST_XMMREGS, FPREGS_XMM, TEST_COREDUMP, 3786 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump."); 3787 3788 X86_REGISTER_TEST(x86_xstate_fpu_read, TEST_XSTATE, FPREGS_FPU, TEST_GETREGS, 3789 "Test reading base FPU registers from debugged program via PT_GETXSTATE."); 3790 X86_REGISTER_TEST(x86_xstate_fpu_write, TEST_XSTATE, FPREGS_FPU, TEST_SETREGS, 3791 "Test writing base FPU registers into debugged program via PT_SETXSTATE."); 3792 X86_REGISTER_TEST(x86_xstate_fpu_core, TEST_XSTATE, FPREGS_FPU, TEST_COREDUMP, 3793 "Test reading base FPU registers from core dump via XSTATE note."); 3794 X86_REGISTER_TEST(x86_xstate_mm_read, TEST_XSTATE, FPREGS_MM, TEST_GETREGS, 3795 "Test reading mm0..mm7 registers from debugged program " 3796 "via PT_GETXSTATE."); 3797 X86_REGISTER_TEST(x86_xstate_mm_write, TEST_XSTATE, FPREGS_MM, TEST_SETREGS, 3798 "Test writing mm0..mm7 registers into debugged program " 3799 "via PT_SETXSTATE."); 3800 X86_REGISTER_TEST(x86_xstate_mm_core, TEST_XSTATE, FPREGS_MM, TEST_COREDUMP, 3801 "Test reading mm0..mm7 registers from core dump via XSTATE note."); 3802 X86_REGISTER_TEST(x86_xstate_xmm_read, TEST_XSTATE, FPREGS_XMM, TEST_GETREGS, 3803 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 3804 "via PT_GETXSTATE."); 3805 X86_REGISTER_TEST(x86_xstate_xmm_write, TEST_XSTATE, FPREGS_XMM, TEST_SETREGS, 3806 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 3807 "via PT_SETXSTATE."); 3808 X86_REGISTER_TEST(x86_xstate_xmm_core, TEST_XSTATE, FPREGS_XMM, TEST_COREDUMP, 3809 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump via XSTATE note."); 3810 X86_REGISTER_TEST(x86_xstate_ymm_read, TEST_XSTATE, FPREGS_YMM, TEST_GETREGS, 3811 "Test reading ymm0..ymm15 (..ymm7 on i386) from debugged program " 3812 "via PT_GETXSTATE."); 3813 X86_REGISTER_TEST(x86_xstate_ymm_write, TEST_XSTATE, FPREGS_YMM, TEST_SETREGS, 3814 "Test writing ymm0..ymm15 (..ymm7 on i386) into debugged program " 3815 "via PT_SETXSTATE."); 3816 X86_REGISTER_TEST(x86_xstate_ymm_core, TEST_XSTATE, FPREGS_YMM, TEST_COREDUMP, 3817 "Test reading ymm0..ymm15 (..ymm7 on i386) from coredump via XSTATE note."); 3818 3819 /// ---------------------------------------------------------------------------- 3820 3821 #if defined(TWAIT_HAVE_STATUS) 3822 3823 static void 3824 thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid) 3825 { 3826 struct dbreg r; 3827 union u dr7; 3828 3829 /* We need to set debug registers for every child */ 3830 DPRINTF("Call GETDBREGS for LWP %d\n", lwpid); 3831 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, lwpid) != -1); 3832 3833 dr7.raw = 0; 3834 /* should be set to 1 according to Intel manual, 17.2 */ 3835 dr7.bits.reserved_10 = 1; 3836 dr7.bits.local_exact_breakpt = 1; 3837 dr7.bits.global_exact_breakpt = 1; 3838 /* use DR0 for breakpoints */ 3839 dr7.bits.global_dr0_breakpoint = 1; 3840 dr7.bits.condition_dr0 = 0; /* exec */ 3841 dr7.bits.len_dr0 = 0; 3842 /* use DR1 for watchpoints */ 3843 dr7.bits.global_dr1_breakpoint = 1; 3844 dr7.bits.condition_dr1 = 1; /* write */ 3845 dr7.bits.len_dr1 = 3; /* 4 bytes */ 3846 r.dr[7] = dr7.raw; 3847 r.dr[0] = (long)(intptr_t)check_happy; 3848 r.dr[1] = (long)(intptr_t)&thread_concurrent_watchpoint_var; 3849 DPRINTF("dr0=%" PRIxREGISTER "\n", r.dr[0]); 3850 DPRINTF("dr1=%" PRIxREGISTER "\n", r.dr[1]); 3851 DPRINTF("dr7=%" PRIxREGISTER "\n", r.dr[7]); 3852 3853 DPRINTF("Call SETDBREGS for LWP %d\n", lwpid); 3854 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, lwpid) != -1); 3855 } 3856 3857 static enum thread_concurrent_sigtrap_event 3858 thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info) 3859 { 3860 enum thread_concurrent_sigtrap_event ret = TCSE_UNKNOWN; 3861 struct dbreg r; 3862 union u dr7; 3863 3864 ATF_CHECK_EQ_MSG(info->psi_siginfo.si_code, TRAP_DBREG, 3865 "lwp=%d, expected TRAP_DBREG (%d), got %d", info->psi_lwpid, 3866 TRAP_DBREG, info->psi_siginfo.si_code); 3867 3868 DPRINTF("Call GETDBREGS for LWP %d\n", info->psi_lwpid); 3869 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, info->psi_lwpid) != -1); 3870 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 3871 r.dr[6], r.dr[7]); 3872 3873 ATF_CHECK_MSG(r.dr[6] & 3, "lwp=%d, got DR6=%" PRIxREGISTER, 3874 info->psi_lwpid, r.dr[6]); 3875 3876 /* Handle only one event at a time, we should get 3877 * a separate SIGTRAP for the other one. 3878 */ 3879 if (r.dr[6] & 1) { 3880 r.dr[6] &= ~1; 3881 3882 /* We need to disable the breakpoint to move 3883 * past it. 3884 * 3885 * TODO: single-step and reenable it? 3886 */ 3887 dr7.raw = r.dr[7]; 3888 dr7.bits.global_dr0_breakpoint = 0; 3889 r.dr[7] = dr7.raw; 3890 3891 ret = TCSE_BREAKPOINT; 3892 } else if (r.dr[6] & 2) { 3893 r.dr[6] &= ~2; 3894 ret = TCSE_WATCHPOINT; 3895 } 3896 3897 DPRINTF("Call SETDBREGS for LWP %d\n", info->psi_lwpid); 3898 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 3899 r.dr[6], r.dr[7]); 3900 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, info->psi_lwpid) != -1); 3901 3902 return ret; 3903 } 3904 3905 #endif /*defined(TWAIT_HAVE_STATUS)*/ 3906 3907 /// ---------------------------------------------------------------------------- 3908 3909 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \ 3910 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \ 3911 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \ 3912 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \ 3913 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \ 3914 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \ 3915 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \ 3916 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \ 3917 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \ 3918 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \ 3919 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \ 3920 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \ 3921 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \ 3922 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \ 3923 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \ 3924 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \ 3925 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \ 3926 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \ 3927 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \ 3928 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \ 3929 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \ 3930 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \ 3931 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \ 3932 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \ 3933 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \ 3934 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \ 3935 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \ 3936 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \ 3937 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \ 3938 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \ 3939 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \ 3940 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \ 3941 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \ 3942 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \ 3943 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \ 3944 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \ 3945 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \ 3946 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \ 3947 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \ 3948 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \ 3949 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \ 3950 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \ 3951 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \ 3952 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \ 3953 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \ 3954 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \ 3955 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \ 3956 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \ 3957 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \ 3958 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \ 3959 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \ 3960 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \ 3961 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \ 3962 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \ 3963 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \ 3964 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \ 3965 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \ 3966 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \ 3967 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \ 3968 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \ 3969 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \ 3970 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve); \ 3971 ATF_TP_ADD_TC_HAVE_DBREGS(tp, x86_cve_2018_8897); \ 3972 ATF_TP_ADD_TC(tp, x86_gpregs32_read); \ 3973 ATF_TP_ADD_TC(tp, x86_gpregs32_write); \ 3974 ATF_TP_ADD_TC(tp, x86_gpregs32_core); \ 3975 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_read); \ 3976 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_write); \ 3977 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_core); \ 3978 ATF_TP_ADD_TC(tp, x86_gpregs64_read); \ 3979 ATF_TP_ADD_TC(tp, x86_gpregs64_write); \ 3980 ATF_TP_ADD_TC(tp, x86_gpregs64_core); \ 3981 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_read); \ 3982 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_write); \ 3983 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_core); \ 3984 ATF_TP_ADD_TC(tp, x86_fpregs_fpu_read); \ 3985 ATF_TP_ADD_TC(tp, x86_fpregs_fpu_write); \ 3986 ATF_TP_ADD_TC(tp, x86_fpregs_fpu_core); \ 3987 ATF_TP_ADD_TC(tp, x86_fpregs_mm_read); \ 3988 ATF_TP_ADD_TC(tp, x86_fpregs_mm_write); \ 3989 ATF_TP_ADD_TC(tp, x86_fpregs_mm_core); \ 3990 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_read); \ 3991 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_write); \ 3992 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_core); \ 3993 ATF_TP_ADD_TC(tp, x86_xstate_fpu_read); \ 3994 ATF_TP_ADD_TC(tp, x86_xstate_fpu_write); \ 3995 ATF_TP_ADD_TC(tp, x86_xstate_fpu_core); \ 3996 ATF_TP_ADD_TC(tp, x86_xstate_mm_read); \ 3997 ATF_TP_ADD_TC(tp, x86_xstate_mm_write); \ 3998 ATF_TP_ADD_TC(tp, x86_xstate_mm_core); \ 3999 ATF_TP_ADD_TC(tp, x86_xstate_xmm_read); \ 4000 ATF_TP_ADD_TC(tp, x86_xstate_xmm_write); \ 4001 ATF_TP_ADD_TC(tp, x86_xstate_xmm_core); \ 4002 ATF_TP_ADD_TC(tp, x86_xstate_ymm_read); \ 4003 ATF_TP_ADD_TC(tp, x86_xstate_ymm_write); \ 4004 ATF_TP_ADD_TC(tp, x86_xstate_ymm_core); 4005 #else 4006 #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() 4007 #endif 4008