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