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