1/* $NetBSD: t_ptrace_x86_wait.h,v 1.31 2020/10/27 08:32:36 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__) 30union 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 60ATF_TC(dbregs_print); 61ATF_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 67ATF_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 118enum dbreg_preserve_mode { 119 dbreg_preserve_mode_none, 120 dbreg_preserve_mode_yield, 121 dbreg_preserve_mode_continued 122}; 123 124static void 125dbreg_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 226ATF_TC(dbregs_preserve_dr0); 227ATF_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 233ATF_TC_BODY(dbregs_preserve_dr0, tc) 234{ 235 dbreg_preserve(0, dbreg_preserve_mode_none); 236} 237 238ATF_TC(dbregs_preserve_dr1); 239ATF_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 245ATF_TC_BODY(dbregs_preserve_dr1, tc) 246{ 247 dbreg_preserve(1, dbreg_preserve_mode_none); 248} 249 250ATF_TC(dbregs_preserve_dr2); 251ATF_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 257ATF_TC_BODY(dbregs_preserve_dr2, tc) 258{ 259 dbreg_preserve(2, dbreg_preserve_mode_none); 260} 261 262ATF_TC(dbregs_preserve_dr3); 263ATF_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 269ATF_TC_BODY(dbregs_preserve_dr3, tc) 270{ 271 dbreg_preserve(3, dbreg_preserve_mode_none); 272} 273 274ATF_TC(dbregs_preserve_dr0_yield); 275ATF_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 282ATF_TC_BODY(dbregs_preserve_dr0_yield, tc) 283{ 284 dbreg_preserve(0, dbreg_preserve_mode_yield); 285} 286 287ATF_TC(dbregs_preserve_dr1_yield); 288ATF_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 295ATF_TC_BODY(dbregs_preserve_dr1_yield, tc) 296{ 297 dbreg_preserve(0, dbreg_preserve_mode_yield); 298} 299 300ATF_TC(dbregs_preserve_dr2_yield); 301ATF_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 308ATF_TC_BODY(dbregs_preserve_dr2_yield, tc) 309{ 310 dbreg_preserve(0, dbreg_preserve_mode_yield); 311} 312 313 314ATF_TC(dbregs_preserve_dr3_yield); 315ATF_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 322ATF_TC_BODY(dbregs_preserve_dr3_yield, tc) 323{ 324 dbreg_preserve(3, dbreg_preserve_mode_yield); 325} 326 327ATF_TC(dbregs_preserve_dr0_continued); 328ATF_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 335ATF_TC_BODY(dbregs_preserve_dr0_continued, tc) 336{ 337 dbreg_preserve(0, dbreg_preserve_mode_continued); 338} 339 340ATF_TC(dbregs_preserve_dr1_continued); 341ATF_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 348ATF_TC_BODY(dbregs_preserve_dr1_continued, tc) 349{ 350 dbreg_preserve(1, dbreg_preserve_mode_continued); 351} 352 353ATF_TC(dbregs_preserve_dr2_continued); 354ATF_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 361ATF_TC_BODY(dbregs_preserve_dr2_continued, tc) 362{ 363 dbreg_preserve(2, dbreg_preserve_mode_continued); 364} 365 366ATF_TC(dbregs_preserve_dr3_continued); 367ATF_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 374ATF_TC_BODY(dbregs_preserve_dr3_continued, tc) 375{ 376 dbreg_preserve(3, dbreg_preserve_mode_continued); 377} 378 379 380static void 381dbregs_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 516ATF_TC(dbregs_dr0_trap_variable_writeonly_byte); 517ATF_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 524ATF_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 532ATF_TC(dbregs_dr1_trap_variable_writeonly_byte); 533ATF_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 540ATF_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 548ATF_TC(dbregs_dr2_trap_variable_writeonly_byte); 549ATF_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 556ATF_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 564ATF_TC(dbregs_dr3_trap_variable_writeonly_byte); 565ATF_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 572ATF_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 580ATF_TC(dbregs_dr0_trap_variable_writeonly_2bytes); 581ATF_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 588ATF_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 596ATF_TC(dbregs_dr1_trap_variable_writeonly_2bytes); 597ATF_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 604ATF_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 612ATF_TC(dbregs_dr2_trap_variable_writeonly_2bytes); 613ATF_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 620ATF_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 628ATF_TC(dbregs_dr3_trap_variable_writeonly_2bytes); 629ATF_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 636ATF_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 644ATF_TC(dbregs_dr0_trap_variable_writeonly_4bytes); 645ATF_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 652ATF_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 660ATF_TC(dbregs_dr1_trap_variable_writeonly_4bytes); 661ATF_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 668ATF_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 676ATF_TC(dbregs_dr2_trap_variable_writeonly_4bytes); 677ATF_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 684ATF_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 692ATF_TC(dbregs_dr3_trap_variable_writeonly_4bytes); 693ATF_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 700ATF_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 708ATF_TC(dbregs_dr0_trap_variable_readwrite_write_byte); 709ATF_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 716ATF_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 724ATF_TC(dbregs_dr1_trap_variable_readwrite_write_byte); 725ATF_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 732ATF_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 740ATF_TC(dbregs_dr2_trap_variable_readwrite_write_byte); 741ATF_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 748ATF_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 756ATF_TC(dbregs_dr3_trap_variable_readwrite_write_byte); 757ATF_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 764ATF_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 772ATF_TC(dbregs_dr0_trap_variable_readwrite_write_2bytes); 773ATF_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 780ATF_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 788ATF_TC(dbregs_dr1_trap_variable_readwrite_write_2bytes); 789ATF_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 796ATF_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 804ATF_TC(dbregs_dr2_trap_variable_readwrite_write_2bytes); 805ATF_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 812ATF_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 820ATF_TC(dbregs_dr3_trap_variable_readwrite_write_2bytes); 821ATF_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 828ATF_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 836ATF_TC(dbregs_dr0_trap_variable_readwrite_write_4bytes); 837ATF_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 844ATF_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 852ATF_TC(dbregs_dr1_trap_variable_readwrite_write_4bytes); 853ATF_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 860ATF_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 868ATF_TC(dbregs_dr2_trap_variable_readwrite_write_4bytes); 869ATF_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 876ATF_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 884ATF_TC(dbregs_dr3_trap_variable_readwrite_write_4bytes); 885ATF_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 892ATF_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 900ATF_TC(dbregs_dr0_trap_variable_readwrite_read_byte); 901ATF_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 908ATF_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 916ATF_TC(dbregs_dr1_trap_variable_readwrite_read_byte); 917ATF_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 924ATF_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 932ATF_TC(dbregs_dr2_trap_variable_readwrite_read_byte); 933ATF_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 940ATF_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 948ATF_TC(dbregs_dr3_trap_variable_readwrite_read_byte); 949ATF_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 956ATF_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 964ATF_TC(dbregs_dr0_trap_variable_readwrite_read_2bytes); 965ATF_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 972ATF_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 980ATF_TC(dbregs_dr1_trap_variable_readwrite_read_2bytes); 981ATF_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 988ATF_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 996ATF_TC(dbregs_dr2_trap_variable_readwrite_read_2bytes); 997ATF_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 1004ATF_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 1012ATF_TC(dbregs_dr3_trap_variable_readwrite_read_2bytes); 1013ATF_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 1020ATF_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 1028ATF_TC(dbregs_dr0_trap_variable_readwrite_read_4bytes); 1029ATF_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 1036ATF_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 1044ATF_TC(dbregs_dr1_trap_variable_readwrite_read_4bytes); 1045ATF_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 1052ATF_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 1060ATF_TC(dbregs_dr2_trap_variable_readwrite_read_4bytes); 1061ATF_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 1068ATF_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 1076ATF_TC(dbregs_dr3_trap_variable_readwrite_read_4bytes); 1077ATF_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 1084ATF_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) 1093ATF_TC(dbregs_dr0_trap_code); 1094ATF_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 1101ATF_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) 1225ATF_TC(dbregs_dr1_trap_code); 1226ATF_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 1233ATF_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) 1357ATF_TC(dbregs_dr2_trap_code); 1358ATF_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 1365ATF_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) 1489ATF_TC(dbregs_dr3_trap_code); 1490ATF_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 1497ATF_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 1620static void * __used 1621x86_main_func(void *arg) 1622{ 1623 1624 return arg; 1625} 1626 1627static void 1628dbregs_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 1739ATF_TC(dbregs_dr0_dont_inherit_lwp); 1740ATF_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 1748ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc) 1749{ 1750 dbregs_dont_inherit_lwp(0); 1751} 1752 1753ATF_TC(dbregs_dr1_dont_inherit_lwp); 1754ATF_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 1762ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc) 1763{ 1764 dbregs_dont_inherit_lwp(1); 1765} 1766 1767ATF_TC(dbregs_dr2_dont_inherit_lwp); 1768ATF_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 1776ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc) 1777{ 1778 dbregs_dont_inherit_lwp(2); 1779} 1780 1781ATF_TC(dbregs_dr3_dont_inherit_lwp); 1782ATF_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 1790ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc) 1791{ 1792 dbregs_dont_inherit_lwp(3); 1793} 1794 1795static void 1796dbregs_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 1895ATF_TC(dbregs_dr0_dont_inherit_execve); 1896ATF_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 1903ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc) 1904{ 1905 dbregs_dont_inherit_execve(0); 1906} 1907 1908ATF_TC(dbregs_dr1_dont_inherit_execve); 1909ATF_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 1916ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc) 1917{ 1918 dbregs_dont_inherit_execve(1); 1919} 1920 1921ATF_TC(dbregs_dr2_dont_inherit_execve); 1922ATF_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 1929ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc) 1930{ 1931 dbregs_dont_inherit_execve(2); 1932} 1933 1934ATF_TC(dbregs_dr3_dont_inherit_execve); 1935ATF_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 1942ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc) 1943{ 1944 dbregs_dont_inherit_execve(3); 1945} 1946 1947/// ---------------------------------------------------------------------------- 1948 1949ATF_TC(x86_cve_2018_8897); 1950ATF_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 1958static void 1959x86_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 2087ATF_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 2178union x86_test_register { 2179 struct { 2180 uint64_t a, b, c, d, e, f, g, h; 2181 } zmm; 2182 struct { 2183 uint64_t a, b, c, d; 2184 } ymm; 2185 struct { 2186 uint64_t a, b; 2187 } xmm; 2188 uint64_t u64; 2189 uint32_t u32; 2190}; 2191 2192struct x86_test_fpu_registers { 2193 struct { 2194 uint64_t mantissa; 2195 uint16_t sign_exp; 2196 } __aligned(16) st[8]; 2197 2198 uint16_t cw; 2199 uint16_t sw; 2200 uint16_t tw; 2201 uint8_t tw_abridged; 2202 uint16_t opcode; 2203 union fp_addr ip; 2204 union fp_addr dp; 2205}; 2206 2207enum x86_test_regset { 2208 TEST_GPREGS, 2209 TEST_FPREGS, 2210 TEST_XMMREGS, 2211 TEST_XSTATE 2212}; 2213 2214/* Please keep them grouped by acceptable x86_test_regset. */ 2215enum x86_test_registers { 2216 /* TEST_GPREGS */ 2217 GPREGS_32, 2218 GPREGS_32_EBP_ESP, 2219 GPREGS_64, 2220 GPREGS_64_R8, 2221 /* TEST_FPREGS/TEST_XMMREGS */ 2222 FPREGS_FPU, 2223 FPREGS_MM, 2224 FPREGS_XMM, 2225 /* TEST_XSTATE */ 2226 FPREGS_YMM, 2227 FPREGS_ZMM 2228}; 2229 2230enum x86_test_regmode { 2231 TEST_GETREGS, 2232 TEST_SETREGS, 2233 TEST_COREDUMP 2234}; 2235 2236static __inline void get_gp32_regs(union x86_test_register out[]) 2237{ 2238#if defined(__i386__) 2239 const uint32_t fill = 0x0F0F0F0F; 2240 2241 __asm__ __volatile__( 2242 /* fill registers with clobber pattern */ 2243 "movl %6, %%eax\n\t" 2244 "movl %6, %%ebx\n\t" 2245 "movl %6, %%ecx\n\t" 2246 "movl %6, %%edx\n\t" 2247 "movl %6, %%esi\n\t" 2248 "movl %6, %%edi\n\t" 2249 "\n\t" 2250 "int3\n\t" 2251 : "=a"(out[0].u32), "=b"(out[1].u32), "=c"(out[2].u32), 2252 "=d"(out[3].u32), "=S"(out[4].u32), "=D"(out[5].u32) 2253 : "g"(fill) 2254 ); 2255#else 2256 __unreachable(); 2257#endif 2258} 2259 2260static __inline void set_gp32_regs(const union x86_test_register data[]) 2261{ 2262#if defined(__i386__) 2263 __asm__ __volatile__( 2264 "int3\n\t" 2265 : 2266 : "a"(data[0].u32), "b"(data[1].u32), "c"(data[2].u32), 2267 "d"(data[3].u32), "S"(data[4].u32), "D"(data[5].u32) 2268 : 2269 ); 2270#else 2271 __unreachable(); 2272#endif 2273} 2274 2275static __inline void get_gp32_ebp_esp_regs(union x86_test_register out[]) 2276{ 2277#if defined(__i386__) 2278 const uint32_t fill = 0x0F0F0F0F; 2279 2280 __asm__ __volatile__( 2281 /* save original ebp & esp using our output registers */ 2282 "movl %%esp, %0\n\t" 2283 "movl %%ebp, %1\n\t" 2284 /* fill them with clobber pattern */ 2285 "movl %2, %%esp\n\t" 2286 "movl %2, %%ebp\n\t" 2287 "\n\t" 2288 "int3\n\t" 2289 "\n\t" 2290 /* restore ebp & esp, and save the result */ 2291 "xchgl %%esp, %0\n\t" 2292 "xchgl %%ebp, %1\n\t" 2293 : "=r"(out[0].u32), "=r"(out[1].u32) 2294 : "g"(fill) 2295 : 2296 ); 2297#else 2298 __unreachable(); 2299#endif 2300} 2301 2302static __inline void set_gp32_ebp_esp_regs(const union x86_test_register data[]) 2303{ 2304#if defined(__i386__) 2305 __asm__ __volatile__( 2306 /* ebp & ebp are a bit tricky, we must not clobber them */ 2307 "movl %%esp, %%eax\n\t" 2308 "movl %%ebp, %%ebx\n\t" 2309 "movl %0, %%esp\n\t" 2310 "movl %1, %%ebp\n\t" 2311 "\n\t" 2312 "int3\n\t" 2313 "\n\t" 2314 "movl %%eax, %%esp\n\t" 2315 "movl %%ebx, %%ebp\n\t" 2316 : 2317 : "ri"(data[0].u32), "ri"(data[1].u32) 2318 : "%eax", "%ebx" 2319 ); 2320#else 2321 __unreachable(); 2322#endif 2323} 2324 2325static __inline void get_gp64_regs(union x86_test_register out[]) 2326{ 2327#if defined(__x86_64__) 2328 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2329 2330 __asm__ __volatile__( 2331 /* save rsp & rbp */ 2332 "movq %%rsp, %6\n\t" 2333 "movq %%rbp, %7\n\t" 2334 "\n\t" 2335 /* fill registers with clobber pattern */ 2336 "movq %8, %%rax\n\t" 2337 "movq %8, %%rbx\n\t" 2338 "movq %8, %%rcx\n\t" 2339 "movq %8, %%rdx\n\t" 2340 "movq %8, %%rsp\n\t" 2341 "movq %8, %%rbp\n\t" 2342 "movq %8, %%rsi\n\t" 2343 "movq %8, %%rdi\n\t" 2344 "\n\t" 2345 "int3\n\t" 2346 "\n\t" 2347 /* swap saved & current rsp & rbp */ 2348 "xchgq %%rsp, %6\n\t" 2349 "xchgq %%rbp, %7\n\t" 2350 : "=a"(out[0].u64), "=b"(out[1].u64), "=c"(out[2].u64), 2351 "=d"(out[3].u64), "=S"(out[4].u64), "=D"(out[5].u64), 2352 "=r"(out[6].u64), "=r"(out[7].u64) 2353 : "g"(fill) 2354 ); 2355#else 2356 __unreachable(); 2357#endif 2358} 2359 2360static __inline void set_gp64_regs(const union x86_test_register data[]) 2361{ 2362#if defined(__x86_64__) 2363 __asm__ __volatile__( 2364 /* rbp & rbp are a bit tricky, we must not clobber them */ 2365 "movq %%rsp, %%r8\n\t" 2366 "movq %%rbp, %%r9\n\t" 2367 "movq %6, %%rsp\n\t" 2368 "movq %7, %%rbp\n\t" 2369 "\n\t" 2370 "int3\n\t" 2371 "\n\t" 2372 "movq %%r8, %%rsp\n\t" 2373 "movq %%r9, %%rbp\n\t" 2374 : 2375 : "a"(data[0].u64), "b"(data[1].u64), "c"(data[2].u64), 2376 "d"(data[3].u64), "S"(data[4].u64), "D"(data[5].u64), 2377 "r"(data[6].u64), "r"(data[7].u64) 2378 : "%r8", "%r9" 2379 ); 2380#else 2381 __unreachable(); 2382#endif 2383} 2384 2385static __inline void get_gp64_r8_regs(union x86_test_register out[]) 2386{ 2387#if defined(__x86_64__) 2388 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2389 2390 __asm__ __volatile__( 2391 /* fill registers with clobber pattern */ 2392 "movq %1, %%r8\n\t" 2393 "movq %1, %%r9\n\t" 2394 "movq %1, %%r10\n\t" 2395 "movq %1, %%r11\n\t" 2396 "movq %1, %%r12\n\t" 2397 "movq %1, %%r13\n\t" 2398 "movq %1, %%r14\n\t" 2399 "movq %1, %%r15\n\t" 2400 "\n\t" 2401 "int3\n\t" 2402 "\n\t" 2403 "movq %%r8, 0x000(%0)\n\t" 2404 "movq %%r9, 0x040(%0)\n\t" 2405 "movq %%r10, 0x080(%0)\n\t" 2406 "movq %%r11, 0x0C0(%0)\n\t" 2407 "movq %%r12, 0x100(%0)\n\t" 2408 "movq %%r13, 0x140(%0)\n\t" 2409 "movq %%r14, 0x180(%0)\n\t" 2410 "movq %%r15, 0x1C0(%0)\n\t" 2411 : 2412 : "a"(out), "m"(fill) 2413 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2414 ); 2415#else 2416 __unreachable(); 2417#endif 2418} 2419 2420static __inline void set_gp64_r8_regs(const union x86_test_register data[]) 2421{ 2422#if defined(__x86_64__) 2423 __asm__ __volatile__( 2424 "movq 0x000(%0), %%r8\n\t" 2425 "movq 0x040(%0), %%r9\n\t" 2426 "movq 0x080(%0), %%r10\n\t" 2427 "movq 0x0C0(%0), %%r11\n\t" 2428 "movq 0x100(%0), %%r12\n\t" 2429 "movq 0x140(%0), %%r13\n\t" 2430 "movq 0x180(%0), %%r14\n\t" 2431 "movq 0x1C0(%0), %%r15\n\t" 2432 "int3\n\t" 2433 : 2434 : "b"(data) 2435 : "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" 2436 ); 2437#else 2438 __unreachable(); 2439#endif 2440} 2441 2442static __inline void get_fpu_regs(struct x86_test_fpu_registers *out) 2443{ 2444 struct save87 fsave; 2445 struct fxsave fxsave; 2446 2447 __CTASSERT(sizeof(out->st[0]) == 16); 2448 2449 __asm__ __volatile__( 2450 "finit\n\t" 2451 "int3\n\t" 2452#if defined(__x86_64__) 2453 "fxsave64 %2\n\t" 2454#else 2455 "fxsave %2\n\t" 2456#endif 2457 "fnstenv %1\n\t" 2458 "fnclex\n\t" 2459 "fstpt 0x00(%0)\n\t" 2460 "fstpt 0x10(%0)\n\t" 2461 "fstpt 0x20(%0)\n\t" 2462 "fstpt 0x30(%0)\n\t" 2463 "fstpt 0x40(%0)\n\t" 2464 "fstpt 0x50(%0)\n\t" 2465 "fstpt 0x60(%0)\n\t" 2466 "fstpt 0x70(%0)\n\t" 2467 : 2468 : "a"(out->st), "m"(fsave), "m"(fxsave) 2469 : "st", "memory" 2470 ); 2471 2472 FORKEE_ASSERT(fsave.s87_cw == fxsave.fx_cw); 2473 FORKEE_ASSERT(fsave.s87_sw == fxsave.fx_sw); 2474 2475 /* fsave contains full tw */ 2476 out->cw = fsave.s87_cw; 2477 out->sw = fsave.s87_sw; 2478 out->tw = fsave.s87_tw; 2479 out->tw_abridged = fxsave.fx_tw; 2480 out->opcode = fxsave.fx_opcode; 2481 out->ip = fxsave.fx_ip; 2482 out->dp = fxsave.fx_dp; 2483} 2484 2485/* used as single-precision float */ 2486uint32_t x86_test_zero = 0; 2487 2488static __inline void set_fpu_regs(const struct x86_test_fpu_registers *data) 2489{ 2490 __CTASSERT(sizeof(data->st[0]) == 16); 2491 2492 __asm__ __volatile__( 2493 "finit\n\t" 2494 "fldcw %1\n\t" 2495 /* load on stack in reverse order to make it easier to read */ 2496 "fldt 0x70(%0)\n\t" 2497 "fldt 0x60(%0)\n\t" 2498 "fldt 0x50(%0)\n\t" 2499 "fldt 0x40(%0)\n\t" 2500 "fldt 0x30(%0)\n\t" 2501 "fldt 0x20(%0)\n\t" 2502 "fldt 0x10(%0)\n\t" 2503 "fldt 0x00(%0)\n\t" 2504 /* free st7 */ 2505 "ffree %%st(7)\n\t" 2506 /* this should trigger a divide-by-zero */ 2507 "fdivs (%2)\n\t" 2508 "int3\n\t" 2509 : 2510 : "a"(&data->st), "m"(data->cw), "b"(&x86_test_zero) 2511 : "st" 2512 ); 2513} 2514 2515__attribute__((target("mmx"))) 2516static __inline void get_mm_regs(union x86_test_register out[]) 2517{ 2518 const uint64_t fill = 0x0F0F0F0F0F0F0F0F; 2519 2520 __asm__ __volatile__( 2521 /* fill registers with clobber pattern */ 2522 "movq %1, %%mm0\n\t" 2523 "movq %1, %%mm1\n\t" 2524 "movq %1, %%mm2\n\t" 2525 "movq %1, %%mm3\n\t" 2526 "movq %1, %%mm4\n\t" 2527 "movq %1, %%mm5\n\t" 2528 "movq %1, %%mm6\n\t" 2529 "movq %1, %%mm7\n\t" 2530 "\n\t" 2531 "int3\n\t" 2532 "\n\t" 2533 "movq %%mm0, 0x000(%0)\n\t" 2534 "movq %%mm1, 0x040(%0)\n\t" 2535 "movq %%mm2, 0x080(%0)\n\t" 2536 "movq %%mm3, 0x0C0(%0)\n\t" 2537 "movq %%mm4, 0x100(%0)\n\t" 2538 "movq %%mm5, 0x140(%0)\n\t" 2539 "movq %%mm6, 0x180(%0)\n\t" 2540 "movq %%mm7, 0x1C0(%0)\n\t" 2541 : 2542 : "a"(out), "m"(fill) 2543 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2544 ); 2545} 2546 2547__attribute__((target("mmx"))) 2548static __inline void set_mm_regs(const union x86_test_register data[]) 2549{ 2550 __asm__ __volatile__( 2551 "movq 0x000(%0), %%mm0\n\t" 2552 "movq 0x040(%0), %%mm1\n\t" 2553 "movq 0x080(%0), %%mm2\n\t" 2554 "movq 0x0C0(%0), %%mm3\n\t" 2555 "movq 0x100(%0), %%mm4\n\t" 2556 "movq 0x140(%0), %%mm5\n\t" 2557 "movq 0x180(%0), %%mm6\n\t" 2558 "movq 0x1C0(%0), %%mm7\n\t" 2559 "int3\n\t" 2560 : 2561 : "b"(data) 2562 : "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7" 2563 ); 2564} 2565 2566__attribute__((target("sse"))) 2567static __inline void get_xmm_regs(union x86_test_register out[]) 2568{ 2569 union x86_test_register fill __aligned(32) = { 2570 .xmm={ 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F } 2571 }; 2572 2573 __asm__ __volatile__( 2574 /* fill registers with clobber pattern */ 2575 "movaps %1, %%xmm0\n\t" 2576 "movaps %1, %%xmm1\n\t" 2577 "movaps %1, %%xmm2\n\t" 2578 "movaps %1, %%xmm3\n\t" 2579 "movaps %1, %%xmm4\n\t" 2580 "movaps %1, %%xmm5\n\t" 2581 "movaps %1, %%xmm6\n\t" 2582 "movaps %1, %%xmm7\n\t" 2583#if defined(__x86_64__) 2584 "movaps %1, %%xmm8\n\t" 2585 "movaps %1, %%xmm9\n\t" 2586 "movaps %1, %%xmm10\n\t" 2587 "movaps %1, %%xmm11\n\t" 2588 "movaps %1, %%xmm12\n\t" 2589 "movaps %1, %%xmm13\n\t" 2590 "movaps %1, %%xmm14\n\t" 2591 "movaps %1, %%xmm15\n\t" 2592#endif 2593 "\n\t" 2594 "int3\n\t" 2595 "\n\t" 2596 "movaps %%xmm0, 0x000(%0)\n\t" 2597 "movaps %%xmm1, 0x040(%0)\n\t" 2598 "movaps %%xmm2, 0x080(%0)\n\t" 2599 "movaps %%xmm3, 0x0C0(%0)\n\t" 2600 "movaps %%xmm4, 0x100(%0)\n\t" 2601 "movaps %%xmm5, 0x140(%0)\n\t" 2602 "movaps %%xmm6, 0x180(%0)\n\t" 2603 "movaps %%xmm7, 0x1C0(%0)\n\t" 2604#if defined(__x86_64__) 2605 "movaps %%xmm8, 0x200(%0)\n\t" 2606 "movaps %%xmm9, 0x240(%0)\n\t" 2607 "movaps %%xmm10, 0x280(%0)\n\t" 2608 "movaps %%xmm11, 0x2C0(%0)\n\t" 2609 "movaps %%xmm12, 0x300(%0)\n\t" 2610 "movaps %%xmm13, 0x340(%0)\n\t" 2611 "movaps %%xmm14, 0x380(%0)\n\t" 2612 "movaps %%xmm15, 0x3C0(%0)\n\t" 2613#endif 2614 : 2615 : "a"(out), "m"(fill) 2616 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" 2617#if defined(__x86_64__) 2618 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", 2619 "%xmm15" 2620#endif 2621 ); 2622} 2623 2624__attribute__((target("sse"))) 2625static __inline void set_xmm_regs(const union x86_test_register data[]) 2626{ 2627 __asm__ __volatile__( 2628 "movaps 0x000(%0), %%xmm0\n\t" 2629 "movaps 0x040(%0), %%xmm1\n\t" 2630 "movaps 0x080(%0), %%xmm2\n\t" 2631 "movaps 0x0C0(%0), %%xmm3\n\t" 2632 "movaps 0x100(%0), %%xmm4\n\t" 2633 "movaps 0x140(%0), %%xmm5\n\t" 2634 "movaps 0x180(%0), %%xmm6\n\t" 2635 "movaps 0x1C0(%0), %%xmm7\n\t" 2636#if defined(__x86_64__) 2637 "movaps 0x200(%0), %%xmm8\n\t" 2638 "movaps 0x240(%0), %%xmm9\n\t" 2639 "movaps 0x280(%0), %%xmm10\n\t" 2640 "movaps 0x2C0(%0), %%xmm11\n\t" 2641 "movaps 0x300(%0), %%xmm12\n\t" 2642 "movaps 0x340(%0), %%xmm13\n\t" 2643 "movaps 0x380(%0), %%xmm14\n\t" 2644 "movaps 0x3C0(%0), %%xmm15\n\t" 2645#endif 2646 "int3\n\t" 2647 : 2648 : "b"(data) 2649 : "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", 2650 "%xmm7" 2651#if defined(__x86_64__) 2652 , "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", 2653 "%xmm14", "%xmm15" 2654#endif 2655 ); 2656} 2657 2658__attribute__((target("avx"))) 2659static __inline void get_ymm_regs(union x86_test_register out[]) 2660{ 2661 union x86_test_register fill __aligned(32) = { 2662 .ymm = { 2663 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2664 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F 2665 } 2666 }; 2667 2668 __asm__ __volatile__( 2669 /* fill registers with clobber pattern */ 2670 "vmovaps %1, %%ymm0\n\t" 2671 "vmovaps %1, %%ymm1\n\t" 2672 "vmovaps %1, %%ymm2\n\t" 2673 "vmovaps %1, %%ymm3\n\t" 2674 "vmovaps %1, %%ymm4\n\t" 2675 "vmovaps %1, %%ymm5\n\t" 2676 "vmovaps %1, %%ymm6\n\t" 2677 "vmovaps %1, %%ymm7\n\t" 2678#if defined(__x86_64__) 2679 "vmovaps %1, %%ymm8\n\t" 2680 "vmovaps %1, %%ymm9\n\t" 2681 "vmovaps %1, %%ymm10\n\t" 2682 "vmovaps %1, %%ymm11\n\t" 2683 "vmovaps %1, %%ymm12\n\t" 2684 "vmovaps %1, %%ymm13\n\t" 2685 "vmovaps %1, %%ymm14\n\t" 2686 "vmovaps %1, %%ymm15\n\t" 2687#endif 2688 "\n\t" 2689 "int3\n\t" 2690 "\n\t" 2691 "vmovaps %%ymm0, 0x000(%0)\n\t" 2692 "vmovaps %%ymm1, 0x040(%0)\n\t" 2693 "vmovaps %%ymm2, 0x080(%0)\n\t" 2694 "vmovaps %%ymm3, 0x0C0(%0)\n\t" 2695 "vmovaps %%ymm4, 0x100(%0)\n\t" 2696 "vmovaps %%ymm5, 0x140(%0)\n\t" 2697 "vmovaps %%ymm6, 0x180(%0)\n\t" 2698 "vmovaps %%ymm7, 0x1C0(%0)\n\t" 2699#if defined(__x86_64__) 2700 "vmovaps %%ymm8, 0x200(%0)\n\t" 2701 "vmovaps %%ymm9, 0x240(%0)\n\t" 2702 "vmovaps %%ymm10, 0x280(%0)\n\t" 2703 "vmovaps %%ymm11, 0x2C0(%0)\n\t" 2704 "vmovaps %%ymm12, 0x300(%0)\n\t" 2705 "vmovaps %%ymm13, 0x340(%0)\n\t" 2706 "vmovaps %%ymm14, 0x380(%0)\n\t" 2707 "vmovaps %%ymm15, 0x3C0(%0)\n\t" 2708#endif 2709 : 2710 : "a"(out), "m"(fill) 2711 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", "%ymm7" 2712#if defined(__x86_64__) 2713 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", "%ymm14", 2714 "%ymm15" 2715#endif 2716 ); 2717} 2718 2719__attribute__((target("avx"))) 2720static __inline void set_ymm_regs(const union x86_test_register data[]) 2721{ 2722 __asm__ __volatile__( 2723 "vmovaps 0x000(%0), %%ymm0\n\t" 2724 "vmovaps 0x040(%0), %%ymm1\n\t" 2725 "vmovaps 0x080(%0), %%ymm2\n\t" 2726 "vmovaps 0x0C0(%0), %%ymm3\n\t" 2727 "vmovaps 0x100(%0), %%ymm4\n\t" 2728 "vmovaps 0x140(%0), %%ymm5\n\t" 2729 "vmovaps 0x180(%0), %%ymm6\n\t" 2730 "vmovaps 0x1C0(%0), %%ymm7\n\t" 2731#if defined(__x86_64__) 2732 "vmovaps 0x200(%0), %%ymm8\n\t" 2733 "vmovaps 0x240(%0), %%ymm9\n\t" 2734 "vmovaps 0x280(%0), %%ymm10\n\t" 2735 "vmovaps 0x2C0(%0), %%ymm11\n\t" 2736 "vmovaps 0x300(%0), %%ymm12\n\t" 2737 "vmovaps 0x340(%0), %%ymm13\n\t" 2738 "vmovaps 0x380(%0), %%ymm14\n\t" 2739 "vmovaps 0x3C0(%0), %%ymm15\n\t" 2740#endif 2741 "int3\n\t" 2742 : 2743 : "b"(data) 2744 : "%ymm0", "%ymm1", "%ymm2", "%ymm3", "%ymm4", "%ymm5", "%ymm6", 2745 "%ymm7" 2746#if defined(__x86_64__) 2747 , "%ymm8", "%ymm9", "%ymm10", "%ymm11", "%ymm12", "%ymm13", 2748 "%ymm14", "%ymm15" 2749#endif 2750 ); 2751} 2752 2753__attribute__((target("avx512f"))) 2754static __inline void get_zmm_regs(union x86_test_register out[]) 2755{ 2756 union x86_test_register fill __aligned(64) = { 2757 .zmm = { 2758 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2759 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2760 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F, 2761 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F 2762 } 2763 }; 2764 2765 __asm__ __volatile__( 2766 /* fill registers with clobber pattern */ 2767 "vmovaps %1, %%zmm0\n\t" 2768 "vmovaps %1, %%zmm1\n\t" 2769 "vmovaps %1, %%zmm2\n\t" 2770 "vmovaps %1, %%zmm3\n\t" 2771 "vmovaps %1, %%zmm4\n\t" 2772 "vmovaps %1, %%zmm5\n\t" 2773 "vmovaps %1, %%zmm6\n\t" 2774 "vmovaps %1, %%zmm7\n\t" 2775#if defined(__x86_64__) 2776 "vmovaps %1, %%zmm8\n\t" 2777 "vmovaps %1, %%zmm9\n\t" 2778 "vmovaps %1, %%zmm10\n\t" 2779 "vmovaps %1, %%zmm11\n\t" 2780 "vmovaps %1, %%zmm12\n\t" 2781 "vmovaps %1, %%zmm13\n\t" 2782 "vmovaps %1, %%zmm14\n\t" 2783 "vmovaps %1, %%zmm15\n\t" 2784 "vmovaps %1, %%zmm16\n\t" 2785 "vmovaps %1, %%zmm17\n\t" 2786 "vmovaps %1, %%zmm18\n\t" 2787 "vmovaps %1, %%zmm19\n\t" 2788 "vmovaps %1, %%zmm20\n\t" 2789 "vmovaps %1, %%zmm21\n\t" 2790 "vmovaps %1, %%zmm22\n\t" 2791 "vmovaps %1, %%zmm23\n\t" 2792 "vmovaps %1, %%zmm24\n\t" 2793 "vmovaps %1, %%zmm25\n\t" 2794 "vmovaps %1, %%zmm26\n\t" 2795 "vmovaps %1, %%zmm27\n\t" 2796 "vmovaps %1, %%zmm28\n\t" 2797 "vmovaps %1, %%zmm29\n\t" 2798 "vmovaps %1, %%zmm30\n\t" 2799 "vmovaps %1, %%zmm31\n\t" 2800#endif 2801 "kmovq %1, %%k0\n\t" 2802 "kmovq %1, %%k1\n\t" 2803 "kmovq %1, %%k2\n\t" 2804 "kmovq %1, %%k3\n\t" 2805 "kmovq %1, %%k4\n\t" 2806 "kmovq %1, %%k5\n\t" 2807 "kmovq %1, %%k6\n\t" 2808 "kmovq %1, %%k7\n\t" 2809 "\n\t" 2810 "int3\n\t" 2811 "\n\t" 2812 "vmovaps %%zmm0, 0x000(%0)\n\t" 2813 "vmovaps %%zmm1, 0x040(%0)\n\t" 2814 "vmovaps %%zmm2, 0x080(%0)\n\t" 2815 "vmovaps %%zmm3, 0x0C0(%0)\n\t" 2816 "vmovaps %%zmm4, 0x100(%0)\n\t" 2817 "vmovaps %%zmm5, 0x140(%0)\n\t" 2818 "vmovaps %%zmm6, 0x180(%0)\n\t" 2819 "vmovaps %%zmm7, 0x1C0(%0)\n\t" 2820#if defined(__x86_64__) 2821 "vmovaps %%zmm8, 0x200(%0)\n\t" 2822 "vmovaps %%zmm9, 0x240(%0)\n\t" 2823 "vmovaps %%zmm10, 0x280(%0)\n\t" 2824 "vmovaps %%zmm11, 0x2C0(%0)\n\t" 2825 "vmovaps %%zmm12, 0x300(%0)\n\t" 2826 "vmovaps %%zmm13, 0x340(%0)\n\t" 2827 "vmovaps %%zmm14, 0x380(%0)\n\t" 2828 "vmovaps %%zmm15, 0x3C0(%0)\n\t" 2829 "vmovaps %%zmm16, 0x400(%0)\n\t" 2830 "vmovaps %%zmm17, 0x440(%0)\n\t" 2831 "vmovaps %%zmm18, 0x480(%0)\n\t" 2832 "vmovaps %%zmm19, 0x4C0(%0)\n\t" 2833 "vmovaps %%zmm20, 0x500(%0)\n\t" 2834 "vmovaps %%zmm21, 0x540(%0)\n\t" 2835 "vmovaps %%zmm22, 0x580(%0)\n\t" 2836 "vmovaps %%zmm23, 0x5C0(%0)\n\t" 2837 "vmovaps %%zmm24, 0x600(%0)\n\t" 2838 "vmovaps %%zmm25, 0x640(%0)\n\t" 2839 "vmovaps %%zmm26, 0x680(%0)\n\t" 2840 "vmovaps %%zmm27, 0x6C0(%0)\n\t" 2841 "vmovaps %%zmm28, 0x700(%0)\n\t" 2842 "vmovaps %%zmm29, 0x740(%0)\n\t" 2843 "vmovaps %%zmm30, 0x780(%0)\n\t" 2844 "vmovaps %%zmm31, 0x7C0(%0)\n\t" 2845#endif 2846 "kmovq %%k0, 0x800(%0)\n\t" 2847 "kmovq %%k1, 0x808(%0)\n\t" 2848 "kmovq %%k2, 0x810(%0)\n\t" 2849 "kmovq %%k3, 0x818(%0)\n\t" 2850 "kmovq %%k4, 0x820(%0)\n\t" 2851 "kmovq %%k5, 0x828(%0)\n\t" 2852 "kmovq %%k6, 0x830(%0)\n\t" 2853 "kmovq %%k7, 0x838(%0)\n\t" 2854 : 2855 : "a"(out), "m"(fill) 2856 : "%zmm0", "%zmm1", "%zmm2", "%zmm3", "%zmm4", "%zmm5", "%zmm6", "%zmm7" 2857#if defined(__x86_64__) 2858 , "%zmm8", "%zmm9", "%zmm10", "%zmm11", "%zmm12", "%zmm13", "%zmm14", 2859 "%zmm15", "%zmm16", "%zmm17", "%zmm18", "%zmm19", "%zmm20", "%zmm21", 2860 "%zmm22", "%zmm23", "%zmm24", "%zmm25", "%zmm26", "%zmm27", "%zmm28", 2861 "%zmm29", "%zmm30", "%zmm31" 2862#endif 2863 , "%k0", "%k1", "%k2", "%k3", "%k4", "%k5", "%k6", "%k7" 2864 ); 2865} 2866 2867__attribute__((target("avx512f"))) 2868static __inline void set_zmm_regs(const union x86_test_register data[]) 2869{ 2870 __asm__ __volatile__( 2871 "vmovaps 0x000(%0), %%zmm0\n\t" 2872 "vmovaps 0x040(%0), %%zmm1\n\t" 2873 "vmovaps 0x080(%0), %%zmm2\n\t" 2874 "vmovaps 0x0C0(%0), %%zmm3\n\t" 2875 "vmovaps 0x100(%0), %%zmm4\n\t" 2876 "vmovaps 0x140(%0), %%zmm5\n\t" 2877 "vmovaps 0x180(%0), %%zmm6\n\t" 2878 "vmovaps 0x1C0(%0), %%zmm7\n\t" 2879#if defined(__x86_64__) 2880 "vmovaps 0x200(%0), %%zmm8\n\t" 2881 "vmovaps 0x240(%0), %%zmm9\n\t" 2882 "vmovaps 0x280(%0), %%zmm10\n\t" 2883 "vmovaps 0x2C0(%0), %%zmm11\n\t" 2884 "vmovaps 0x300(%0), %%zmm12\n\t" 2885 "vmovaps 0x340(%0), %%zmm13\n\t" 2886 "vmovaps 0x380(%0), %%zmm14\n\t" 2887 "vmovaps 0x3C0(%0), %%zmm15\n\t" 2888 "vmovaps 0x400(%0), %%zmm16\n\t" 2889 "vmovaps 0x440(%0), %%zmm17\n\t" 2890 "vmovaps 0x480(%0), %%zmm18\n\t" 2891 "vmovaps 0x4C0(%0), %%zmm19\n\t" 2892 "vmovaps 0x500(%0), %%zmm20\n\t" 2893 "vmovaps 0x540(%0), %%zmm21\n\t" 2894 "vmovaps 0x580(%0), %%zmm22\n\t" 2895 "vmovaps 0x5C0(%0), %%zmm23\n\t" 2896 "vmovaps 0x600(%0), %%zmm24\n\t" 2897 "vmovaps 0x640(%0), %%zmm25\n\t" 2898 "vmovaps 0x680(%0), %%zmm26\n\t" 2899 "vmovaps 0x6C0(%0), %%zmm27\n\t" 2900 "vmovaps 0x700(%0), %%zmm28\n\t" 2901 "vmovaps 0x740(%0), %%zmm29\n\t" 2902 "vmovaps 0x780(%0), %%zmm30\n\t" 2903 "vmovaps 0x7C0(%0), %%zmm31\n\t" 2904#endif 2905 "kmovq 0x800(%0), %%k0\n\t" 2906 "kmovq 0x808(%0), %%k1\n\t" 2907 "kmovq 0x810(%0), %%k2\n\t" 2908 "kmovq 0x818(%0), %%k3\n\t" 2909 "kmovq 0x820(%0), %%k4\n\t" 2910 "kmovq 0x828(%0), %%k5\n\t" 2911 "kmovq 0x830(%0), %%k6\n\t" 2912 "kmovq 0x838(%0), %%k7\n\t" 2913 "int3\n\t" 2914 : 2915 : "b"(data) 2916 : "%zmm0", "%zmm1", "%zmm2", "%zmm3", "%zmm4", "%zmm5", "%zmm6", "%zmm7" 2917#if defined(__x86_64__) 2918 , "%zmm8", "%zmm9", "%zmm10", "%zmm11", "%zmm12", "%zmm13", "%zmm14", 2919 "%zmm15", "%zmm16", "%zmm17", "%zmm18", "%zmm19", "%zmm20", "%zmm21", 2920 "%zmm22", "%zmm23", "%zmm24", "%zmm25", "%zmm26", "%zmm27", "%zmm28", 2921 "%zmm29", "%zmm30", "%zmm31" 2922#endif 2923 , "%k0", "%k1", "%k2", "%k3", "%k4", 2924 "%k5", "%k6", "%k7" 2925 ); 2926} 2927 2928static void 2929x86_register_test(enum x86_test_regset regset, enum x86_test_registers regs, 2930 enum x86_test_regmode regmode) 2931{ 2932 const int exitval = 5; 2933 pid_t child, wpid; 2934#if defined(TWAIT_HAVE_STATUS) 2935 const int sigval = SIGTRAP; 2936 int status; 2937#endif 2938 struct reg gpr; 2939 struct fpreg fpr; 2940#if defined(__i386__) 2941 struct xmmregs xmm; 2942#endif 2943 struct xstate xst; 2944 struct iovec iov; 2945 struct fxsave* fxs = NULL; 2946 uint64_t xst_flags = 0; 2947 char core_path[] = "/tmp/core.XXXXXX"; 2948 int core_fd; 2949 2950 const union x86_test_register expected[] __aligned(64) = { 2951 {{ 0x0706050403020100, 0x0F0E0D0C0B0A0908, 2952 0x1716151413121110, 0x1F1E1D1C1B1A1918, 2953 0x2726252423222120, 0x2F2E2D2C2B2A2928, 2954 0x3736353433323130, 0x3F3E3D3C3B3A3938, }}, 2955 {{ 0x0807060504030201, 0x100F0E0D0C0B0A09, 2956 0x1817161514131211, 0x201F1E1D1C1B1A19, 2957 0x2827262524232221, 0x302F2E2D2C2B2A29, 2958 0x3837363534333231, 0x403F3E3D3C3B3A39, }}, 2959 {{ 0x0908070605040302, 0x11100F0E0D0C0B0A, 2960 0x1918171615141312, 0x21201F1E1D1C1B1A, 2961 0x2928272625242322, 0x31302F2E2D2C2B2A, 2962 0x3938373635343332, 0x41403F3E3D3C3B3A, }}, 2963 {{ 0x0A09080706050403, 0x1211100F0E0D0C0B, 2964 0x1A19181716151413, 0x2221201F1E1D1C1B, 2965 0x2A29282726252423, 0x3231302F2E2D2C2B, 2966 0x3A39383736353433, 0x4241403F3E3D3C3B, }}, 2967 {{ 0x0B0A090807060504, 0x131211100F0E0D0C, 2968 0x1B1A191817161514, 0x232221201F1E1D1C, 2969 0x2B2A292827262524, 0x333231302F2E2D2C, 2970 0x3B3A393837363534, 0x434241403F3E3D3C, }}, 2971 {{ 0x0C0B0A0908070605, 0x14131211100F0E0D, 2972 0x1C1B1A1918171615, 0x24232221201F1E1D, 2973 0x2C2B2A2928272625, 0x34333231302F2E2D, 2974 0x3C3B3A3938373635, 0x44434241403F3E3D, }}, 2975 {{ 0x0D0C0B0A09080706, 0x1514131211100F0E, 2976 0x1D1C1B1A19181716, 0x2524232221201F1E, 2977 0x2D2C2B2A29282726, 0x3534333231302F2E, 2978 0x3D3C3B3A39383736, 0x4544434241403F3E, }}, 2979 {{ 0x0E0D0C0B0A090807, 0x161514131211100F, 2980 0x1E1D1C1B1A191817, 0x262524232221201F, 2981 0x2E2D2C2B2A292827, 0x363534333231302F, 2982 0x3E3D3C3B3A393837, 0x464544434241403F, }}, 2983 {{ 0x0F0E0D0C0B0A0908, 0x1716151413121110, 2984 0x1F1E1D1C1B1A1918, 0x2726252423222120, 2985 0x2F2E2D2C2B2A2928, 0x3736353433323130, 2986 0x3F3E3D3C3B3A3938, 0x4746454443424140, }}, 2987 {{ 0x100F0E0D0C0B0A09, 0x1817161514131211, 2988 0x201F1E1D1C1B1A19, 0x2827262524232221, 2989 0x302F2E2D2C2B2A29, 0x3837363534333231, 2990 0x403F3E3D3C3B3A39, 0x4847464544434241, }}, 2991 {{ 0x11100F0E0D0C0B0A, 0x1918171615141312, 2992 0x21201F1E1D1C1B1A, 0x2928272625242322, 2993 0x31302F2E2D2C2B2A, 0x3938373635343332, 2994 0x41403F3E3D3C3B3A, 0x4948474645444342, }}, 2995 {{ 0x1211100F0E0D0C0B, 0x1A19181716151413, 2996 0x2221201F1E1D1C1B, 0x2A29282726252423, 2997 0x3231302F2E2D2C2B, 0x3A39383736353433, 2998 0x4241403F3E3D3C3B, 0x4A49484746454443, }}, 2999 {{ 0x131211100F0E0D0C, 0x1B1A191817161514, 3000 0x232221201F1E1D1C, 0x2B2A292827262524, 3001 0x333231302F2E2D2C, 0x3B3A393837363534, 3002 0x434241403F3E3D3C, 0x4B4A494847464544, }}, 3003 {{ 0x14131211100F0E0D, 0x1C1B1A1918171615, 3004 0x24232221201F1E1D, 0x2C2B2A2928272625, 3005 0x34333231302F2E2D, 0x3C3B3A3938373635, 3006 0x44434241403F3E3D, 0x4C4B4A4948474645, }}, 3007 {{ 0x1514131211100F0E, 0x1D1C1B1A19181716, 3008 0x2524232221201F1E, 0x2D2C2B2A29282726, 3009 0x3534333231302F2E, 0x3D3C3B3A39383736, 3010 0x4544434241403F3E, 0x4D4C4B4A49484746, }}, 3011 {{ 0x161514131211100F, 0x1E1D1C1B1A191817, 3012 0x262524232221201F, 0x2E2D2C2B2A292827, 3013 0x363534333231302F, 0x3E3D3C3B3A393837, 3014 0x464544434241403F, 0x4E4D4C4B4A494847, }}, 3015 {{ 0x1716151413121110, 0x1F1E1D1C1B1A1918, 3016 0x2726252423222120, 0x2F2E2D2C2B2A2928, 3017 0x3736353433323130, 0x3F3E3D3C3B3A3938, 3018 0x4746454443424140, 0x4F4E4D4C4B4A4948, }}, 3019 {{ 0x1817161514131211, 0x201F1E1D1C1B1A19, 3020 0x2827262524232221, 0x302F2E2D2C2B2A29, 3021 0x3837363534333231, 0x403F3E3D3C3B3A39, 3022 0x4847464544434241, 0x504F4E4D4C4B4A49, }}, 3023 {{ 0x1918171615141312, 0x21201F1E1D1C1B1A, 3024 0x2928272625242322, 0x31302F2E2D2C2B2A, 3025 0x3938373635343332, 0x41403F3E3D3C3B3A, 3026 0x4948474645444342, 0x51504F4E4D4C4B4A, }}, 3027 {{ 0x1A19181716151413, 0x2221201F1E1D1C1B, 3028 0x2A29282726252423, 0x3231302F2E2D2C2B, 3029 0x3A39383736353433, 0x4241403F3E3D3C3B, 3030 0x4A49484746454443, 0x5251504F4E4D4C4B, }}, 3031 {{ 0x1B1A191817161514, 0x232221201F1E1D1C, 3032 0x2B2A292827262524, 0x333231302F2E2D2C, 3033 0x3B3A393837363534, 0x434241403F3E3D3C, 3034 0x4B4A494847464544, 0x535251504F4E4D4C, }}, 3035 {{ 0x1C1B1A1918171615, 0x24232221201F1E1D, 3036 0x2C2B2A2928272625, 0x34333231302F2E2D, 3037 0x3C3B3A3938373635, 0x44434241403F3E3D, 3038 0x4C4B4A4948474645, 0x54535251504F4E4D, }}, 3039 {{ 0x1D1C1B1A19181716, 0x2524232221201F1E, 3040 0x2D2C2B2A29282726, 0x3534333231302F2E, 3041 0x3D3C3B3A39383736, 0x4544434241403F3E, 3042 0x4D4C4B4A49484746, 0x5554535251504F4E, }}, 3043 {{ 0x1E1D1C1B1A191817, 0x262524232221201F, 3044 0x2E2D2C2B2A292827, 0x363534333231302F, 3045 0x3E3D3C3B3A393837, 0x464544434241403F, 3046 0x4E4D4C4B4A494847, 0x565554535251504F, }}, 3047 {{ 0x1F1E1D1C1B1A1918, 0x2726252423222120, 3048 0x2F2E2D2C2B2A2928, 0x3736353433323130, 3049 0x3F3E3D3C3B3A3938, 0x4746454443424140, 3050 0x4F4E4D4C4B4A4948, 0x5756555453525150, }}, 3051 {{ 0x201F1E1D1C1B1A19, 0x2827262524232221, 3052 0x302F2E2D2C2B2A29, 0x3837363534333231, 3053 0x403F3E3D3C3B3A39, 0x4847464544434241, 3054 0x504F4E4D4C4B4A49, 0x5857565554535251, }}, 3055 {{ 0x21201F1E1D1C1B1A, 0x2928272625242322, 3056 0x31302F2E2D2C2B2A, 0x3938373635343332, 3057 0x41403F3E3D3C3B3A, 0x4948474645444342, 3058 0x51504F4E4D4C4B4A, 0x5958575655545352, }}, 3059 {{ 0x2221201F1E1D1C1B, 0x2A29282726252423, 3060 0x3231302F2E2D2C2B, 0x3A39383736353433, 3061 0x4241403F3E3D3C3B, 0x4A49484746454443, 3062 0x5251504F4E4D4C4B, 0x5A59585756555453, }}, 3063 {{ 0x232221201F1E1D1C, 0x2B2A292827262524, 3064 0x333231302F2E2D2C, 0x3B3A393837363534, 3065 0x434241403F3E3D3C, 0x4B4A494847464544, 3066 0x535251504F4E4D4C, 0x5B5A595857565554, }}, 3067 {{ 0x24232221201F1E1D, 0x2C2B2A2928272625, 3068 0x34333231302F2E2D, 0x3C3B3A3938373635, 3069 0x44434241403F3E3D, 0x4C4B4A4948474645, 3070 0x54535251504F4E4D, 0x5C5B5A5958575655, }}, 3071 {{ 0x2524232221201F1E, 0x2D2C2B2A29282726, 3072 0x3534333231302F2E, 0x3D3C3B3A39383736, 3073 0x4544434241403F3E, 0x4D4C4B4A49484746, 3074 0x5554535251504F4E, 0x5D5C5B5A59585756, }}, 3075 {{ 0x262524232221201F, 0x2E2D2C2B2A292827, 3076 0x363534333231302F, 0x3E3D3C3B3A393837, 3077 0x464544434241403F, 0x4E4D4C4B4A494847, 3078 0x565554535251504F, 0x5E5D5C5B5A595857, }}, 3079 /* k0..k7 */ 3080 {{ 0x2726252423222120, 0x2F2E2D2C2B2A2928, 3081 0x3736353433323130, 0x3F3E3D3C3B3A3938, 3082 0x4746454443424140, 0x4F4E4D4C4B4A4948, 3083 0x5756555453525150, 0x5F5E5D5C5B5A5958, }}, 3084 }; 3085 3086 const struct x86_test_fpu_registers expected_fpu = { 3087 .st = { 3088 {0x8000000000000000, 0x4000}, /* +2.0 */ 3089 {0x3f00000000000000, 0x0000}, /* 1.654785e-4932 */ 3090 {0x0000000000000000, 0x0000}, /* +0 */ 3091 {0x0000000000000000, 0x8000}, /* -0 */ 3092 {0x8000000000000000, 0x7fff}, /* +inf */ 3093 {0x8000000000000000, 0xffff}, /* -inf */ 3094 {0xc000000000000000, 0xffff}, /* nan */ 3095 /* st(7) will be freed to test tag word better */ 3096 {0x0000000000000000, 0x0000}, /* +0 */ 3097 }, 3098 /* 0000 0011 0111 1011 3099 * PU OZDI -- unmask divide-by-zero exc. 3100 * RR --------- reserved 3101 * PC ------------ 64-bit precision 3102 * RC -------------- round to nearest 3103 * I ----------------- allow interrupts (unused) 3104 */ 3105 .cw = 0x037b, 3106 /* 1000 0000 1000 0100 3107 * SPU OZDI -- divide-by-zero exception 3108 * I ---------- interrupt (exception handling) 3109 * C CCC ------------ condition codes 3110 * TO P --------------- top register is 0 3111 * B -------------------- FPU is busy 3112 */ 3113 .sw = 0x8084, 3114 /* 1110 1010 0101 1000 3115 * R7R6 R5R4 R3R2 R1R0 3116 * nz -- non-zero (+2.0) 3117 * sp ---- special (denormal) 3118 * zrzr ------- zeroes 3119 * sp spsp ------------ specials (NaN + infinities) 3120 * em ------------------- empty register 3121 */ 3122 .tw = 0xea58, 3123 /* 0111 1111 -- registers 0 to 6 are used */ 3124 .tw_abridged = 0x7f, 3125 /* FDIV */ 3126 .opcode = 0x0033, 3127 /* random bits for IP/DP write test 3128 * keep it below 48 bits since it can be truncated 3129 */ 3130 .ip = {.fa_64 = 0x00000a9876543210}, 3131 .dp = {.fa_64 = 0x0000056789abcdef}, 3132 }; 3133 3134 bool need_32 = false, need_64 = false, need_cpuid = false; 3135 3136 switch (regs) { 3137 case GPREGS_32: 3138 case GPREGS_32_EBP_ESP: 3139 need_32 = true; 3140 break; 3141 case GPREGS_64: 3142 case GPREGS_64_R8: 3143 need_64 = true; 3144 break; 3145 case FPREGS_FPU: 3146 break; 3147 case FPREGS_MM: 3148 case FPREGS_XMM: 3149 case FPREGS_YMM: 3150 case FPREGS_ZMM: 3151 need_cpuid = true; 3152 break; 3153 } 3154 3155 if (need_32) { 3156#if defined(__x86_64__) 3157 atf_tc_skip("Test requires 32-bit mode"); 3158#endif 3159 } 3160 if (need_64) { 3161#if defined(__i386__) 3162 atf_tc_skip("Test requires 64-bit mode"); 3163#endif 3164 } 3165 3166 if (need_cpuid) { 3167 /* verify whether needed instruction sets are supported here */ 3168 unsigned int eax, ebx, ecx, edx; 3169 unsigned int eax7, ebx7, ecx7, edx7; 3170 3171 DPRINTF("Before invoking cpuid\n"); 3172 if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx)) 3173 atf_tc_skip("CPUID is not supported by the CPU"); 3174 3175 DPRINTF("cpuid[eax=1]: ECX = %08x, EDX = %08xd\n", ecx, edx); 3176 3177 switch (regs) { 3178 case FPREGS_ZMM: 3179 /* ZMM is in EAX=7, ECX=0 */ 3180 if (!__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7)) 3181 atf_tc_skip( 3182 "AVX512F is not supported by the CPU"); 3183 DPRINTF("cpuid[eax=7,ecx=0]: EBX = %08x\n", ebx7); 3184 if (!(ebx7 & bit_AVX512F)) 3185 atf_tc_skip( 3186 "AVX512F is not supported by the CPU"); 3187 /*FALLTHROUGH*/ 3188 case FPREGS_YMM: 3189 if (!(ecx & bit_AVX)) 3190 atf_tc_skip("AVX is not supported by the CPU"); 3191 /*FALLTHROUGH*/ 3192 case FPREGS_XMM: 3193 if (!(edx & bit_SSE)) 3194 atf_tc_skip("SSE is not supported by the CPU"); 3195 break; 3196 case FPREGS_MM: 3197 if (!(edx & bit_MMX)) 3198 atf_tc_skip("MMX is not supported by the CPU"); 3199 break; 3200 case GPREGS_32: 3201 case GPREGS_32_EBP_ESP: 3202 case GPREGS_64: 3203 case GPREGS_64_R8: 3204 case FPREGS_FPU: 3205 __unreachable(); 3206 } 3207 } 3208 3209 DPRINTF("Before forking process PID=%d\n", getpid()); 3210 SYSCALL_REQUIRE((child = fork()) != -1); 3211 if (child == 0) { 3212 union x86_test_register vals[__arraycount(expected)] __aligned(64); 3213 struct x86_test_fpu_registers vals_fpu; 3214 3215 DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid()); 3216 FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); 3217 3218 DPRINTF("Before running assembly from child\n"); 3219 switch (regmode) { 3220 case TEST_GETREGS: 3221 case TEST_COREDUMP: 3222 switch (regs) { 3223 case GPREGS_32: 3224 set_gp32_regs(expected); 3225 break; 3226 case GPREGS_32_EBP_ESP: 3227 set_gp32_ebp_esp_regs(expected); 3228 break; 3229 case GPREGS_64: 3230 set_gp64_regs(expected); 3231 break; 3232 case GPREGS_64_R8: 3233 set_gp64_r8_regs(expected); 3234 break; 3235 case FPREGS_FPU: 3236 set_fpu_regs(&expected_fpu); 3237 break; 3238 case FPREGS_MM: 3239 set_mm_regs(expected); 3240 break; 3241 case FPREGS_XMM: 3242 set_xmm_regs(expected); 3243 break; 3244 case FPREGS_YMM: 3245 set_ymm_regs(expected); 3246 break; 3247 case FPREGS_ZMM: 3248 set_zmm_regs(expected); 3249 break; 3250 } 3251 break; 3252 case TEST_SETREGS: 3253 switch (regs) { 3254 case GPREGS_32: 3255 get_gp32_regs(vals); 3256 break; 3257 case GPREGS_32_EBP_ESP: 3258 get_gp32_ebp_esp_regs(vals); 3259 break; 3260 case GPREGS_64: 3261 get_gp64_regs(vals); 3262 break; 3263 case GPREGS_64_R8: 3264 get_gp64_r8_regs(vals); 3265 break; 3266 case FPREGS_FPU: 3267 get_fpu_regs(&vals_fpu); 3268 break; 3269 case FPREGS_MM: 3270 get_mm_regs(vals); 3271 break; 3272 case FPREGS_XMM: 3273 get_xmm_regs(vals); 3274 break; 3275 case FPREGS_YMM: 3276 get_ymm_regs(vals); 3277 break; 3278 case FPREGS_ZMM: 3279 get_zmm_regs(vals); 3280 break; 3281 } 3282 3283 DPRINTF("Before comparing results\n"); 3284 switch (regs) { 3285 case GPREGS_32: 3286 FORKEE_ASSERT(!memcmp(&vals[5].u32, 3287 &expected[5].u32, sizeof(vals->u32))); 3288 FORKEE_ASSERT(!memcmp(&vals[4].u32, 3289 &expected[4].u32, sizeof(vals->u32))); 3290 FORKEE_ASSERT(!memcmp(&vals[3].u32, 3291 &expected[3].u32, sizeof(vals->u32))); 3292 FORKEE_ASSERT(!memcmp(&vals[2].u32, 3293 &expected[2].u32, sizeof(vals->u32))); 3294 /*FALLTHROUGH*/ 3295 case GPREGS_32_EBP_ESP: 3296 FORKEE_ASSERT(!memcmp(&vals[1].u32, 3297 &expected[1].u32, sizeof(vals->u32))); 3298 FORKEE_ASSERT(!memcmp(&vals[0].u32, 3299 &expected[0].u32, sizeof(vals->u32))); 3300 break; 3301 case GPREGS_64: 3302 case GPREGS_64_R8: 3303 case FPREGS_MM: 3304 FORKEE_ASSERT(!memcmp(&vals[0].u64, 3305 &expected[0].u64, sizeof(vals->u64))); 3306 FORKEE_ASSERT(!memcmp(&vals[1].u64, 3307 &expected[1].u64, sizeof(vals->u64))); 3308 FORKEE_ASSERT(!memcmp(&vals[2].u64, 3309 &expected[2].u64, sizeof(vals->u64))); 3310 FORKEE_ASSERT(!memcmp(&vals[3].u64, 3311 &expected[3].u64, sizeof(vals->u64))); 3312 FORKEE_ASSERT(!memcmp(&vals[4].u64, 3313 &expected[4].u64, sizeof(vals->u64))); 3314 FORKEE_ASSERT(!memcmp(&vals[5].u64, 3315 &expected[5].u64, sizeof(vals->u64))); 3316 FORKEE_ASSERT(!memcmp(&vals[6].u64, 3317 &expected[6].u64, sizeof(vals->u64))); 3318 FORKEE_ASSERT(!memcmp(&vals[7].u64, 3319 &expected[7].u64, sizeof(vals->u64))); 3320 break; 3321 case FPREGS_FPU: 3322 FORKEE_ASSERT(vals_fpu.cw == expected_fpu.cw); 3323 FORKEE_ASSERT(vals_fpu.sw == expected_fpu.sw); 3324 FORKEE_ASSERT(vals_fpu.tw == expected_fpu.tw); 3325 FORKEE_ASSERT(vals_fpu.tw_abridged 3326 == expected_fpu.tw_abridged); 3327 FORKEE_ASSERT(vals_fpu.ip.fa_64 3328 == expected_fpu.ip.fa_64); 3329 FORKEE_ASSERT(vals_fpu.dp.fa_64 3330 == expected_fpu.dp.fa_64); 3331 3332 FORKEE_ASSERT(vals_fpu.st[0].sign_exp 3333 == expected_fpu.st[0].sign_exp); 3334 FORKEE_ASSERT(vals_fpu.st[0].mantissa 3335 == expected_fpu.st[0].mantissa); 3336 FORKEE_ASSERT(vals_fpu.st[1].sign_exp 3337 == expected_fpu.st[1].sign_exp); 3338 FORKEE_ASSERT(vals_fpu.st[1].mantissa 3339 == expected_fpu.st[1].mantissa); 3340 FORKEE_ASSERT(vals_fpu.st[2].sign_exp 3341 == expected_fpu.st[2].sign_exp); 3342 FORKEE_ASSERT(vals_fpu.st[2].mantissa 3343 == expected_fpu.st[2].mantissa); 3344 FORKEE_ASSERT(vals_fpu.st[3].sign_exp 3345 == expected_fpu.st[3].sign_exp); 3346 FORKEE_ASSERT(vals_fpu.st[3].mantissa 3347 == expected_fpu.st[3].mantissa); 3348 FORKEE_ASSERT(vals_fpu.st[4].sign_exp 3349 == expected_fpu.st[4].sign_exp); 3350 FORKEE_ASSERT(vals_fpu.st[4].mantissa 3351 == expected_fpu.st[4].mantissa); 3352 FORKEE_ASSERT(vals_fpu.st[5].sign_exp 3353 == expected_fpu.st[5].sign_exp); 3354 FORKEE_ASSERT(vals_fpu.st[5].mantissa 3355 == expected_fpu.st[5].mantissa); 3356 FORKEE_ASSERT(vals_fpu.st[6].sign_exp 3357 == expected_fpu.st[6].sign_exp); 3358 FORKEE_ASSERT(vals_fpu.st[6].mantissa 3359 == expected_fpu.st[6].mantissa); 3360 /* st(7) is left empty == undefined */ 3361 break; 3362 case FPREGS_XMM: 3363 FORKEE_ASSERT(!memcmp(&vals[0].xmm, 3364 &expected[0].xmm, sizeof(vals->xmm))); 3365 FORKEE_ASSERT(!memcmp(&vals[1].xmm, 3366 &expected[1].xmm, sizeof(vals->xmm))); 3367 FORKEE_ASSERT(!memcmp(&vals[2].xmm, 3368 &expected[2].xmm, sizeof(vals->xmm))); 3369 FORKEE_ASSERT(!memcmp(&vals[3].xmm, 3370 &expected[3].xmm, sizeof(vals->xmm))); 3371 FORKEE_ASSERT(!memcmp(&vals[4].xmm, 3372 &expected[4].xmm, sizeof(vals->xmm))); 3373 FORKEE_ASSERT(!memcmp(&vals[5].xmm, 3374 &expected[5].xmm, sizeof(vals->xmm))); 3375 FORKEE_ASSERT(!memcmp(&vals[6].xmm, 3376 &expected[6].xmm, sizeof(vals->xmm))); 3377 FORKEE_ASSERT(!memcmp(&vals[7].xmm, 3378 &expected[7].xmm, sizeof(vals->xmm))); 3379#if defined(__x86_64__) 3380 FORKEE_ASSERT(!memcmp(&vals[8].xmm, 3381 &expected[8].xmm, sizeof(vals->xmm))); 3382 FORKEE_ASSERT(!memcmp(&vals[9].xmm, 3383 &expected[9].xmm, sizeof(vals->xmm))); 3384 FORKEE_ASSERT(!memcmp(&vals[10].xmm, 3385 &expected[10].xmm, sizeof(vals->xmm))); 3386 FORKEE_ASSERT(!memcmp(&vals[11].xmm, 3387 &expected[11].xmm, sizeof(vals->xmm))); 3388 FORKEE_ASSERT(!memcmp(&vals[12].xmm, 3389 &expected[12].xmm, sizeof(vals->xmm))); 3390 FORKEE_ASSERT(!memcmp(&vals[13].xmm, 3391 &expected[13].xmm, sizeof(vals->xmm))); 3392 FORKEE_ASSERT(!memcmp(&vals[14].xmm, 3393 &expected[14].xmm, sizeof(vals->xmm))); 3394 FORKEE_ASSERT(!memcmp(&vals[15].xmm, 3395 &expected[15].xmm, sizeof(vals->xmm))); 3396#endif 3397 break; 3398 case FPREGS_YMM: 3399 FORKEE_ASSERT(!memcmp(&vals[0].ymm, 3400 &expected[0].ymm, sizeof(vals->ymm))); 3401 FORKEE_ASSERT(!memcmp(&vals[1].ymm, 3402 &expected[1].ymm, sizeof(vals->ymm))); 3403 FORKEE_ASSERT(!memcmp(&vals[2].ymm, 3404 &expected[2].ymm, sizeof(vals->ymm))); 3405 FORKEE_ASSERT(!memcmp(&vals[3].ymm, 3406 &expected[3].ymm, sizeof(vals->ymm))); 3407 FORKEE_ASSERT(!memcmp(&vals[4].ymm, 3408 &expected[4].ymm, sizeof(vals->ymm))); 3409 FORKEE_ASSERT(!memcmp(&vals[5].ymm, 3410 &expected[5].ymm, sizeof(vals->ymm))); 3411 FORKEE_ASSERT(!memcmp(&vals[6].ymm, 3412 &expected[6].ymm, sizeof(vals->ymm))); 3413 FORKEE_ASSERT(!memcmp(&vals[7].ymm, 3414 &expected[7].ymm, sizeof(vals->ymm))); 3415#if defined(__x86_64__) 3416 FORKEE_ASSERT(!memcmp(&vals[8].ymm, 3417 &expected[8].ymm, sizeof(vals->ymm))); 3418 FORKEE_ASSERT(!memcmp(&vals[9].ymm, 3419 &expected[9].ymm, sizeof(vals->ymm))); 3420 FORKEE_ASSERT(!memcmp(&vals[10].ymm, 3421 &expected[10].ymm, sizeof(vals->ymm))); 3422 FORKEE_ASSERT(!memcmp(&vals[11].ymm, 3423 &expected[11].ymm, sizeof(vals->ymm))); 3424 FORKEE_ASSERT(!memcmp(&vals[12].ymm, 3425 &expected[12].ymm, sizeof(vals->ymm))); 3426 FORKEE_ASSERT(!memcmp(&vals[13].ymm, 3427 &expected[13].ymm, sizeof(vals->ymm))); 3428 FORKEE_ASSERT(!memcmp(&vals[14].ymm, 3429 &expected[14].ymm, sizeof(vals->ymm))); 3430 FORKEE_ASSERT(!memcmp(&vals[15].ymm, 3431 &expected[15].ymm, sizeof(vals->ymm))); 3432#endif 3433 break; 3434 case FPREGS_ZMM: 3435 FORKEE_ASSERT(!memcmp(&vals[0].zmm, 3436 &expected[0].zmm, sizeof(vals->zmm))); 3437 FORKEE_ASSERT(!memcmp(&vals[1].zmm, 3438 &expected[1].zmm, sizeof(vals->zmm))); 3439 FORKEE_ASSERT(!memcmp(&vals[2].zmm, 3440 &expected[2].zmm, sizeof(vals->zmm))); 3441 FORKEE_ASSERT(!memcmp(&vals[3].zmm, 3442 &expected[3].zmm, sizeof(vals->zmm))); 3443 FORKEE_ASSERT(!memcmp(&vals[4].zmm, 3444 &expected[4].zmm, sizeof(vals->zmm))); 3445 FORKEE_ASSERT(!memcmp(&vals[5].zmm, 3446 &expected[5].zmm, sizeof(vals->zmm))); 3447 FORKEE_ASSERT(!memcmp(&vals[6].zmm, 3448 &expected[6].zmm, sizeof(vals->zmm))); 3449 FORKEE_ASSERT(!memcmp(&vals[7].zmm, 3450 &expected[7].zmm, sizeof(vals->zmm))); 3451#if defined(__x86_64__) 3452 FORKEE_ASSERT(!memcmp(&vals[8].zmm, 3453 &expected[8].zmm, sizeof(vals->zmm))); 3454 FORKEE_ASSERT(!memcmp(&vals[9].zmm, 3455 &expected[9].zmm, sizeof(vals->zmm))); 3456 FORKEE_ASSERT(!memcmp(&vals[10].zmm, 3457 &expected[10].zmm, sizeof(vals->zmm))); 3458 FORKEE_ASSERT(!memcmp(&vals[11].zmm, 3459 &expected[11].zmm, sizeof(vals->zmm))); 3460 FORKEE_ASSERT(!memcmp(&vals[12].zmm, 3461 &expected[12].zmm, sizeof(vals->zmm))); 3462 FORKEE_ASSERT(!memcmp(&vals[13].zmm, 3463 &expected[13].zmm, sizeof(vals->zmm))); 3464 FORKEE_ASSERT(!memcmp(&vals[14].zmm, 3465 &expected[14].zmm, sizeof(vals->zmm))); 3466 FORKEE_ASSERT(!memcmp(&vals[15].zmm, 3467 &expected[15].zmm, sizeof(vals->zmm))); 3468 FORKEE_ASSERT(!memcmp(&vals[16].zmm, 3469 &expected[16].zmm, sizeof(vals->zmm))); 3470 FORKEE_ASSERT(!memcmp(&vals[17].zmm, 3471 &expected[17].zmm, sizeof(vals->zmm))); 3472 FORKEE_ASSERT(!memcmp(&vals[18].zmm, 3473 &expected[18].zmm, sizeof(vals->zmm))); 3474 FORKEE_ASSERT(!memcmp(&vals[19].zmm, 3475 &expected[19].zmm, sizeof(vals->zmm))); 3476 FORKEE_ASSERT(!memcmp(&vals[20].zmm, 3477 &expected[20].zmm, sizeof(vals->zmm))); 3478 FORKEE_ASSERT(!memcmp(&vals[21].zmm, 3479 &expected[21].zmm, sizeof(vals->zmm))); 3480 FORKEE_ASSERT(!memcmp(&vals[22].zmm, 3481 &expected[22].zmm, sizeof(vals->zmm))); 3482 FORKEE_ASSERT(!memcmp(&vals[23].zmm, 3483 &expected[23].zmm, sizeof(vals->zmm))); 3484 FORKEE_ASSERT(!memcmp(&vals[24].zmm, 3485 &expected[24].zmm, sizeof(vals->zmm))); 3486 FORKEE_ASSERT(!memcmp(&vals[25].zmm, 3487 &expected[25].zmm, sizeof(vals->zmm))); 3488 FORKEE_ASSERT(!memcmp(&vals[26].zmm, 3489 &expected[26].zmm, sizeof(vals->zmm))); 3490 FORKEE_ASSERT(!memcmp(&vals[27].zmm, 3491 &expected[27].zmm, sizeof(vals->zmm))); 3492 FORKEE_ASSERT(!memcmp(&vals[28].zmm, 3493 &expected[28].zmm, sizeof(vals->zmm))); 3494 FORKEE_ASSERT(!memcmp(&vals[29].zmm, 3495 &expected[29].zmm, sizeof(vals->zmm))); 3496 FORKEE_ASSERT(!memcmp(&vals[30].zmm, 3497 &expected[30].zmm, sizeof(vals->zmm))); 3498 FORKEE_ASSERT(!memcmp(&vals[31].zmm, 3499 &expected[31].zmm, sizeof(vals->zmm))); 3500#endif 3501 /* k0..k7 */ 3502 FORKEE_ASSERT(vals[32].zmm.a == expected[32].zmm.a); 3503 FORKEE_ASSERT(vals[32].zmm.b == expected[32].zmm.b); 3504 FORKEE_ASSERT(vals[32].zmm.c == expected[32].zmm.c); 3505 FORKEE_ASSERT(vals[32].zmm.d == expected[32].zmm.d); 3506 FORKEE_ASSERT(vals[32].zmm.e == expected[32].zmm.e); 3507 FORKEE_ASSERT(vals[32].zmm.f == expected[32].zmm.f); 3508 FORKEE_ASSERT(vals[32].zmm.g == expected[32].zmm.g); 3509 FORKEE_ASSERT(vals[32].zmm.h == expected[32].zmm.h); 3510 break; 3511 } 3512 break; 3513 } 3514 3515 DPRINTF("Before exiting of the child process\n"); 3516 _exit(exitval); 3517 } 3518 DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child); 3519 3520 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 3521 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 3522 3523 validate_status_stopped(status, sigval); 3524 3525 if (regset == TEST_XSTATE) { 3526 switch (regs) { 3527 case FPREGS_FPU: 3528 case FPREGS_MM: 3529 xst_flags |= XCR0_X87; 3530 break; 3531 case FPREGS_ZMM: 3532 xst_flags |= XCR0_Opmask | XCR0_ZMM_Hi256; 3533#if defined(__x86_64__) 3534 xst_flags |= XCR0_Hi16_ZMM; 3535#endif 3536 /*FALLTHROUGH*/ 3537 case FPREGS_YMM: 3538 xst_flags |= XCR0_YMM_Hi128; 3539 /*FALLTHROUGH*/ 3540 case FPREGS_XMM: 3541 xst_flags |= XCR0_SSE; 3542 break; 3543 case GPREGS_32: 3544 case GPREGS_32_EBP_ESP: 3545 case GPREGS_64: 3546 case GPREGS_64_R8: 3547 __unreachable(); 3548 break; 3549 } 3550 } 3551 3552 switch (regmode) { 3553 case TEST_GETREGS: 3554 case TEST_SETREGS: 3555 if (regset == TEST_GPREGS || regs == FPREGS_FPU) { 3556 DPRINTF("Call GETREGS for the child process\n"); 3557 SYSCALL_REQUIRE(ptrace(PT_GETREGS, child, &gpr, 0) 3558 != -1); 3559 } 3560 3561 switch (regset) { 3562 case TEST_GPREGS: 3563 /* already handled above */ 3564 break; 3565 case TEST_XMMREGS: 3566#if defined(__i386__) 3567 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3568 DPRINTF("Call GETXMMREGS for the child process\n"); 3569 SYSCALL_REQUIRE(ptrace(PT_GETXMMREGS, child, &xmm, 0) 3570 != -1); 3571 fxs = &xmm.fxstate; 3572 break; 3573#else 3574 /*FALLTHROUGH*/ 3575#endif 3576 case TEST_FPREGS: 3577#if defined(__x86_64__) 3578 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3579 fxs = &fpr.fxstate; 3580#else 3581 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_XMM); 3582#endif 3583 DPRINTF("Call GETFPREGS for the child process\n"); 3584 SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) 3585 != -1); 3586 break; 3587 case TEST_XSTATE: 3588 ATF_REQUIRE(regs >= FPREGS_FPU); 3589 iov.iov_base = &xst; 3590 iov.iov_len = sizeof(xst); 3591 3592 DPRINTF("Call GETXSTATE for the child process\n"); 3593 SYSCALL_REQUIRE(ptrace(PT_GETXSTATE, child, &iov, 0) 3594 != -1); 3595 3596 ATF_REQUIRE((xst.xs_rfbm & xst_flags) == xst_flags); 3597 switch (regmode) { 3598 case TEST_SETREGS: 3599 xst.xs_rfbm = xst_flags; 3600 xst.xs_xstate_bv = xst_flags; 3601 break; 3602 case TEST_GETREGS: 3603 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3604 == xst_flags); 3605 break; 3606 case TEST_COREDUMP: 3607 __unreachable(); 3608 break; 3609 } 3610 3611 fxs = &xst.xs_fxsave; 3612 break; 3613 } 3614 break; 3615 case TEST_COREDUMP: 3616 SYSCALL_REQUIRE((core_fd = mkstemp(core_path)) != -1); 3617 close(core_fd); 3618 3619 DPRINTF("Call DUMPCORE for the child process\n"); 3620 SYSCALL_REQUIRE(ptrace(PT_DUMPCORE, child, core_path, 3621 strlen(core_path)) != -1); 3622 3623 if (regset == TEST_GPREGS || regs == FPREGS_FPU) { 3624 DPRINTF("Parse core file for PT_GETREGS\n"); 3625 ATF_REQUIRE_EQ(core_find_note(core_path, 3626 "NetBSD-CORE@*", PT_GETREGS, &gpr, sizeof(gpr)), 3627 sizeof(gpr)); 3628 } 3629 3630 switch (regset) { 3631 case TEST_GPREGS: 3632 /* handled above */ 3633 break; 3634 case TEST_XMMREGS: 3635#if defined(__i386__) 3636 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3637 unlink(core_path); 3638 atf_tc_skip("XMMREGS not supported in core dumps"); 3639 break; 3640#else 3641 /*FALLTHROUGH*/ 3642#endif 3643 case TEST_FPREGS: 3644#if defined(__x86_64__) 3645 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_YMM); 3646 fxs = &fpr.fxstate; 3647#else 3648 ATF_REQUIRE(regs >= FPREGS_FPU && regs < FPREGS_XMM); 3649#endif 3650 DPRINTF("Parse core file for PT_GETFPREGS\n"); 3651 ATF_REQUIRE_EQ(core_find_note(core_path, 3652 "NetBSD-CORE@*", PT_GETFPREGS, &fpr, sizeof(fpr)), 3653 sizeof(fpr)); 3654 break; 3655 case TEST_XSTATE: 3656 ATF_REQUIRE(regs >= FPREGS_FPU); 3657 DPRINTF("Parse core file for PT_GETXSTATE\n"); 3658 ATF_REQUIRE_EQ(core_find_note(core_path, 3659 "NetBSD-CORE@*", PT_GETXSTATE, &xst, sizeof(xst)), 3660 sizeof(xst)); 3661 ATF_REQUIRE((xst.xs_xstate_bv & xst_flags) 3662 == xst_flags); 3663 fxs = &xst.xs_fxsave; 3664 break; 3665 } 3666 unlink(core_path); 3667 } 3668 3669#if defined(__x86_64__) 3670#define ST_EXP(n) fxs->fx_87_ac[n].r.f87_exp_sign 3671#define ST_MAN(n) fxs->fx_87_ac[n].r.f87_mantissa 3672#else 3673#define ST_EXP(n) *( \ 3674 regset == TEST_FPREGS \ 3675 ? &fpr.fstate.s87_ac[n].f87_exp_sign \ 3676 : &fxs->fx_87_ac[n].r.f87_exp_sign \ 3677 ) 3678#define ST_MAN(n) *( \ 3679 regset == TEST_FPREGS \ 3680 ? &fpr.fstate.s87_ac[n].f87_mantissa \ 3681 : &fxs->fx_87_ac[n].r.f87_mantissa \ 3682 ) 3683#endif 3684 3685 switch (regmode) { 3686 case TEST_GETREGS: 3687 case TEST_COREDUMP: 3688 switch (regs) { 3689 case GPREGS_32: 3690#if defined(__i386__) 3691 ATF_CHECK_EQ((uint32_t)gpr.r_eax, expected[0].u32); 3692 ATF_CHECK_EQ((uint32_t)gpr.r_ebx, expected[1].u32); 3693 ATF_CHECK_EQ((uint32_t)gpr.r_ecx, expected[2].u32); 3694 ATF_CHECK_EQ((uint32_t)gpr.r_edx, expected[3].u32); 3695 ATF_CHECK_EQ((uint32_t)gpr.r_esi, expected[4].u32); 3696 ATF_CHECK_EQ((uint32_t)gpr.r_edi, expected[5].u32); 3697#endif 3698 break; 3699 case GPREGS_32_EBP_ESP: 3700#if defined(__i386__) 3701 ATF_CHECK_EQ((uint32_t)gpr.r_esp, expected[0].u32); 3702 ATF_CHECK_EQ((uint32_t)gpr.r_ebp, expected[1].u32); 3703#endif 3704 break; 3705 case GPREGS_64: 3706#if defined(__x86_64__) 3707 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RAX], 3708 expected[0].u64); 3709 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBX], 3710 expected[1].u64); 3711 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RCX], 3712 expected[2].u64); 3713 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDX], 3714 expected[3].u64); 3715 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSI], 3716 expected[4].u64); 3717 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RDI], 3718 expected[5].u64); 3719 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RSP], 3720 expected[6].u64); 3721 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_RBP], 3722 expected[7].u64); 3723#endif 3724 break; 3725 case GPREGS_64_R8: 3726#if defined(__x86_64__) 3727 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R8], 3728 expected[0].u64); 3729 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R9], 3730 expected[1].u64); 3731 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R10], 3732 expected[2].u64); 3733 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R11], 3734 expected[3].u64); 3735 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R12], 3736 expected[4].u64); 3737 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R13], 3738 expected[5].u64); 3739 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R14], 3740 expected[6].u64); 3741 ATF_CHECK_EQ((uint64_t)gpr.regs[_REG_R15], 3742 expected[7].u64); 3743#endif 3744 break; 3745 case FPREGS_FPU: 3746#if defined(__i386__) 3747 if (regset == TEST_FPREGS) { 3748 /* GETFPREGS on i386 */ 3749 ATF_CHECK_EQ(fpr.fstate.s87_cw, 3750 expected_fpu.cw); 3751 ATF_CHECK_EQ(fpr.fstate.s87_sw, 3752 expected_fpu.sw); 3753 ATF_CHECK_EQ(fpr.fstate.s87_tw, 3754 expected_fpu.tw); 3755 ATF_CHECK_EQ(fpr.fstate.s87_opcode, 3756 expected_fpu.opcode); 3757 ATF_CHECK_EQ(fpr.fstate.s87_ip.fa_32.fa_off, 3758 (uint32_t)gpr.r_eip - 3); 3759 ATF_CHECK_EQ(fpr.fstate.s87_dp.fa_32.fa_off, 3760 (uint32_t)&x86_test_zero); 3761 /* note: fa_seg is missing on newer CPUs */ 3762 } else 3763#endif 3764 { 3765 /* amd64 or GETXSTATE on i386 */ 3766 ATF_CHECK_EQ(fxs->fx_cw, expected_fpu.cw); 3767 ATF_CHECK_EQ(fxs->fx_sw, expected_fpu.sw); 3768 ATF_CHECK_EQ(fxs->fx_tw, 3769 expected_fpu.tw_abridged); 3770 ATF_CHECK_EQ(fxs->fx_opcode, 3771 expected_fpu.opcode); 3772#if defined(__x86_64__) 3773 ATF_CHECK_EQ(fxs->fx_ip.fa_64, 3774 ((uint64_t)gpr.regs[_REG_RIP]) - 3); 3775 ATF_CHECK_EQ(fxs->fx_dp.fa_64, 3776 (uint64_t)&x86_test_zero); 3777#else 3778 ATF_CHECK_EQ(fxs->fx_ip.fa_32.fa_off, 3779 (uint32_t)gpr.r_eip - 3); 3780 ATF_CHECK_EQ(fxs->fx_dp.fa_32.fa_off, 3781 (uint32_t)&x86_test_zero); 3782 /* note: fa_seg is missing on newer CPUs */ 3783#endif 3784 } 3785 3786 ATF_CHECK_EQ(ST_EXP(0), expected_fpu.st[0].sign_exp); 3787 ATF_CHECK_EQ(ST_MAN(0), expected_fpu.st[0].mantissa); 3788 ATF_CHECK_EQ(ST_EXP(1), expected_fpu.st[1].sign_exp); 3789 ATF_CHECK_EQ(ST_MAN(1), expected_fpu.st[1].mantissa); 3790 ATF_CHECK_EQ(ST_EXP(2), expected_fpu.st[2].sign_exp); 3791 ATF_CHECK_EQ(ST_MAN(2), expected_fpu.st[2].mantissa); 3792 ATF_CHECK_EQ(ST_EXP(3), expected_fpu.st[3].sign_exp); 3793 ATF_CHECK_EQ(ST_MAN(3), expected_fpu.st[3].mantissa); 3794 ATF_CHECK_EQ(ST_EXP(4), expected_fpu.st[4].sign_exp); 3795 ATF_CHECK_EQ(ST_MAN(4), expected_fpu.st[4].mantissa); 3796 ATF_CHECK_EQ(ST_EXP(5), expected_fpu.st[5].sign_exp); 3797 ATF_CHECK_EQ(ST_MAN(5), expected_fpu.st[5].mantissa); 3798 ATF_CHECK_EQ(ST_EXP(6), expected_fpu.st[6].sign_exp); 3799 ATF_CHECK_EQ(ST_MAN(6), expected_fpu.st[6].mantissa); 3800 ATF_CHECK_EQ(ST_EXP(7), expected_fpu.st[7].sign_exp); 3801 ATF_CHECK_EQ(ST_MAN(7), expected_fpu.st[7].mantissa); 3802 break; 3803 case FPREGS_MM: 3804 ATF_CHECK_EQ(ST_MAN(0), expected[0].u64); 3805 ATF_CHECK_EQ(ST_MAN(1), expected[1].u64); 3806 ATF_CHECK_EQ(ST_MAN(2), expected[2].u64); 3807 ATF_CHECK_EQ(ST_MAN(3), expected[3].u64); 3808 ATF_CHECK_EQ(ST_MAN(4), expected[4].u64); 3809 ATF_CHECK_EQ(ST_MAN(5), expected[5].u64); 3810 ATF_CHECK_EQ(ST_MAN(6), expected[6].u64); 3811 ATF_CHECK_EQ(ST_MAN(7), expected[7].u64); 3812 break; 3813 case FPREGS_ZMM: 3814 /* zmm0..zmm15 are split between xmm, ymm_hi128 and zmm_hi256 */ 3815 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[0], 3816 &expected[0].zmm.e, sizeof(expected->zmm)/2)); 3817 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[1], 3818 &expected[1].zmm.e, sizeof(expected->zmm)/2)); 3819 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[2], 3820 &expected[2].zmm.e, sizeof(expected->zmm)/2)); 3821 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[3], 3822 &expected[3].zmm.e, sizeof(expected->zmm)/2)); 3823 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[4], 3824 &expected[4].zmm.e, sizeof(expected->zmm)/2)); 3825 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[5], 3826 &expected[5].zmm.e, sizeof(expected->zmm)/2)); 3827 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[6], 3828 &expected[6].zmm.e, sizeof(expected->zmm)/2)); 3829 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[7], 3830 &expected[7].zmm.e, sizeof(expected->zmm)/2)); 3831#if defined(__x86_64__) 3832 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[8], 3833 &expected[8].zmm.e, sizeof(expected->zmm)/2)); 3834 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[9], 3835 &expected[9].zmm.e, sizeof(expected->zmm)/2)); 3836 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[10], 3837 &expected[10].zmm.e, sizeof(expected->zmm)/2)); 3838 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[11], 3839 &expected[11].zmm.e, sizeof(expected->zmm)/2)); 3840 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[12], 3841 &expected[12].zmm.e, sizeof(expected->zmm)/2)); 3842 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[13], 3843 &expected[13].zmm.e, sizeof(expected->zmm)/2)); 3844 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[14], 3845 &expected[14].zmm.e, sizeof(expected->zmm)/2)); 3846 ATF_CHECK(!memcmp(&xst.xs_zmm_hi256.xs_zmm[15], 3847 &expected[15].zmm.e, sizeof(expected->zmm)/2)); 3848 /* zmm16..zmm31 are stored as a whole */ 3849 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[0], 3850 &expected[16].zmm, sizeof(expected->zmm))); 3851 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[1], 3852 &expected[17].zmm, sizeof(expected->zmm))); 3853 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[2], 3854 &expected[18].zmm, sizeof(expected->zmm))); 3855 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[3], 3856 &expected[19].zmm, sizeof(expected->zmm))); 3857 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[4], 3858 &expected[20].zmm, sizeof(expected->zmm))); 3859 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[5], 3860 &expected[21].zmm, sizeof(expected->zmm))); 3861 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[6], 3862 &expected[22].zmm, sizeof(expected->zmm))); 3863 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[7], 3864 &expected[23].zmm, sizeof(expected->zmm))); 3865 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[8], 3866 &expected[24].zmm, sizeof(expected->zmm))); 3867 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[9], 3868 &expected[25].zmm, sizeof(expected->zmm))); 3869 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[10], 3870 &expected[26].zmm, sizeof(expected->zmm))); 3871 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[11], 3872 &expected[27].zmm, sizeof(expected->zmm))); 3873 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[12], 3874 &expected[28].zmm, sizeof(expected->zmm))); 3875 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[13], 3876 &expected[29].zmm, sizeof(expected->zmm))); 3877 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[14], 3878 &expected[30].zmm, sizeof(expected->zmm))); 3879 ATF_CHECK(!memcmp(&xst.xs_hi16_zmm.xs_hi16_zmm[15], 3880 &expected[31].zmm, sizeof(expected->zmm))); 3881#endif 3882 /* k0..k7 */ 3883 ATF_CHECK(xst.xs_opmask.xs_k[0] == expected[32].zmm.a); 3884 ATF_CHECK(xst.xs_opmask.xs_k[1] == expected[32].zmm.b); 3885 ATF_CHECK(xst.xs_opmask.xs_k[2] == expected[32].zmm.c); 3886 ATF_CHECK(xst.xs_opmask.xs_k[3] == expected[32].zmm.d); 3887 ATF_CHECK(xst.xs_opmask.xs_k[4] == expected[32].zmm.e); 3888 ATF_CHECK(xst.xs_opmask.xs_k[5] == expected[32].zmm.f); 3889 ATF_CHECK(xst.xs_opmask.xs_k[6] == expected[32].zmm.g); 3890 ATF_CHECK(xst.xs_opmask.xs_k[7] == expected[32].zmm.h); 3891 /*FALLTHROUGH*/ 3892 case FPREGS_YMM: 3893 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[0], 3894 &expected[0].ymm.c, sizeof(expected->ymm)/2)); 3895 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[1], 3896 &expected[1].ymm.c, sizeof(expected->ymm)/2)); 3897 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[2], 3898 &expected[2].ymm.c, sizeof(expected->ymm)/2)); 3899 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[3], 3900 &expected[3].ymm.c, sizeof(expected->ymm)/2)); 3901 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[4], 3902 &expected[4].ymm.c, sizeof(expected->ymm)/2)); 3903 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[5], 3904 &expected[5].ymm.c, sizeof(expected->ymm)/2)); 3905 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[6], 3906 &expected[6].ymm.c, sizeof(expected->ymm)/2)); 3907 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[7], 3908 &expected[7].ymm.c, sizeof(expected->ymm)/2)); 3909#if defined(__x86_64__) 3910 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[8], 3911 &expected[8].ymm.c, sizeof(expected->ymm)/2)); 3912 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[9], 3913 &expected[9].ymm.c, sizeof(expected->ymm)/2)); 3914 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[10], 3915 &expected[10].ymm.c, sizeof(expected->ymm)/2)); 3916 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[11], 3917 &expected[11].ymm.c, sizeof(expected->ymm)/2)); 3918 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[12], 3919 &expected[12].ymm.c, sizeof(expected->ymm)/2)); 3920 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[13], 3921 &expected[13].ymm.c, sizeof(expected->ymm)/2)); 3922 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[14], 3923 &expected[14].ymm.c, sizeof(expected->ymm)/2)); 3924 ATF_CHECK(!memcmp(&xst.xs_ymm_hi128.xs_ymm[15], 3925 &expected[15].ymm.c, sizeof(expected->ymm)/2)); 3926#endif 3927 /*FALLTHROUGH*/ 3928 case FPREGS_XMM: 3929 ATF_CHECK(!memcmp(&fxs->fx_xmm[0], &expected[0].ymm.a, 3930 sizeof(expected->ymm)/2)); 3931 ATF_CHECK(!memcmp(&fxs->fx_xmm[1], &expected[1].ymm.a, 3932 sizeof(expected->ymm)/2)); 3933 ATF_CHECK(!memcmp(&fxs->fx_xmm[2], &expected[2].ymm.a, 3934 sizeof(expected->ymm)/2)); 3935 ATF_CHECK(!memcmp(&fxs->fx_xmm[3], &expected[3].ymm.a, 3936 sizeof(expected->ymm)/2)); 3937 ATF_CHECK(!memcmp(&fxs->fx_xmm[4], &expected[4].ymm.a, 3938 sizeof(expected->ymm)/2)); 3939 ATF_CHECK(!memcmp(&fxs->fx_xmm[5], &expected[5].ymm.a, 3940 sizeof(expected->ymm)/2)); 3941 ATF_CHECK(!memcmp(&fxs->fx_xmm[6], &expected[6].ymm.a, 3942 sizeof(expected->ymm)/2)); 3943 ATF_CHECK(!memcmp(&fxs->fx_xmm[7], &expected[7].ymm.a, 3944 sizeof(expected->ymm)/2)); 3945#if defined(__x86_64__) 3946 ATF_CHECK(!memcmp(&fxs->fx_xmm[8], &expected[8].ymm.a, 3947 sizeof(expected->ymm)/2)); 3948 ATF_CHECK(!memcmp(&fxs->fx_xmm[9], &expected[9].ymm.a, 3949 sizeof(expected->ymm)/2)); 3950 ATF_CHECK(!memcmp(&fxs->fx_xmm[10], &expected[10].ymm.a, 3951 sizeof(expected->ymm)/2)); 3952 ATF_CHECK(!memcmp(&fxs->fx_xmm[11], &expected[11].ymm.a, 3953 sizeof(expected->ymm)/2)); 3954 ATF_CHECK(!memcmp(&fxs->fx_xmm[12], &expected[12].ymm.a, 3955 sizeof(expected->ymm)/2)); 3956 ATF_CHECK(!memcmp(&fxs->fx_xmm[13], &expected[13].ymm.a, 3957 sizeof(expected->ymm)/2)); 3958 ATF_CHECK(!memcmp(&fxs->fx_xmm[14], &expected[14].ymm.a, 3959 sizeof(expected->ymm)/2)); 3960 ATF_CHECK(!memcmp(&fxs->fx_xmm[15], &expected[15].ymm.a, 3961 sizeof(expected->ymm)/2)); 3962#endif 3963 break; 3964 } 3965 break; 3966 case TEST_SETREGS: 3967 switch (regs) { 3968 case GPREGS_32: 3969#if defined(__i386__) 3970 gpr.r_eax = expected[0].u32; 3971 gpr.r_ebx = expected[1].u32; 3972 gpr.r_ecx = expected[2].u32; 3973 gpr.r_edx = expected[3].u32; 3974 gpr.r_esi = expected[4].u32; 3975 gpr.r_edi = expected[5].u32; 3976#endif 3977 break; 3978 case GPREGS_32_EBP_ESP: 3979#if defined(__i386__) 3980 gpr.r_esp = expected[0].u32; 3981 gpr.r_ebp = expected[1].u32; 3982#endif 3983 break; 3984 case GPREGS_64: 3985#if defined(__x86_64__) 3986 gpr.regs[_REG_RAX] = expected[0].u64; 3987 gpr.regs[_REG_RBX] = expected[1].u64; 3988 gpr.regs[_REG_RCX] = expected[2].u64; 3989 gpr.regs[_REG_RDX] = expected[3].u64; 3990 gpr.regs[_REG_RSI] = expected[4].u64; 3991 gpr.regs[_REG_RDI] = expected[5].u64; 3992 gpr.regs[_REG_RSP] = expected[6].u64; 3993 gpr.regs[_REG_RBP] = expected[7].u64; 3994#endif 3995 break; 3996 case GPREGS_64_R8: 3997#if defined(__x86_64__) 3998 gpr.regs[_REG_R8] = expected[0].u64; 3999 gpr.regs[_REG_R9] = expected[1].u64; 4000 gpr.regs[_REG_R10] = expected[2].u64; 4001 gpr.regs[_REG_R11] = expected[3].u64; 4002 gpr.regs[_REG_R12] = expected[4].u64; 4003 gpr.regs[_REG_R13] = expected[5].u64; 4004 gpr.regs[_REG_R14] = expected[6].u64; 4005 gpr.regs[_REG_R15] = expected[7].u64; 4006#endif 4007 break; 4008 case FPREGS_FPU: 4009#if defined(__i386__) 4010 if (regset == TEST_FPREGS) { 4011 /* SETFPREGS on i386 */ 4012 fpr.fstate.s87_cw = expected_fpu.cw; 4013 fpr.fstate.s87_sw = expected_fpu.sw; 4014 fpr.fstate.s87_tw = expected_fpu.tw; 4015 fpr.fstate.s87_opcode = expected_fpu.opcode; 4016 fpr.fstate.s87_ip = expected_fpu.ip; 4017 fpr.fstate.s87_dp = expected_fpu.dp; 4018 } else 4019#endif /*defined(__i386__)*/ 4020 { 4021 /* amd64 or SETXSTATE on i386 */ 4022 fxs->fx_cw = expected_fpu.cw; 4023 fxs->fx_sw = expected_fpu.sw; 4024 fxs->fx_tw = expected_fpu.tw_abridged; 4025 fxs->fx_opcode = expected_fpu.opcode; 4026 fxs->fx_ip = expected_fpu.ip; 4027 fxs->fx_dp = expected_fpu.dp; 4028 } 4029 4030 ST_EXP(0) = expected_fpu.st[0].sign_exp; 4031 ST_MAN(0) = expected_fpu.st[0].mantissa; 4032 ST_EXP(1) = expected_fpu.st[1].sign_exp; 4033 ST_MAN(1) = expected_fpu.st[1].mantissa; 4034 ST_EXP(2) = expected_fpu.st[2].sign_exp; 4035 ST_MAN(2) = expected_fpu.st[2].mantissa; 4036 ST_EXP(3) = expected_fpu.st[3].sign_exp; 4037 ST_MAN(3) = expected_fpu.st[3].mantissa; 4038 ST_EXP(4) = expected_fpu.st[4].sign_exp; 4039 ST_MAN(4) = expected_fpu.st[4].mantissa; 4040 ST_EXP(5) = expected_fpu.st[5].sign_exp; 4041 ST_MAN(5) = expected_fpu.st[5].mantissa; 4042 ST_EXP(6) = expected_fpu.st[6].sign_exp; 4043 ST_MAN(6) = expected_fpu.st[6].mantissa; 4044 ST_EXP(7) = expected_fpu.st[7].sign_exp; 4045 ST_MAN(7) = expected_fpu.st[7].mantissa; 4046 break; 4047 case FPREGS_MM: 4048 ST_MAN(0) = expected[0].u64; 4049 ST_MAN(1) = expected[1].u64; 4050 ST_MAN(2) = expected[2].u64; 4051 ST_MAN(3) = expected[3].u64; 4052 ST_MAN(4) = expected[4].u64; 4053 ST_MAN(5) = expected[5].u64; 4054 ST_MAN(6) = expected[6].u64; 4055 ST_MAN(7) = expected[7].u64; 4056 break; 4057 case FPREGS_ZMM: 4058 /* zmm0..zmm15 are split between xmm, ymm_hi128, zmm_hi256 */ 4059 memcpy(&xst.xs_zmm_hi256.xs_zmm[0], 4060 &expected[0].zmm.e, sizeof(expected->zmm)/2); 4061 memcpy(&xst.xs_zmm_hi256.xs_zmm[1], 4062 &expected[1].zmm.e, sizeof(expected->zmm)/2); 4063 memcpy(&xst.xs_zmm_hi256.xs_zmm[2], 4064 &expected[2].zmm.e, sizeof(expected->zmm)/2); 4065 memcpy(&xst.xs_zmm_hi256.xs_zmm[3], 4066 &expected[3].zmm.e, sizeof(expected->zmm)/2); 4067 memcpy(&xst.xs_zmm_hi256.xs_zmm[4], 4068 &expected[4].zmm.e, sizeof(expected->zmm)/2); 4069 memcpy(&xst.xs_zmm_hi256.xs_zmm[5], 4070 &expected[5].zmm.e, sizeof(expected->zmm)/2); 4071 memcpy(&xst.xs_zmm_hi256.xs_zmm[6], 4072 &expected[6].zmm.e, sizeof(expected->zmm)/2); 4073 memcpy(&xst.xs_zmm_hi256.xs_zmm[7], 4074 &expected[7].zmm.e, sizeof(expected->zmm)/2); 4075#if defined(__x86_64__) 4076 memcpy(&xst.xs_zmm_hi256.xs_zmm[8], 4077 &expected[8].zmm.e, sizeof(expected->zmm)/2); 4078 memcpy(&xst.xs_zmm_hi256.xs_zmm[9], 4079 &expected[9].zmm.e, sizeof(expected->zmm)/2); 4080 memcpy(&xst.xs_zmm_hi256.xs_zmm[10], 4081 &expected[10].zmm.e, sizeof(expected->zmm)/2); 4082 memcpy(&xst.xs_zmm_hi256.xs_zmm[11], 4083 &expected[11].zmm.e, sizeof(expected->zmm)/2); 4084 memcpy(&xst.xs_zmm_hi256.xs_zmm[12], 4085 &expected[12].zmm.e, sizeof(expected->zmm)/2); 4086 memcpy(&xst.xs_zmm_hi256.xs_zmm[13], 4087 &expected[13].zmm.e, sizeof(expected->zmm)/2); 4088 memcpy(&xst.xs_zmm_hi256.xs_zmm[14], 4089 &expected[14].zmm.e, sizeof(expected->zmm)/2); 4090 memcpy(&xst.xs_zmm_hi256.xs_zmm[15], 4091 &expected[15].zmm.e, sizeof(expected->zmm)/2); 4092 /* zmm16..zmm31 are stored as a whole */ 4093 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[0], 4094 &expected[16].zmm, sizeof(expected->zmm)); 4095 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[1], 4096 &expected[17].zmm, sizeof(expected->zmm)); 4097 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[2], 4098 &expected[18].zmm, sizeof(expected->zmm)); 4099 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[3], 4100 &expected[19].zmm, sizeof(expected->zmm)); 4101 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[4], 4102 &expected[20].zmm, sizeof(expected->zmm)); 4103 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[5], 4104 &expected[21].zmm, sizeof(expected->zmm)); 4105 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[6], 4106 &expected[22].zmm, sizeof(expected->zmm)); 4107 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[7], 4108 &expected[23].zmm, sizeof(expected->zmm)); 4109 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[8], 4110 &expected[24].zmm, sizeof(expected->zmm)); 4111 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[9], 4112 &expected[25].zmm, sizeof(expected->zmm)); 4113 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[10], 4114 &expected[26].zmm, sizeof(expected->zmm)); 4115 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[11], 4116 &expected[27].zmm, sizeof(expected->zmm)); 4117 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[12], 4118 &expected[28].zmm, sizeof(expected->zmm)); 4119 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[13], 4120 &expected[29].zmm, sizeof(expected->zmm)); 4121 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[14], 4122 &expected[30].zmm, sizeof(expected->zmm)); 4123 memcpy(&xst.xs_hi16_zmm.xs_hi16_zmm[15], 4124 &expected[31].zmm, sizeof(expected->zmm)); 4125#endif 4126 /* k0..k7 */ 4127 xst.xs_opmask.xs_k[0] = expected[32].zmm.a; 4128 xst.xs_opmask.xs_k[1] = expected[32].zmm.b; 4129 xst.xs_opmask.xs_k[2] = expected[32].zmm.c; 4130 xst.xs_opmask.xs_k[3] = expected[32].zmm.d; 4131 xst.xs_opmask.xs_k[4] = expected[32].zmm.e; 4132 xst.xs_opmask.xs_k[5] = expected[32].zmm.f; 4133 xst.xs_opmask.xs_k[6] = expected[32].zmm.g; 4134 xst.xs_opmask.xs_k[7] = expected[32].zmm.h; 4135 /*FALLTHROUGH*/ 4136 case FPREGS_YMM: 4137 memcpy(&xst.xs_ymm_hi128.xs_ymm[0], 4138 &expected[0].ymm.c, sizeof(expected->ymm)/2); 4139 memcpy(&xst.xs_ymm_hi128.xs_ymm[1], 4140 &expected[1].ymm.c, sizeof(expected->ymm)/2); 4141 memcpy(&xst.xs_ymm_hi128.xs_ymm[2], 4142 &expected[2].ymm.c, sizeof(expected->ymm)/2); 4143 memcpy(&xst.xs_ymm_hi128.xs_ymm[3], 4144 &expected[3].ymm.c, sizeof(expected->ymm)/2); 4145 memcpy(&xst.xs_ymm_hi128.xs_ymm[4], 4146 &expected[4].ymm.c, sizeof(expected->ymm)/2); 4147 memcpy(&xst.xs_ymm_hi128.xs_ymm[5], 4148 &expected[5].ymm.c, sizeof(expected->ymm)/2); 4149 memcpy(&xst.xs_ymm_hi128.xs_ymm[6], 4150 &expected[6].ymm.c, sizeof(expected->ymm)/2); 4151 memcpy(&xst.xs_ymm_hi128.xs_ymm[7], 4152 &expected[7].ymm.c, sizeof(expected->ymm)/2); 4153#if defined(__x86_64__) 4154 memcpy(&xst.xs_ymm_hi128.xs_ymm[8], 4155 &expected[8].ymm.c, sizeof(expected->ymm)/2); 4156 memcpy(&xst.xs_ymm_hi128.xs_ymm[9], 4157 &expected[9].ymm.c, sizeof(expected->ymm)/2); 4158 memcpy(&xst.xs_ymm_hi128.xs_ymm[10], 4159 &expected[10].ymm.c, sizeof(expected->ymm)/2); 4160 memcpy(&xst.xs_ymm_hi128.xs_ymm[11], 4161 &expected[11].ymm.c, sizeof(expected->ymm)/2); 4162 memcpy(&xst.xs_ymm_hi128.xs_ymm[12], 4163 &expected[12].ymm.c, sizeof(expected->ymm)/2); 4164 memcpy(&xst.xs_ymm_hi128.xs_ymm[13], 4165 &expected[13].ymm.c, sizeof(expected->ymm)/2); 4166 memcpy(&xst.xs_ymm_hi128.xs_ymm[14], 4167 &expected[14].ymm.c, sizeof(expected->ymm)/2); 4168 memcpy(&xst.xs_ymm_hi128.xs_ymm[15], 4169 &expected[15].ymm.c, sizeof(expected->ymm)/2); 4170#endif 4171 /*FALLTHROUGH*/ 4172 case FPREGS_XMM: 4173 memcpy(&fxs->fx_xmm[0], &expected[0].ymm.a, 4174 sizeof(expected->ymm)/2); 4175 memcpy(&fxs->fx_xmm[1], &expected[1].ymm.a, 4176 sizeof(expected->ymm)/2); 4177 memcpy(&fxs->fx_xmm[2], &expected[2].ymm.a, 4178 sizeof(expected->ymm)/2); 4179 memcpy(&fxs->fx_xmm[3], &expected[3].ymm.a, 4180 sizeof(expected->ymm)/2); 4181 memcpy(&fxs->fx_xmm[4], &expected[4].ymm.a, 4182 sizeof(expected->ymm)/2); 4183 memcpy(&fxs->fx_xmm[5], &expected[5].ymm.a, 4184 sizeof(expected->ymm)/2); 4185 memcpy(&fxs->fx_xmm[6], &expected[6].ymm.a, 4186 sizeof(expected->ymm)/2); 4187 memcpy(&fxs->fx_xmm[7], &expected[7].ymm.a, 4188 sizeof(expected->ymm)/2); 4189#if defined(__x86_64__) 4190 memcpy(&fxs->fx_xmm[8], &expected[8].ymm.a, 4191 sizeof(expected->ymm)/2); 4192 memcpy(&fxs->fx_xmm[9], &expected[9].ymm.a, 4193 sizeof(expected->ymm)/2); 4194 memcpy(&fxs->fx_xmm[10], &expected[10].ymm.a, 4195 sizeof(expected->ymm)/2); 4196 memcpy(&fxs->fx_xmm[11], &expected[11].ymm.a, 4197 sizeof(expected->ymm)/2); 4198 memcpy(&fxs->fx_xmm[12], &expected[12].ymm.a, 4199 sizeof(expected->ymm)/2); 4200 memcpy(&fxs->fx_xmm[13], &expected[13].ymm.a, 4201 sizeof(expected->ymm)/2); 4202 memcpy(&fxs->fx_xmm[14], &expected[14].ymm.a, 4203 sizeof(expected->ymm)/2); 4204 memcpy(&fxs->fx_xmm[15], &expected[15].ymm.a, 4205 sizeof(expected->ymm)/2); 4206#endif 4207 break; 4208 } 4209 4210 switch (regset) { 4211 case TEST_GPREGS: 4212 DPRINTF("Call SETREGS for the child process\n"); 4213 SYSCALL_REQUIRE(ptrace(PT_SETREGS, child, &gpr, 0) 4214 != -1); 4215 break; 4216 case TEST_XMMREGS: 4217#if defined(__i386__) 4218 DPRINTF("Call SETXMMREGS for the child process\n"); 4219 SYSCALL_REQUIRE(ptrace(PT_SETXMMREGS, child, &xmm, 0) 4220 != -1); 4221 break; 4222#else 4223 /*FALLTHROUGH*/ 4224#endif 4225 case TEST_FPREGS: 4226 DPRINTF("Call SETFPREGS for the child process\n"); 4227 SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &fpr, 0) 4228 != -1); 4229 break; 4230 case TEST_XSTATE: 4231 DPRINTF("Call SETXSTATE for the child process\n"); 4232 SYSCALL_REQUIRE(ptrace(PT_SETXSTATE, child, &iov, 0) 4233 != -1); 4234 break; 4235 } 4236 break; 4237 } 4238 4239#undef ST_EXP 4240#undef ST_MAN 4241 4242 DPRINTF("Before resuming the child process where it left off and " 4243 "without signal to be sent\n"); 4244 SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); 4245 4246 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4247 TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); 4248 4249 validate_status_exited(status, exitval); 4250 4251 DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME); 4252 TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); 4253} 4254 4255#define X86_REGISTER_TEST(test, regset, regs, regmode, descr) \ 4256ATF_TC(test); \ 4257ATF_TC_HEAD(test, tc) \ 4258{ \ 4259 atf_tc_set_md_var(tc, "descr", descr); \ 4260} \ 4261 \ 4262ATF_TC_BODY(test, tc) \ 4263{ \ 4264 x86_register_test(regset, regs, regmode); \ 4265} 4266 4267X86_REGISTER_TEST(x86_gpregs32_read, TEST_GPREGS, GPREGS_32, TEST_GETREGS, 4268 "Test reading basic 32-bit gp registers from debugged program " 4269 "via PT_GETREGS."); 4270X86_REGISTER_TEST(x86_gpregs32_write, TEST_GPREGS, GPREGS_32, TEST_SETREGS, 4271 "Test writing basic 32-bit gp registers into debugged program " 4272 "via PT_SETREGS."); 4273X86_REGISTER_TEST(x86_gpregs32_core, TEST_GPREGS, GPREGS_32, TEST_COREDUMP, 4274 "Test reading basic 32-bit gp registers from core dump."); 4275X86_REGISTER_TEST(x86_gpregs32_ebp_esp_read, TEST_GPREGS, GPREGS_32_EBP_ESP, 4276 TEST_GETREGS, "Test reading ebp & esp registers from debugged program " 4277 "via PT_GETREGS."); 4278X86_REGISTER_TEST(x86_gpregs32_ebp_esp_write, TEST_GPREGS, GPREGS_32_EBP_ESP, 4279 TEST_SETREGS, "Test writing ebp & esp registers into debugged program " 4280 "via PT_SETREGS."); 4281X86_REGISTER_TEST(x86_gpregs32_ebp_esp_core, TEST_GPREGS, GPREGS_32_EBP_ESP, 4282 TEST_COREDUMP, "Test reading ebp & esp registers from core dump."); 4283 4284X86_REGISTER_TEST(x86_gpregs64_read, TEST_GPREGS, GPREGS_64, TEST_GETREGS, 4285 "Test reading basic 64-bit gp registers from debugged program " 4286 "via PT_GETREGS."); 4287X86_REGISTER_TEST(x86_gpregs64_write, TEST_GPREGS, GPREGS_64, TEST_SETREGS, 4288 "Test writing basic 64-bit gp registers into debugged program " 4289 "via PT_SETREGS."); 4290X86_REGISTER_TEST(x86_gpregs64_core, TEST_GPREGS, GPREGS_64, TEST_COREDUMP, 4291 "Test reading basic 64-bit gp registers from core dump."); 4292X86_REGISTER_TEST(x86_gpregs64_r8_read, TEST_GPREGS, GPREGS_64_R8, TEST_GETREGS, 4293 "Test reading r8..r15 registers from debugged program via PT_GETREGS."); 4294X86_REGISTER_TEST(x86_gpregs64_r8_write, TEST_GPREGS, GPREGS_64_R8, 4295 TEST_SETREGS, "Test writing r8..r15 registers into debugged program " 4296 "via PT_SETREGS."); 4297X86_REGISTER_TEST(x86_gpregs64_r8_core, TEST_GPREGS, GPREGS_64_R8, 4298 TEST_COREDUMP, "Test reading r8..r15 registers from core dump."); 4299 4300X86_REGISTER_TEST(x86_fpregs_fpu_read, TEST_FPREGS, FPREGS_FPU, TEST_GETREGS, 4301 "Test reading base FPU registers from debugged program via PT_GETFPREGS."); 4302X86_REGISTER_TEST(x86_fpregs_fpu_write, TEST_FPREGS, FPREGS_FPU, TEST_SETREGS, 4303 "Test writing base FPU registers into debugged program via PT_SETFPREGS."); 4304X86_REGISTER_TEST(x86_fpregs_fpu_core, TEST_FPREGS, FPREGS_FPU, TEST_COREDUMP, 4305 "Test reading base FPU registers from coredump."); 4306X86_REGISTER_TEST(x86_fpregs_mm_read, TEST_FPREGS, FPREGS_MM, TEST_GETREGS, 4307 "Test reading mm0..mm7 registers from debugged program " 4308 "via PT_GETFPREGS."); 4309X86_REGISTER_TEST(x86_fpregs_mm_write, TEST_FPREGS, FPREGS_MM, TEST_SETREGS, 4310 "Test writing mm0..mm7 registers into debugged program " 4311 "via PT_SETFPREGS."); 4312X86_REGISTER_TEST(x86_fpregs_mm_core, TEST_FPREGS, FPREGS_MM, TEST_COREDUMP, 4313 "Test reading mm0..mm7 registers from coredump."); 4314X86_REGISTER_TEST(x86_fpregs_xmm_read, TEST_XMMREGS, FPREGS_XMM, TEST_GETREGS, 4315 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 4316 "via PT_GETFPREGS (PT_GETXMMREGS on i386)."); 4317X86_REGISTER_TEST(x86_fpregs_xmm_write, TEST_XMMREGS, FPREGS_XMM, TEST_SETREGS, 4318 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 4319 "via PT_SETFPREGS (PT_SETXMMREGS on i386)."); 4320X86_REGISTER_TEST(x86_fpregs_xmm_core, TEST_XMMREGS, FPREGS_XMM, TEST_COREDUMP, 4321 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump."); 4322 4323X86_REGISTER_TEST(x86_xstate_fpu_read, TEST_XSTATE, FPREGS_FPU, TEST_GETREGS, 4324 "Test reading base FPU registers from debugged program via PT_GETXSTATE."); 4325X86_REGISTER_TEST(x86_xstate_fpu_write, TEST_XSTATE, FPREGS_FPU, TEST_SETREGS, 4326 "Test writing base FPU registers into debugged program via PT_SETXSTATE."); 4327X86_REGISTER_TEST(x86_xstate_fpu_core, TEST_XSTATE, FPREGS_FPU, TEST_COREDUMP, 4328 "Test reading base FPU registers from core dump via XSTATE note."); 4329X86_REGISTER_TEST(x86_xstate_mm_read, TEST_XSTATE, FPREGS_MM, TEST_GETREGS, 4330 "Test reading mm0..mm7 registers from debugged program " 4331 "via PT_GETXSTATE."); 4332X86_REGISTER_TEST(x86_xstate_mm_write, TEST_XSTATE, FPREGS_MM, TEST_SETREGS, 4333 "Test writing mm0..mm7 registers into debugged program " 4334 "via PT_SETXSTATE."); 4335X86_REGISTER_TEST(x86_xstate_mm_core, TEST_XSTATE, FPREGS_MM, TEST_COREDUMP, 4336 "Test reading mm0..mm7 registers from core dump via XSTATE note."); 4337X86_REGISTER_TEST(x86_xstate_xmm_read, TEST_XSTATE, FPREGS_XMM, TEST_GETREGS, 4338 "Test reading xmm0..xmm15 (..xmm7 on i386) from debugged program " 4339 "via PT_GETXSTATE."); 4340X86_REGISTER_TEST(x86_xstate_xmm_write, TEST_XSTATE, FPREGS_XMM, TEST_SETREGS, 4341 "Test writing xmm0..xmm15 (..xmm7 on i386) into debugged program " 4342 "via PT_SETXSTATE."); 4343X86_REGISTER_TEST(x86_xstate_xmm_core, TEST_XSTATE, FPREGS_XMM, TEST_COREDUMP, 4344 "Test reading xmm0..xmm15 (..xmm7 on i386) from coredump via XSTATE note."); 4345X86_REGISTER_TEST(x86_xstate_ymm_read, TEST_XSTATE, FPREGS_YMM, TEST_GETREGS, 4346 "Test reading ymm0..ymm15 (..ymm7 on i386) from debugged program " 4347 "via PT_GETXSTATE."); 4348X86_REGISTER_TEST(x86_xstate_ymm_write, TEST_XSTATE, FPREGS_YMM, TEST_SETREGS, 4349 "Test writing ymm0..ymm15 (..ymm7 on i386) into debugged program " 4350 "via PT_SETXSTATE."); 4351X86_REGISTER_TEST(x86_xstate_ymm_core, TEST_XSTATE, FPREGS_YMM, TEST_COREDUMP, 4352 "Test reading ymm0..ymm15 (..ymm7 on i386) from coredump via XSTATE note."); 4353X86_REGISTER_TEST(x86_xstate_zmm_read, TEST_XSTATE, FPREGS_ZMM, TEST_GETREGS, 4354 "Test reading zmm0..zmm31 (..zmm7 on i386), k0..k7 from debugged program " 4355 "via PT_GETXSTATE."); 4356X86_REGISTER_TEST(x86_xstate_zmm_write, TEST_XSTATE, FPREGS_ZMM, TEST_SETREGS, 4357 "Test writing zmm0..zmm31 (..zmm7 on i386), k0..k7 into debugged program " 4358 "via PT_SETXSTATE."); 4359X86_REGISTER_TEST(x86_xstate_zmm_core, TEST_XSTATE, FPREGS_ZMM, TEST_COREDUMP, 4360 "Test reading zmm0..zmm31 (..zmm7 on i386), k0..k7 from coredump " 4361 "via XSTATE note."); 4362 4363/// ---------------------------------------------------------------------------- 4364 4365#if defined(TWAIT_HAVE_STATUS) 4366 4367static void 4368thread_concurrent_lwp_setup(pid_t child, lwpid_t lwpid) 4369{ 4370 struct dbreg r; 4371 union u dr7; 4372 4373 /* We need to set debug registers for every child */ 4374 DPRINTF("Call GETDBREGS for LWP %d\n", lwpid); 4375 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, lwpid) != -1); 4376 4377 dr7.raw = 0; 4378 /* should be set to 1 according to Intel manual, 17.2 */ 4379 dr7.bits.reserved_10 = 1; 4380 dr7.bits.local_exact_breakpt = 1; 4381 dr7.bits.global_exact_breakpt = 1; 4382 /* use DR0 for breakpoints */ 4383 dr7.bits.global_dr0_breakpoint = 1; 4384 dr7.bits.condition_dr0 = 0; /* exec */ 4385 dr7.bits.len_dr0 = 0; 4386 /* use DR1 for watchpoints */ 4387 dr7.bits.global_dr1_breakpoint = 1; 4388 dr7.bits.condition_dr1 = 1; /* write */ 4389 dr7.bits.len_dr1 = 3; /* 4 bytes */ 4390 r.dr[7] = dr7.raw; 4391 r.dr[0] = (long)(intptr_t)check_happy; 4392 r.dr[1] = (long)(intptr_t)&thread_concurrent_watchpoint_var; 4393 DPRINTF("dr0=%" PRIxREGISTER "\n", r.dr[0]); 4394 DPRINTF("dr1=%" PRIxREGISTER "\n", r.dr[1]); 4395 DPRINTF("dr7=%" PRIxREGISTER "\n", r.dr[7]); 4396 4397 DPRINTF("Call SETDBREGS for LWP %d\n", lwpid); 4398 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, lwpid) != -1); 4399} 4400 4401static enum thread_concurrent_sigtrap_event 4402thread_concurrent_handle_sigtrap(pid_t child, ptrace_siginfo_t *info) 4403{ 4404 enum thread_concurrent_sigtrap_event ret = TCSE_UNKNOWN; 4405 struct dbreg r; 4406 union u dr7; 4407 4408 ATF_CHECK_EQ_MSG(info->psi_siginfo.si_code, TRAP_DBREG, 4409 "lwp=%d, expected TRAP_DBREG (%d), got %d", info->psi_lwpid, 4410 TRAP_DBREG, info->psi_siginfo.si_code); 4411 4412 DPRINTF("Call GETDBREGS for LWP %d\n", info->psi_lwpid); 4413 SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r, info->psi_lwpid) != -1); 4414 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 4415 r.dr[6], r.dr[7]); 4416 4417 ATF_CHECK_MSG(r.dr[6] & 3, "lwp=%d, got DR6=%" PRIxREGISTER, 4418 info->psi_lwpid, r.dr[6]); 4419 4420 /* Handle only one event at a time, we should get 4421 * a separate SIGTRAP for the other one. 4422 */ 4423 if (r.dr[6] & 1) { 4424 r.dr[6] &= ~1; 4425 4426 /* We need to disable the breakpoint to move 4427 * past it. 4428 * 4429 * TODO: single-step and reenable it? 4430 */ 4431 dr7.raw = r.dr[7]; 4432 dr7.bits.global_dr0_breakpoint = 0; 4433 r.dr[7] = dr7.raw; 4434 4435 ret = TCSE_BREAKPOINT; 4436 } else if (r.dr[6] & 2) { 4437 r.dr[6] &= ~2; 4438 ret = TCSE_WATCHPOINT; 4439 } 4440 4441 DPRINTF("Call SETDBREGS for LWP %d\n", info->psi_lwpid); 4442 DPRINTF("dr6=%" PRIxREGISTER ", dr7=%" PRIxREGISTER "\n", 4443 r.dr[6], r.dr[7]); 4444 SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r, info->psi_lwpid) != -1); 4445 4446 return ret; 4447} 4448 4449#endif /*defined(TWAIT_HAVE_STATUS)*/ 4450 4451/// ---------------------------------------------------------------------------- 4452 4453#define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \ 4454 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \ 4455 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \ 4456 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \ 4457 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \ 4458 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \ 4459 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \ 4460 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \ 4461 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \ 4462 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \ 4463 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \ 4464 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \ 4465 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \ 4466 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \ 4467 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \ 4468 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \ 4469 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \ 4470 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \ 4471 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \ 4472 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \ 4473 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \ 4474 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \ 4475 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \ 4476 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \ 4477 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \ 4478 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \ 4479 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \ 4480 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \ 4481 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \ 4482 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \ 4483 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \ 4484 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \ 4485 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \ 4486 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \ 4487 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \ 4488 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \ 4489 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \ 4490 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \ 4491 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \ 4492 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \ 4493 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \ 4494 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \ 4495 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \ 4496 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \ 4497 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \ 4498 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \ 4499 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \ 4500 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \ 4501 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \ 4502 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \ 4503 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \ 4504 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \ 4505 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \ 4506 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \ 4507 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \ 4508 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \ 4509 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \ 4510 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \ 4511 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \ 4512 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \ 4513 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \ 4514 ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve); \ 4515 ATF_TP_ADD_TC_HAVE_DBREGS(tp, x86_cve_2018_8897); \ 4516 ATF_TP_ADD_TC(tp, x86_gpregs32_read); \ 4517 ATF_TP_ADD_TC(tp, x86_gpregs32_write); \ 4518 ATF_TP_ADD_TC(tp, x86_gpregs32_core); \ 4519 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_read); \ 4520 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_write); \ 4521 ATF_TP_ADD_TC(tp, x86_gpregs32_ebp_esp_core); \ 4522 ATF_TP_ADD_TC(tp, x86_gpregs64_read); \ 4523 ATF_TP_ADD_TC(tp, x86_gpregs64_write); \ 4524 ATF_TP_ADD_TC(tp, x86_gpregs64_core); \ 4525 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_read); \ 4526 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_write); \ 4527 ATF_TP_ADD_TC(tp, x86_gpregs64_r8_core); \ 4528 ATF_TP_ADD_TC(tp, x86_fpregs_fpu_read); \ 4529 ATF_TP_ADD_TC(tp, x86_fpregs_fpu_write); \ 4530 ATF_TP_ADD_TC(tp, x86_fpregs_fpu_core); \ 4531 ATF_TP_ADD_TC(tp, x86_fpregs_mm_read); \ 4532 ATF_TP_ADD_TC(tp, x86_fpregs_mm_write); \ 4533 ATF_TP_ADD_TC(tp, x86_fpregs_mm_core); \ 4534 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_read); \ 4535 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_write); \ 4536 ATF_TP_ADD_TC(tp, x86_fpregs_xmm_core); \ 4537 ATF_TP_ADD_TC(tp, x86_xstate_fpu_read); \ 4538 ATF_TP_ADD_TC(tp, x86_xstate_fpu_write); \ 4539 ATF_TP_ADD_TC(tp, x86_xstate_fpu_core); \ 4540 ATF_TP_ADD_TC(tp, x86_xstate_mm_read); \ 4541 ATF_TP_ADD_TC(tp, x86_xstate_mm_write); \ 4542 ATF_TP_ADD_TC(tp, x86_xstate_mm_core); \ 4543 ATF_TP_ADD_TC(tp, x86_xstate_xmm_read); \ 4544 ATF_TP_ADD_TC(tp, x86_xstate_xmm_write); \ 4545 ATF_TP_ADD_TC(tp, x86_xstate_xmm_core); \ 4546 ATF_TP_ADD_TC(tp, x86_xstate_ymm_read); \ 4547 ATF_TP_ADD_TC(tp, x86_xstate_ymm_write); \ 4548 ATF_TP_ADD_TC(tp, x86_xstate_ymm_core); \ 4549 ATF_TP_ADD_TC(tp, x86_xstate_zmm_read); \ 4550 ATF_TP_ADD_TC(tp, x86_xstate_zmm_write); \ 4551 ATF_TP_ADD_TC(tp, x86_xstate_zmm_core); 4552#else 4553#define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() 4554#endif 4555