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