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