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