Home | History | Annotate | Line # | Download | only in sys
t_ptrace_x86_wait.h revision 1.14
      1  1.14    mgorny /*	$NetBSD: t_ptrace_x86_wait.h,v 1.14 2019/06/04 12:17:05 mgorny Exp $	*/
      2   1.1     kamil 
      3   1.1     kamil /*-
      4   1.9     kamil  * 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.8     kamil 		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.8     kamil 		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.8     kamil 		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.1     kamil volatile lwpid_t x86_the_lwp_id = 0;
   1621   1.1     kamil 
   1622   1.1     kamil static void __used
   1623   1.1     kamil x86_lwp_main_func(void *arg)
   1624   1.1     kamil {
   1625   1.1     kamil 	x86_the_lwp_id = _lwp_self();
   1626   1.1     kamil 	_lwp_exit();
   1627   1.1     kamil }
   1628   1.1     kamil 
   1629   1.1     kamil static void
   1630   1.1     kamil dbregs_dont_inherit_lwp(int reg)
   1631   1.1     kamil {
   1632   1.1     kamil 	const int exitval = 5;
   1633   1.1     kamil 	const int sigval = SIGSTOP;
   1634   1.1     kamil 	pid_t child, wpid;
   1635   1.1     kamil #if defined(TWAIT_HAVE_STATUS)
   1636   1.1     kamil 	int status;
   1637   1.1     kamil #endif
   1638   1.1     kamil 	ptrace_state_t state;
   1639   1.1     kamil 	const int slen = sizeof(state);
   1640   1.1     kamil 	ptrace_event_t event;
   1641   1.1     kamil 	const int elen = sizeof(event);
   1642   1.1     kamil 	ucontext_t uc;
   1643   1.1     kamil 	lwpid_t lid;
   1644   1.1     kamil 	static const size_t ssize = 16*1024;
   1645   1.1     kamil 	void *stack;
   1646   1.1     kamil 	size_t i;
   1647   1.1     kamil 	struct dbreg r1;
   1648   1.1     kamil 	struct dbreg r2;
   1649   1.1     kamil 
   1650   1.5     kamil 	if (!can_we_set_dbregs()) {
   1651   1.5     kamil 		atf_tc_skip("Either run this test as root or set sysctl(3) "
   1652   1.5     kamil 		            "security.models.extensions.user_set_dbregs to 1");
   1653   1.5     kamil 	}
   1654   1.5     kamil 
   1655   1.2  christos 	DPRINTF("Before forking process PID=%d\n", getpid());
   1656   1.2  christos 	SYSCALL_REQUIRE((child = fork()) != -1);
   1657   1.1     kamil 	if (child == 0) {
   1658   1.2  christos 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1659   1.1     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1660   1.1     kamil 
   1661   1.2  christos 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1662   1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
   1663   1.1     kamil 
   1664   1.2  christos 		DPRINTF("Before allocating memory for stack in child\n");
   1665   1.1     kamil 		FORKEE_ASSERT((stack = malloc(ssize)) != NULL);
   1666   1.1     kamil 
   1667   1.2  christos 		DPRINTF("Before making context for new lwp in child\n");
   1668   1.1     kamil 		_lwp_makecontext(&uc, x86_lwp_main_func, NULL, NULL, stack,
   1669   1.1     kamil 		    ssize);
   1670   1.1     kamil 
   1671   1.2  christos 		DPRINTF("Before creating new in child\n");
   1672   1.1     kamil 		FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0);
   1673   1.1     kamil 
   1674   1.2  christos 		DPRINTF("Before waiting for lwp %d to exit\n", lid);
   1675   1.1     kamil 		FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0);
   1676   1.1     kamil 
   1677   1.2  christos 		DPRINTF("Before verifying that reported %d and running lid %d "
   1678   1.1     kamil 		    "are the same\n", lid, x86_the_lwp_id);
   1679   1.1     kamil 		FORKEE_ASSERT_EQ(lid, x86_the_lwp_id);
   1680   1.1     kamil 
   1681   1.2  christos 		DPRINTF("Before exiting of the child process\n");
   1682   1.1     kamil 		_exit(exitval);
   1683   1.1     kamil 	}
   1684   1.2  christos 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1685   1.1     kamil 
   1686   1.2  christos 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1687   1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1688   1.1     kamil 
   1689   1.1     kamil 	validate_status_stopped(status, sigval);
   1690   1.1     kamil 
   1691   1.2  christos 	DPRINTF("Set empty EVENT_MASK for the child %d\n", child);
   1692   1.1     kamil 	event.pe_set_event = PTRACE_LWP_CREATE;
   1693   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1);
   1694   1.1     kamil 
   1695   1.2  christos 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
   1696   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
   1697   1.1     kamil 
   1698   1.2  christos 	DPRINTF("State of the debug registers (r1):\n");
   1699   1.1     kamil 	for (i = 0; i < __arraycount(r1.dr); i++)
   1700   1.2  christos 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
   1701   1.1     kamil 
   1702   1.1     kamil 	r1.dr[reg] = (long)(intptr_t)check_happy;
   1703   1.2  christos 	DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n",
   1704   1.1     kamil 	    reg, reg, r1.dr[0]);
   1705   1.1     kamil 
   1706   1.2  christos 	DPRINTF("New state of the debug registers (r1):\n");
   1707   1.1     kamil 	for (i = 0; i < __arraycount(r1.dr); i++)
   1708   1.2  christos 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
   1709   1.1     kamil 
   1710   1.2  christos 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
   1711   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
   1712   1.1     kamil 
   1713   1.2  christos 	DPRINTF("Before resuming the child process where it left off and "
   1714   1.1     kamil 	    "without signal to be sent\n");
   1715   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1716   1.1     kamil 
   1717   1.2  christos 	DPRINTF("Before calling %s() for the child - expected stopped "
   1718   1.1     kamil 	    "SIGTRAP\n", TWAIT_FNAME);
   1719   1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1720   1.1     kamil 
   1721   1.1     kamil 	validate_status_stopped(status, SIGTRAP);
   1722   1.1     kamil 
   1723   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1);
   1724   1.1     kamil 
   1725   1.1     kamil 	ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE);
   1726   1.1     kamil 
   1727   1.1     kamil 	lid = state.pe_lwp;
   1728   1.2  christos 	DPRINTF("Reported PTRACE_LWP_CREATE event with lid %d\n", lid);
   1729   1.1     kamil 
   1730   1.2  christos 	DPRINTF("Call GETDBREGS for the child process new lwp (r2)\n");
   1731   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, lid) != -1);
   1732   1.1     kamil 
   1733   1.2  christos 	DPRINTF("State of the debug registers (r2):\n");
   1734   1.1     kamil 	for (i = 0; i < __arraycount(r2.dr); i++)
   1735   1.2  christos 		DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]);
   1736   1.1     kamil 
   1737   1.2  christos 	DPRINTF("Assert that (r1) and (r2) are not the same\n");
   1738   1.1     kamil 	ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0);
   1739   1.1     kamil 
   1740   1.2  christos 	DPRINTF("Before resuming the child process where it left off and "
   1741   1.1     kamil 	    "without signal to be sent\n");
   1742   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1743   1.1     kamil 
   1744   1.2  christos 	DPRINTF("Before calling %s() for the child - expected exited\n",
   1745   1.1     kamil 	    TWAIT_FNAME);
   1746   1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1747   1.1     kamil 
   1748   1.1     kamil 	validate_status_exited(status, exitval);
   1749   1.1     kamil 
   1750   1.2  christos 	DPRINTF("Before calling %s() for the child - expected no process\n",
   1751   1.1     kamil 	    TWAIT_FNAME);
   1752   1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1753   1.1     kamil }
   1754   1.1     kamil 
   1755   1.1     kamil ATF_TC(dbregs_dr0_dont_inherit_lwp);
   1756   1.1     kamil ATF_TC_HEAD(dbregs_dr0_dont_inherit_lwp, tc)
   1757   1.1     kamil {
   1758   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1759   1.1     kamil 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
   1760   1.1     kamil 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 0 from "
   1761   1.1     kamil 	    "the forker thread is not inherited");
   1762   1.1     kamil }
   1763   1.1     kamil 
   1764   1.1     kamil ATF_TC_BODY(dbregs_dr0_dont_inherit_lwp, tc)
   1765   1.1     kamil {
   1766   1.1     kamil 	dbregs_dont_inherit_lwp(0);
   1767   1.1     kamil }
   1768   1.1     kamil 
   1769   1.1     kamil ATF_TC(dbregs_dr1_dont_inherit_lwp);
   1770   1.1     kamil ATF_TC_HEAD(dbregs_dr1_dont_inherit_lwp, tc)
   1771   1.1     kamil {
   1772   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1773   1.1     kamil 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
   1774   1.1     kamil 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 1 from "
   1775   1.1     kamil 	    "the forker thread is not inherited");
   1776   1.1     kamil }
   1777   1.1     kamil 
   1778   1.1     kamil ATF_TC_BODY(dbregs_dr1_dont_inherit_lwp, tc)
   1779   1.1     kamil {
   1780   1.1     kamil 	dbregs_dont_inherit_lwp(1);
   1781   1.1     kamil }
   1782   1.1     kamil 
   1783   1.1     kamil ATF_TC(dbregs_dr2_dont_inherit_lwp);
   1784   1.1     kamil ATF_TC_HEAD(dbregs_dr2_dont_inherit_lwp, tc)
   1785   1.1     kamil {
   1786   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1787   1.1     kamil 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
   1788   1.1     kamil 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 2 from "
   1789   1.1     kamil 	    "the forker thread is not inherited");
   1790   1.1     kamil }
   1791   1.1     kamil 
   1792   1.1     kamil ATF_TC_BODY(dbregs_dr2_dont_inherit_lwp, tc)
   1793   1.1     kamil {
   1794   1.1     kamil 	dbregs_dont_inherit_lwp(2);
   1795   1.1     kamil }
   1796   1.1     kamil 
   1797   1.1     kamil ATF_TC(dbregs_dr3_dont_inherit_lwp);
   1798   1.1     kamil ATF_TC_HEAD(dbregs_dr3_dont_inherit_lwp, tc)
   1799   1.1     kamil {
   1800   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1801   1.1     kamil 	    "Verify that 1 LWP creation is intercepted by ptrace(2) with "
   1802   1.1     kamil 	    "EVENT_MASK set to PTRACE_LWP_CREATE and Debug Register 3 from "
   1803   1.1     kamil 	    "the forker thread is not inherited");
   1804   1.1     kamil }
   1805   1.1     kamil 
   1806   1.1     kamil ATF_TC_BODY(dbregs_dr3_dont_inherit_lwp, tc)
   1807   1.1     kamil {
   1808   1.1     kamil 	dbregs_dont_inherit_lwp(3);
   1809   1.1     kamil }
   1810   1.1     kamil 
   1811   1.1     kamil static void
   1812   1.1     kamil dbregs_dont_inherit_execve(int reg)
   1813   1.1     kamil {
   1814   1.1     kamil 	const int sigval = SIGTRAP;
   1815   1.1     kamil 	pid_t child, wpid;
   1816   1.1     kamil #if defined(TWAIT_HAVE_STATUS)
   1817   1.1     kamil 	int status;
   1818   1.1     kamil #endif
   1819   1.1     kamil 	size_t i;
   1820   1.1     kamil 	struct dbreg r1;
   1821   1.1     kamil 	struct dbreg r2;
   1822   1.1     kamil 
   1823   1.1     kamil 	struct ptrace_siginfo info;
   1824   1.1     kamil 	memset(&info, 0, sizeof(info));
   1825   1.1     kamil 
   1826   1.5     kamil 	if (!can_we_set_dbregs()) {
   1827   1.5     kamil 		atf_tc_skip("Either run this test as root or set sysctl(3) "
   1828   1.5     kamil 		            "security.models.extensions.user_set_dbregs to 1");
   1829   1.5     kamil 	}
   1830   1.5     kamil 
   1831   1.2  christos 	DPRINTF("Before forking process PID=%d\n", getpid());
   1832   1.2  christos 	SYSCALL_REQUIRE((child = fork()) != -1);
   1833   1.1     kamil 	if (child == 0) {
   1834   1.2  christos 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   1835   1.1     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   1836   1.1     kamil 
   1837   1.2  christos 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   1838   1.1     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
   1839   1.1     kamil 
   1840   1.2  christos 		DPRINTF("Before calling execve(2) from child\n");
   1841   1.1     kamil 		execlp("/bin/echo", "/bin/echo", NULL);
   1842   1.1     kamil 
   1843   1.1     kamil 		FORKEE_ASSERT(0 && "Not reached");
   1844   1.1     kamil 	}
   1845   1.2  christos 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   1846   1.1     kamil 
   1847   1.2  christos 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1848   1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1849   1.1     kamil 
   1850   1.1     kamil 	validate_status_stopped(status, sigval);
   1851   1.1     kamil 
   1852   1.2  christos 	DPRINTF("Call GETDBREGS for the child process (r1)\n");
   1853   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r1, 0) != -1);
   1854   1.1     kamil 
   1855   1.2  christos 	DPRINTF("State of the debug registers (r1):\n");
   1856   1.1     kamil 	for (i = 0; i < __arraycount(r1.dr); i++)
   1857   1.2  christos 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
   1858   1.1     kamil 
   1859   1.1     kamil 	r1.dr[reg] = (long)(intptr_t)check_happy;
   1860   1.2  christos 	DPRINTF("Set DR%d (r1.dr[%d]) to new value %" PRIxREGISTER "\n",
   1861   1.1     kamil 	    reg, reg, r1.dr[reg]);
   1862   1.1     kamil 
   1863   1.2  christos 	DPRINTF("New state of the debug registers (r1):\n");
   1864   1.1     kamil 	for (i = 0; i < __arraycount(r1.dr); i++)
   1865   1.2  christos 		DPRINTF("r1[%zu]=%" PRIxREGISTER "\n", i, r1.dr[i]);
   1866   1.1     kamil 
   1867   1.2  christos 	DPRINTF("Call SETDBREGS for the child process (r1)\n");
   1868   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &r1, 0) != -1);
   1869   1.1     kamil 
   1870   1.2  christos 	DPRINTF("Before resuming the child process where it left off and "
   1871   1.1     kamil 	    "without signal to be sent\n");
   1872   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1873   1.1     kamil 
   1874   1.2  christos 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1875   1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1876   1.1     kamil 
   1877   1.1     kamil 	validate_status_stopped(status, sigval);
   1878   1.1     kamil 
   1879   1.2  christos 	DPRINTF("Before calling ptrace(2) with PT_GET_SIGINFO for child\n");
   1880   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1);
   1881   1.1     kamil 
   1882   1.2  christos 	DPRINTF("Signal traced to lwpid=%d\n", info.psi_lwpid);
   1883   1.2  christos 	DPRINTF("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n",
   1884   1.1     kamil 	    info.psi_siginfo.si_signo, info.psi_siginfo.si_code,
   1885   1.1     kamil 	    info.psi_siginfo.si_errno);
   1886   1.1     kamil 
   1887   1.1     kamil 	ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval);
   1888   1.1     kamil 	ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC);
   1889   1.1     kamil 
   1890   1.2  christos 	DPRINTF("Call GETDBREGS for the child process after execve(2)\n");
   1891   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &r2, 0) != -1);
   1892   1.1     kamil 
   1893   1.2  christos 	DPRINTF("State of the debug registers (r2):\n");
   1894   1.1     kamil 	for (i = 0; i < __arraycount(r2.dr); i++)
   1895   1.2  christos 		DPRINTF("r2[%zu]=%" PRIxREGISTER "\n", i, r2.dr[i]);
   1896   1.1     kamil 
   1897   1.2  christos 	DPRINTF("Assert that (r1) and (r2) are not the same\n");
   1898   1.1     kamil 	ATF_REQUIRE(memcmp(&r1, &r2, sizeof(r1)) != 0);
   1899   1.1     kamil 
   1900   1.2  christos 	DPRINTF("Before resuming the child process where it left off and "
   1901   1.1     kamil 	    "without signal to be sent\n");
   1902   1.2  christos 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   1903   1.1     kamil 
   1904   1.2  christos 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1905   1.1     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   1906   1.1     kamil 
   1907   1.2  christos 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   1908   1.1     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   1909   1.1     kamil }
   1910   1.1     kamil 
   1911   1.1     kamil ATF_TC(dbregs_dr0_dont_inherit_execve);
   1912   1.1     kamil ATF_TC_HEAD(dbregs_dr0_dont_inherit_execve, tc)
   1913   1.1     kamil {
   1914   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1915   1.1     kamil 	    "Verify that execve(2) is intercepted by tracer and Debug "
   1916   1.1     kamil 	    "Register 0 is reset");
   1917   1.1     kamil }
   1918   1.1     kamil 
   1919   1.1     kamil ATF_TC_BODY(dbregs_dr0_dont_inherit_execve, tc)
   1920   1.1     kamil {
   1921   1.1     kamil 	dbregs_dont_inherit_execve(0);
   1922   1.1     kamil }
   1923   1.1     kamil 
   1924   1.1     kamil ATF_TC(dbregs_dr1_dont_inherit_execve);
   1925   1.1     kamil ATF_TC_HEAD(dbregs_dr1_dont_inherit_execve, tc)
   1926   1.1     kamil {
   1927   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1928   1.1     kamil 	    "Verify that execve(2) is intercepted by tracer and Debug "
   1929   1.1     kamil 	    "Register 1 is reset");
   1930   1.1     kamil }
   1931   1.1     kamil 
   1932   1.1     kamil ATF_TC_BODY(dbregs_dr1_dont_inherit_execve, tc)
   1933   1.1     kamil {
   1934   1.1     kamil 	dbregs_dont_inherit_execve(1);
   1935   1.1     kamil }
   1936   1.1     kamil 
   1937   1.1     kamil ATF_TC(dbregs_dr2_dont_inherit_execve);
   1938   1.1     kamil ATF_TC_HEAD(dbregs_dr2_dont_inherit_execve, tc)
   1939   1.1     kamil {
   1940   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1941   1.1     kamil 	    "Verify that execve(2) is intercepted by tracer and Debug "
   1942   1.1     kamil 	    "Register 2 is reset");
   1943   1.1     kamil }
   1944   1.1     kamil 
   1945   1.1     kamil ATF_TC_BODY(dbregs_dr2_dont_inherit_execve, tc)
   1946   1.1     kamil {
   1947   1.1     kamil 	dbregs_dont_inherit_execve(2);
   1948   1.1     kamil }
   1949   1.1     kamil 
   1950   1.1     kamil ATF_TC(dbregs_dr3_dont_inherit_execve);
   1951   1.1     kamil ATF_TC_HEAD(dbregs_dr3_dont_inherit_execve, tc)
   1952   1.1     kamil {
   1953   1.1     kamil 	atf_tc_set_md_var(tc, "descr",
   1954   1.1     kamil 	    "Verify that execve(2) is intercepted by tracer and Debug "
   1955   1.1     kamil 	    "Register 3 is reset");
   1956   1.1     kamil }
   1957   1.1     kamil 
   1958   1.1     kamil ATF_TC_BODY(dbregs_dr3_dont_inherit_execve, tc)
   1959   1.1     kamil {
   1960   1.1     kamil 	dbregs_dont_inherit_execve(3);
   1961   1.1     kamil }
   1962   1.7     kamil 
   1963   1.7     kamil /// ----------------------------------------------------------------------------
   1964   1.7     kamil 
   1965   1.7     kamil ATF_TC(x86_cve_2018_8897);
   1966   1.7     kamil ATF_TC_HEAD(x86_cve_2018_8897, tc)
   1967   1.7     kamil {
   1968   1.7     kamil 	atf_tc_set_md_var(tc, "descr",
   1969   1.7     kamil 	    "Verify mitigation for CVE-2018-8897 (POP SS debug exception)");
   1970   1.7     kamil }
   1971   1.7     kamil 
   1972   1.7     kamil #define X86_CVE_2018_8897_PAGE 0x5000 /* page addressable by 32-bit registers */
   1973   1.7     kamil 
   1974   1.7     kamil static void
   1975   1.7     kamil x86_cve_2018_8897_trigger(void)
   1976   1.7     kamil {
   1977   1.7     kamil 	/*
   1978   1.7     kamil 	 * A function to trigger the POP SS (CVE-2018-8897) vulnerability
   1979   1.7     kamil 	 *
   1980   1.7     kamil 	 * ifdef __x86_64__
   1981   1.7     kamil 	 *
   1982   1.7     kamil 	 * We need to switch to 32-bit mode execution on 64-bit kernel.
   1983   1.7     kamil 	 * This is achieved with far jump instruction and GDT descriptor
   1984   1.7     kamil 	 * set to 32-bit CS selector. The 32-bit CS selector is kernel
   1985   1.7     kamil 	 * specific, in the NetBSD case registered as GUCODE32_SEL
   1986   1.7     kamil 	 * that is equal to (14 (decimal) << 3) with GDT and user
   1987   1.7     kamil 	 * privilege level (this makes it 0x73).
   1988   1.7     kamil 	 *
   1989   1.7     kamil 	 * In UNIX as(1) assembly x86_64 far jump is coded as ljmp.
   1990   1.7     kamil 	 * amd64 ljmp requires an indirect address with cs:RIP.
   1991   1.7     kamil 	 *
   1992   1.7     kamil 	 * When we are running in 32-bit mode, it's similar to the
   1993   1.7     kamil 	 * mode as if the binary had been launched in netbsd32.
   1994   1.7     kamil 	 *
   1995   1.7     kamil 	 * There are two versions of this exploit, one with RIP
   1996   1.7     kamil 	 * relative code and the other with static addresses.
   1997   1.7     kamil 	 * The first one is PIE code aware, the other no-PIE one.
   1998   1.7     kamil 	 *
   1999   1.7     kamil 	 *
   2000   1.7     kamil 	 * After switching to the 32-bit mode we can move on to the remaining
   2001   1.7     kamil 	 * part of the exploit.
   2002   1.7     kamil 	 *
   2003   1.7     kamil 	 * endif //  __x86_64__
   2004   1.7     kamil 	 *
   2005   1.7     kamil 	 * Set the stack pointer to the page we allocated earlier. Remember
   2006   1.7     kamil 	 * that we put an SS selector exactly at this address, so we can pop.
   2007   1.7     kamil 	 *
   2008   1.7     kamil 	 * movl    $0x5000,%esp
   2009   1.7     kamil 	 *
   2010   1.7     kamil 	 * Pop the SS selector off the stack. This reloads the SS selector,
   2011   1.7     kamil 	 * which is fine. Remember that we set DR0 at address 0x5000, which
   2012   1.7     kamil 	 * we are now reading. Therefore, on this instruction, the CPU will
   2013   1.7     kamil 	 * raise a #DB exception.
   2014   1.7     kamil 	 *
   2015   1.7     kamil 	 * But the "pop %ss" instruction is special: it blocks exceptions
   2016   1.7     kamil 	 * until the next instruction is executed. So the #DB that we just
   2017   1.7     kamil 	 * raised is actually blocked.
   2018   1.7     kamil 	 *
   2019   1.7     kamil 	 * pop %ss
   2020   1.7     kamil 	 *
   2021   1.7     kamil 	 * We are still here, and didn't receive the #DB. After we execute
   2022   1.7     kamil 	 * this instruction, the effect of "pop %ss" will disappear, and
   2023   1.7     kamil 	 * we will receive the #DB for real.
   2024   1.7     kamil 	 *
   2025   1.7     kamil 	 * int $4
   2026   1.7     kamil 	 *
   2027   1.7     kamil 	 * Here the bug happens. We executed "int $4", so we entered the
   2028   1.7     kamil 	 * kernel, with interrupts disabled. The #DB that was pending is
   2029   1.7     kamil 	 * received. But, it is received immediately in kernel mode, and is
   2030   1.7     kamil 	 * _NOT_ received when interrupts are enabled again.
   2031   1.7     kamil 	 *
   2032   1.7     kamil 	 * It means that, in the first instruction of the $4 handler, we
   2033   1.7     kamil 	 * think we are safe with interrupts disabled. But we aren't, and
   2034   1.7     kamil 	 * just got interrupted.
   2035   1.7     kamil 	 *
   2036   1.7     kamil 	 * The new interrupt handler doesn't handle this particular context:
   2037   1.7     kamil 	 * we are entered in kernel mode, the previous context was kernel
   2038   1.7     kamil 	 * mode too but it still had the user context loaded.
   2039   1.7     kamil 	 *
   2040   1.7     kamil 	 * We find ourselves not doing a 'swapgs'. At the end of the day, it
   2041   1.7     kamil 	 * means that we call trap() with a curcpu() that is fully
   2042   1.7     kamil 	 * controllable by userland. From then on, it is easy to escalate
   2043   1.7     kamil 	 * privileges.
   2044   1.7     kamil 	 *
   2045   1.7     kamil 	 * With SVS it also means we don't switch CR3, so this results in a
   2046   1.7     kamil 	 * triple fault, which this time cannot be turned to a privilege
   2047   1.7     kamil 	 * escalation.
   2048   1.7     kamil 	 */
   2049   1.7     kamil 
   2050   1.7     kamil #if __x86_64__
   2051   1.7     kamil #if __PIE__
   2052   1.7     kamil 	void *csRIP;
   2053   1.7     kamil 
   2054   1.7     kamil 	csRIP = malloc(sizeof(int) + sizeof(short));
   2055   1.7     kamil 	FORKEE_ASSERT(csRIP != NULL);
   2056   1.7     kamil 
   2057   1.7     kamil 	__asm__ __volatile__(
   2058   1.7     kamil 		"	leal 24(%%eip), %%eax\n\t"
   2059   1.7     kamil 		"	movq %0, %%rdx\n\t"
   2060   1.7     kamil 		"	movl %%eax, (%%rdx)\n\t"
   2061   1.7     kamil 		"	movw $0x73, 4(%%rdx)\n\t"
   2062   1.7     kamil 		"	movq %1, %%rax\n\t"
   2063   1.7     kamil 		"	ljmp *(%%rax)\n\t"
   2064   1.7     kamil 		"	.code32\n\t"
   2065   1.7     kamil 		"	movl $0x5000, %%esp\n\t"
   2066   1.7     kamil 		"	pop %%ss\n\t"
   2067   1.7     kamil 		"	int $4\n\t"
   2068   1.7     kamil 		"	.code64\n\t"
   2069   1.7     kamil 		: "=m"(csRIP)
   2070   1.7     kamil 		: "m"(csRIP)
   2071   1.7     kamil 		: "%rax", "%rdx", "%rsp"
   2072   1.7     kamil 		);
   2073   1.7     kamil #else /* !__PIE__ */
   2074   1.7     kamil 	__asm__ __volatile__(
   2075   1.7     kamil 		"       movq $farjmp32, %%rax\n\t"
   2076   1.7     kamil 		"       ljmp *(%%rax)\n\t"
   2077   1.7     kamil 		"farjmp32:\n\t"
   2078   1.7     kamil 		"       .long trigger32\n\t"
   2079   1.7     kamil 		"       .word 0x73\n\t"
   2080   1.7     kamil 		"       .code32\n\t"
   2081   1.7     kamil 		"trigger32:\n\t"
   2082   1.7     kamil 		"       movl $0x5000, %%esp\n\t"
   2083   1.7     kamil 		"       pop %%ss\n\t"
   2084   1.7     kamil 		"       int $4\n\t"
   2085   1.7     kamil 		"       .code64\n\t"
   2086   1.7     kamil 		:
   2087   1.7     kamil 		:
   2088   1.7     kamil 		: "%rax", "%rsp"
   2089   1.7     kamil 		);
   2090   1.7     kamil #endif
   2091   1.7     kamil #elif __i386__
   2092   1.7     kamil 	__asm__ __volatile__(
   2093   1.7     kamil 		"movl $0x5000, %%esp\n\t"
   2094   1.7     kamil 		"pop %%ss\n\t"
   2095   1.7     kamil 		"int $4\n\t"
   2096   1.7     kamil 		:
   2097   1.7     kamil 		:
   2098   1.7     kamil 		: "%esp"
   2099   1.7     kamil 		);
   2100   1.7     kamil #endif
   2101   1.7     kamil }
   2102   1.7     kamil 
   2103   1.7     kamil ATF_TC_BODY(x86_cve_2018_8897, tc)
   2104   1.7     kamil {
   2105   1.7     kamil 	const int sigval = SIGSTOP;
   2106   1.7     kamil 	pid_t child, wpid;
   2107   1.7     kamil #if defined(TWAIT_HAVE_STATUS)
   2108   1.7     kamil 	int status;
   2109   1.7     kamil #endif
   2110   1.7     kamil 	char *trap_page;
   2111   1.7     kamil 	struct dbreg db;
   2112   1.7     kamil 
   2113   1.7     kamil 
   2114   1.7     kamil 	if (!can_we_set_dbregs()) {
   2115   1.7     kamil 		atf_tc_skip("Either run this test as root or set sysctl(3) "
   2116   1.7     kamil 		            "security.models.extensions.user_set_dbregs to 1");
   2117   1.7     kamil 	}
   2118   1.7     kamil 
   2119   1.7     kamil 	DPRINTF("Before forking process PID=%d\n", getpid());
   2120   1.7     kamil 	SYSCALL_REQUIRE((child = fork()) != -1);
   2121   1.7     kamil 	if (child == 0) {
   2122   1.7     kamil 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   2123   1.7     kamil 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   2124   1.7     kamil 
   2125   1.7     kamil 		trap_page = mmap((void *)X86_CVE_2018_8897_PAGE,
   2126   1.7     kamil 		                 sysconf(_SC_PAGESIZE), PROT_READ|PROT_WRITE,
   2127   1.7     kamil 		                 MAP_FIXED|MAP_ANON|MAP_PRIVATE, -1, 0);
   2128   1.7     kamil 
   2129   1.7     kamil 		/* trigger page fault */
   2130   1.7     kamil 		memset(trap_page, 0, sysconf(_SC_PAGESIZE));
   2131   1.7     kamil 
   2132   1.7     kamil 		// kernel GDT
   2133   1.7     kamil #if __x86_64__
   2134   1.7     kamil 		/* SS selector (descriptor 9 (0x4f >> 3)) */
   2135   1.7     kamil 		*trap_page = 0x4f;
   2136   1.7     kamil #elif __i386__
   2137   1.7     kamil 		/* SS selector (descriptor 4 (0x23 >> 3)) */
   2138   1.7     kamil 		*trap_page = 0x23;
   2139   1.7     kamil #endif
   2140   1.7     kamil 
   2141   1.7     kamil 		DPRINTF("Before raising %s from child\n", strsignal(sigval));
   2142   1.7     kamil 		FORKEE_ASSERT(raise(sigval) == 0);
   2143   1.7     kamil 
   2144   1.7     kamil 		x86_cve_2018_8897_trigger();
   2145   1.7     kamil 
   2146   1.7     kamil 		/* NOTREACHED */
   2147   1.7     kamil 		FORKEE_ASSERTX(0 && "This shall not be reached");
   2148   1.7     kamil 	}
   2149   1.7     kamil 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   2150   1.7     kamil 
   2151   1.7     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2152   1.7     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2153   1.7     kamil 
   2154   1.7     kamil 	validate_status_stopped(status, sigval);
   2155   1.7     kamil 
   2156   1.7     kamil 	DPRINTF("Call GETDBREGS for the child process\n");
   2157   1.7     kamil 	SYSCALL_REQUIRE(ptrace(PT_GETDBREGS, child, &db, 0) != -1);
   2158   1.7     kamil 
   2159   1.7     kamil 	/*
   2160   1.7     kamil 	 * Set up the dbregs. We put the 0x5000 address in DR0.
   2161   1.7     kamil 	 * It means that, the first time we touch this, the CPU will trigger a
   2162   1.7     kamil 	 * #DB exception.
   2163   1.7     kamil 	 */
   2164   1.7     kamil 	db.dr[0] = X86_CVE_2018_8897_PAGE;
   2165   1.7     kamil 	db.dr[7] = 0x30003;
   2166   1.7     kamil 
   2167   1.7     kamil 	DPRINTF("Call SETDBREGS for the child process\n");
   2168   1.7     kamil 	SYSCALL_REQUIRE(ptrace(PT_SETDBREGS, child, &db, 0) != -1);
   2169   1.7     kamil 
   2170   1.7     kamil 	DPRINTF("Before resuming the child process where it left off and "
   2171   1.7     kamil 	    "without signal to be sent\n");
   2172   1.7     kamil 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2173   1.7     kamil 
   2174   1.7     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2175   1.7     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2176   1.7     kamil 
   2177   1.7     kamil 	// In this test we receive SIGFPE, is this appropriate?
   2178   1.7     kamil //	validate_status_stopped(status, SIGFPE);
   2179   1.7     kamil 
   2180   1.7     kamil 	DPRINTF("Kill the child process\n");
   2181   1.7     kamil 	SYSCALL_REQUIRE(ptrace(PT_KILL, child, NULL, 0) != -1);
   2182   1.7     kamil 
   2183   1.7     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2184   1.7     kamil 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2185   1.7     kamil 
   2186   1.7     kamil 	validate_status_signaled(status, SIGKILL, 0);
   2187   1.7     kamil 
   2188   1.7     kamil 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2189   1.7     kamil 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   2190   1.7     kamil }
   2191   1.7     kamil 
   2192  1.10    mgorny ATF_TC(x86_regs_mm_read);
   2193  1.10    mgorny ATF_TC_HEAD(x86_regs_mm_read, tc)
   2194  1.10    mgorny {
   2195  1.10    mgorny 	atf_tc_set_md_var(tc, "descr",
   2196  1.10    mgorny 		"Set MMX (mm0..mm7) reg values from debugged program and read "
   2197  1.10    mgorny 		"them via PT_GETFPREGS, comparing values against expected.");
   2198  1.10    mgorny }
   2199  1.10    mgorny 
   2200  1.10    mgorny __attribute__((target("mmx")))
   2201  1.10    mgorny static __inline void set_mm_regs(const uint64_t mm[])
   2202  1.10    mgorny {
   2203  1.10    mgorny 	__asm__ __volatile__(
   2204  1.10    mgorny 		"movq    0x00(%0), %%mm0\n\t"
   2205  1.10    mgorny 		"movq    0x08(%0), %%mm1\n\t"
   2206  1.10    mgorny 		"movq    0x10(%0), %%mm2\n\t"
   2207  1.10    mgorny 		"movq    0x18(%0), %%mm3\n\t"
   2208  1.10    mgorny 		"movq    0x20(%0), %%mm4\n\t"
   2209  1.10    mgorny 		"movq    0x28(%0), %%mm5\n\t"
   2210  1.10    mgorny 		"movq    0x30(%0), %%mm6\n\t"
   2211  1.10    mgorny 		"movq    0x38(%0), %%mm7\n\t"
   2212  1.10    mgorny 		"int3\n\t"
   2213  1.10    mgorny 		:
   2214  1.10    mgorny 		: "b"(mm)
   2215  1.10    mgorny 		: "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
   2216  1.10    mgorny 	);
   2217  1.10    mgorny }
   2218  1.10    mgorny 
   2219  1.10    mgorny ATF_TC_BODY(x86_regs_mm_read, tc)
   2220  1.10    mgorny {
   2221  1.10    mgorny 	const int exitval = 5;
   2222  1.10    mgorny 	pid_t child, wpid;
   2223  1.10    mgorny #if defined(TWAIT_HAVE_STATUS)
   2224  1.10    mgorny 	const int sigval = SIGTRAP;
   2225  1.10    mgorny 	int status;
   2226  1.10    mgorny #endif
   2227  1.10    mgorny 	struct fpreg fpr;
   2228  1.10    mgorny 
   2229  1.10    mgorny 	const uint64_t mm[] = {
   2230  1.10    mgorny 		0x0001020304050607,
   2231  1.10    mgorny 		0x1011121314151617,
   2232  1.10    mgorny 		0x2021222324252627,
   2233  1.10    mgorny 		0x3031323334353637,
   2234  1.10    mgorny 		0x4041424344454647,
   2235  1.10    mgorny 		0x5051525354555657,
   2236  1.10    mgorny 		0x6061626364656667,
   2237  1.10    mgorny 		0x7071727374757677,
   2238  1.10    mgorny 	};
   2239  1.10    mgorny 
   2240  1.10    mgorny 	/* verify whether MMX is supported here */
   2241  1.10    mgorny 	DPRINTF("Before invoking cpuid\n");
   2242  1.10    mgorny 	{
   2243  1.10    mgorny 		unsigned int eax, ebx, ecx, edx;
   2244  1.10    mgorny 		if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
   2245  1.10    mgorny 			atf_tc_skip("CPUID is not supported by the CPU");
   2246  1.10    mgorny 
   2247  1.10    mgorny 		DPRINTF("cpuid: EDX = %08x\n", edx);
   2248  1.10    mgorny 
   2249  1.10    mgorny 		if (!(edx & bit_MMX))
   2250  1.10    mgorny 			atf_tc_skip("MMX is not supported by the CPU");
   2251  1.10    mgorny 	}
   2252  1.10    mgorny 
   2253  1.10    mgorny 	DPRINTF("Before forking process PID=%d\n", getpid());
   2254  1.10    mgorny 	SYSCALL_REQUIRE((child = fork()) != -1);
   2255  1.10    mgorny 	if (child == 0) {
   2256  1.10    mgorny 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   2257  1.10    mgorny 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   2258  1.10    mgorny 
   2259  1.10    mgorny 		DPRINTF("Before running assembly from child\n");
   2260  1.10    mgorny 		set_mm_regs(mm);
   2261  1.10    mgorny 
   2262  1.10    mgorny 		DPRINTF("Before exiting of the child process\n");
   2263  1.10    mgorny 		_exit(exitval);
   2264  1.10    mgorny 	}
   2265  1.10    mgorny 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   2266  1.10    mgorny 
   2267  1.10    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2268  1.10    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2269  1.10    mgorny 
   2270  1.10    mgorny 	validate_status_stopped(status, sigval);
   2271  1.10    mgorny 
   2272  1.10    mgorny 	DPRINTF("Call GETFPREGS for the child process\n");
   2273  1.10    mgorny 	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
   2274  1.10    mgorny 
   2275  1.10    mgorny #if defined(__x86_64__)
   2276  1.10    mgorny #define MM_REG(n) fpr.fxstate.fx_87_ac[n].r.f87_mantissa
   2277  1.10    mgorny #else
   2278  1.11    mgorny #define MM_REG(n) fpr.fstate.s87_ac[n].f87_mantissa
   2279  1.10    mgorny #endif
   2280  1.10    mgorny 
   2281  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(0), mm[0]);
   2282  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(1), mm[1]);
   2283  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(2), mm[2]);
   2284  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(3), mm[3]);
   2285  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(4), mm[4]);
   2286  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(5), mm[5]);
   2287  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(6), mm[6]);
   2288  1.10    mgorny 	ATF_CHECK_EQ(MM_REG(7), mm[7]);
   2289  1.10    mgorny 
   2290  1.10    mgorny #undef MM_REG
   2291  1.10    mgorny 
   2292  1.10    mgorny 	DPRINTF("Before resuming the child process where it left off and "
   2293  1.10    mgorny 	    "without signal to be sent\n");
   2294  1.10    mgorny 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2295  1.10    mgorny 
   2296  1.10    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2297  1.10    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2298  1.10    mgorny 
   2299  1.10    mgorny 	validate_status_exited(status, exitval);
   2300  1.10    mgorny 
   2301  1.10    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2302  1.10    mgorny 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   2303  1.10    mgorny }
   2304  1.10    mgorny 
   2305  1.13    mgorny __attribute__((target("mmx")))
   2306  1.13    mgorny static __inline void get_mm_regs(uint64_t v_mm[])
   2307  1.13    mgorny {
   2308  1.13    mgorny 	const uint64_t fill = 0x0F0F0F0F0F0F0F0F;
   2309  1.13    mgorny 
   2310  1.13    mgorny 	__asm__ __volatile__(
   2311  1.13    mgorny 		/* fill registers with clobber pattern */
   2312  1.13    mgorny 		"movq    %1, %%mm0\n\t"
   2313  1.13    mgorny 		"movq    %1, %%mm1\n\t"
   2314  1.13    mgorny 		"movq    %1, %%mm2\n\t"
   2315  1.13    mgorny 		"movq    %1, %%mm3\n\t"
   2316  1.13    mgorny 		"movq    %1, %%mm4\n\t"
   2317  1.13    mgorny 		"movq    %1, %%mm5\n\t"
   2318  1.13    mgorny 		"movq    %1, %%mm6\n\t"
   2319  1.13    mgorny 		"movq    %1, %%mm7\n\t"
   2320  1.13    mgorny 		"\n\t"
   2321  1.13    mgorny 		"int3\n\t"
   2322  1.13    mgorny 		"\n\t"
   2323  1.13    mgorny 		"movq    %%mm0, 0x00(%0)\n\t"
   2324  1.13    mgorny 		"movq    %%mm1, 0x08(%0)\n\t"
   2325  1.13    mgorny 		"movq    %%mm2, 0x10(%0)\n\t"
   2326  1.13    mgorny 		"movq    %%mm3, 0x18(%0)\n\t"
   2327  1.13    mgorny 		"movq    %%mm4, 0x20(%0)\n\t"
   2328  1.13    mgorny 		"movq    %%mm5, 0x28(%0)\n\t"
   2329  1.13    mgorny 		"movq    %%mm6, 0x30(%0)\n\t"
   2330  1.13    mgorny 		"movq    %%mm7, 0x38(%0)\n\t"
   2331  1.13    mgorny 		:
   2332  1.13    mgorny 		: "a"(v_mm), "m"(fill)
   2333  1.13    mgorny 		: "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
   2334  1.13    mgorny 	);
   2335  1.13    mgorny }
   2336  1.13    mgorny 
   2337  1.13    mgorny ATF_TC(x86_regs_mm_write);
   2338  1.13    mgorny ATF_TC_HEAD(x86_regs_mm_write, tc)
   2339  1.13    mgorny {
   2340  1.13    mgorny 	atf_tc_set_md_var(tc, "descr",
   2341  1.13    mgorny 		"Set mm0..mm7 reg values into a debugged program via "
   2342  1.13    mgorny 		"PT_SETFPREGS and compare the result against expected.");
   2343  1.13    mgorny }
   2344  1.13    mgorny 
   2345  1.13    mgorny ATF_TC_BODY(x86_regs_mm_write, tc)
   2346  1.13    mgorny {
   2347  1.13    mgorny 	const int exitval = 5;
   2348  1.13    mgorny 	pid_t child, wpid;
   2349  1.13    mgorny #if defined(TWAIT_HAVE_STATUS)
   2350  1.13    mgorny 	const int sigval = SIGTRAP;
   2351  1.13    mgorny 	int status;
   2352  1.13    mgorny #endif
   2353  1.13    mgorny 	struct fpreg fpr;
   2354  1.13    mgorny 
   2355  1.13    mgorny 	const uint64_t mm[] = {
   2356  1.13    mgorny 		0x0001020304050607,
   2357  1.13    mgorny 		0x1011121314151617,
   2358  1.13    mgorny 		0x2021222324252627,
   2359  1.13    mgorny 		0x3031323334353637,
   2360  1.13    mgorny 		0x4041424344454647,
   2361  1.13    mgorny 		0x5051525354555657,
   2362  1.13    mgorny 		0x6061626364656667,
   2363  1.13    mgorny 		0x7071727374757677,
   2364  1.13    mgorny 	};
   2365  1.13    mgorny 
   2366  1.13    mgorny 	/* verify whether MMX is supported here */
   2367  1.13    mgorny 	DPRINTF("Before invoking cpuid\n");
   2368  1.13    mgorny 	{
   2369  1.13    mgorny 		unsigned int eax, ebx, ecx, edx;
   2370  1.13    mgorny 		if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
   2371  1.13    mgorny 			atf_tc_skip("CPUID is not supported by the CPU");
   2372  1.13    mgorny 
   2373  1.13    mgorny 		DPRINTF("cpuid: EDX = %08x\n", edx);
   2374  1.13    mgorny 
   2375  1.13    mgorny 		if (!(edx & bit_MMX))
   2376  1.13    mgorny 			atf_tc_skip("MMX is not supported by the CPU");
   2377  1.13    mgorny 	}
   2378  1.13    mgorny 
   2379  1.13    mgorny 	DPRINTF("Before forking process PID=%d\n", getpid());
   2380  1.13    mgorny 	SYSCALL_REQUIRE((child = fork()) != -1);
   2381  1.13    mgorny 	if (child == 0) {
   2382  1.13    mgorny 		uint64_t v_mm[8];
   2383  1.13    mgorny 
   2384  1.13    mgorny 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   2385  1.13    mgorny 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   2386  1.13    mgorny 
   2387  1.13    mgorny 		DPRINTF("Before running assembly from child\n");
   2388  1.13    mgorny 		get_mm_regs(v_mm);
   2389  1.13    mgorny 
   2390  1.14    mgorny 		DPRINTF("Before comparing results\n");
   2391  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[0], mm[0]);
   2392  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[1], mm[1]);
   2393  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[2], mm[2]);
   2394  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[3], mm[3]);
   2395  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[4], mm[4]);
   2396  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[5], mm[5]);
   2397  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[6], mm[6]);
   2398  1.13    mgorny 		FORKEE_ASSERT_EQ(v_mm[7], mm[7]);
   2399  1.13    mgorny 
   2400  1.13    mgorny 		DPRINTF("Before exiting of the child process\n");
   2401  1.13    mgorny 		_exit(exitval);
   2402  1.13    mgorny 	}
   2403  1.13    mgorny 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   2404  1.13    mgorny 
   2405  1.13    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2406  1.13    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2407  1.13    mgorny 
   2408  1.13    mgorny 	validate_status_stopped(status, sigval);
   2409  1.13    mgorny 
   2410  1.13    mgorny 	DPRINTF("Call GETFPREGS for the child process\n");
   2411  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
   2412  1.13    mgorny 
   2413  1.13    mgorny #if defined(__x86_64__)
   2414  1.13    mgorny #define MM_REG(n) fpr.fxstate.fx_87_ac[n].r.f87_mantissa
   2415  1.13    mgorny #else
   2416  1.13    mgorny #define MM_REG(n) fpr.fstate.s87_ac[n].f87_mantissa
   2417  1.13    mgorny #endif
   2418  1.13    mgorny 
   2419  1.13    mgorny 	MM_REG(0) = mm[0];
   2420  1.13    mgorny 	MM_REG(1) = mm[1];
   2421  1.13    mgorny 	MM_REG(2) = mm[2];
   2422  1.13    mgorny 	MM_REG(3) = mm[3];
   2423  1.13    mgorny 	MM_REG(4) = mm[4];
   2424  1.13    mgorny 	MM_REG(5) = mm[5];
   2425  1.13    mgorny 	MM_REG(6) = mm[6];
   2426  1.13    mgorny 	MM_REG(7) = mm[7];
   2427  1.13    mgorny 
   2428  1.13    mgorny #undef MM_REG
   2429  1.13    mgorny 
   2430  1.13    mgorny 	DPRINTF("Call SETFPREGS for the child process\n");
   2431  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &fpr, 0) != -1);
   2432  1.13    mgorny 
   2433  1.13    mgorny 	DPRINTF("Before resuming the child process where it left off and "
   2434  1.13    mgorny 	    "without signal to be sent\n");
   2435  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2436  1.13    mgorny 
   2437  1.13    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2438  1.13    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2439  1.13    mgorny 
   2440  1.13    mgorny 	validate_status_exited(status, exitval);
   2441  1.13    mgorny 
   2442  1.13    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2443  1.13    mgorny 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   2444  1.13    mgorny }
   2445  1.13    mgorny 
   2446  1.10    mgorny __attribute__((target("sse")))
   2447  1.10    mgorny static __inline void set_xmm_regs(const void* xmm)
   2448  1.10    mgorny {
   2449  1.10    mgorny 	__asm__ __volatile__(
   2450  1.10    mgorny 		"movaps   0x00(%0), %%xmm0\n\t"
   2451  1.10    mgorny 		"movaps   0x10(%0), %%xmm1\n\t"
   2452  1.10    mgorny 		"movaps   0x20(%0), %%xmm2\n\t"
   2453  1.10    mgorny 		"movaps   0x30(%0), %%xmm3\n\t"
   2454  1.10    mgorny 		"movaps   0x40(%0), %%xmm4\n\t"
   2455  1.10    mgorny 		"movaps   0x50(%0), %%xmm5\n\t"
   2456  1.10    mgorny 		"movaps   0x60(%0), %%xmm6\n\t"
   2457  1.10    mgorny 		"movaps   0x70(%0), %%xmm7\n\t"
   2458  1.10    mgorny #if defined(__x86_64__)
   2459  1.10    mgorny 		"movaps   0x80(%0), %%xmm8\n\t"
   2460  1.10    mgorny 		"movaps   0x90(%0), %%xmm9\n\t"
   2461  1.10    mgorny 		"movaps   0xA0(%0), %%xmm10\n\t"
   2462  1.10    mgorny 		"movaps   0xB0(%0), %%xmm11\n\t"
   2463  1.10    mgorny 		"movaps   0xC0(%0), %%xmm12\n\t"
   2464  1.10    mgorny 		"movaps   0xD0(%0), %%xmm13\n\t"
   2465  1.10    mgorny 		"movaps   0xE0(%0), %%xmm14\n\t"
   2466  1.10    mgorny 		"movaps   0xF0(%0), %%xmm15\n\t"
   2467  1.10    mgorny #endif
   2468  1.10    mgorny 		"int3\n\t"
   2469  1.10    mgorny 		:
   2470  1.10    mgorny 		: "b"(xmm)
   2471  1.10    mgorny 		: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6",
   2472  1.10    mgorny 		"%xmm7"
   2473  1.10    mgorny #if defined(__x86_64__)
   2474  1.10    mgorny 		, "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13",
   2475  1.10    mgorny 		"%xmm14", "%xmm15"
   2476  1.10    mgorny #endif
   2477  1.10    mgorny 	);
   2478  1.10    mgorny }
   2479  1.10    mgorny 
   2480  1.10    mgorny ATF_TC(x86_regs_xmm_read);
   2481  1.10    mgorny ATF_TC_HEAD(x86_regs_xmm_read, tc)
   2482  1.10    mgorny {
   2483  1.10    mgorny 	atf_tc_set_md_var(tc, "descr",
   2484  1.10    mgorny 		"Set xmm0..xmm15 (..xmm7 on i386) reg values from debugged program "
   2485  1.10    mgorny 		"and read them via PT_GETFPREGS (PT_GETXMMREGS on i386), comparing "
   2486  1.10    mgorny 		"values against expected.");
   2487  1.10    mgorny }
   2488  1.10    mgorny 
   2489  1.10    mgorny ATF_TC_BODY(x86_regs_xmm_read, tc)
   2490  1.10    mgorny {
   2491  1.10    mgorny 	const int exitval = 5;
   2492  1.10    mgorny 	pid_t child, wpid;
   2493  1.10    mgorny #if defined(TWAIT_HAVE_STATUS)
   2494  1.10    mgorny 	const int sigval = SIGTRAP;
   2495  1.10    mgorny 	int status;
   2496  1.10    mgorny #endif
   2497  1.10    mgorny #if defined(__x86_64__)
   2498  1.10    mgorny 	struct fpreg fpr;
   2499  1.10    mgorny #else
   2500  1.11    mgorny 	struct xmmregs fpr;
   2501  1.10    mgorny #endif
   2502  1.10    mgorny 
   2503  1.10    mgorny 	const struct {
   2504  1.10    mgorny 		uint64_t a, b;
   2505  1.10    mgorny 	} xmm[] __aligned(16) = {
   2506  1.10    mgorny 		{ 0x0706050403020100, 0x0F0E0D0C0B0A0908, },
   2507  1.10    mgorny 		{ 0x0807060504030201, 0x100F0E0D0C0B0A09, },
   2508  1.10    mgorny 		{ 0x0908070605040302, 0x11100F0E0D0C0B0A, },
   2509  1.10    mgorny 		{ 0x0A09080706050403, 0x1211100F0E0D0C0B, },
   2510  1.10    mgorny 		{ 0x0B0A090807060504, 0x131211100F0E0D0C, },
   2511  1.10    mgorny 		{ 0x0C0B0A0908070605, 0x14131211100F0E0D, },
   2512  1.10    mgorny 		{ 0x0D0C0B0A09080706, 0x1514131211100F0E, },
   2513  1.10    mgorny 		{ 0x0E0D0C0B0A090807, 0x161514131211100F, },
   2514  1.10    mgorny #if defined(__x86_64__)
   2515  1.10    mgorny 		{ 0x0F0E0D0C0B0A0908, 0x1716151413121110, },
   2516  1.10    mgorny 		{ 0x100F0E0D0C0B0A09, 0x1817161514131211, },
   2517  1.10    mgorny 		{ 0x11100F0E0D0C0B0A, 0x1918171615141312, },
   2518  1.10    mgorny 		{ 0x1211100F0E0D0C0B, 0x1A19181716151413, },
   2519  1.10    mgorny 		{ 0x131211100F0E0D0C, 0x1B1A191817161514, },
   2520  1.10    mgorny 		{ 0x14131211100F0E0D, 0x1C1B1A1918171615, },
   2521  1.10    mgorny 		{ 0x1514131211100F0E, 0x1D1C1B1A19181716, },
   2522  1.10    mgorny 		{ 0x161514131211100F, 0x1E1D1C1B1A191817, },
   2523  1.10    mgorny #endif
   2524  1.10    mgorny 	};
   2525  1.10    mgorny 
   2526  1.10    mgorny 	/* verify whether SSE is supported here */
   2527  1.10    mgorny 	DPRINTF("Before invoking cpuid\n");
   2528  1.10    mgorny 	{
   2529  1.10    mgorny 		unsigned int eax, ebx, ecx, edx;
   2530  1.10    mgorny 		if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
   2531  1.10    mgorny 			atf_tc_skip("CPUID is not supported by the CPU");
   2532  1.10    mgorny 
   2533  1.10    mgorny 		DPRINTF("cpuid: EDX = %08x\n", edx);
   2534  1.10    mgorny 
   2535  1.10    mgorny 		if (!(edx & bit_SSE))
   2536  1.10    mgorny 			atf_tc_skip("SSE is not supported by the CPU");
   2537  1.10    mgorny 	}
   2538  1.10    mgorny 
   2539  1.10    mgorny 	DPRINTF("Before forking process PID=%d\n", getpid());
   2540  1.10    mgorny 	SYSCALL_REQUIRE((child = fork()) != -1);
   2541  1.10    mgorny 	if (child == 0) {
   2542  1.10    mgorny 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   2543  1.10    mgorny 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   2544  1.10    mgorny 
   2545  1.10    mgorny 		DPRINTF("Before running assembly from child\n");
   2546  1.10    mgorny 		set_xmm_regs(xmm);
   2547  1.10    mgorny 
   2548  1.10    mgorny 		DPRINTF("Before exiting of the child process\n");
   2549  1.10    mgorny 		_exit(exitval);
   2550  1.10    mgorny 	}
   2551  1.10    mgorny 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   2552  1.10    mgorny 
   2553  1.10    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2554  1.10    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2555  1.10    mgorny 
   2556  1.10    mgorny 	validate_status_stopped(status, sigval);
   2557  1.10    mgorny 
   2558  1.10    mgorny #if defined(__x86_64__)
   2559  1.10    mgorny 	DPRINTF("Call GETFPREGS for the child process\n");
   2560  1.10    mgorny 	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
   2561  1.10    mgorny #else
   2562  1.10    mgorny 	DPRINTF("Call GETXMMREGS for the child process\n");
   2563  1.10    mgorny 	SYSCALL_REQUIRE(ptrace(PT_GETXMMREGS, child, &fpr, 0) != -1);
   2564  1.10    mgorny #endif
   2565  1.10    mgorny 
   2566  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[0], &xmm[0], sizeof(*xmm)));
   2567  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[1], &xmm[1], sizeof(*xmm)));
   2568  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[2], &xmm[2], sizeof(*xmm)));
   2569  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[3], &xmm[3], sizeof(*xmm)));
   2570  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[4], &xmm[4], sizeof(*xmm)));
   2571  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[5], &xmm[5], sizeof(*xmm)));
   2572  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[6], &xmm[6], sizeof(*xmm)));
   2573  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[7], &xmm[7], sizeof(*xmm)));
   2574  1.10    mgorny #if defined(__x86_64__)
   2575  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[8], &xmm[8], sizeof(*xmm)));
   2576  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[9], &xmm[9], sizeof(*xmm)));
   2577  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[10], &xmm[10], sizeof(*xmm)));
   2578  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[11], &xmm[11], sizeof(*xmm)));
   2579  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[12], &xmm[12], sizeof(*xmm)));
   2580  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[13], &xmm[13], sizeof(*xmm)));
   2581  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[14], &xmm[14], sizeof(*xmm)));
   2582  1.11    mgorny 	ATF_CHECK(!memcmp(&fpr.fxstate.fx_xmm[15], &xmm[15], sizeof(*xmm)));
   2583  1.10    mgorny #endif
   2584  1.10    mgorny 
   2585  1.10    mgorny 	DPRINTF("Before resuming the child process where it left off and "
   2586  1.10    mgorny 	    "without signal to be sent\n");
   2587  1.10    mgorny 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2588  1.10    mgorny 
   2589  1.10    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2590  1.10    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2591  1.10    mgorny 
   2592  1.10    mgorny 	validate_status_exited(status, exitval);
   2593  1.10    mgorny 
   2594  1.10    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2595  1.10    mgorny 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   2596  1.10    mgorny }
   2597  1.13    mgorny 
   2598  1.13    mgorny __attribute__((target("sse")))
   2599  1.13    mgorny static __inline void get_xmm_regs(void* v_xmm)
   2600  1.13    mgorny {
   2601  1.13    mgorny 	const struct {
   2602  1.13    mgorny 		uint64_t a, b;
   2603  1.13    mgorny 	} fill = {0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F};
   2604  1.13    mgorny 
   2605  1.13    mgorny 	__asm__ __volatile__(
   2606  1.13    mgorny 		/* fill registers with clobber pattern */
   2607  1.13    mgorny 		"movaps  %1, %%xmm0\n\t"
   2608  1.13    mgorny 		"movaps  %1, %%xmm1\n\t"
   2609  1.13    mgorny 		"movaps  %1, %%xmm2\n\t"
   2610  1.13    mgorny 		"movaps  %1, %%xmm3\n\t"
   2611  1.13    mgorny 		"movaps  %1, %%xmm4\n\t"
   2612  1.13    mgorny 		"movaps  %1, %%xmm5\n\t"
   2613  1.13    mgorny 		"movaps  %1, %%xmm6\n\t"
   2614  1.13    mgorny 		"movaps  %1, %%xmm7\n\t"
   2615  1.13    mgorny #if defined(__x86_64__)
   2616  1.13    mgorny 		"movaps  %1, %%xmm8\n\t"
   2617  1.13    mgorny 		"movaps  %1, %%xmm9\n\t"
   2618  1.13    mgorny 		"movaps  %1, %%xmm10\n\t"
   2619  1.13    mgorny 		"movaps  %1, %%xmm11\n\t"
   2620  1.13    mgorny 		"movaps  %1, %%xmm12\n\t"
   2621  1.13    mgorny 		"movaps  %1, %%xmm13\n\t"
   2622  1.13    mgorny 		"movaps  %1, %%xmm14\n\t"
   2623  1.13    mgorny 		"movaps  %1, %%xmm15\n\t"
   2624  1.13    mgorny #endif
   2625  1.13    mgorny 		"\n\t"
   2626  1.13    mgorny 		"int3\n\t"
   2627  1.13    mgorny 		"\n\t"
   2628  1.13    mgorny 		"movaps  %%xmm0, 0x00(%0)\n\t"
   2629  1.13    mgorny 		"movaps  %%xmm1, 0x10(%0)\n\t"
   2630  1.13    mgorny 		"movaps  %%xmm2, 0x20(%0)\n\t"
   2631  1.13    mgorny 		"movaps  %%xmm3, 0x30(%0)\n\t"
   2632  1.13    mgorny 		"movaps  %%xmm4, 0x40(%0)\n\t"
   2633  1.13    mgorny 		"movaps  %%xmm5, 0x50(%0)\n\t"
   2634  1.13    mgorny 		"movaps  %%xmm6, 0x60(%0)\n\t"
   2635  1.13    mgorny 		"movaps  %%xmm7, 0x70(%0)\n\t"
   2636  1.13    mgorny #if defined(__x86_64__)
   2637  1.13    mgorny 		"movaps  %%xmm8, 0x80(%0)\n\t"
   2638  1.13    mgorny 		"movaps  %%xmm9, 0x90(%0)\n\t"
   2639  1.13    mgorny 		"movaps  %%xmm10, 0xA0(%0)\n\t"
   2640  1.13    mgorny 		"movaps  %%xmm11, 0xB0(%0)\n\t"
   2641  1.13    mgorny 		"movaps  %%xmm12, 0xC0(%0)\n\t"
   2642  1.13    mgorny 		"movaps  %%xmm13, 0xD0(%0)\n\t"
   2643  1.13    mgorny 		"movaps  %%xmm14, 0xE0(%0)\n\t"
   2644  1.13    mgorny 		"movaps  %%xmm15, 0xF0(%0)\n\t"
   2645  1.13    mgorny #endif
   2646  1.13    mgorny 		:
   2647  1.13    mgorny 		: "a"(v_xmm), "m"(fill)
   2648  1.13    mgorny 		: "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7"
   2649  1.13    mgorny #if defined(__x86_64__)
   2650  1.13    mgorny 		, "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14",
   2651  1.13    mgorny 		"%xmm15"
   2652  1.13    mgorny #endif
   2653  1.13    mgorny 	);
   2654  1.13    mgorny }
   2655  1.13    mgorny 
   2656  1.13    mgorny ATF_TC(x86_regs_xmm_write);
   2657  1.13    mgorny ATF_TC_HEAD(x86_regs_xmm_write, tc)
   2658  1.13    mgorny {
   2659  1.13    mgorny 	atf_tc_set_md_var(tc, "descr",
   2660  1.13    mgorny 		"Set xmm0..xmm15 (..xmm7 on i386) reg values into a debugged "
   2661  1.13    mgorny 		"program via PT_SETFPREGS (PT_SETXMMREGS on i386) and compare "
   2662  1.13    mgorny 		"the result against expected.");
   2663  1.13    mgorny }
   2664  1.13    mgorny 
   2665  1.13    mgorny ATF_TC_BODY(x86_regs_xmm_write, tc)
   2666  1.13    mgorny {
   2667  1.13    mgorny 	const int exitval = 5;
   2668  1.13    mgorny 	pid_t child, wpid;
   2669  1.13    mgorny #if defined(TWAIT_HAVE_STATUS)
   2670  1.13    mgorny 	const int sigval = SIGTRAP;
   2671  1.13    mgorny 	int status;
   2672  1.13    mgorny #endif
   2673  1.13    mgorny #if defined(__x86_64__)
   2674  1.13    mgorny 	struct fpreg fpr;
   2675  1.13    mgorny #else
   2676  1.13    mgorny 	struct xmmregs fpr;
   2677  1.13    mgorny #endif
   2678  1.13    mgorny 
   2679  1.13    mgorny 	const struct {
   2680  1.13    mgorny 		uint64_t a, b;
   2681  1.13    mgorny 	} xmm[] __aligned(16) = {
   2682  1.13    mgorny 		{ 0x0706050403020100, 0x0F0E0D0C0B0A0908, },
   2683  1.13    mgorny 		{ 0x0807060504030201, 0x100F0E0D0C0B0A09, },
   2684  1.13    mgorny 		{ 0x0908070605040302, 0x11100F0E0D0C0B0A, },
   2685  1.13    mgorny 		{ 0x0A09080706050403, 0x1211100F0E0D0C0B, },
   2686  1.13    mgorny 		{ 0x0B0A090807060504, 0x131211100F0E0D0C, },
   2687  1.13    mgorny 		{ 0x0C0B0A0908070605, 0x14131211100F0E0D, },
   2688  1.13    mgorny 		{ 0x0D0C0B0A09080706, 0x1514131211100F0E, },
   2689  1.13    mgorny 		{ 0x0E0D0C0B0A090807, 0x161514131211100F, },
   2690  1.13    mgorny #if defined(__x86_64__)
   2691  1.13    mgorny 		{ 0x0F0E0D0C0B0A0908, 0x1716151413121110, },
   2692  1.13    mgorny 		{ 0x100F0E0D0C0B0A09, 0x1817161514131211, },
   2693  1.13    mgorny 		{ 0x11100F0E0D0C0B0A, 0x1918171615141312, },
   2694  1.13    mgorny 		{ 0x1211100F0E0D0C0B, 0x1A19181716151413, },
   2695  1.13    mgorny 		{ 0x131211100F0E0D0C, 0x1B1A191817161514, },
   2696  1.13    mgorny 		{ 0x14131211100F0E0D, 0x1C1B1A1918171615, },
   2697  1.13    mgorny 		{ 0x1514131211100F0E, 0x1D1C1B1A19181716, },
   2698  1.13    mgorny 		{ 0x161514131211100F, 0x1E1D1C1B1A191817, },
   2699  1.13    mgorny #endif
   2700  1.13    mgorny 	};
   2701  1.13    mgorny 
   2702  1.13    mgorny 	/* verify whether SSE is supported here */
   2703  1.13    mgorny 	DPRINTF("Before invoking cpuid\n");
   2704  1.13    mgorny 	{
   2705  1.13    mgorny 		unsigned int eax, ebx, ecx, edx;
   2706  1.13    mgorny 		if (!__get_cpuid(1, &eax, &ebx, &ecx, &edx))
   2707  1.13    mgorny 			atf_tc_skip("CPUID is not supported by the CPU");
   2708  1.13    mgorny 
   2709  1.13    mgorny 		DPRINTF("cpuid: EDX = %08x\n", edx);
   2710  1.13    mgorny 
   2711  1.13    mgorny 		if (!(edx & bit_SSE))
   2712  1.13    mgorny 			atf_tc_skip("SSE is not supported by the CPU");
   2713  1.13    mgorny 	}
   2714  1.13    mgorny 
   2715  1.13    mgorny 	DPRINTF("Before forking process PID=%d\n", getpid());
   2716  1.13    mgorny 	SYSCALL_REQUIRE((child = fork()) != -1);
   2717  1.13    mgorny 	if (child == 0) {
   2718  1.13    mgorny 		struct {
   2719  1.13    mgorny 			uint64_t a, b;
   2720  1.13    mgorny 		} v_xmm[16] __aligned(16);
   2721  1.13    mgorny 
   2722  1.13    mgorny 		DPRINTF("Before calling PT_TRACE_ME from child %d\n", getpid());
   2723  1.13    mgorny 		FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1);
   2724  1.13    mgorny 
   2725  1.13    mgorny 		DPRINTF("Before running assembly from child\n");
   2726  1.13    mgorny 		get_xmm_regs(v_xmm);
   2727  1.13    mgorny 
   2728  1.14    mgorny 		DPRINTF("Before comparing results\n");
   2729  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[0], &xmm[0], sizeof(*xmm)));
   2730  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[1], &xmm[1], sizeof(*xmm)));
   2731  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[2], &xmm[2], sizeof(*xmm)));
   2732  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[3], &xmm[3], sizeof(*xmm)));
   2733  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[4], &xmm[4], sizeof(*xmm)));
   2734  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[5], &xmm[5], sizeof(*xmm)));
   2735  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[6], &xmm[6], sizeof(*xmm)));
   2736  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[7], &xmm[7], sizeof(*xmm)));
   2737  1.13    mgorny #if defined(__x86_64__)
   2738  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[8], &xmm[8], sizeof(*xmm)));
   2739  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[9], &xmm[9], sizeof(*xmm)));
   2740  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[10], &xmm[10], sizeof(*xmm)));
   2741  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[11], &xmm[11], sizeof(*xmm)));
   2742  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[12], &xmm[12], sizeof(*xmm)));
   2743  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[13], &xmm[13], sizeof(*xmm)));
   2744  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[14], &xmm[14], sizeof(*xmm)));
   2745  1.13    mgorny 		FORKEE_ASSERT(!memcmp(&v_xmm[15], &xmm[15], sizeof(*xmm)));
   2746  1.13    mgorny #endif
   2747  1.13    mgorny 
   2748  1.13    mgorny 		DPRINTF("Before exiting of the child process\n");
   2749  1.13    mgorny 		_exit(exitval);
   2750  1.13    mgorny 	}
   2751  1.13    mgorny 	DPRINTF("Parent process PID=%d, child's PID=%d\n", getpid(), child);
   2752  1.13    mgorny 
   2753  1.13    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2754  1.13    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2755  1.13    mgorny 
   2756  1.13    mgorny 	validate_status_stopped(status, sigval);
   2757  1.13    mgorny 
   2758  1.13    mgorny #if defined(__x86_64__)
   2759  1.13    mgorny 	DPRINTF("Call GETFPREGS for the child process\n");
   2760  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_GETFPREGS, child, &fpr, 0) != -1);
   2761  1.13    mgorny #else
   2762  1.13    mgorny 	DPRINTF("Call GETXMMREGS for the child process\n");
   2763  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_GETXMMREGS, child, &fpr, 0) != -1);
   2764  1.13    mgorny #endif
   2765  1.13    mgorny 
   2766  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[0], &xmm[0], sizeof(*xmm));
   2767  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[1], &xmm[1], sizeof(*xmm));
   2768  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[2], &xmm[2], sizeof(*xmm));
   2769  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[3], &xmm[3], sizeof(*xmm));
   2770  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[4], &xmm[4], sizeof(*xmm));
   2771  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[5], &xmm[5], sizeof(*xmm));
   2772  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[6], &xmm[6], sizeof(*xmm));
   2773  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[7], &xmm[7], sizeof(*xmm));
   2774  1.13    mgorny #if defined(__x86_64__)
   2775  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[8], &xmm[8], sizeof(*xmm));
   2776  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[9], &xmm[9], sizeof(*xmm));
   2777  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[10], &xmm[10], sizeof(*xmm));
   2778  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[11], &xmm[11], sizeof(*xmm));
   2779  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[12], &xmm[12], sizeof(*xmm));
   2780  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[13], &xmm[13], sizeof(*xmm));
   2781  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[14], &xmm[14], sizeof(*xmm));
   2782  1.13    mgorny 	memcpy(&fpr.fxstate.fx_xmm[15], &xmm[15], sizeof(*xmm));
   2783  1.13    mgorny #endif
   2784  1.13    mgorny 
   2785  1.13    mgorny #if defined(__x86_64__)
   2786  1.13    mgorny 	DPRINTF("Call SETFPREGS for the child process\n");
   2787  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_SETFPREGS, child, &fpr, 0) != -1);
   2788  1.13    mgorny #else
   2789  1.13    mgorny 	DPRINTF("Call SETXMMREGS for the child process\n");
   2790  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_SETXMMREGS, child, &fpr, 0) != -1);
   2791  1.13    mgorny #endif
   2792  1.13    mgorny 
   2793  1.13    mgorny 	DPRINTF("Before resuming the child process where it left off and "
   2794  1.13    mgorny 	    "without signal to be sent\n");
   2795  1.13    mgorny 	SYSCALL_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1);
   2796  1.13    mgorny 
   2797  1.13    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2798  1.13    mgorny 	TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child);
   2799  1.13    mgorny 
   2800  1.13    mgorny 	validate_status_exited(status, exitval);
   2801  1.13    mgorny 
   2802  1.13    mgorny 	DPRINTF("Before calling %s() for the child\n", TWAIT_FNAME);
   2803  1.13    mgorny 	TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0));
   2804  1.13    mgorny }
   2805   1.7     kamil /// ----------------------------------------------------------------------------
   2806   1.7     kamil 
   2807   1.1     kamil #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86() \
   2808   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_print); \
   2809   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0); \
   2810   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1); \
   2811   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2); \
   2812   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3); \
   2813   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_yield); \
   2814   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_yield); \
   2815   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_yield); \
   2816   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_yield); \
   2817   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr0_continued); \
   2818   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr1_continued); \
   2819   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr2_continued); \
   2820   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_preserve_dr3_continued); \
   2821   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_byte); \
   2822   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_byte); \
   2823   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_byte); \
   2824   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_byte); \
   2825   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_2bytes); \
   2826   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_2bytes); \
   2827   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_2bytes); \
   2828   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_2bytes); \
   2829   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_writeonly_4bytes); \
   2830   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_writeonly_4bytes); \
   2831   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_writeonly_4bytes); \
   2832   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_writeonly_4bytes); \
   2833   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_byte); \
   2834   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_byte); \
   2835   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_byte); \
   2836   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_byte); \
   2837   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_2bytes); \
   2838   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_2bytes); \
   2839   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_2bytes); \
   2840   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_2bytes); \
   2841   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_write_4bytes); \
   2842   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_write_4bytes); \
   2843   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_write_4bytes); \
   2844   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_write_4bytes); \
   2845   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_byte); \
   2846   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_byte); \
   2847   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_byte); \
   2848   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_byte); \
   2849   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_2bytes); \
   2850   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_2bytes); \
   2851   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_2bytes); \
   2852   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_2bytes); \
   2853   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_variable_readwrite_read_4bytes); \
   2854   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_variable_readwrite_read_4bytes); \
   2855   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_variable_readwrite_read_4bytes); \
   2856   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_variable_readwrite_read_4bytes); \
   2857   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_trap_code); \
   2858   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_trap_code); \
   2859   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_trap_code); \
   2860   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_trap_code); \
   2861   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_lwp); \
   2862   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_lwp); \
   2863   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_lwp); \
   2864   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_lwp); \
   2865   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr0_dont_inherit_execve); \
   2866   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr1_dont_inherit_execve); \
   2867   1.1     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr2_dont_inherit_execve); \
   2868   1.7     kamil 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, dbregs_dr3_dont_inherit_execve); \
   2869  1.10    mgorny 	ATF_TP_ADD_TC_HAVE_DBREGS(tp, x86_cve_2018_8897); \
   2870  1.10    mgorny 	ATF_TP_ADD_TC_HAVE_FPREGS(tp, x86_regs_mm_read); \
   2871  1.13    mgorny 	ATF_TP_ADD_TC_HAVE_FPREGS(tp, x86_regs_mm_write); \
   2872  1.13    mgorny 	ATF_TP_ADD_TC_HAVE_FPREGS(tp, x86_regs_xmm_read); \
   2873  1.13    mgorny 	ATF_TP_ADD_TC_HAVE_FPREGS(tp, x86_regs_xmm_write);
   2874   1.1     kamil #else
   2875   1.1     kamil #define ATF_TP_ADD_TCS_PTRACE_WAIT_X86()
   2876   1.1     kamil #endif
   2877