1 /*
2 * Check decoding of ptrace syscall.
3 *
4 * Copyright (c) 2016 Dmitry V. Levin <ldv@strace.io>
5 * Copyright (c) 2016-2023 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13 #include "print_fields.h"
14
15 #include <errno.h>
16 #include "ptrace.h"
17 #include <inttypes.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25 #include <linux/audit.h>
26 #include <sys/uio.h>
27 #include <sys/user.h>
28
29 #include "cur_audit_arch.h"
30
31 #include "xlat.h"
32 #define XLAT_MACROS_ONLY
33 # include "xlat/elf_em.h"
34 #undef XLAT_MACROS_ONLY
35 #include "xlat/audit_arch.h"
36
37 #define NULL_FD 23
38 #define NULL_STR "/dev/null"
39
40 #ifndef NULL_FD_STR
41 # define NULL_FD_STR ""
42 #endif
43
44 static const char null_path[] = "/dev/null";
45
46 #if SIZEOF_LONG > 4
47 # define UP64BIT(a_) a_
48 #else
49 # define UP64BIT(a_)
50 #endif
51
52 struct valstraux {
53 int val;
54 const char *str;
55 const char *aux;
56 };
57
58 static const char *errstr;
59
60 static long
61 do_ptrace(const unsigned long request,
62 const unsigned int pid,
63 const unsigned long addr,
64 const unsigned long data)
65 {
66 const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
67 const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
68 const kernel_ulong_t arg1 = request;
69 const kernel_ulong_t arg2 = fill | pid;
70 const kernel_ulong_t arg3 = addr;
71 const kernel_ulong_t arg4 = data;
72 long rc = syscall(__NR_ptrace, arg1, arg2, arg3, arg4, bad, bad);
73 errstr = sprintrc(rc);
74 return rc;
75 }
76
77 #if defined PTRACE_GETREGS || defined PTRACE_GETREGS64 || defined PTRACE_GETFPREGS
78 static long
79 do_ptrace_regs(const unsigned long request,
80 const unsigned int pid,
81 const unsigned long regs_addr)
82 {
83 const unsigned long bad = (unsigned long) 0xdeadbeefdeadbeefULL;
84 # ifdef __sparc__
85 const unsigned long arg_addr = regs_addr;
86 const unsigned long arg_data = bad;
87 # else
88 const unsigned long arg_addr = bad;
89 const unsigned long arg_data = regs_addr;
90 # endif
91 return do_ptrace(request, pid, arg_addr, arg_data);
92 }
93 #endif /* PTRACE_GETREGS || PTRACE_GETREGS64 || PTRACE_GETFPREGS */
94
95 #ifndef PTRACE_PEEKSIGINFO_SHARED
96 # define PTRACE_PEEKSIGINFO_SHARED (1 << 0)
97 #endif
98
99 static void
100 test_peeksiginfo(int pid, const unsigned long bad_request)
101 {
102 do_ptrace(PTRACE_PEEKSIGINFO, pid, 0, bad_request);
103 printf("ptrace(" XLAT_FMT ", %d, NULL, %#lx) = %s\n",
104 XLAT_ARGS(PTRACE_PEEKSIGINFO), pid, bad_request, errstr);
105
106 struct psi {
107 unsigned long long off;
108 unsigned int flags, nr;
109 };
110 TAIL_ALLOC_OBJECT_CONST_PTR(struct psi, psi);
111
112 psi->off = 0xdeadbeeffacefeedULL;
113 psi->flags = 1;
114 psi->nr = 42;
115
116 do_ptrace(PTRACE_PEEKSIGINFO, pid, (uintptr_t) psi, bad_request);
117 printf("ptrace(" XLAT_FMT ", %d, {off=%llu"
118 ", flags=" XLAT_FMT ", nr=%u}, %#lx) = %s\n",
119 XLAT_ARGS(PTRACE_PEEKSIGINFO), pid, psi->off,
120 XLAT_ARGS(PTRACE_PEEKSIGINFO_SHARED),
121 psi->nr, bad_request, errstr);
122
123 pid = fork();
124 if (pid < 0)
125 perror_msg_and_fail("fork");
126
127 if (!pid) {
128 sigset_t mask;
129 sigemptyset(&mask);
130 sigaddset(&mask, SIGUSR1);
131 sigaddset(&mask, SIGUSR2);
132 sigaddset(&mask, SIGALRM);
133
134 if (sigprocmask(SIG_BLOCK, &mask, NULL))
135 perror_msg_and_fail("sigprocmask");
136
137 raise(SIGUSR1);
138 raise(SIGUSR2);
139 raise(SIGALRM);
140
141 if (do_ptrace(PTRACE_TRACEME, 0, 0, 0))
142 perror_msg_and_fail("child: PTRACE_TRACEME");
143
144 raise(SIGSTOP);
145 _exit(0);
146 }
147
148 const unsigned int nsigs = 4;
149 const uid_t uid = geteuid();
150 siginfo_t *sigs = tail_alloc(sizeof(*sigs) * nsigs);
151
152 psi->off = 0;
153 psi->flags = 0;
154 psi->nr = nsigs;
155
156 for (;;) {
157 int status, tracee, saved;
158
159 errno = 0;
160 tracee = wait(&status);
161 if (tracee <= 0) {
162 if (errno == EINTR)
163 continue;
164 saved = errno;
165 kill(pid, SIGKILL);
166 errno = saved;
167 perror_msg_and_fail("wait");
168 }
169 if (WIFEXITED(status)) {
170 if (WEXITSTATUS(status) == 0)
171 break;
172 error_msg_and_fail("unexpected exit status %#x",
173 WEXITSTATUS(status));
174 }
175 if (WIFSIGNALED(status))
176 error_msg_and_fail("unexpected signal %u",
177 WTERMSIG(status));
178 if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) {
179 kill(pid, SIGKILL);
180 error_msg_and_fail("unexpected wait status %#x",
181 status);
182 }
183
184 long rc = do_ptrace(PTRACE_PEEKSIGINFO, pid,
185 (uintptr_t) psi, (uintptr_t) sigs);
186 if (rc < 0) {
187 printf("ptrace(" XLAT_FMT ", %d, {off=%llu, flags=0"
188 ", nr=%u}, %p) = %s\n",
189 XLAT_ARGS(PTRACE_PEEKSIGINFO),
190 pid, psi->off, psi->nr, sigs, errstr);
191 } else {
192 printf("ptrace(" XLAT_FMT ", %d"
193 ", {off=%llu, flags=0, nr=%u}"
194 ", [{si_signo=" XLAT_FMT_U ", si_code=" XLAT_FMT
195 ", si_pid=%d, si_uid=%d}"
196 ", {si_signo=" XLAT_FMT_U ", si_code=" XLAT_FMT
197 ", si_pid=%d, si_uid=%d}"
198 ", {si_signo=" XLAT_FMT_U ", si_code=" XLAT_FMT
199 ", si_pid=%d, si_uid=%d}"
200 "]) = %s\n",
201 XLAT_ARGS(PTRACE_PEEKSIGINFO),
202 pid, psi->off, psi->nr,
203 XLAT_ARGS(SIGUSR1), XLAT_ARGS(SI_TKILL),
204 pid, (int) uid,
205 XLAT_ARGS(SIGUSR2), XLAT_ARGS(SI_TKILL),
206 pid, (int) uid,
207 XLAT_ARGS(SIGALRM), XLAT_ARGS(SI_TKILL),
208 pid, (int) uid,
209 errstr);
210 }
211
212 if (do_ptrace(PTRACE_CONT, pid, 0, 0)) {
213 saved = errno;
214 kill(pid, SIGKILL);
215 errno = saved;
216 perror_msg_and_fail("ptrace");
217 }
218 printf("ptrace(" XLAT_FMT ", %d, NULL, 0) = 0\n",
219 XLAT_ARGS(PTRACE_CONT), pid);
220 }
221 }
222
223 #undef TRACEE_REGS_STRUCT
224 #if defined __x86_64__ || defined __i386__
225 # define TRACEE_REGS_STRUCT struct user_regs_struct
226 #elif defined __powerpc__ || defined __powerpc64__
227 # define TRACEE_REGS_STRUCT struct pt_regs
228 #elif defined __arm__
229 # define TRACEE_REGS_STRUCT struct pt_regs
230 #elif defined __arm64__ || defined __aarch64__ || defined __loongarch__
231 # define TRACEE_REGS_STRUCT struct user_pt_regs
232 #elif defined __s390__ || defined __s390x__
233 # define TRACEE_REGS_STRUCT s390_regs
234 #elif defined __sparc__
235 # ifdef __arch64__
236 typedef struct {
237 unsigned long g[8];
238 unsigned long o[8];
239 unsigned long l[8];
240 unsigned long i[8];
241 unsigned long tstate;
242 unsigned long tpc;
243 unsigned long tnpc;
244 unsigned long y;
245 } sparc64_regs;
246 # define TRACEE_REGS_STRUCT sparc64_regs
247 # else /* sparc32 */
248 typedef struct {
249 unsigned int g[8];
250 unsigned int o[8];
251 unsigned int l[8];
252 unsigned int i[8];
253 unsigned int psr;
254 unsigned int pc;
255 unsigned int npc;
256 unsigned int y;
257 unsigned int wim;
258 unsigned int tbr;
259 } sparc32_regs;
260 # define TRACEE_REGS_STRUCT sparc32_regs
261 # endif
262 #elif defined __riscv
263 # define TRACEE_REGS_STRUCT struct user_regs_struct
264 #elif defined __mips__
265 typedef struct {
266 # ifdef LINUX_MIPSO32
267 unsigned long unused[6];
268 # endif
269 unsigned long regs[32];
270 unsigned long lo;
271 unsigned long hi;
272 unsigned long cp0_epc;
273 unsigned long cp0_badvaddr;
274 unsigned long cp0_status;
275 unsigned long cp0_cause;
276 } mips_regs;
277 # define TRACEE_REGS_STRUCT mips_regs
278 #endif
279
280 static void
281 print_prstatus_regset(const void *const rs, const size_t size)
282 {
283 if (!size || size % sizeof(kernel_ulong_t)) {
284 printf("%p", rs);
285 return;
286 }
287
288 #ifdef TRACEE_REGS_STRUCT
289 const TRACEE_REGS_STRUCT *const regs = rs;
290
291 fputs("{", stdout);
292
293 # if defined __x86_64__
294
295 PRINT_FIELD_X(*regs, r15);
296 if (size >= offsetofend(TRACEE_REGS_STRUCT, r14)) {
297 fputs(", ", stdout);
298 PRINT_FIELD_X(*regs, r14);
299 }
300 if (size >= offsetofend(TRACEE_REGS_STRUCT, r13)) {
301 fputs(", ", stdout);
302 PRINT_FIELD_X(*regs, r13);
303 }
304 if (size >= offsetofend(TRACEE_REGS_STRUCT, r12)) {
305 fputs(", ", stdout);
306 PRINT_FIELD_X(*regs, r12);
307 }
308 if (size >= offsetofend(TRACEE_REGS_STRUCT, rbp)) {
309 fputs(", ", stdout);
310 PRINT_FIELD_X(*regs, rbp);
311 }
312 if (size >= offsetofend(TRACEE_REGS_STRUCT, rbx)) {
313 fputs(", ", stdout);
314 PRINT_FIELD_X(*regs, rbx);
315 }
316 if (size >= offsetofend(TRACEE_REGS_STRUCT, r11)) {
317 fputs(", ", stdout);
318 PRINT_FIELD_X(*regs, r11);
319 }
320 if (size >= offsetofend(TRACEE_REGS_STRUCT, r10)) {
321 fputs(", ", stdout);
322 PRINT_FIELD_X(*regs, r10);
323 }
324 if (size >= offsetofend(TRACEE_REGS_STRUCT, r9)) {
325 fputs(", ", stdout);
326 PRINT_FIELD_X(*regs, r9);
327 }
328 if (size >= offsetofend(TRACEE_REGS_STRUCT, r8)) {
329 fputs(", ", stdout);
330 PRINT_FIELD_X(*regs, r8);
331 }
332 if (size >= offsetofend(TRACEE_REGS_STRUCT, rax)) {
333 fputs(", ", stdout);
334 PRINT_FIELD_X(*regs, rax);
335 }
336 if (size >= offsetofend(TRACEE_REGS_STRUCT, rcx)) {
337 fputs(", ", stdout);
338 PRINT_FIELD_X(*regs, rcx);
339 }
340 if (size >= offsetofend(TRACEE_REGS_STRUCT, rdx)) {
341 fputs(", ", stdout);
342 PRINT_FIELD_X(*regs, rdx);
343 }
344 if (size >= offsetofend(TRACEE_REGS_STRUCT, rsi)) {
345 fputs(", ", stdout);
346 PRINT_FIELD_X(*regs, rsi);
347 }
348 if (size >= offsetofend(TRACEE_REGS_STRUCT, rdi)) {
349 fputs(", ", stdout);
350 PRINT_FIELD_X(*regs, rdi);
351 }
352 if (size >= offsetofend(TRACEE_REGS_STRUCT, orig_rax)) {
353 fputs(", ", stdout);
354 PRINT_FIELD_X(*regs, orig_rax);
355 }
356 if (size >= offsetofend(TRACEE_REGS_STRUCT, rip)) {
357 fputs(", ", stdout);
358 PRINT_FIELD_X(*regs, rip);
359 }
360 if (size >= offsetofend(TRACEE_REGS_STRUCT, cs)) {
361 fputs(", ", stdout);
362 PRINT_FIELD_X(*regs, cs);
363 }
364 if (size >= offsetofend(TRACEE_REGS_STRUCT, eflags)) {
365 fputs(", ", stdout);
366 PRINT_FIELD_X(*regs, eflags);
367 }
368 if (size >= offsetofend(TRACEE_REGS_STRUCT, rsp)) {
369 fputs(", ", stdout);
370 PRINT_FIELD_X(*regs, rsp);
371 }
372 if (size >= offsetofend(TRACEE_REGS_STRUCT, ss)) {
373 fputs(", ", stdout);
374 PRINT_FIELD_X(*regs, ss);
375 }
376 if (size >= offsetofend(TRACEE_REGS_STRUCT, fs_base)) {
377 fputs(", ", stdout);
378 PRINT_FIELD_X(*regs, fs_base);
379 }
380 if (size >= offsetofend(TRACEE_REGS_STRUCT, gs_base)) {
381 fputs(", ", stdout);
382 PRINT_FIELD_X(*regs, gs_base);
383 }
384 if (size >= offsetofend(TRACEE_REGS_STRUCT, ds)) {
385 fputs(", ", stdout);
386 PRINT_FIELD_X(*regs, ds);
387 }
388 if (size >= offsetofend(TRACEE_REGS_STRUCT, es)) {
389 fputs(", ", stdout);
390 PRINT_FIELD_X(*regs, es);
391 }
392 if (size >= offsetofend(TRACEE_REGS_STRUCT, fs)) {
393 fputs(", ", stdout);
394 PRINT_FIELD_X(*regs, fs);
395 }
396 if (size >= offsetofend(TRACEE_REGS_STRUCT, gs)) {
397 fputs(", ", stdout);
398 PRINT_FIELD_X(*regs, gs);
399 }
400
401 # elif defined __i386__
402
403 PRINT_FIELD_X(*regs, ebx);
404 if (size >= offsetofend(TRACEE_REGS_STRUCT, ecx)) {
405 fputs(", ", stdout);
406 PRINT_FIELD_X(*regs, ecx);
407 }
408 if (size >= offsetofend(TRACEE_REGS_STRUCT, edx)) {
409 fputs(", ", stdout);
410 PRINT_FIELD_X(*regs, edx);
411 }
412 if (size >= offsetofend(TRACEE_REGS_STRUCT, esi)) {
413 fputs(", ", stdout);
414 PRINT_FIELD_X(*regs, esi);
415 }
416 if (size >= offsetofend(TRACEE_REGS_STRUCT, edi)) {
417 fputs(", ", stdout);
418 PRINT_FIELD_X(*regs, edi);
419 }
420 if (size >= offsetofend(TRACEE_REGS_STRUCT, ebp)) {
421 fputs(", ", stdout);
422 PRINT_FIELD_X(*regs, ebp);
423 }
424 if (size >= offsetofend(TRACEE_REGS_STRUCT, eax)) {
425 fputs(", ", stdout);
426 PRINT_FIELD_X(*regs, eax);
427 }
428 if (size >= offsetofend(TRACEE_REGS_STRUCT, xds)) {
429 fputs(", ", stdout);
430 PRINT_FIELD_X(*regs, xds);
431 }
432 if (size >= offsetofend(TRACEE_REGS_STRUCT, xes)) {
433 fputs(", ", stdout);
434 PRINT_FIELD_X(*regs, xes);
435 }
436 if (size >= offsetofend(TRACEE_REGS_STRUCT, xfs)) {
437 fputs(", ", stdout);
438 PRINT_FIELD_X(*regs, xfs);
439 }
440 if (size >= offsetofend(TRACEE_REGS_STRUCT, xgs)) {
441 fputs(", ", stdout);
442 PRINT_FIELD_X(*regs, xgs);
443 }
444 if (size >= offsetofend(TRACEE_REGS_STRUCT, orig_eax)) {
445 fputs(", ", stdout);
446 PRINT_FIELD_X(*regs, orig_eax);
447 }
448 if (size >= offsetofend(TRACEE_REGS_STRUCT, eip)) {
449 fputs(", ", stdout);
450 PRINT_FIELD_X(*regs, eip);
451 }
452 if (size >= offsetofend(TRACEE_REGS_STRUCT, xcs)) {
453 fputs(", ", stdout);
454 PRINT_FIELD_X(*regs, xcs);
455 }
456 if (size >= offsetofend(TRACEE_REGS_STRUCT, eflags)) {
457 fputs(", ", stdout);
458 PRINT_FIELD_X(*regs, eflags);
459 }
460 if (size >= offsetofend(TRACEE_REGS_STRUCT, esp)) {
461 fputs(", ", stdout);
462 PRINT_FIELD_X(*regs, esp);
463 }
464 if (size >= offsetofend(TRACEE_REGS_STRUCT, xss)) {
465 fputs(", ", stdout);
466 PRINT_FIELD_X(*regs, xss);
467 }
468
469 # elif defined __powerpc__ || defined __powerpc64__
470
471 fputs("gpr=[", stdout);
472 for (unsigned int i = 0; i < ARRAY_SIZE(regs->gpr); ++i) {
473 if (size > i * sizeof(regs->gpr[i])) {
474 if (i)
475 fputs(", ", stdout);
476 PRINT_VAL_X(regs->gpr[i]);
477 }
478 }
479 fputs("]", stdout);
480 if (size >= offsetofend(TRACEE_REGS_STRUCT, nip)) {
481 fputs(", ", stdout);
482 PRINT_FIELD_X(*regs, nip);
483 }
484 if (size >= offsetofend(TRACEE_REGS_STRUCT, msr)) {
485 fputs(", ", stdout);
486 PRINT_FIELD_X(*regs, msr);
487 }
488 if (size >= offsetofend(TRACEE_REGS_STRUCT, orig_gpr3)) {
489 fputs(", ", stdout);
490 PRINT_FIELD_X(*regs, orig_gpr3);
491 }
492 if (size >= offsetofend(TRACEE_REGS_STRUCT, ctr)) {
493 fputs(", ", stdout);
494 PRINT_FIELD_X(*regs, ctr);
495 }
496 if (size >= offsetofend(TRACEE_REGS_STRUCT, link)) {
497 fputs(", ", stdout);
498 PRINT_FIELD_X(*regs, link);
499 }
500 if (size >= offsetofend(TRACEE_REGS_STRUCT, xer)) {
501 fputs(", ", stdout);
502 PRINT_FIELD_X(*regs, xer);
503 }
504 if (size >= offsetofend(TRACEE_REGS_STRUCT, ccr)) {
505 fputs(", ", stdout);
506 PRINT_FIELD_X(*regs, ccr);
507 }
508 # ifdef __powerpc64__
509 if (size >= offsetofend(TRACEE_REGS_STRUCT, softe)) {
510 fputs(", ", stdout);
511 PRINT_FIELD_X(*regs, softe);
512 }
513 # else
514 if (size >= offsetofend(TRACEE_REGS_STRUCT, mq)) {
515 fputs(", ", stdout);
516 PRINT_FIELD_X(*regs, mq);
517 }
518 # endif
519 if (size >= offsetofend(TRACEE_REGS_STRUCT, trap)) {
520 fputs(", ", stdout);
521 PRINT_FIELD_X(*regs, trap);
522 }
523 if (size >= offsetofend(TRACEE_REGS_STRUCT, dar)) {
524 fputs(", ", stdout);
525 PRINT_FIELD_X(*regs, dar);
526 }
527 if (size >= offsetofend(TRACEE_REGS_STRUCT, dsisr)) {
528 fputs(", ", stdout);
529 PRINT_FIELD_X(*regs, dsisr);
530 }
531 if (size >= offsetofend(TRACEE_REGS_STRUCT, result)) {
532 fputs(", ", stdout);
533 PRINT_FIELD_X(*regs, result);
534 }
535
536 # elif defined __arm__
537
538 fputs("uregs=[", stdout);
539 for (unsigned int i = 0; i < ARRAY_SIZE(regs->uregs); ++i) {
540 if (size > i * sizeof(regs->uregs[i])) {
541 if (i)
542 fputs(", ", stdout);
543 PRINT_VAL_X(regs->uregs[i]);
544 }
545 }
546 fputs("]", stdout);
547
548 # elif defined __arm64__ || defined __aarch64__
549
550 fputs("regs=[", stdout);
551 for (unsigned int i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
552 if (size > i * sizeof(regs->regs[i])) {
553 if (i)
554 fputs(", ", stdout);
555 PRINT_VAL_X(regs->regs[i]);
556 }
557 }
558 fputs("]", stdout);
559 if (size >= offsetofend(TRACEE_REGS_STRUCT, sp)) {
560 fputs(", ", stdout);
561 PRINT_FIELD_X(*regs, sp);
562 }
563 if (size >= offsetofend(TRACEE_REGS_STRUCT, pc)) {
564 fputs(", ", stdout);
565 PRINT_FIELD_X(*regs, pc);
566 }
567 if (size >= offsetofend(TRACEE_REGS_STRUCT, pstate)) {
568 fputs(", ", stdout);
569 PRINT_FIELD_X(*regs, pstate);
570 }
571
572 # elif defined __s390__ || defined __s390x__
573
574 fputs("psw={", stdout);
575 PRINT_FIELD_X(regs->psw, mask);
576 if (size >= sizeof(regs->psw)) {
577 fputs(", ", stdout);
578 PRINT_FIELD_X(regs->psw, addr);
579 }
580 fputs("}", stdout);
581 if (size > offsetof(TRACEE_REGS_STRUCT, gprs)) {
582 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, gprs);
583 fputs(", gprs=[", stdout);
584 for (unsigned int i = 0; i < ARRAY_SIZE(regs->gprs); ++i) {
585 if (len > i * sizeof(regs->gprs[i])) {
586 if (i)
587 fputs(", ", stdout);
588 PRINT_VAL_X(regs->gprs[i]);
589 }
590 }
591 fputs("]", stdout);
592 }
593 if (size > offsetof(TRACEE_REGS_STRUCT, acrs)) {
594 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, acrs);
595 fputs(", acrs=[", stdout);
596 for (unsigned int i = 0; i < ARRAY_SIZE(regs->acrs); ++i) {
597 if (len > i * sizeof(regs->acrs[i])) {
598 if (i)
599 fputs(", ", stdout);
600 PRINT_VAL_X(regs->acrs[i]);
601 }
602 }
603 fputs("]", stdout);
604 }
605 if (size >= offsetofend(TRACEE_REGS_STRUCT, orig_gpr2)) {
606 fputs(", ", stdout);
607 PRINT_FIELD_X(*regs, orig_gpr2);
608 }
609
610 # elif defined __sparc__
611
612 fputs("g=[", stdout);
613 for (unsigned int j = 0; j < ARRAY_SIZE(regs->g); ++j) {
614 if (size > j * sizeof(regs->g[j])) {
615 if (j)
616 fputs(", ", stdout);
617 PRINT_VAL_X(regs->g[j]);
618 }
619 }
620 fputs("]", stdout);
621 if (size > offsetof(TRACEE_REGS_STRUCT, o)) {
622 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, o);
623 fputs(", o=[", stdout);
624 for (unsigned int j = 0; j < ARRAY_SIZE(regs->o); ++j) {
625 if (len > j * sizeof(regs->o[j])) {
626 if (j)
627 fputs(", ", stdout);
628 PRINT_VAL_X(regs->o[j]);
629 }
630 }
631 fputs("]", stdout);
632 }
633 if (size > offsetof(TRACEE_REGS_STRUCT, l)) {
634 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, l);
635 fputs(", l=[", stdout);
636 for (unsigned int j = 0; j < ARRAY_SIZE(regs->l); ++j) {
637 if (len > j * sizeof(regs->l[j])) {
638 if (j)
639 fputs(", ", stdout);
640 PRINT_VAL_X(regs->l[j]);
641 }
642 }
643 fputs("]", stdout);
644 }
645 if (size > offsetof(TRACEE_REGS_STRUCT, i)) {
646 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, i);
647 fputs(", i=[", stdout);
648 for (unsigned int j = 0; j < ARRAY_SIZE(regs->i); ++j) {
649 if (len > j * sizeof(regs->i[j])) {
650 if (j)
651 fputs(", ", stdout);
652 PRINT_VAL_X(regs->i[j]);
653 }
654 }
655 fputs("]", stdout);
656 }
657 # ifdef __arch64__
658 if (size >= offsetofend(TRACEE_REGS_STRUCT, tstate)) {
659 fputs(", ", stdout);
660 PRINT_FIELD_X(*regs, tstate);
661 }
662 if (size >= offsetofend(TRACEE_REGS_STRUCT, tpc)) {
663 fputs(", ", stdout);
664 PRINT_FIELD_X(*regs, tpc);
665 }
666 if (size >= offsetofend(TRACEE_REGS_STRUCT, tnpc)) {
667 fputs(", ", stdout);
668 PRINT_FIELD_X(*regs, tnpc);
669 }
670 if (size >= offsetofend(TRACEE_REGS_STRUCT, y)) {
671 fputs(", ", stdout);
672 PRINT_FIELD_X(*regs, y);
673 }
674 # else /* sparc32 */
675 if (size >= offsetofend(TRACEE_REGS_STRUCT, psr)) {
676 fputs(", ", stdout);
677 PRINT_FIELD_X(*regs, psr);
678 }
679 if (size >= offsetofend(TRACEE_REGS_STRUCT, pc)) {
680 fputs(", ", stdout);
681 PRINT_FIELD_X(*regs, pc);
682 }
683 if (size >= offsetofend(TRACEE_REGS_STRUCT, npc)) {
684 fputs(", ", stdout);
685 PRINT_FIELD_X(*regs, npc);
686 }
687 if (size >= offsetofend(TRACEE_REGS_STRUCT, y)) {
688 fputs(", ", stdout);
689 PRINT_FIELD_X(*regs, y);
690 }
691 if (size >= offsetofend(TRACEE_REGS_STRUCT, wim)) {
692 fputs(", ", stdout);
693 PRINT_FIELD_X(*regs, wim);
694 }
695 if (size >= offsetofend(TRACEE_REGS_STRUCT, tbr)) {
696 fputs(", ", stdout);
697 PRINT_FIELD_X(*regs, tbr);
698 }
699 # endif
700
701 # elif defined __riscv
702
703 PRINT_FIELD_X(*regs, pc);
704 if (size >= offsetofend(TRACEE_REGS_STRUCT, ra)) {
705 fputs(", ", stdout);
706 PRINT_FIELD_X(*regs, ra);
707 }
708 if (size >= offsetofend(TRACEE_REGS_STRUCT, sp)) {
709 fputs(", ", stdout);
710 PRINT_FIELD_X(*regs, sp);
711 }
712 if (size >= offsetofend(TRACEE_REGS_STRUCT, gp)) {
713 fputs(", ", stdout);
714 PRINT_FIELD_X(*regs, gp);
715 }
716 if (size >= offsetofend(TRACEE_REGS_STRUCT, tp)) {
717 fputs(", ", stdout);
718 PRINT_FIELD_X(*regs, tp);
719 }
720 if (size >= offsetofend(TRACEE_REGS_STRUCT, t0)) {
721 fputs(", ", stdout);
722 PRINT_FIELD_X(*regs, t0);
723 }
724 if (size >= offsetofend(TRACEE_REGS_STRUCT, t1)) {
725 fputs(", ", stdout);
726 PRINT_FIELD_X(*regs, t1);
727 }
728 if (size >= offsetofend(TRACEE_REGS_STRUCT, t2)) {
729 fputs(", ", stdout);
730 PRINT_FIELD_X(*regs, t2);
731 }
732 if (size >= offsetofend(TRACEE_REGS_STRUCT, s0)) {
733 fputs(", ", stdout);
734 PRINT_FIELD_X(*regs, s0);
735 }
736 if (size >= offsetofend(TRACEE_REGS_STRUCT, s1)) {
737 fputs(", ", stdout);
738 PRINT_FIELD_X(*regs, s1);
739 }
740 if (size >= offsetofend(TRACEE_REGS_STRUCT, a0)) {
741 fputs(", ", stdout);
742 PRINT_FIELD_X(*regs, a0);
743 }
744 if (size >= offsetofend(TRACEE_REGS_STRUCT, a1)) {
745 fputs(", ", stdout);
746 PRINT_FIELD_X(*regs, a1);
747 }
748 if (size >= offsetofend(TRACEE_REGS_STRUCT, a2)) {
749 fputs(", ", stdout);
750 PRINT_FIELD_X(*regs, a2);
751 }
752 if (size >= offsetofend(TRACEE_REGS_STRUCT, a3)) {
753 fputs(", ", stdout);
754 PRINT_FIELD_X(*regs, a3);
755 }
756 if (size >= offsetofend(TRACEE_REGS_STRUCT, a4)) {
757 fputs(", ", stdout);
758 PRINT_FIELD_X(*regs, a4);
759 }
760 if (size >= offsetofend(TRACEE_REGS_STRUCT, a5)) {
761 fputs(", ", stdout);
762 PRINT_FIELD_X(*regs, a5);
763 }
764 if (size >= offsetofend(TRACEE_REGS_STRUCT, a6)) {
765 fputs(", ", stdout);
766 PRINT_FIELD_X(*regs, a6);
767 }
768 if (size >= offsetofend(TRACEE_REGS_STRUCT, a7)) {
769 fputs(", ", stdout);
770 PRINT_FIELD_X(*regs, a7);
771 }
772 if (size >= offsetofend(TRACEE_REGS_STRUCT, s2)) {
773 fputs(", ", stdout);
774 PRINT_FIELD_X(*regs, s2);
775 }
776 if (size >= offsetofend(TRACEE_REGS_STRUCT, s3)) {
777 fputs(", ", stdout);
778 PRINT_FIELD_X(*regs, s3);
779 }
780 if (size >= offsetofend(TRACEE_REGS_STRUCT, s4)) {
781 fputs(", ", stdout);
782 PRINT_FIELD_X(*regs, s4);
783 }
784 if (size >= offsetofend(TRACEE_REGS_STRUCT, s5)) {
785 fputs(", ", stdout);
786 PRINT_FIELD_X(*regs, s5);
787 }
788 if (size >= offsetofend(TRACEE_REGS_STRUCT, s6)) {
789 fputs(", ", stdout);
790 PRINT_FIELD_X(*regs, s6);
791 }
792 if (size >= offsetofend(TRACEE_REGS_STRUCT, s7)) {
793 fputs(", ", stdout);
794 PRINT_FIELD_X(*regs, s7);
795 }
796 if (size >= offsetofend(TRACEE_REGS_STRUCT, s8)) {
797 fputs(", ", stdout);
798 PRINT_FIELD_X(*regs, s8);
799 }
800 if (size >= offsetofend(TRACEE_REGS_STRUCT, s9)) {
801 fputs(", ", stdout);
802 PRINT_FIELD_X(*regs, s9);
803 }
804 if (size >= offsetofend(TRACEE_REGS_STRUCT, s10)) {
805 fputs(", ", stdout);
806 PRINT_FIELD_X(*regs, s10);
807 }
808 if (size >= offsetofend(TRACEE_REGS_STRUCT, s11)) {
809 fputs(", ", stdout);
810 PRINT_FIELD_X(*regs, s11);
811 }
812 if (size >= offsetofend(TRACEE_REGS_STRUCT, t3)) {
813 fputs(", ", stdout);
814 PRINT_FIELD_X(*regs, t3);
815 }
816 if (size >= offsetofend(TRACEE_REGS_STRUCT, t4)) {
817 fputs(", ", stdout);
818 PRINT_FIELD_X(*regs, t4);
819 }
820 if (size >= offsetofend(TRACEE_REGS_STRUCT, t5)) {
821 fputs(", ", stdout);
822 PRINT_FIELD_X(*regs, t5);
823 }
824 if (size >= offsetofend(TRACEE_REGS_STRUCT, t6)) {
825 fputs(", ", stdout);
826 PRINT_FIELD_X(*regs, t6);
827 }
828
829 # elif defined __mips__
830
831 if (size > offsetof(TRACEE_REGS_STRUCT, regs)) {
832 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, regs);
833 fputs("regs=[", stdout);
834 for (unsigned int i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
835 if (len > i * sizeof(regs->regs[i])) {
836 if (i)
837 fputs(", ", stdout);
838 PRINT_VAL_X(regs->regs[i]);
839 }
840 }
841 fputs("]", stdout);
842 }
843 if (size >= offsetofend(TRACEE_REGS_STRUCT, lo)) {
844 fputs(", ", stdout);
845 PRINT_FIELD_X(*regs, lo);
846 }
847 if (size >= offsetofend(TRACEE_REGS_STRUCT, hi)) {
848 fputs(", ", stdout);
849 PRINT_FIELD_X(*regs, hi);
850 }
851 if (size >= offsetofend(TRACEE_REGS_STRUCT, cp0_epc)) {
852 fputs(", ", stdout);
853 PRINT_FIELD_X(*regs, cp0_epc);
854 }
855 if (size >= offsetofend(TRACEE_REGS_STRUCT, cp0_badvaddr)) {
856 fputs(", ", stdout);
857 PRINT_FIELD_X(*regs, cp0_badvaddr);
858 }
859 if (size >= offsetofend(TRACEE_REGS_STRUCT, cp0_status)) {
860 fputs(", ", stdout);
861 PRINT_FIELD_X(*regs, cp0_status);
862 }
863 if (size >= offsetofend(TRACEE_REGS_STRUCT, cp0_cause)) {
864 fputs(", ", stdout);
865 PRINT_FIELD_X(*regs, cp0_cause);
866 }
867
868 # elif defined __loongarch__
869
870 if (size > offsetof(TRACEE_REGS_STRUCT, regs)) {
871 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, regs);
872 fputs("regs=[", stdout);
873 for (unsigned int i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
874 if (len > i * sizeof(regs->regs[i])) {
875 if (i)
876 fputs(", ", stdout);
877 PRINT_VAL_X(regs->regs[i]);
878 }
879 }
880 fputs("]", stdout);
881 }
882 if (size >= offsetofend(TRACEE_REGS_STRUCT, orig_a0)) {
883 fputs(", ", stdout);
884 PRINT_FIELD_X(*regs, orig_a0);
885 }
886 if (size >= offsetofend(TRACEE_REGS_STRUCT, csr_era)) {
887 fputs(", ", stdout);
888 PRINT_FIELD_X(*regs, csr_era);
889 }
890 if (size >= offsetofend(TRACEE_REGS_STRUCT, csr_badv)) {
891 fputs(", ", stdout);
892 PRINT_FIELD_X(*regs, csr_badv);
893 }
894 if (size > offsetof(TRACEE_REGS_STRUCT, reserved)) {
895 const size_t len = size - offsetof(TRACEE_REGS_STRUCT, reserved);
896 fputs(", reserved=[", stdout);
897 for (unsigned int i = 0; i < ARRAY_SIZE(regs->reserved); ++i) {
898 if (len > i * sizeof(regs->reserved[i])) {
899 if (i)
900 fputs(", ", stdout);
901 PRINT_VAL_X(regs->reserved[i]);
902 }
903 }
904 fputs("]", stdout);
905 }
906
907 # endif /*
908 __aarch64__ ||
909 __arm64__ ||
910 __arm__ ||
911 __i386__ ||
912 __loongarch__ ||
913 __mips__ ||
914 __powerpc64__ ||
915 __powerpc__ ||
916 __riscv ||
917 __s390__ ||
918 __s390x__ ||
919 __sparc__ ||
920 __x86_64__
921 */
922
923 if (size > sizeof(*regs))
924 fputs(", ...", stdout);
925 fputs("}", stdout);
926
927 #else /* !TRACEE_REGS_STRUCT */
928
929 printf("%p", rs);
930
931 #endif /* TRACEE_REGS_STRUCT */
932 }
933
934 #ifdef PTRACE_GETREGS
935 static void
936 print_pt_regs(const void *const rs, const size_t size)
937 {
938 # if defined __mips__
939
940 const struct pt_regs *const regs = rs;
941 if (size != sizeof(*regs))
942 error_msg_and_fail("expected size %zu, got size %zu",
943 sizeof(*regs), size);
944 fputs("{regs=[", stdout);
945 for (unsigned int j = 0; j < ARRAY_SIZE(regs->regs); ++j) {
946 if (j)
947 fputs(", ", stdout);
948 printf("%#llx", (unsigned long long) regs->regs[j]);
949 }
950 fputs("], ", stdout);
951 PRINT_FIELD_X(*regs, lo);
952 fputs(", ", stdout);
953 PRINT_FIELD_X(*regs, hi);
954 fputs(", ", stdout);
955 PRINT_FIELD_X(*regs, cp0_epc);
956 fputs(", ", stdout);
957 PRINT_FIELD_X(*regs, cp0_badvaddr);
958 fputs(", ", stdout);
959 PRINT_FIELD_X(*regs, cp0_status);
960 fputs(", ", stdout);
961 PRINT_FIELD_X(*regs, cp0_cause);
962 fputs("}", stdout);
963
964 # elif defined __sparc__
965
966 # ifdef __arch64__
967 printf("%p", rs);
968 # else
969 const struct {
970 unsigned int psr;
971 unsigned int pc;
972 unsigned int npc;
973 unsigned int y;
974 unsigned int u_regs[15];
975 } *const regs = rs;
976 if (size != sizeof(*regs))
977 error_msg_and_fail("expected size %zu, got size %zu",
978 sizeof(*regs), size);
979 printf("{psr=%#x, pc=%#x, npc=%#x, y=%#x, u_regs=[",
980 regs->psr, regs->pc, regs->npc, regs->y);
981 for (unsigned int j = 0; j < ARRAY_SIZE(regs->u_regs); ++j) {
982 if (j)
983 fputs(", ", stdout);
984 printf("%#x", regs->u_regs[j]);
985 }
986 fputs("]}", stdout);
987 # endif /* !__arch64__ */
988
989 # elif defined TRACEE_REGS_STRUCT
990
991 if (size != sizeof(TRACEE_REGS_STRUCT))
992 error_msg_and_fail("expected size %zu, got size %zu",
993 sizeof(TRACEE_REGS_STRUCT), size);
994 print_prstatus_regset(rs, size);
995
996 # else /* !TRACEE_REGS_STRUCT */
997
998 printf("%p", rs);
999
1000 # endif
1001 }
1002
1003 static void
1004 do_getregs_setregs(const int pid,
1005 void *const regbuf,
1006 const unsigned int regsize,
1007 unsigned int *const actual_size)
1008 {
1009 if (do_ptrace_regs(PTRACE_GETREGS, pid, (uintptr_t) regbuf)) {
1010 printf("ptrace(" XLAT_FMT ", %d, %p) = %s\n",
1011 XLAT_ARGS(PTRACE_GETREGS), pid, regbuf, errstr);
1012 return; /* skip PTRACE_SETREGS */
1013 } else {
1014 printf("ptrace(" XLAT_FMT ", %d, ",
1015 XLAT_ARGS(PTRACE_GETREGS), pid);
1016 print_pt_regs(regbuf, regsize);
1017 printf(") = %s\n", errstr);
1018 if (*actual_size)
1019 return; /* skip PTRACE_SETREGS */
1020 else
1021 *actual_size = regsize;
1022 }
1023
1024 # if defined __sparc__ && !defined __arch64__
1025 /*
1026 * On sparc32 PTRACE_SETREGS of size greater than 120
1027 * has interesting side effects.
1028 */
1029 if (regsize > 120)
1030 return;
1031 # endif /* __sparc__ && !__arch64__ */
1032
1033 do_ptrace_regs(PTRACE_SETREGS, pid, (uintptr_t) regbuf);
1034 printf("ptrace(" XLAT_FMT ", %d, ", XLAT_ARGS(PTRACE_SETREGS), pid);
1035 print_pt_regs(regbuf, regsize);
1036 printf(") = %s\n", errstr);
1037 }
1038 #endif /* PTRACE_GETREGS */
1039
1040 #ifdef PTRACE_GETREGS64
1041 static void
1042 print_pt_regs64(const void *const rs, const size_t size)
1043 {
1044 # if defined __powerpc__ || defined __powerpc64__
1045 # ifdef __powerpc64__
1046 const struct pt_regs *const regs = rs;
1047 # else /* __powerpc__ */
1048 const struct {
1049 unsigned long long gpr[32];
1050 unsigned long long nip;
1051 unsigned long long msr;
1052 unsigned long long orig_gpr3;
1053 unsigned long long ctr;
1054 unsigned long long link;
1055 unsigned long long xer;
1056 unsigned long long ccr;
1057 unsigned long long softe;
1058 unsigned long long trap;
1059 unsigned long long dar;
1060 unsigned long long dsisr;
1061 unsigned long long result;
1062 } *const regs = rs;
1063 # endif /* __powerpc__ */
1064 if (size != sizeof(*regs))
1065 error_msg_and_fail("expected size %zu, got size %zu",
1066 sizeof(*regs), size);
1067 for (unsigned int j = 0; j < ARRAY_SIZE(regs->gpr); ++j)
1068 printf("%s%#llx", j ? ", " : "{gpr=[",
1069 (unsigned long long) regs->gpr[j]);
1070 printf("], nip=%#llx", (unsigned long long) regs->nip);
1071 printf(", msr=%#llx", (unsigned long long) regs->msr);
1072 printf(", orig_gpr3=%#llx", (unsigned long long) regs->orig_gpr3);
1073 printf(", ctr=%#llx", (unsigned long long) regs->ctr);
1074 printf(", link=%#llx", (unsigned long long) regs->link);
1075 printf(", xer=%#llx", (unsigned long long) regs->xer);
1076 printf(", ccr=%#llx", (unsigned long long) regs->ccr);
1077 printf(", softe=%#llx", (unsigned long long) regs->softe);
1078 printf(", trap=%#llx", (unsigned long long) regs->trap);
1079 printf(", dar=%#llx", (unsigned long long) regs->dar);
1080 printf(", dsisr=%#llx", (unsigned long long) regs->dsisr);
1081 printf(", result=%#llx}", (unsigned long long) regs->result);
1082
1083 # elif defined __sparc__ && defined __arch64__
1084
1085 const struct {
1086 unsigned long u_regs[16];
1087 unsigned long tstate;
1088 unsigned long tpc;
1089 unsigned long tnpc;
1090 } *const regs = rs;
1091 if (size != sizeof(*regs))
1092 error_msg_and_fail("expected size %zu, got size %zu",
1093 sizeof(*regs), size);
1094 for (unsigned int j = 0; j < ARRAY_SIZE(regs->u_regs); ++j)
1095 printf("%s%#lx", j ? ", " : "{u_regs=[", regs->u_regs[j]);
1096 printf("], tstate=%#lx", regs->tstate);
1097 printf(", tpc=%#lx", regs->tpc);
1098 printf(", tnpc=%#lx}", regs->tnpc);
1099
1100 # else /* !(__powerpc__ || __powerpc64__ || (__sparc__ && __arch64__)) */
1101
1102 printf("%p", rs);
1103
1104 # endif
1105 }
1106
1107 static void
1108 do_getregs64_setregs64(const int pid,
1109 void *const regbuf,
1110 const unsigned int regsize,
1111 unsigned int *const actual_size)
1112 {
1113 if (do_ptrace_regs(PTRACE_GETREGS64, pid, (uintptr_t) regbuf)) {
1114 printf("ptrace(" XLAT_FMT ", %d, %p) = %s\n",
1115 XLAT_ARGS(PTRACE_GETREGS64), pid, regbuf, errstr);
1116 return; /* skip PTRACE_SETREGS64 */
1117 } else {
1118 printf("ptrace(" XLAT_FMT ", %d, ",
1119 XLAT_ARGS(PTRACE_GETREGS64), pid);
1120 print_pt_regs64(regbuf, regsize);
1121 printf(") = %s\n", errstr);
1122 if (*actual_size)
1123 return; /* skip PTRACE_SETREGS64 */
1124 else
1125 *actual_size = regsize;
1126 }
1127
1128 do_ptrace_regs(PTRACE_SETREGS64, pid, (uintptr_t) regbuf);
1129 printf("ptrace(" XLAT_FMT ", %d, ", XLAT_ARGS(PTRACE_SETREGS64), pid);
1130 print_pt_regs64(regbuf, regsize);
1131 printf(") = %s\n", errstr);
1132 }
1133 #endif /* PTRACE_GETREGS64 */
1134
1135 #if defined __powerpc__ || defined __powerpc64__
1136 # define FPREGSET_SLOT_SIZE sizeof(uint64_t)
1137 #else
1138 # define FPREGSET_SLOT_SIZE sizeof(kernel_ulong_t)
1139 #endif
1140
1141 #undef TRACEE_REGS_STRUCT
1142 #if defined __x86_64__ || defined __i386__
1143 # define TRACEE_REGS_STRUCT struct user_fpregs_struct
1144 #elif defined __powerpc__ || defined __powerpc64__
1145 typedef struct {
1146 uint64_t fpr[32];
1147 uint64_t fpscr;
1148 } ppc_fpregs_struct;
1149 # define TRACEE_REGS_STRUCT ppc_fpregs_struct
1150 #elif defined __loongarch__
1151 # define TRACEE_REGS_STRUCT struct user_fp_state
1152 #endif
1153
1154 static void
1155 print_fpregset(const void *const rs, const size_t size)
1156 {
1157 if (!size || size % FPREGSET_SLOT_SIZE) {
1158 printf("%p", rs);
1159 return;
1160 }
1161
1162 #ifdef TRACEE_REGS_STRUCT
1163 const TRACEE_REGS_STRUCT *const regs = rs;
1164
1165 fputs("{", stdout);
1166
1167 # if defined __i386__
1168
1169 PRINT_FIELD_X(*regs, cwd);
1170 if (size >= offsetofend(TRACEE_REGS_STRUCT, swd)) {
1171 fputs(", ", stdout);
1172 PRINT_FIELD_X(*regs, swd);
1173 }
1174 if (size >= offsetofend(TRACEE_REGS_STRUCT, twd)) {
1175 fputs(", ", stdout);
1176 PRINT_FIELD_X(*regs, twd);
1177 }
1178 if (size >= offsetofend(TRACEE_REGS_STRUCT, fip)) {
1179 fputs(", ", stdout);
1180 PRINT_FIELD_X(*regs, fip);
1181 }
1182 if (size >= offsetofend(TRACEE_REGS_STRUCT, fcs)) {
1183 fputs(", ", stdout);
1184 PRINT_FIELD_X(*regs, fcs);
1185 }
1186 if (size >= offsetofend(TRACEE_REGS_STRUCT, foo)) {
1187 fputs(", ", stdout);
1188 PRINT_FIELD_X(*regs, foo);
1189 }
1190 if (size >= offsetofend(TRACEE_REGS_STRUCT, fos)) {
1191 fputs(", ", stdout);
1192 PRINT_FIELD_X(*regs, fos);
1193 }
1194 if (size > offsetof(TRACEE_REGS_STRUCT, st_space)) {
1195 const size_t len =
1196 size - offsetof(TRACEE_REGS_STRUCT, st_space);
1197 fputs(", st_space=[", stdout);
1198 for (unsigned int i = 0; i < ARRAY_SIZE(regs->st_space); ++i) {
1199 if (len > i * sizeof(regs->st_space[i])) {
1200 if (i)
1201 fputs(", ", stdout);
1202 PRINT_VAL_X(regs->st_space[i]);
1203 }
1204 }
1205 fputs("]", stdout);
1206 }
1207
1208 # elif defined __x86_64__
1209
1210 PRINT_FIELD_X(*regs, cwd);
1211 if (size >= offsetofend(TRACEE_REGS_STRUCT, swd)) {
1212 fputs(", ", stdout);
1213 PRINT_FIELD_X(*regs, swd);
1214 }
1215 if (size >= offsetofend(TRACEE_REGS_STRUCT, ftw)) {
1216 fputs(", ", stdout);
1217 PRINT_FIELD_X(*regs, ftw);
1218 }
1219 if (size >= offsetofend(TRACEE_REGS_STRUCT, fop)) {
1220 fputs(", ", stdout);
1221 PRINT_FIELD_X(*regs, fop);
1222 }
1223 if (size >= offsetofend(TRACEE_REGS_STRUCT, rip)) {
1224 fputs(", ", stdout);
1225 PRINT_FIELD_X(*regs, rip);
1226 }
1227 if (size >= offsetofend(TRACEE_REGS_STRUCT, rdp)) {
1228 fputs(", ", stdout);
1229 PRINT_FIELD_X(*regs, rdp);
1230 }
1231 if (size >= offsetofend(TRACEE_REGS_STRUCT, mxcsr)) {
1232 fputs(", ", stdout);
1233 PRINT_FIELD_X(*regs, mxcsr);
1234 }
1235 if (size >= offsetofend(TRACEE_REGS_STRUCT, mxcr_mask)) {
1236 fputs(", ", stdout);
1237 PRINT_FIELD_X(*regs, mxcr_mask);
1238 }
1239 if (size > offsetof(TRACEE_REGS_STRUCT, st_space)) {
1240 const size_t len =
1241 size - offsetof(TRACEE_REGS_STRUCT, st_space);
1242 fputs(", st_space=[", stdout);
1243 for (unsigned int i = 0; i < ARRAY_SIZE(regs->st_space); ++i) {
1244 if (len > i * sizeof(regs->st_space[i])) {
1245 if (i)
1246 fputs(", ", stdout);
1247 PRINT_VAL_X(regs->st_space[i]);
1248 }
1249 }
1250 fputs("]", stdout);
1251 }
1252 if (size > offsetof(TRACEE_REGS_STRUCT, xmm_space)) {
1253 const size_t len =
1254 size - offsetof(TRACEE_REGS_STRUCT, xmm_space);
1255 fputs(", xmm_space=[", stdout);
1256 for (unsigned int i = 0; i < ARRAY_SIZE(regs->xmm_space); ++i) {
1257 if (len > i * sizeof(regs->xmm_space[i])) {
1258 if (i)
1259 fputs(", ", stdout);
1260 PRINT_VAL_X(regs->xmm_space[i]);
1261 }
1262 }
1263 fputs("]", stdout);
1264 }
1265 if (size > offsetof(TRACEE_REGS_STRUCT, padding)) {
1266 const size_t len =
1267 size - offsetof(TRACEE_REGS_STRUCT, padding);
1268 fputs(", padding=[", stdout);
1269 for (unsigned int i = 0; i < ARRAY_SIZE(regs->padding); ++i) {
1270 if (len > i * sizeof(regs->padding[i])) {
1271 if (i)
1272 fputs(", ", stdout);
1273 PRINT_VAL_X(regs->padding[i]);
1274 }
1275 }
1276 fputs("]", stdout);
1277 }
1278
1279 # elif defined __powerpc__ || defined __powerpc64__
1280
1281 fputs("fpr=[", stdout);
1282 for (unsigned int i = 0; i < ARRAY_SIZE(regs->fpr); ++i) {
1283 if (size > i * sizeof(regs->fpr[i])) {
1284 if (i)
1285 fputs(", ", stdout);
1286 PRINT_VAL_X(regs->fpr[i]);
1287 }
1288 }
1289 fputs("]", stdout);
1290 if (size >= offsetofend(TRACEE_REGS_STRUCT, fpscr)) {
1291 fputs(", ", stdout);
1292 PRINT_FIELD_X(*regs, fpscr);
1293 }
1294
1295 # elif defined __loongarch__
1296
1297 fputs("fpr=[", stdout);
1298 for (unsigned int i = 0; i < ARRAY_SIZE(regs->fpr); ++i) {
1299 if (size > i * sizeof(regs->fpr[i])) {
1300 if (i)
1301 fputs(", ", stdout);
1302 PRINT_VAL_X(regs->fpr[i]);
1303 }
1304 }
1305 fputs("]", stdout);
1306 if (size >= offsetofend(TRACEE_REGS_STRUCT, fcc)) {
1307 fputs(", ", stdout);
1308 PRINT_FIELD_X(*regs, fcc);
1309 }
1310 if (size >= offsetofend(TRACEE_REGS_STRUCT, fcsr)) {
1311 fputs(", ", stdout);
1312 PRINT_FIELD_X(*regs, fcsr);
1313 }
1314
1315 # endif /*
1316 __i386__ ||
1317 __loongarch__ ||
1318 __powerpc64__ ||
1319 __powerpc__ ||
1320 __x86_64__
1321 */
1322
1323 if (size > sizeof(*regs))
1324 fputs(", ...", stdout);
1325 fputs("}", stdout);
1326
1327 #else /* !TRACEE_REGS_STRUCT */
1328
1329 printf("%p", rs);
1330
1331 #endif /* TRACEE_REGS_STRUCT */
1332 }
1333
1334 #ifdef PTRACE_GETFPREGS
1335 static void
1336 print_pt_fpregs(const void *const rs, const size_t size)
1337 {
1338 # ifdef TRACEE_REGS_STRUCT
1339
1340 if (size != sizeof(TRACEE_REGS_STRUCT))
1341 error_msg_and_fail("expected size %zu, got size %zu",
1342 sizeof(TRACEE_REGS_STRUCT), size);
1343 print_fpregset(rs, size);
1344
1345 # else /* !TRACEE_REGS_STRUCT */
1346
1347 printf("%p", rs);
1348
1349 # endif
1350 }
1351
1352 static void
1353 do_getfpregs_setfpregs(const int pid,
1354 void *const regbuf,
1355 const unsigned int regsize,
1356 unsigned int *const actual_size)
1357 {
1358 if (do_ptrace_regs(PTRACE_GETFPREGS, pid, (uintptr_t) regbuf)) {
1359 printf("ptrace(" XLAT_FMT ", %d, %p) = %s\n",
1360 XLAT_ARGS(PTRACE_GETFPREGS), pid, regbuf, errstr);
1361 return; /* skip PTRACE_SETFPREGS */
1362 } else {
1363 printf("ptrace(" XLAT_FMT ", %d, ",
1364 XLAT_ARGS(PTRACE_GETFPREGS), pid);
1365 print_pt_fpregs(regbuf, regsize);
1366 printf(") = %s\n", errstr);
1367 if (*actual_size)
1368 return; /* skip PTRACE_SETFPREGS */
1369 else
1370 *actual_size = regsize;
1371 }
1372
1373 do_ptrace_regs(PTRACE_SETFPREGS, pid, (uintptr_t) regbuf);
1374 printf("ptrace(" XLAT_FMT ", %d, ", XLAT_ARGS(PTRACE_SETFPREGS), pid);
1375 print_pt_fpregs(regbuf, regsize);
1376 printf(") = %s\n", errstr);
1377 }
1378 #endif /* PTRACE_GETFPREGS */
1379
1380 static void
1381 do_getregset_setregset(const int pid,
1382 const unsigned int nt,
1383 const char *const nt_str,
1384 void *const regbuf,
1385 const unsigned int regsize,
1386 unsigned int *actual_size,
1387 struct iovec *const iov,
1388 void (*print_regset_fn)(const void *, size_t))
1389 {
1390 iov->iov_base = regbuf;
1391 iov->iov_len = regsize;
1392 do_ptrace(PTRACE_GETREGSET, pid, nt, (uintptr_t) iov);
1393 if (iov->iov_len == regsize) {
1394 printf("ptrace(" XLAT_FMT ", %d, " XLAT_FMT ", {iov_base=",
1395 XLAT_ARGS(PTRACE_GETREGSET), pid, XLAT_SEL(nt, nt_str));
1396 print_regset_fn(iov->iov_base, iov->iov_len);
1397 printf(", iov_len=%lu}) = %s\n",
1398 (unsigned long) iov->iov_len, errstr);
1399 if (*actual_size)
1400 return; /* skip PTRACE_SETREGSET */
1401 } else {
1402 printf("ptrace(" XLAT_FMT ", %d, " XLAT_FMT ", {iov_base=",
1403 XLAT_ARGS(PTRACE_GETREGSET), pid, XLAT_SEL(nt, nt_str));
1404 print_regset_fn(iov->iov_base, iov->iov_len);
1405 printf(", iov_len=%u => %lu}) = %s\n",
1406 regsize, (unsigned long) iov->iov_len, errstr);
1407 if (*actual_size)
1408 error_msg_and_fail("iov_len changed again"
1409 " from %u to %lu", regsize,
1410 (unsigned long) iov->iov_len);
1411 *actual_size = iov->iov_len;
1412 }
1413
1414 #if defined __sparc__ && !defined __arch64__
1415 /*
1416 * On sparc32 PTRACE_SETREGSET NT_PRSTATUS of size greater than 120
1417 * has interesting side effects.
1418 */
1419 if (nt == 1 && regsize > 120)
1420 return;
1421 #endif /* __sparc__ && !__arch64__ */
1422
1423 iov->iov_len = regsize;
1424 do_ptrace(PTRACE_SETREGSET, pid, nt, (uintptr_t) iov);
1425 if (iov->iov_len == regsize) {
1426 printf("ptrace(" XLAT_FMT ", %d, " XLAT_FMT ", {iov_base=",
1427 XLAT_ARGS(PTRACE_SETREGSET), pid, XLAT_SEL(nt, nt_str));
1428 print_regset_fn(iov->iov_base, regsize);
1429 printf(", iov_len=%lu}) = %s\n",
1430 (unsigned long) iov->iov_len, errstr);
1431 } else {
1432 printf("ptrace(" XLAT_FMT ", %d, " XLAT_FMT ", {iov_base=",
1433 XLAT_ARGS(PTRACE_SETREGSET), pid, XLAT_SEL(nt, nt_str));
1434 print_regset_fn(iov->iov_base, regsize);
1435 printf(", iov_len=%u => %lu}) = %s\n",
1436 regsize, (unsigned long) iov->iov_len, errstr);
1437 }
1438 }
1439
1440 static void
1441 test_getregset_setregset(int pid)
1442 {
1443 TAIL_ALLOC_OBJECT_CONST_PTR(struct iovec, iov);
1444 unsigned long addr = (uintptr_t) (iov + 1);
1445
1446 iov->iov_base = (void *) addr;
1447 iov->iov_len = sizeof(kernel_ulong_t);
1448
1449 do_ptrace(PTRACE_GETREGSET, pid, 1, (uintptr_t) iov);
1450 printf("ptrace(" XLAT_FMT ", %d, " XLAT_KNOWN(0x1, "NT_PRSTATUS")
1451 ", {iov_base=%p, iov_len=%lu}) = %s\n",
1452 XLAT_ARGS(PTRACE_GETREGSET), pid,
1453 iov->iov_base, (unsigned long) iov->iov_len, errstr);
1454
1455 do_ptrace(PTRACE_SETREGSET, pid, 3, (uintptr_t) iov);
1456 printf("ptrace(" XLAT_FMT ", %d, " XLAT_KNOWN(0x3, "NT_PRPSINFO")
1457 ", {iov_base=%p, iov_len=%lu}) = %s\n",
1458 XLAT_ARGS(PTRACE_SETREGSET), pid,
1459 iov->iov_base, (unsigned long) iov->iov_len, errstr);
1460
1461 #ifdef PTRACE_GETREGS
1462 do_ptrace_regs(PTRACE_GETREGS, pid, addr);
1463 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1464 XLAT_ARGS(PTRACE_GETREGS), pid, addr, errstr);
1465 #endif
1466 #ifdef PTRACE_SETREGS
1467 do_ptrace_regs(PTRACE_SETREGS, pid, addr);
1468 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1469 XLAT_ARGS(PTRACE_SETREGS), pid, addr, errstr);
1470 #endif
1471 #ifdef PTRACE_GETFPREGS
1472 do_ptrace_regs(PTRACE_GETFPREGS, pid, addr);
1473 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1474 XLAT_ARGS(PTRACE_GETFPREGS), pid, addr, errstr);
1475 #endif
1476 #ifdef PTRACE_SETFPREGS
1477 do_ptrace_regs(PTRACE_SETFPREGS, pid, addr);
1478 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1479 XLAT_ARGS(PTRACE_SETFPREGS), pid, addr, errstr);
1480 #endif
1481
1482 for (; addr > (uintptr_t) iov; --addr) {
1483 do_ptrace(PTRACE_GETREGSET, pid, 1, addr);
1484 printf("ptrace(" XLAT_FMT ", %d, "
1485 XLAT_KNOWN(0x1, "NT_PRSTATUS") ", %#lx) = %s\n",
1486 XLAT_ARGS(PTRACE_GETREGSET), pid, addr, errstr);
1487
1488 do_ptrace(PTRACE_SETREGSET, pid, 2, addr);
1489 printf("ptrace(" XLAT_FMT ", %d, "
1490 XLAT_KNOWN(0x2, "NT_FPREGSET") ", %#lx) = %s\n",
1491 XLAT_ARGS(PTRACE_SETREGSET), pid, addr, errstr);
1492 }
1493
1494 pid = fork();
1495 if (pid < 0)
1496 perror_msg_and_fail("fork");
1497
1498 if (!pid) {
1499 if (do_ptrace(PTRACE_TRACEME, 0, 0, 0))
1500 perror_msg_and_fail("child: PTRACE_TRACEME");
1501
1502 raise(SIGSTOP);
1503 if (chdir("")) {
1504 ;
1505 }
1506 _exit(0);
1507 }
1508
1509 const unsigned int regset_buf_size = 4096 - 64;
1510 char *const regset_buf_endptr = midtail_alloc(0, regset_buf_size);
1511
1512 for (;;) {
1513 int status, tracee, saved;
1514
1515 errno = 0;
1516 tracee = wait(&status);
1517 if (tracee <= 0) {
1518 if (errno == EINTR)
1519 continue;
1520 saved = errno;
1521 kill(pid, SIGKILL);
1522 errno = saved;
1523 perror_msg_and_fail("wait");
1524 }
1525 if (WIFEXITED(status)) {
1526 if (WEXITSTATUS(status) == 0)
1527 break;
1528 error_msg_and_fail("unexpected exit status %#x",
1529 WEXITSTATUS(status));
1530 }
1531 if (WIFSIGNALED(status))
1532 error_msg_and_fail("unexpected signal %u",
1533 WTERMSIG(status));
1534 if (!WIFSTOPPED(status)) {
1535 kill(pid, SIGKILL);
1536 error_msg_and_fail("unexpected wait status %#x",
1537 status);
1538 }
1539
1540 static unsigned int actual_prstatus_size;
1541 for (unsigned int i = actual_prstatus_size;
1542 i <= regset_buf_size &&
1543 (!actual_prstatus_size ||
1544 actual_prstatus_size + 1 >= i);
1545 ++i) {
1546 do_getregset_setregset(pid, 1, "NT_PRSTATUS",
1547 regset_buf_endptr - i, i,
1548 &actual_prstatus_size,
1549 iov, print_prstatus_regset);
1550 }
1551 /*
1552 * In an unlikely case NT_PRSTATUS is not supported,
1553 * use regset_buf_size.
1554 */
1555 if (!actual_prstatus_size)
1556 actual_prstatus_size = regset_buf_size;
1557
1558 static unsigned int actual_fpregset_size;
1559 for (unsigned int i = actual_fpregset_size;
1560 i <= regset_buf_size &&
1561 (!actual_fpregset_size ||
1562 actual_fpregset_size + 1 >= i);
1563 ++i) {
1564 do_getregset_setregset(pid, 2, "NT_FPREGSET",
1565 regset_buf_endptr - i, i,
1566 &actual_fpregset_size,
1567 iov, print_fpregset);
1568 }
1569 /*
1570 * In an unlikely case NT_FPREGSET is not supported,
1571 * use regset_buf_size.
1572 */
1573 if (!actual_fpregset_size)
1574 actual_fpregset_size = regset_buf_size;
1575
1576 #ifdef PTRACE_GETREGS
1577 static unsigned int actual_pt_regs_size
1578 # ifdef __mips__
1579 /*
1580 * For some reason MIPS kernels do not report
1581 * PTRACE_GETREGS EFAULT errors.
1582 */
1583 = 38 * 8
1584 # endif
1585 ;
1586 for (unsigned int i = actual_pt_regs_size;
1587 i <= (actual_pt_regs_size ?: regset_buf_size);
1588 ++i) {
1589 do_getregs_setregs(pid, regset_buf_endptr - i, i,
1590 &actual_pt_regs_size);
1591 }
1592 /*
1593 * In an unlikely case PTRACE_GETREGS is not supported,
1594 * use regset_buf_size.
1595 */
1596 if (!actual_pt_regs_size)
1597 actual_pt_regs_size = regset_buf_size;
1598 #endif
1599
1600 #ifdef PTRACE_GETREGS64
1601 static unsigned int actual_pt_regs64_size;
1602 for (unsigned int i = actual_pt_regs64_size;
1603 i <= (actual_pt_regs64_size ?: regset_buf_size);
1604 ++i) {
1605 do_getregs64_setregs64(pid, regset_buf_endptr - i, i,
1606 &actual_pt_regs64_size);
1607 }
1608 /*
1609 * In an unlikely case PTRACE_GETREGS64 is not supported,
1610 * use regset_buf_size.
1611 */
1612 if (!actual_pt_regs64_size)
1613 actual_pt_regs64_size = regset_buf_size;
1614 #endif
1615
1616 #ifdef PTRACE_GETFPREGS
1617 static unsigned int actual_pt_fpregs_size
1618 # ifdef __mips__
1619 /*
1620 * For some reason MIPS kernels do not report
1621 * PTRACE_GETFPREGS EFAULT errors.
1622 */
1623 = 33 * 8
1624 # endif
1625 ;
1626 for (unsigned int i = actual_pt_fpregs_size;
1627 i <= (actual_pt_fpregs_size ?: regset_buf_size);
1628 ++i) {
1629 do_getfpregs_setfpregs(pid, regset_buf_endptr - i, i,
1630 &actual_pt_fpregs_size);
1631 }
1632 /*
1633 * In an unlikely case PTRACE_GETFPREGS is not supported,
1634 * use regset_buf_size.
1635 */
1636 if (!actual_pt_fpregs_size)
1637 actual_pt_fpregs_size = regset_buf_size;
1638 #endif
1639
1640 if (WSTOPSIG(status) == SIGSTOP)
1641 kill(pid, SIGCONT);
1642
1643 if (do_ptrace(PTRACE_SYSCALL, pid, 0, 0)) {
1644 saved = errno;
1645 kill(pid, SIGKILL);
1646 errno = saved;
1647 perror_msg_and_fail("ptrace");
1648 }
1649 printf("ptrace(" XLAT_FMT ", %d, NULL, 0) = 0\n",
1650 XLAT_ARGS(PTRACE_SYSCALL), pid);
1651 }
1652 }
1653
1654 #if defined __arm64__ || defined __aarch64__
1655 static void
1656 check_compat_ptrace_req(const unsigned int req, const char *const s,
1657 const int pid)
1658 {
1659 do_ptrace(req, pid, 0, 0);
1660 printf("ptrace(%#x" NRAW(" /* ") "%s" NRAW(" */")
1661 ", %d, NULL, NULL) = %s\n",
1662 req, XLAT_RAW ? "" : s, pid, errstr);
1663
1664 do_ptrace(req, pid, 0xbadc0deddeadface, 0xfacefeeddecaffed);
1665 printf("ptrace(%#x" NRAW(" /* ") "%s" NRAW(" */")
1666 ", %d, 0xbadc0deddeadface, 0xfacefeeddecaffed) = %s\n",
1667 req, XLAT_RAW ? "" : s, pid, errstr);
1668 }
1669
1670 static void
1671 test_compat_ptrace(const int pid)
1672 {
1673 check_compat_ptrace_req(12, "COMPAT_PTRACE_GETREGS", pid);
1674 check_compat_ptrace_req(13, "COMPAT_PTRACE_SETREGS", pid);
1675 check_compat_ptrace_req(14, "COMPAT_PTRACE_GETFPREGS", pid);
1676 check_compat_ptrace_req(15, "COMPAT_PTRACE_SETFPREGS", pid);
1677 check_compat_ptrace_req(22, "COMPAT_PTRACE_GET_THREAD_AREA", pid);
1678 check_compat_ptrace_req(23, "COMPAT_PTRACE_SET_SYSCALL", pid);
1679 check_compat_ptrace_req(27, "COMPAT_PTRACE_GETVFPREGS", pid);
1680 check_compat_ptrace_req(28, "COMPAT_PTRACE_SETVFPREGS", pid);
1681 check_compat_ptrace_req(29, "COMPAT_PTRACE_GETHBPREGS", pid);
1682 check_compat_ptrace_req(30, "COMPAT_PTRACE_SETHBPREGS", pid);
1683 }
1684 #else /* !(__arm64__ || __aarch64__) */
1685 static void test_compat_ptrace(const int pid) {}
1686 #endif
1687
1688 int
1689 main(void)
1690 {
1691 const unsigned long bad_request =
1692 (unsigned long) 0xdeadbeeffffffeedULL;
1693 const unsigned long bad_data =
1694 (unsigned long) 0xdeadcafefffff00dULL;
1695 const int pid = getpid();
1696
1697 int null_fd = open(null_path, O_RDONLY);
1698 if (null_fd < 0)
1699 perror_msg_and_fail("open(\"%s\")", null_path);
1700 if (null_fd != NULL_FD) {
1701 if (dup2(null_fd, NULL_FD) < 0)
1702 perror_msg_and_fail("dup2(%d, NULL_FD)", null_fd);
1703 close(null_fd);
1704 }
1705
1706 TAIL_ALLOC_OBJECT_CONST_PTR(uint64_t, filter_off);
1707
1708 const unsigned int sigset_size = get_sigset_size();
1709
1710 void *const k_set = tail_alloc(sigset_size);
1711 TAIL_ALLOC_OBJECT_CONST_PTR(siginfo_t, sip);
1712
1713 do_ptrace(bad_request, pid, 0, 0);
1714 printf("ptrace(%#lx" NRAW(" /* PTRACE_??? */")
1715 ", %d, NULL, NULL) = %s\n",
1716 bad_request, pid, errstr);
1717
1718 do_ptrace(PTRACE_PEEKDATA, pid, bad_request, bad_data);
1719 #ifdef IA64
1720 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1721 XLAT_ARGS(PTRACE_PEEKDATA), pid, bad_request, errstr);
1722 #else
1723 printf("ptrace(" XLAT_FMT ", %d, %#lx, %#lx) = %s\n",
1724 XLAT_ARGS(PTRACE_PEEKDATA), pid, bad_request, bad_data, errstr);
1725 #endif
1726
1727 do_ptrace(PTRACE_PEEKTEXT, pid, bad_request, bad_data);
1728 #ifdef IA64
1729 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1730 XLAT_ARGS(PTRACE_PEEKTEXT), pid, bad_request, errstr);
1731 #else
1732 printf("ptrace(" XLAT_FMT ", %d, %#lx, %#lx) = %s\n",
1733 XLAT_ARGS(PTRACE_PEEKTEXT), pid, bad_request, bad_data, errstr);
1734 #endif
1735
1736 do_ptrace(PTRACE_PEEKUSER, pid, bad_request, bad_data);
1737 #ifdef IA64
1738 printf("ptrace(" XLAT_FMT ", %d, %#lx) = %s\n",
1739 XLAT_ARGS(PTRACE_PEEKUSER), pid, bad_request, errstr);
1740 #else
1741 printf("ptrace(" XLAT_FMT ", %d, %#lx, %#lx) = %s\n",
1742 XLAT_ARGS(PTRACE_PEEKUSER), pid, bad_request, bad_data, errstr);
1743 #endif
1744
1745 do_ptrace(PTRACE_POKEUSER, pid, bad_request, bad_data);
1746 printf("ptrace(" XLAT_FMT ", %d, %#lx, %#lx) = %s\n",
1747 XLAT_ARGS(PTRACE_POKEUSER), pid, bad_request, bad_data, errstr);
1748
1749 do_ptrace(PTRACE_ATTACH, pid, 0, 0);
1750 printf("ptrace(" XLAT_FMT ", %d) = %s\n",
1751 XLAT_ARGS(PTRACE_ATTACH), pid, errstr);
1752
1753 do_ptrace(PTRACE_INTERRUPT, pid, 0, 0);
1754 printf("ptrace(" XLAT_FMT ", %d) = %s\n",
1755 XLAT_ARGS(PTRACE_INTERRUPT), pid, errstr);
1756
1757 do_ptrace(PTRACE_KILL, pid, 0, 0);
1758 printf("ptrace(" XLAT_FMT ", %d) = %s\n",
1759 XLAT_ARGS(PTRACE_KILL), pid, errstr);
1760
1761 do_ptrace(PTRACE_LISTEN, pid, 0, 0);
1762 printf("ptrace(" XLAT_FMT ", %d) = %s\n",
1763 XLAT_ARGS(PTRACE_LISTEN), pid, errstr);
1764
1765 sigset_t libc_set;
1766 sigemptyset(&libc_set);
1767 sigaddset(&libc_set, SIGUSR1);
1768 memcpy(k_set, &libc_set, sigset_size);
1769
1770 do_ptrace(PTRACE_SETSIGMASK, pid, sigset_size, (uintptr_t) k_set);
1771 printf("ptrace(" XLAT_FMT ", %d, %u, [" XLAT_FMT_U "]) = %s\n",
1772 XLAT_ARGS(PTRACE_SETSIGMASK), pid, sigset_size,
1773 XLAT_SEL(SIGUSR1, "USR1"), errstr);
1774
1775 do_ptrace(PTRACE_GETSIGMASK, pid, sigset_size, (uintptr_t) k_set);
1776 printf("ptrace(" XLAT_FMT ", %d, %u, %p) = %s\n",
1777 XLAT_ARGS(PTRACE_GETSIGMASK), pid, sigset_size, k_set, errstr);
1778
1779 do_ptrace(PTRACE_SECCOMP_GET_FILTER, pid, 42, 0);
1780 printf("ptrace(" XLAT_FMT ", %d, 42, NULL) = %s\n",
1781 XLAT_ARGS(PTRACE_SECCOMP_GET_FILTER), pid, errstr);
1782
1783 do_ptrace(PTRACE_SECCOMP_GET_METADATA, pid, bad_data, 0);
1784 printf("ptrace(" XLAT_FMT ", %d, %lu, NULL) = %s\n",
1785 XLAT_ARGS(PTRACE_SECCOMP_GET_METADATA), pid, bad_data, errstr);
1786
1787 do_ptrace(PTRACE_SECCOMP_GET_METADATA, pid, 7,
1788 (uintptr_t) filter_off);
1789 printf("ptrace(" XLAT_FMT ", %d, 7, %p) = %s\n",
1790 XLAT_ARGS(PTRACE_SECCOMP_GET_METADATA), pid, filter_off, errstr);
1791
1792 *filter_off = 0xfacefeeddeadc0deULL;
1793 do_ptrace(PTRACE_SECCOMP_GET_METADATA, pid, bad_data,
1794 (uintptr_t) filter_off);
1795 printf("ptrace(" XLAT_FMT ", %d, %lu, {filter_off=%" PRIu64 "}) = %s\n",
1796 XLAT_ARGS(PTRACE_SECCOMP_GET_METADATA),
1797 pid, bad_data, *filter_off, errstr);
1798
1799 do_ptrace(PTRACE_GETEVENTMSG, pid, bad_request, bad_data);
1800 printf("ptrace(" XLAT_FMT ", %d, %#lx, %#lx) = %s\n",
1801 XLAT_ARGS(PTRACE_GETEVENTMSG),
1802 pid, bad_request, bad_data, errstr);
1803
1804 /* SIGIO */
1805 memset(sip, -1, sizeof(*sip));
1806 sip->si_signo = SIGIO;
1807 sip->si_code = 1;
1808 sip->si_errno = ENOENT;
1809 sip->si_band = -2;
1810 sip->si_fd = NULL_FD;
1811
1812 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
1813 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
1814 ", si_code=" XLAT_FMT ", si_errno=" XLAT_FMT_U ", si_band=-2"
1815 ", si_fd=%d%s}) = %s\n",
1816 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request, XLAT_ARGS(SIGIO),
1817 XLAT_ARGS(POLL_IN), XLAT_ARGS(ENOENT), NULL_FD, NULL_FD_STR,
1818 errstr);
1819
1820 /* SIGTRAP */
1821 struct valstraux trap_codes[] = {
1822 { ARG_XLAT_KNOWN(0x1, "TRAP_BRKPT") },
1823 #ifdef TRAP_TRACEFLOW
1824 { ARG_XLAT_KNOWN(0x2, "TRAP_TRACEFLOW") },
1825 #else
1826 { ARG_XLAT_KNOWN(0x2, "TRAP_TRACE") },
1827 #endif
1828 #ifdef TRAP_WATCHPT
1829 { ARG_XLAT_KNOWN(0x3, "TRAP_WATCHPT") },
1830 #else
1831 { ARG_XLAT_KNOWN(0x3, "TRAP_BRANCH") },
1832 #endif
1833 #ifdef TRAP_ILLTRAP
1834 { ARG_XLAT_KNOWN(0x4, "TRAP_ILLTRAP") },
1835 #else
1836 { ARG_XLAT_KNOWN(0x4, "TRAP_HWBKPT") },
1837 #endif
1838 { ARG_XLAT_KNOWN(0x5, "TRAP_UNK"), ""
1839 #if defined __alpha__ && defined HAVE_SIGINFO_T_SI_TRAPNO
1840 ", si_trapno=0 /* GEN_??? */"
1841 },
1842 { ARG_XLAT_KNOWN(0x5, "TRAP_UNK"),
1843 ", si_trapno=" XLAT_KNOWN(-1, "GEN_INTOVF" },
1844 { ARG_XLAT_KNOWN(0x5, "TRAP_UNK"),
1845 ", si_trapno=" XLAT_KNOWN(-25, "GEN_SUBRNG7" },
1846 { ARG_XLAT_KNOWN(0x5, "TRAP_UNK"), ""
1847 ", si_trapno=-26 /* GEN_??? */" },
1848 { ARG_XLAT_KNOWN(0x5, "TRAP_UNK"), ""
1849 ", si_trapno=-1234567890 /* GEN_??? */"
1850 #endif /* __alpha__ && HAVE_SIGINFO_T_SI_TRAPNO */
1851 },
1852 { ARG_XLAT_KNOWN(0x6, "TRAP_PERF"), ""
1853 #ifdef HAVE_SIGINFO_T_SI_PERF_DATA
1854 ", si_perf_data=0"
1855 # ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
1856 ", si_perf_type=" XLAT_KNOWN(0, "PERF_TYPE_HARDWARE")
1857 # endif
1858 # ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
1859 ", si_perf_flags=0"
1860 # endif
1861 },
1862 { ARG_XLAT_KNOWN(0x6, "TRAP_PERF"), ""
1863 ", si_perf_data=0x1"
1864 # ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
1865 ", si_perf_type=" XLAT_KNOWN(0x1, "PERF_TYPE_SOFTWARE")
1866 # endif
1867 # ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
1868 ", si_perf_flags=" XLAT_KNOWN(0x1, "TRAP_PERF_FLAG_ASYNC")
1869 # endif
1870 },
1871 { ARG_XLAT_KNOWN(0x6, "TRAP_PERF"), ""
1872 ", si_perf_data=0x" UP64BIT("12345678") "90abcdef"
1873 # ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
1874 ", si_perf_type=" XLAT_KNOWN(0x5, "PERF_TYPE_BREAKPOINT")
1875 # endif
1876 # ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
1877 ", si_perf_flags="
1878 XLAT_KNOWN(0xdeadbeef, "TRAP_PERF_FLAG_ASYNC|0xdeadbeee")
1879 # endif
1880 },
1881 { ARG_XLAT_KNOWN(0x6, "TRAP_PERF"), ""
1882 ", si_perf_data=0x" UP64BIT("badc0ded") "deadface"
1883 # ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
1884 ", si_perf_type=" XLAT_UNKNOWN(0x6, "PERF_TYPE_???")
1885 # endif
1886 # ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
1887 ", si_perf_flags="
1888 XLAT_UNKNOWN(0xcafec0de, "TRAP_PERF_FLAG_???")
1889 # endif
1890 #endif /* HAVE_SIGINFO_T_SI_PERF_DATA */
1891 },
1892 { ARG_STR(0x7) },
1893 { ARG_STR(0x499602d2) },
1894 };
1895 int trap_unk_vecs[] = { 0, 1234567890, -1234567890 };
1896 struct {
1897 unsigned long data;
1898 uint32_t type;
1899 uint32_t flags;
1900 } trap_perf_vecs[] = {
1901 { 0, 0, 0 },
1902 { 1, 1, 1 },
1903 { (unsigned long) 0x1234567890abcdefULL, 5, 0xdeadbeef },
1904 { (unsigned long) 0xbadc0deddeadfaceULL, 6, 0xcafec0de },
1905 };
1906 size_t trap_unk_pos = 0;
1907 size_t trap_perf_pos = 0;
1908
1909 memset(sip, -1, sizeof(*sip));
1910 sip->si_signo = SIGTRAP;
1911 sip->si_code = 1;
1912 sip->si_errno = ENOENT;
1913 sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
1914
1915 for (size_t i = 0; i < ARRAY_SIZE(trap_codes); i++) {
1916 sip->si_code = trap_codes[i].val;
1917
1918 switch (sip->si_code) {
1919 case 5: /* TRAP_UNK */
1920 #if defined __alpha__ && defined HAVE_SIGINFO_T_SI_TRAPNO
1921 sip->si_trapno = trap_unk_vecs[trap_unk_pos];
1922 #endif
1923 trap_unk_pos = (trap_unk_pos + 1)
1924 % ARRAY_SIZE(trap_unk_vecs);
1925 break;
1926 case 6: /* TRAP_PERF */
1927 #ifdef HAVE_SIGINFO_T_SI_PERF_DATA
1928 sip->si_perf_data = trap_perf_vecs[trap_perf_pos].data;
1929 #endif
1930 #ifdef HAVE_SIGINFO_T_SI_PERF_TYPE
1931 sip->si_perf_type = trap_perf_vecs[trap_perf_pos].type;
1932 #endif
1933 #ifdef HAVE_SIGINFO_T_SI_PERF_FLAGS
1934 sip->si_perf_flags = trap_perf_vecs[trap_perf_pos].flags;
1935 #endif
1936 trap_perf_pos = (trap_perf_pos + 1)
1937 % ARRAY_SIZE(trap_perf_vecs);
1938 break;
1939 };
1940
1941 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
1942 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
1943 ", si_code=%s, si_errno=" XLAT_FMT_U ", si_addr=%p%s}"
1944 ") = %s\n",
1945 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
1946 XLAT_ARGS(SIGTRAP), trap_codes[i].str, XLAT_ARGS(ENOENT),
1947 sip->si_addr, trap_codes[i].aux ?: "", errstr);
1948 }
1949
1950 /* SIGILL */
1951 memset(sip, -1, sizeof(*sip));
1952 sip->si_signo = SIGILL;
1953 sip->si_code = 1;
1954 sip->si_errno = ENOENT;
1955 sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
1956 #ifdef si_trapno
1957 sip->si_trapno = -12;
1958 #endif
1959
1960 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
1961 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
1962 ", si_code=" XLAT_FMT ", si_errno=" XLAT_FMT_U ", si_addr=%p"
1963 #ifdef __sparc__
1964 ", si_trapno=-12"
1965 #endif
1966 "}) = %s\n",
1967 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
1968 XLAT_ARGS(SIGILL), XLAT_ARGS(ILL_ILLOPC), XLAT_ARGS(ENOENT),
1969 sip->si_addr, errstr);
1970
1971 /* SIGFPE */
1972 memset(sip, -1, sizeof(*sip));
1973 sip->si_signo = SIGFPE;
1974 sip->si_code = 1;
1975 sip->si_errno = ENOENT;
1976 sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
1977 #ifdef si_trapno
1978 sip->si_trapno = -7;
1979 #endif
1980
1981 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
1982 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
1983 ", si_code=" XLAT_FMT ", si_errno=" XLAT_FMT_U ", si_addr=%p"
1984 #if defined __alpha__ && defined HAVE_SIGINFO_T_SI_TRAPNO
1985 ", si_trapno=" XLAT_KNOWN(-7, "GEN_FLTINE")
1986 #endif
1987 "}) = %s\n",
1988 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
1989 XLAT_ARGS(SIGFPE), XLAT_ARGS(FPE_INTDIV), XLAT_ARGS(ENOENT),
1990 sip->si_addr, errstr);
1991
1992 /* SIGBUS */
1993 struct valstraux bus_codes[] = {
1994 { ARG_XLAT_KNOWN(0x1, "BUS_ADRALN") },
1995 { ARG_XLAT_KNOWN(0x2, "BUS_ADRERR") },
1996 { ARG_XLAT_KNOWN(0x3, "BUS_OBJERR") },
1997 #ifdef BUS_OPFETCH
1998 { ARG_XLAT_KNOWN(0x4, "BUS_OPFETCH") },
1999 #else
2000 { ARG_XLAT_KNOWN(0x4, "BUS_MCEERR_AR"),
2001 # ifdef HAVE_SIGINFO_T_SI_ADDR_LSB
2002 ", si_addr_lsb=0xdead"
2003 # endif
2004 },
2005 #endif
2006 { ARG_XLAT_KNOWN(0x5, "BUS_MCEERR_AO"),
2007 #if !defined(BUS_OPFETCH) && defined(HAVE_SIGINFO_T_SI_ADDR_LSB)
2008 ", si_addr_lsb=0xdead"
2009 #endif
2010 },
2011 { ARG_STR(0x6) },
2012 { ARG_STR(0x499602d2) },
2013 };
2014
2015 memset(sip, -1, sizeof(*sip));
2016 sip->si_signo = SIGBUS;
2017 sip->si_code = 1;
2018 sip->si_errno = -2;
2019 sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
2020 #ifdef HAVE_SIGINFO_T_SI_ADDR_LSB
2021 sip->si_addr_lsb = 0xdead;
2022 #endif
2023 for (size_t i = 0; i < ARRAY_SIZE(bus_codes); i++) {
2024 sip->si_code = bus_codes[i].val;
2025
2026 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2027 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2028 ", si_code=%s, si_errno=%u, si_addr=%p%s}) = %s\n",
2029 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2030 XLAT_ARGS(SIGBUS), bus_codes[i].str,
2031 sip->si_errno, sip->si_addr, bus_codes[i].aux ?: "",
2032 errstr);
2033 }
2034
2035 /* SIGPROF */
2036 memset(sip, -1, sizeof(*sip));
2037 sip->si_signo = SIGPROF;
2038 sip->si_code = 0xbadc0ded;
2039 sip->si_errno = -2;
2040 sip->si_pid = 0;
2041 sip->si_uid = 3;
2042 sip->si_ptr = 0;
2043
2044 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2045 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2046 ", si_code=%#x, si_errno=%u, si_pid=0, si_uid=3}) = %s\n",
2047 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2048 XLAT_ARGS(SIGPROF), sip->si_code, sip->si_errno, errstr);
2049
2050 /* SIGSEGV */
2051 struct valstraux segv_codes[] = {
2052 { ARG_XLAT_KNOWN(0x1, "SEGV_MAPERR") },
2053 { ARG_XLAT_KNOWN(0x2, "SEGV_ACCERR") },
2054 #ifdef SEGV_STACKFLOW
2055 { ARG_XLAT_KNOWN(0x3, "SEGV_STACKFLOW") },
2056 #else
2057 { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"), ""
2058 # ifdef HAVE_SIGINFO_T_SI_LOWER
2059 ", si_lower=NULL, si_upper=NULL"
2060 },
2061 { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"),
2062 ", si_lower=NULL"
2063 ", si_upper=0x" UP64BIT("deadc0de") "beadfeed" },
2064 { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"),
2065 ", si_lower=0x" UP64BIT("facecafe") "befeeded"
2066 ", si_upper=NULL" },
2067 { ARG_XLAT_KNOWN(0x3, "SEGV_BNDERR"),
2068 ", si_lower=0x" UP64BIT("beefface") "cafedead"
2069 ", si_upper=0x" UP64BIT("badc0ded") "dadfaced",
2070 # endif /* HAVE_SIGINFO_T_SI_LOWER */
2071 },
2072 #endif /* SEGV_STACKFLOW */
2073 #ifdef __SEGV_PSTKOVF
2074 { ARG_XLAT_KNOWN(0x4, "__SEGV_PSTKOVF") },
2075 #else
2076 { ARG_XLAT_KNOWN(0x4, "SEGV_PKUERR"), ""
2077 # ifdef HAVE_SIGINFO_T_SI_PKEY
2078 ", si_pkey=0"
2079 },
2080 { ARG_XLAT_KNOWN(0x4, "SEGV_PKUERR"), ", si_pkey=1234567890" },
2081 { ARG_XLAT_KNOWN(0x4, "SEGV_PKUERR"), ", si_pkey=3141592653"
2082 # endif /* HAVE_SIGINFO_T_SI_PKEY */
2083 },
2084 #endif /* __SEGV_PSTKOVF */
2085 { ARG_XLAT_KNOWN(0x5, "SEGV_ACCADI") },
2086 { ARG_XLAT_KNOWN(0x6, "SEGV_ADIDERR") },
2087 { ARG_XLAT_KNOWN(0x7, "SEGV_ADIPERR") },
2088 { ARG_XLAT_KNOWN(0x8, "SEGV_MTEAERR") },
2089 { ARG_XLAT_KNOWN(0x9, "SEGV_MTESERR") },
2090 { ARG_STR(0xa) },
2091 { ARG_STR(0x499602d2) },
2092 };
2093 uint32_t segv_pkey_vecs[] = { 0, 1234567890, 3141592653U };
2094 struct {
2095 void *lower;
2096 void *upper;
2097 } segv_bnd_vecs[] = {
2098 { 0, 0 },
2099 { 0, (void *) (uintptr_t) 0xdeadc0debeadfeedULL },
2100 { (void *) (uintptr_t) 0xfacecafebefeededULL, 0 },
2101 { (void *) (uintptr_t) 0xbeeffacecafedeadULL,
2102 (void *) (uintptr_t) 0xbadc0deddadfacedULL },
2103 };
2104 size_t segv_pkey_pos = 0;
2105 size_t segv_bnd_pos = 0;
2106
2107 memset(sip, -1, sizeof(*sip));
2108 sip->si_signo = SIGSEGV;
2109 sip->si_errno = 0;
2110 sip->si_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
2111
2112 for (size_t i = 0; i < ARRAY_SIZE(segv_codes); i++) {
2113 sip->si_code = segv_codes[i].val;
2114
2115 switch (sip->si_code) {
2116 case 3: /* SEGV_BNDERR */
2117 #ifdef HAVE_SIGINFO_T_SI_LOWER
2118 sip->si_lower = segv_bnd_vecs[segv_bnd_pos].lower;
2119 sip->si_upper = segv_bnd_vecs[segv_bnd_pos].upper;
2120 #endif
2121 segv_bnd_pos = (segv_bnd_pos + 1)
2122 % ARRAY_SIZE(segv_bnd_vecs);
2123 break;
2124 case 4: /* SEGV_PKUERR */
2125 #ifdef HAVE_SIGINFO_T_SI_PKEY
2126 sip->si_pkey = segv_pkey_vecs[segv_pkey_pos];
2127 #endif
2128 segv_pkey_pos = (segv_pkey_pos + 1)
2129 % ARRAY_SIZE(segv_pkey_vecs);
2130 break;
2131 };
2132
2133 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2134 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2135 ", si_code=%s, si_addr=%p%s}) = %s\n",
2136 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2137 XLAT_ARGS(SIGSEGV), segv_codes[i].str,
2138 sip->si_addr, segv_codes[i].aux ?: "", errstr);
2139 }
2140
2141 /* SIGSYS */
2142 #ifdef HAVE_SIGINFO_T_SI_SYSCALL
2143 memset(sip, -1, sizeof(*sip));
2144 sip->si_signo = SIGSYS;
2145 sip->si_code = 1;
2146 sip->si_errno = ENOENT;
2147 sip->si_call_addr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
2148 sip->si_syscall = -1U;
2149 sip->si_arch = AUDIT_ARCH_X86_64;
2150
2151 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2152 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2153 ", si_code=" XLAT_KNOWN(0x1, "SYS_SECCOMP") ", si_errno="
2154 XLAT_FMT_U ", si_call_addr=%p, si_syscall=%u, si_arch=" XLAT_FMT
2155 "}) = %s\n",
2156 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2157 XLAT_ARGS(SIGSYS), XLAT_ARGS(ENOENT), sip->si_call_addr,
2158 sip->si_syscall, XLAT_ARGS(AUDIT_ARCH_X86_64), errstr);
2159
2160 sip->si_errno = 3141592653U;
2161 sip->si_call_addr = NULL;
2162 sip->si_syscall = __NR_read;
2163 sip->si_arch = 0xda7a1057;
2164
2165 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2166 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2167 ", si_code=" XLAT_KNOWN(0x1, "SYS_SECCOMP") ", si_errno=%u"
2168 ", si_call_addr=NULL, si_syscall=%u, si_arch=%#x"
2169 NRAW(" /* AUDIT_ARCH_??? */") "}) = %s\n",
2170 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2171 XLAT_ARGS(SIGSYS), sip->si_errno, sip->si_syscall, sip->si_arch,
2172 errstr);
2173
2174 # ifdef CUR_AUDIT_ARCH
2175 sip->si_arch = CUR_AUDIT_ARCH;
2176
2177 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2178 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2179 ", si_code=" XLAT_KNOWN(0x1, "SYS_SECCOMP") ", si_errno=%u"
2180 ", si_call_addr=NULL, si_syscall=" XLAT_FMT_U ", si_arch=%s}"
2181 ") = %s\n",
2182 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2183 XLAT_ARGS(SIGSYS), sip->si_errno, XLAT_ARGS(__NR_read),
2184 sprintxval(audit_arch, CUR_AUDIT_ARCH, "AUDIT_ARCH_???"),
2185 errstr);
2186 # endif
2187 # if defined(PERS0_AUDIT_ARCH)
2188 sip->si_arch = PERS0_AUDIT_ARCH;
2189 sip->si_syscall = PERS0__NR_gettid;
2190
2191 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2192 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2193 ", si_code=" XLAT_KNOWN(0x1, "SYS_SECCOMP") ", si_errno=%u"
2194 ", si_call_addr=NULL, si_syscall=%u" NRAW(" /* gettid */")
2195 ", si_arch=%s}) = %s\n",
2196 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2197 XLAT_ARGS(SIGSYS), sip->si_errno, PERS0__NR_gettid,
2198 sprintxval(audit_arch, PERS0_AUDIT_ARCH, "AUDIT_ARCH_???"),
2199 errstr);
2200 # endif
2201 # if defined(M32_AUDIT_ARCH)
2202 sip->si_arch = M32_AUDIT_ARCH;
2203 sip->si_syscall = M32__NR_gettid;
2204
2205 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2206 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2207 ", si_code=" XLAT_KNOWN(0x1, "SYS_SECCOMP") ", si_errno=%u"
2208 ", si_call_addr=NULL, si_syscall=%u" NRAW(" /* gettid */")
2209 ", si_arch=%s}) = %s\n",
2210 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2211 XLAT_ARGS(SIGSYS), sip->si_errno, M32__NR_gettid,
2212 sprintxval(audit_arch, M32_AUDIT_ARCH, "AUDIT_ARCH_???"),
2213 errstr);
2214 # endif
2215 # if defined(MX32_AUDIT_ARCH)
2216 sip->si_arch = MX32_AUDIT_ARCH;
2217 sip->si_syscall = MX32__NR_gettid;
2218
2219 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2220 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2221 ", si_code=" XLAT_KNOWN(0x1, "SYS_SECCOMP") ", si_errno=%u"
2222 ", si_call_addr=NULL, si_syscall=%u" NRAW(" /* gettid */")
2223 ", si_arch=%s}) = %s\n",
2224 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2225 XLAT_ARGS(SIGSYS), sip->si_errno, MX32__NR_gettid,
2226 sprintxval(audit_arch, MX32_AUDIT_ARCH, "AUDIT_ARCH_???"),
2227 errstr);
2228 # endif
2229 #endif
2230
2231 /* SI_TIMER */
2232 #if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
2233 memset(sip, -1, sizeof(*sip));
2234 sip->si_signo = SIGHUP;
2235 sip->si_code = SI_TIMER;
2236 sip->si_errno = ENOENT;
2237 sip->si_timerid = 0xdeadbeef;
2238 sip->si_overrun = -1;
2239 sip->si_ptr = (void *) (unsigned long) 0xfacefeeddeadbeefULL;
2240
2241 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2242 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2243 ", si_code=" XLAT_FMT ", si_errno=" XLAT_FMT_U ", si_timerid=%#x"
2244 ", si_overrun=%d, si_int=%d, si_ptr=%p}) = %s\n",
2245 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2246 XLAT_ARGS(SIGHUP), XLAT_ARGS(SI_TIMER), XLAT_ARGS(ENOENT),
2247 sip->si_timerid, sip->si_overrun, sip->si_int, sip->si_ptr,
2248 errstr);
2249 #endif
2250
2251 /* SI_SIGIO */
2252 memset(sip, -1, sizeof(*sip));
2253 sip->si_signo = SIGSEGV;
2254 sip->si_code = SI_SIGIO;
2255 sip->si_errno = ENOENT;
2256 sip->si_band = -1234567890;
2257 sip->si_fd = NULL_FD;
2258
2259 do_ptrace(PTRACE_SETSIGINFO, pid, bad_request, (uintptr_t) sip);
2260 printf("ptrace(" XLAT_FMT ", %d, %#lx, {si_signo=" XLAT_FMT_U
2261 ", si_code=" XLAT_FMT ", si_errno=" XLAT_FMT_U
2262 ", si_band=-1234567890, si_fd=%d%s}) = %s\n",
2263 XLAT_ARGS(PTRACE_SETSIGINFO), pid, bad_request,
2264 XLAT_ARGS(SIGSEGV), XLAT_ARGS(SI_SIGIO), XLAT_ARGS(ENOENT),
2265 NULL_FD, NULL_FD_STR, errstr);
2266
2267 do_ptrace(PTRACE_GETSIGINFO, pid, bad_request, (uintptr_t) sip);
2268 printf("ptrace(" XLAT_FMT ", %d, %#lx, %p) = %s\n",
2269 XLAT_ARGS(PTRACE_GETSIGINFO), pid, bad_request, sip, errstr);
2270
2271 do_ptrace(PTRACE_CONT, pid, 0, SIGUSR1);
2272 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2273 XLAT_ARGS(PTRACE_CONT), pid, XLAT_ARGS(SIGUSR1), errstr);
2274
2275 do_ptrace(PTRACE_DETACH, pid, 0, SIGUSR2);
2276 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2277 XLAT_ARGS(PTRACE_DETACH), pid, XLAT_ARGS(SIGUSR2), errstr);
2278
2279 do_ptrace(PTRACE_SYSCALL, pid, 0, SIGUSR1);
2280 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2281 XLAT_ARGS(PTRACE_SYSCALL), pid, XLAT_ARGS(SIGUSR1), errstr);
2282
2283 #ifdef PTRACE_SINGLESTEP
2284 do_ptrace(PTRACE_SINGLESTEP, pid, 0, SIGUSR2);
2285 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2286 XLAT_ARGS(PTRACE_SINGLESTEP), pid, XLAT_ARGS(SIGUSR2), errstr);
2287 #endif
2288
2289 #ifdef PTRACE_SINGLEBLOCK
2290 do_ptrace(PTRACE_SINGLEBLOCK, pid, 0, SIGUSR1);
2291 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2292 XLAT_ARGS(PTRACE_SINGLEBLOCK), pid, XLAT_ARGS(SIGUSR1), errstr);
2293 #endif
2294
2295 #ifdef PTRACE_SYSEMU
2296 do_ptrace(PTRACE_SYSEMU, pid, 0, SIGUSR2);
2297 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2298 XLAT_ARGS(PTRACE_SYSEMU), pid, XLAT_ARGS(SIGUSR2), errstr);
2299 #endif
2300 #ifdef PTRACE_SYSEMU_SINGLESTEP
2301 do_ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, SIGUSR1);
2302 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT_U ") = %s\n",
2303 XLAT_ARGS(PTRACE_SYSEMU_SINGLESTEP), pid, XLAT_ARGS(SIGUSR1),
2304 errstr);
2305 #endif
2306
2307 do_ptrace(PTRACE_SETOPTIONS,
2308 pid, 0, PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE);
2309 printf("ptrace(" XLAT_FMT ", %d, NULL, " XLAT_FMT ") = %s\n",
2310 XLAT_ARGS(PTRACE_SETOPTIONS), pid,
2311 XLAT_ARGS(PTRACE_O_TRACEFORK|PTRACE_O_TRACECLONE), errstr);
2312
2313 do_ptrace(PTRACE_SEIZE, pid, bad_request, PTRACE_O_TRACESYSGOOD);
2314 printf("ptrace(" XLAT_FMT ", %d, %#lx, " XLAT_FMT ") = %s\n",
2315 XLAT_ARGS(PTRACE_SEIZE), pid, bad_request,
2316 XLAT_ARGS(PTRACE_O_TRACESYSGOOD), errstr);
2317
2318 test_peeksiginfo(pid, bad_request);
2319 test_getregset_setregset(pid);
2320 test_compat_ptrace(pid);
2321
2322 do_ptrace(PTRACE_TRACEME, 0, 0, 0);
2323 printf("ptrace(" XLAT_FMT ") = %s\n",
2324 XLAT_ARGS(PTRACE_TRACEME), errstr);
2325
2326 puts("+++ exited with 0 +++");
2327 return 0;
2328 }