2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 #include <sys/resource.h>
47 #include <sys/utsname.h>
49 #include <sys/syscall.h>
52 #include <machine/reg.h>
56 #include <sys/ptrace.h>
61 #ifndef PTRACE_PEEKUSR
62 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
64 #ifndef PTRACE_POKEUSR
65 # define PTRACE_POKEUSR PTRACE_POKEUSER
69 #ifdef HAVE_LINUX_PTRACE_H
71 # ifdef HAVE_STRUCT_IA64_FPREG
72 # define ia64_fpreg XXX_ia64_fpreg
74 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
75 # define pt_all_user_regs XXX_pt_all_user_regs
77 #include <linux/ptrace.h>
79 # undef pt_all_user_regs
82 #if defined (LINUX) && defined (SPARC64)
84 # undef PTRACE_GETREGS
85 # define PTRACE_GETREGS PTRACE_GETREGS64
86 # undef PTRACE_SETREGS
87 # define PTRACE_SETREGS PTRACE_SETREGS64
88 #endif /* LINUX && SPARC64 */
90 #ifdef HAVE_LINUX_FUTEX_H
91 # include <linux/futex.h>
103 # ifndef FUTEX_REQUEUE
104 # define FUTEX_REQUEUE 3
110 #include <asm/posix_types.h>
112 #define GETGROUPS_T __kernel_gid_t
114 #define GETGROUPS32_T __kernel_gid32_t
117 #if defined(LINUX) && defined(IA64)
118 # include <asm/ptrace_offsets.h>
119 # include <asm/rse.h>
123 # include <sys/prctl.h>
125 static const struct xlat prctl_options[] = {
127 { PR_MAXPROCS, "PR_MAXPROCS" },
130 { PR_ISBLOCKED, "PR_ISBLOCKED" },
132 #ifdef PR_SETSTACKSIZE
133 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
135 #ifdef PR_GETSTACKSIZE
136 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
139 { PR_MAXPPROCS, "PR_MAXPPROCS" },
141 #ifdef PR_UNBLKONEXEC
142 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
145 { PR_ATOMICSIM, "PR_ATOMICSIM" },
148 { PR_SETEXITSIG, "PR_SETEXITSIG" },
151 { PR_RESIDENT, "PR_RESIDENT" },
154 { PR_ATTACHADDR, "PR_ATTACHADDR" },
157 { PR_DETACHADDR, "PR_DETACHADDR" },
160 { PR_TERMCHILD, "PR_TERMCHILD" },
163 { PR_GETSHMASK, "PR_GETSHMASK" },
166 { PR_GETNSHARE, "PR_GETNSHARE" },
169 { PR_COREPID, "PR_COREPID" },
171 #ifdef PR_ATTACHADDRPERM
172 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
174 #ifdef PR_PTHREADEXIT
175 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
177 #ifdef PR_SET_PDEATHSIG
178 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
180 #ifdef PR_GET_PDEATHSIG
181 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
183 #ifdef PR_GET_DUMPABLE
184 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
186 #ifdef PR_SET_DUMPABLE
187 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
189 #ifdef PR_GET_UNALIGN
190 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
192 #ifdef PR_SET_UNALIGN
193 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
195 #ifdef PR_GET_KEEPCAPS
196 { PR_GET_KEEPCAPS, "PR_GET_KEEPCAPS" },
198 #ifdef PR_SET_KEEPCAPS
199 { PR_SET_KEEPCAPS, "PR_SET_KEEPCAPS" },
202 { PR_GET_FPEMU, "PR_GET_FPEMU" },
205 { PR_SET_FPEMU, "PR_SET_FPEMU" },
208 { PR_GET_FPEXC, "PR_GET_FPEXC" },
211 { PR_SET_FPEXC, "PR_SET_FPEXC" },
214 { PR_GET_TIMING, "PR_GET_TIMING" },
217 { PR_SET_TIMING, "PR_SET_TIMING" },
220 { PR_SET_NAME, "PR_SET_NAME" },
223 { PR_GET_NAME, "PR_GET_NAME" },
226 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
229 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
231 #ifdef PR_GET_SECCOMP
232 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
234 #ifdef PR_SET_SECCOMP
235 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
238 { PR_GET_TSC, "PR_GET_TSC" },
241 { PR_SET_TSC, "PR_SET_TSC" },
243 #ifdef PR_GET_SECUREBITS
244 { PR_GET_SECUREBITS, "PR_GET_SECUREBITS" },
246 #ifdef PR_SET_SECUREBITS
247 { PR_SET_SECUREBITS, "PR_SET_SECUREBITS" },
254 unalignctl_string (unsigned int ctl)
259 #ifdef PR_UNALIGN_NOPRINT
260 case PR_UNALIGN_NOPRINT:
263 #ifdef PR_UNALIGN_SIGBUS
264 case PR_UNALIGN_SIGBUS:
270 sprintf(buf, "%x", ctl);
282 printxval(prctl_options, tcp->u_arg[0], "PR_???");
283 switch (tcp->u_arg[0]) {
288 #ifdef PR_SET_PDEATHSIG
289 case PR_SET_PDEATHSIG:
290 tprintf(", %lu", tcp->u_arg[1]);
293 #ifdef PR_GET_PDEATHSIG
294 case PR_GET_PDEATHSIG:
297 #ifdef PR_SET_DUMPABLE
298 case PR_SET_DUMPABLE:
299 tprintf(", %lu", tcp->u_arg[1]);
302 #ifdef PR_GET_DUMPABLE
303 case PR_GET_DUMPABLE:
306 #ifdef PR_SET_UNALIGN
308 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
311 #ifdef PR_GET_UNALIGN
313 tprintf(", %#lx", tcp->u_arg[1]);
316 #ifdef PR_SET_KEEPCAPS
317 case PR_SET_KEEPCAPS:
318 tprintf(", %lu", tcp->u_arg[1]);
321 #ifdef PR_GET_KEEPCAPS
322 case PR_GET_KEEPCAPS:
326 for (i = 1; i < tcp->u_nargs; i++)
327 tprintf(", %#lx", tcp->u_arg[i]);
331 switch (tcp->u_arg[0]) {
332 #ifdef PR_GET_PDEATHSIG
333 case PR_GET_PDEATHSIG:
334 if (umove(tcp, tcp->u_arg[1], &i) < 0)
335 tprintf(", %#lx", tcp->u_arg[1]);
337 tprintf(", {%u}", i);
340 #ifdef PR_GET_DUMPABLE
341 case PR_GET_DUMPABLE:
342 return RVAL_UDECIMAL;
344 #ifdef PR_GET_UNALIGN
346 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
348 tcp->auxstr = unalignctl_string(i);
351 #ifdef PR_GET_KEEPCAPS
352 case PR_GET_KEEPCAPS:
353 return RVAL_UDECIMAL;
361 #endif /* HAVE_PRCTL */
363 #if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
372 #endif /* FREEBSD || SUNOS4 || SVR4 */
379 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
380 tprintf(", %lu", tcp->u_arg[1]);
385 #if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
392 tprintf("%#lx", tcp->u_arg[0]);
394 printpath(tcp, tcp->u_arg[0]);
395 tprintf(", %lu", tcp->u_arg[1]);
399 #endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
402 sys_setdomainname(tcp)
406 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
407 tprintf(", %lu", tcp->u_arg[1]);
415 sys_getdomainname(tcp)
420 tprintf("%#lx", tcp->u_arg[0]);
422 printpath(tcp, tcp->u_arg[0]);
423 tprintf(", %lu", tcp->u_arg[1]);
434 fprintf(stderr, "_exit returned!\n");
437 /* special case: we stop tracing this process, finish line now */
438 tprintf("%ld) ", tcp->u_arg[0]);
450 tcp->flags |= TCB_EXITING;
451 #ifdef __NR_exit_group
454 if (tcp->scno == 252)
455 tcp->flags |= TCB_GROUP_EXITING;
458 if (known_scno(tcp) == __NR_exit_group)
459 tcp->flags |= TCB_GROUP_EXITING;
465 /* TCP is creating a child we want to follow.
466 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
467 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
469 fork_tcb(struct tcb *tcp)
471 if (nprocs == tcbtabsize)
474 tcp->flags |= TCB_FOLLOWFORK;
480 sys_fork(struct tcb *tcp)
482 if (exiting(tcp) && !syserror(tcp)) {
484 tcp->auxstr = "child process";
485 return RVAL_UDECIMAL | RVAL_STR;
498 tprintf ("%ld", tcp->u_arg[0]);
500 else if (!syserror(tcp)) {
502 tcp->auxstr = "child process";
503 return RVAL_UDECIMAL | RVAL_STR;
515 struct tcb *tcpchild;
519 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
529 tcpchild = alloctcb(tcp->u_rval);
530 if (proc_open(tcpchild, 2) < 0)
536 #else /* !USE_PROCFS */
540 /* defines copied from linux/sched.h since we can't include that
541 * ourselves (it conflicts with *lots* of libc includes)
543 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
544 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
545 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
546 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
547 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
548 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
549 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
550 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
551 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
552 #define CLONE_THREAD 0x00010000 /* Same thread group? */
553 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
554 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
555 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
556 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
557 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
558 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
559 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
560 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
562 static const struct xlat clone_flags[] = {
563 { CLONE_VM, "CLONE_VM" },
564 { CLONE_FS, "CLONE_FS" },
565 { CLONE_FILES, "CLONE_FILES" },
566 { CLONE_SIGHAND, "CLONE_SIGHAND" },
567 { CLONE_IDLETASK, "CLONE_IDLETASK"},
568 { CLONE_PTRACE, "CLONE_PTRACE" },
569 { CLONE_VFORK, "CLONE_VFORK" },
570 { CLONE_PARENT, "CLONE_PARENT" },
571 { CLONE_THREAD, "CLONE_THREAD" },
572 { CLONE_NEWNS, "CLONE_NEWNS" },
573 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
574 { CLONE_SETTLS, "CLONE_SETTLS" },
575 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
576 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
577 { CLONE_DETACHED, "CLONE_DETACHED" },
578 { CLONE_UNTRACED, "CLONE_UNTRACED" },
579 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
584 # include <asm/ldt.h>
585 # ifdef HAVE_STRUCT_USER_DESC
586 # define modify_ldt_ldt_s user_desc
588 extern void print_ldt_entry();
594 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
595 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
596 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
597 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
598 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
604 # elif defined X86_64 || defined ALPHA
623 unsigned long flags = tcp->u_arg[ARG_FLAGS];
624 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
625 # ifdef ARG_STACKSIZE
626 if (ARG_STACKSIZE != -1)
627 tprintf("stack_size=%#lx, ",
628 tcp->u_arg[ARG_STACKSIZE]);
631 printflags(clone_flags, flags &~ CSIGNAL, NULL);
632 if ((flags & CSIGNAL) != 0)
633 tprintf("|%s", signame(flags & CSIGNAL));
634 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
635 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
637 if (flags & CLONE_PARENT_SETTID)
638 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
639 if (flags & CLONE_SETTLS) {
641 struct modify_ldt_ldt_s copy;
642 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
643 tprintf(", {entry_number:%d, ",
648 print_ldt_entry(©);
652 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
654 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
655 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
661 sys_unshare(struct tcb *tcp)
664 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
674 return RVAL_UDECIMAL;
679 change_syscall(struct tcb *tcp, int new)
683 /* Attempt to make vfork into fork, which we can follow. */
684 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
687 #elif defined(X86_64)
688 /* Attempt to make vfork into fork, which we can follow. */
689 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
692 #elif defined(POWERPC)
693 if (ptrace(PTRACE_POKEUSER, tcp->pid,
694 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
697 #elif defined(S390) || defined(S390X)
698 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
699 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
703 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
706 #elif defined(SPARC) || defined(SPARC64)
708 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
710 regs.u_regs[U_REG_G1] = new;
711 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
715 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
719 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
723 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
727 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
734 break; /* x86 SYS_fork */
739 fprintf(stderr, "%s: unexpected syscall %d\n",
743 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
745 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
749 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
753 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
757 /* Top half of reg encodes the no. of args n as 0x1n.
758 Assume 0 args as kernel never actually checks... */
759 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
763 #elif defined(CRISV10) || defined(CRISV32)
764 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
768 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
769 # ifndef PTRACE_SET_SYSCALL
770 # define PTRACE_SET_SYSCALL 23
773 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
778 if (ptrace(PTRACE_POKEUSER, tcp->pid,
779 (char*)PTREGS_OFFSET_REG(0),
783 #elif defined(MICROBLAZE)
784 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR(0)), new)<0)
788 #warning Do not know how to handle change_syscall for this architecture
789 #endif /* architecture */
796 internal_fork(struct tcb *tcp)
805 struct tcb *tcpchild;
809 if (!(tcp->flags & TCB_FOLLOWFORK))
812 bpt = tcp->flags & TCB_BPTSET;
822 #ifdef CLONE_PTRACE /* See new setbpt code. */
823 tcpchild = pid2tcb(pid);
824 if (tcpchild != NULL) {
825 /* The child already reported its startup trap
826 before the parent reported its syscall return. */
828 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
829 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
831 [preattached child %d of %d in weird state!]\n",
835 #endif /* CLONE_PTRACE */
838 tcpchild = alloctcb(pid);
842 /* Attach to the new child */
843 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
846 perror("PTRACE_ATTACH");
847 fprintf(stderr, "Too late?\n");
851 #endif /* !CLONE_PTRACE */
856 tcpchild->flags |= TCB_ATTACHED;
857 /* Child has BPT too, must be removed on first occasion. */
859 tcpchild->flags |= TCB_BPTSET;
860 tcpchild->baddr = tcp->baddr;
861 memcpy(tcpchild->inst, tcp->inst,
862 sizeof tcpchild->inst);
864 tcpchild->parent = tcp;
866 if (tcpchild->flags & TCB_SUSPENDED) {
867 /* The child was born suspended, due to our having
868 forced CLONE_PTRACE. */
872 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
873 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
878 Process %u resumed (parent %d ready)\n",
883 fprintf(stderr, "Process %d attached\n", pid);
886 #ifdef TCB_CLONE_THREAD
889 * Save the flags used in this call,
890 * in case we point TCP to our parent below.
892 int call_flags = tcp->u_arg[ARG_FLAGS];
893 if ((tcp->flags & TCB_CLONE_THREAD) &&
894 tcp->parent != NULL) {
895 /* The parent in this clone is itself a
896 thread belonging to another process.
897 There is no meaning to the parentage
898 relationship of the new child with the
899 thread, only with the process. We
900 associate the new thread with our
901 parent. Since this is done for every
902 new thread, there will never be a
903 TCB_CLONE_THREAD process that has
907 tcpchild->parent = tcp;
910 if (call_flags & CLONE_THREAD) {
911 tcpchild->flags |= TCB_CLONE_THREAD;
912 ++tcp->nclone_threads;
914 if (call_flags & CLONE_DETACHED) {
915 tcpchild->flags |= TCB_CLONE_DETACHED;
916 ++tcp->nclone_detached;
919 #endif /* TCB_CLONE_THREAD */
930 struct tcb *tcpchild;
935 if (known_scno(tcp) == SYS_vfork) {
936 /* Attempt to make vfork into fork, which we can follow. */
937 if (change_syscall(tcp, SYS_fork) < 0)
942 if (!followfork || dont_follow)
949 int bpt = tcp->flags & TCB_BPTSET;
951 if (!(tcp->flags & TCB_FOLLOWFORK))
961 tcpchild = alloctcb(pid);
964 /* The child must have run before it can be attached. */
969 select(0, NULL, NULL, NULL, &tv);
971 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
972 perror("PTRACE_ATTACH");
973 fprintf(stderr, "Too late?\n");
978 /* Try to catch the new process as soon as possible. */
981 for (i = 0; i < 1024; i++)
982 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
985 perror("PTRACE_ATTACH");
986 fprintf(stderr, "Too late?\n");
993 tcpchild->flags |= TCB_ATTACHED;
994 /* Child has BPT too, must be removed on first occasion */
996 tcpchild->flags |= TCB_BPTSET;
997 tcpchild->baddr = tcp->baddr;
998 memcpy(tcpchild->inst, tcp->inst,
999 sizeof tcpchild->inst);
1001 tcpchild->parent = tcp;
1004 fprintf(stderr, "Process %d attached\n", pid);
1011 #endif /* !USE_PROCFS */
1013 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1020 return RVAL_UDECIMAL;
1024 #endif /* SUNOS4 || LINUX || FREEBSD */
1028 static char idstr[16];
1035 sprintf(idstr, "ppid %lu", getrval2(tcp));
1036 tcp->auxstr = idstr;
1047 sprintf(idstr, "euid %lu", getrval2(tcp));
1048 tcp->auxstr = idstr;
1059 sprintf(idstr, "egid %lu", getrval2(tcp));
1060 tcp->auxstr = idstr;
1074 if (entering(tcp)) {
1075 tprintf("%u", (uid_t) tcp->u_arg[0]);
1084 if (entering(tcp)) {
1085 tprintf("%u", (gid_t) tcp->u_arg[0]);
1091 sys_getresuid(struct tcb *tcp)
1096 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1097 tcp->u_arg[1], tcp->u_arg[2]);
1099 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1100 tprintf("%#lx, ", tcp->u_arg[0]);
1102 tprintf("[%lu], ", (unsigned long) uid);
1103 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1104 tprintf("%#lx, ", tcp->u_arg[1]);
1106 tprintf("[%lu], ", (unsigned long) uid);
1107 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1108 tprintf("%#lx", tcp->u_arg[2]);
1110 tprintf("[%lu]", (unsigned long) uid);
1123 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1124 tcp->u_arg[1], tcp->u_arg[2]);
1126 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1127 tprintf("%#lx, ", tcp->u_arg[0]);
1129 tprintf("[%lu], ", (unsigned long) gid);
1130 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1131 tprintf("%#lx, ", tcp->u_arg[1]);
1133 tprintf("[%lu], ", (unsigned long) gid);
1134 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1135 tprintf("%#lx", tcp->u_arg[2]);
1137 tprintf("[%lu]", (unsigned long) gid);
1149 if (entering(tcp)) {
1150 printuid("", tcp->u_arg[0]);
1151 printuid(", ", tcp->u_arg[1]);
1160 if (entering(tcp)) {
1161 printuid("", tcp->u_arg[0]);
1162 printuid(", ", tcp->u_arg[1]);
1167 #if defined(LINUX) || defined(FREEBSD)
1172 if (entering(tcp)) {
1173 printuid("", tcp->u_arg[0]);
1174 printuid(", ", tcp->u_arg[1]);
1175 printuid(", ", tcp->u_arg[2]);
1183 if (entering(tcp)) {
1184 printuid("", tcp->u_arg[0]);
1185 printuid(", ", tcp->u_arg[1]);
1186 printuid(", ", tcp->u_arg[2]);
1191 #endif /* LINUX || FREEBSD */
1197 if (entering(tcp)) {
1198 unsigned long len, size, start, cur, end, abbrev_end;
1202 len = tcp->u_arg[0];
1203 tprintf("%lu, ", len);
1208 start = tcp->u_arg[1];
1213 size = len * sizeof(gid);
1215 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1216 tprintf("%#lx", start);
1220 abbrev_end = start + max_strlen * sizeof(gid);
1221 if (abbrev_end < start)
1227 for (cur = start; cur < end; cur += sizeof(gid)) {
1230 if (cur >= abbrev_end) {
1234 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1239 tprintf("%lu", (unsigned long) gid);
1243 tprintf(" %#lx", tcp->u_arg[1]);
1254 if (entering(tcp)) {
1255 len = tcp->u_arg[0];
1256 tprintf("%lu, ", len);
1258 unsigned long size, start, cur, end, abbrev_end;
1267 start = tcp->u_arg[1];
1272 if (tcp->u_arg[0] == 0) {
1273 tprintf("%#lx", start);
1276 size = len * sizeof(gid);
1278 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1279 size / sizeof(gid) != len || end < start) {
1280 tprintf("%#lx", start);
1284 abbrev_end = start + max_strlen * sizeof(gid);
1285 if (abbrev_end < start)
1291 for (cur = start; cur < end; cur += sizeof(gid)) {
1294 if (cur >= abbrev_end) {
1298 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1303 tprintf("%lu", (unsigned long) gid);
1307 tprintf(" %#lx", tcp->u_arg[1]);
1314 sys_setgroups32(tcp)
1317 if (entering(tcp)) {
1318 unsigned long len, size, start, cur, end, abbrev_end;
1322 len = tcp->u_arg[0];
1323 tprintf("%lu, ", len);
1328 start = tcp->u_arg[1];
1333 size = len * sizeof(gid);
1335 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1336 tprintf("%#lx", start);
1340 abbrev_end = start + max_strlen * sizeof(gid);
1341 if (abbrev_end < start)
1347 for (cur = start; cur < end; cur += sizeof(gid)) {
1350 if (cur >= abbrev_end) {
1354 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1359 tprintf("%lu", (unsigned long) gid);
1363 tprintf(" %#lx", tcp->u_arg[1]);
1369 sys_getgroups32(tcp)
1374 if (entering(tcp)) {
1375 len = tcp->u_arg[0];
1376 tprintf("%lu, ", len);
1378 unsigned long size, start, cur, end, abbrev_end;
1387 start = tcp->u_arg[1];
1392 size = len * sizeof(gid);
1394 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1395 size / sizeof(gid) != len || end < start) {
1396 tprintf("%#lx", start);
1400 abbrev_end = start + max_strlen * sizeof(gid);
1401 if (abbrev_end < start)
1407 for (cur = start; cur < end; cur += sizeof(gid)) {
1410 if (cur >= abbrev_end) {
1414 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1419 tprintf("%lu", (unsigned long) gid);
1423 tprintf(" %#lx", tcp->u_arg[1]);
1429 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1434 if (entering(tcp)) {
1436 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1441 #endif /* ALPHA || SUNOS4 || SVR4 */
1447 if (entering(tcp)) {
1449 tprintf("%lu", tcp->u_arg[0]);
1459 if (entering(tcp)) {
1460 tprintf("%lu", tcp->u_arg[0]);
1476 if (entering(tcp)) {
1477 tprintf("%lu", tcp->u_arg[0]);
1486 if (entering(tcp)) {
1487 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1494 #include <sys/privilege.h>
1497 static const struct xlat procpriv_cmds [] = {
1498 { SETPRV, "SETPRV" },
1499 { CLRPRV, "CLRPRV" },
1500 { PUTPRV, "PUTPRV" },
1501 { GETPRV, "GETPRV" },
1502 { CNTPRV, "CNTPRV" },
1507 static const struct xlat procpriv_priv [] = {
1508 { P_OWNER, "P_OWNER" },
1509 { P_AUDIT, "P_AUDIT" },
1510 { P_COMPAT, "P_COMPAT" },
1511 { P_DACREAD, "P_DACREAD" },
1512 { P_DACWRITE, "P_DACWRITE" },
1514 { P_FILESYS, "P_FILESYS" },
1515 { P_MACREAD, "P_MACREAD" },
1516 { P_MACWRITE, "P_MACWRITE" },
1517 { P_MOUNT, "P_MOUNT" },
1518 { P_MULTIDIR, "P_MULTIDIR" },
1519 { P_SETPLEVEL, "P_SETPLEVEL" },
1520 { P_SETSPRIV, "P_SETSPRIV" },
1521 { P_SETUID, "P_SETUID" },
1522 { P_SYSOPS, "P_SYSOPS" },
1523 { P_SETUPRIV, "P_SETUPRIV" },
1524 { P_DRIVER, "P_DRIVER" },
1525 { P_RTIME, "P_RTIME" },
1526 { P_MACUPGRADE, "P_MACUPGRADE" },
1527 { P_FSYSRANGE, "P_FSYSRANGE" },
1528 { P_SETFLEVEL, "P_SETFLEVEL" },
1529 { P_AUDITWR, "P_AUDITWR" },
1530 { P_TSHAR, "P_TSHAR" },
1531 { P_PLOCK, "P_PLOCK" },
1532 { P_CORE, "P_CORE" },
1533 { P_LOADMOD, "P_LOADMOD" },
1534 { P_BIND, "P_BIND" },
1535 { P_ALLPRIVS, "P_ALLPRIVS" },
1540 static const struct xlat procpriv_type [] = {
1541 { PS_FIX, "PS_FIX" },
1542 { PS_INH, "PS_INH" },
1543 { PS_MAX, "PS_MAX" },
1544 { PS_WKG, "PS_WKG" },
1550 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1553 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1554 int dots = len > max;
1557 if (len > max) len = max;
1560 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1562 tprintf ("%#lx", addr);
1568 for (i = 0; i < len; ++i) {
1571 if (i) tprintf (", ");
1573 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1574 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1576 tprintf ("%s|%s", t, p);
1579 tprintf ("%#lx", buf [i]);
1583 if (dots) tprintf (" ...");
1593 if (entering(tcp)) {
1594 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1595 switch (tcp->u_arg[0]) {
1597 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1605 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1606 tprintf (", %ld", tcp->u_arg[2]);
1609 else if (tcp->u_arg[0] == GETPRV) {
1610 if (syserror (tcp)) {
1611 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1615 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1616 tprintf (", %ld", tcp->u_arg[2]);
1623 #endif /* UNIXWARE */
1627 printargv(tcp, addr)
1634 char data[sizeof(long)];
1640 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1641 if (umoven(tcp, addr, personality_wordsize[current_personality],
1643 tprintf("%#lx", addr);
1646 if (personality_wordsize[current_personality] == 4)
1651 printstr(tcp, cp.p64, -1);
1652 addr += personality_wordsize[current_personality];
1655 tprintf("%s...", sep);
1659 printargc(fmt, tcp, addr)
1667 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1668 addr += sizeof(char *);
1670 tprintf(fmt, count, count == 1 ? "" : "s");
1673 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1675 sys_execv(struct tcb *tcp)
1677 if (entering(tcp)) {
1678 printpath(tcp, tcp->u_arg[0]);
1680 tprintf(", %#lx", tcp->u_arg[1]);
1683 printargv(tcp, tcp->u_arg[1]);
1689 #endif /* SPARC || SPARC64 || SUNOS4 */
1692 sys_execve(struct tcb *tcp)
1694 if (entering(tcp)) {
1695 printpath(tcp, tcp->u_arg[0]);
1697 tprintf(", %#lx", tcp->u_arg[1]);
1700 printargv(tcp, tcp->u_arg[1]);
1704 tprintf(", %#lx", tcp->u_arg[2]);
1705 else if (abbrev(tcp))
1706 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1709 printargv(tcp, tcp->u_arg[2]);
1718 int sys_rexecve(tcp)
1721 if (entering (tcp)) {
1723 tprintf (", %ld", tcp->u_arg[3]);
1735 if (exiting(tcp) && !syserror(tcp) && followfork)
1738 #if defined LINUX && defined TCB_WAITEXECVE
1739 if (exiting(tcp) && syserror(tcp))
1740 tcp->flags &= ~TCB_WAITEXECVE;
1742 tcp->flags |= TCB_WAITEXECVE;
1743 #endif /* LINUX && TCB_WAITEXECVE */
1749 #define __WNOTHREAD 0x20000000
1752 #define __WALL 0x40000000
1755 #define __WCLONE 0x80000000
1759 static const struct xlat wait4_options[] = {
1760 { WNOHANG, "WNOHANG" },
1762 { WUNTRACED, "WUNTRACED" },
1765 { WEXITED, "WEXITED" },
1768 { WTRAPPED, "WTRAPPED" },
1771 { WSTOPPED, "WSTOPPED" },
1774 { WCONTINUED, "WCONTINUED" },
1777 { WNOWAIT, "WNOWAIT" },
1780 { __WCLONE, "__WCLONE" },
1783 { __WALL, "__WALL" },
1786 { __WNOTHREAD, "__WNOTHREAD" },
1791 #if !defined WCOREFLAG && defined WCOREFLG
1792 # define WCOREFLAG WCOREFLG
1795 # define WCOREFLAG 0x80
1798 # define WCOREDUMP(status) ((status) & 0200)
1803 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1806 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1816 * Here is a tricky presentation problem. This solution
1817 * is still not entirely satisfactory but since there
1818 * are no wait status constructors it will have to do.
1820 if (WIFSTOPPED(status)) {
1821 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1822 signame(WSTOPSIG(status)));
1823 status &= ~W_STOPCODE(WSTOPSIG(status));
1825 else if (WIFSIGNALED(status)) {
1826 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1827 signame(WTERMSIG(status)),
1828 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1829 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1831 else if (WIFEXITED(status)) {
1832 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1833 WEXITSTATUS(status));
1835 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1838 tprintf("[%#x]", status);
1845 tprintf(" | %#x]", status);
1851 printwaitn(struct tcb *tcp, int n, int bitness)
1856 if (entering(tcp)) {
1858 /* On Linux, kernel-side pid_t is typedef'ed to int
1859 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1860 * pid argument to int on 64bit arches, producing,
1861 * for example, wait4(4294967295, ...) instead of -1
1862 * in strace. We have to use int here, not long.
1864 int pid = tcp->u_arg[0];
1865 tprintf("%d, ", pid);
1868 * Sign-extend a 32-bit value when that's what it is.
1870 long pid = tcp->u_arg[0];
1871 if (personality_wordsize[current_personality] < sizeof pid)
1872 pid = (long) (int) pid;
1873 tprintf("%ld, ", pid);
1879 else if (syserror(tcp) || tcp->u_rval == 0)
1880 tprintf("%#lx", tcp->u_arg[1]);
1881 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1884 exited = printstatus(status);
1887 printflags(wait4_options, tcp->u_arg[2], "W???");
1894 else if (tcp->u_rval > 0) {
1897 printrusage32(tcp, tcp->u_arg[3]);
1900 printrusage(tcp, tcp->u_arg[3]);
1904 else if (tcp->u_rval > 0 && exited)
1905 printrusage(tcp, tcp->u_arg[3]);
1908 tprintf("%#lx", tcp->u_arg[3]);
1915 internal_wait(tcp, flagarg)
1921 #ifdef TCB_CLONE_THREAD
1922 if (tcp->flags & TCB_CLONE_THREAD)
1923 /* The children we wait for are our parent's children. */
1924 got_kids = (tcp->parent->nchildren
1925 > tcp->parent->nclone_detached);
1927 got_kids = (tcp->nchildren > tcp->nclone_detached);
1929 got_kids = tcp->nchildren > 0;
1932 if (entering(tcp) && got_kids) {
1933 /* There are children that this parent should block for.
1934 But ptrace made us the parent of the traced children
1935 and the real parent will get ECHILD from the wait call.
1937 XXX If we attached with strace -f -p PID, then there
1938 may be untraced dead children the parent could be reaping
1939 now, but we make him block. */
1941 /* ??? WTA: fix bug with hanging children */
1943 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1945 * There are traced children. We'll make the parent
1946 * block to avoid a false ECHILD error due to our
1947 * ptrace having stolen the children. However,
1948 * we shouldn't block if there are zombies to reap.
1949 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1951 struct tcb *child = NULL;
1952 if (tcp->nzombies > 0 &&
1953 (tcp->u_arg[0] == -1 ||
1954 (child = pid2tcb(tcp->u_arg[0])) == NULL))
1956 if (tcp->u_arg[0] > 0) {
1958 * If the parent waits for a specified child
1959 * PID, then it must get ECHILD right away
1960 * if that PID is not one of its children.
1961 * Make sure that the requested PID matches
1962 * one of the parent's children that we are
1963 * tracing, and don't suspend it otherwise.
1966 child = pid2tcb(tcp->u_arg[0]);
1967 if (child == NULL || child->parent != (
1968 #ifdef TCB_CLONE_THREAD
1969 (tcp->flags & TCB_CLONE_THREAD)
1973 (child->flags & TCB_EXITING))
1976 tcp->flags |= TCB_SUSPENDED;
1977 tcp->waitpid = tcp->u_arg[0];
1978 #ifdef TCB_CLONE_THREAD
1979 if (tcp->flags & TCB_CLONE_THREAD)
1980 tcp->parent->nclone_waiting++;
1984 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1985 if (tcp->u_arg[flagarg] & WNOHANG) {
1986 /* We must force a fake result of 0 instead of
1987 the ECHILD error. */
1988 return force_result(tcp, 0, 0);
1991 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1992 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1994 * We just reaped a child we don't know about,
1995 * presumably a zombie we already droptcb'd.
2009 /* The library wrapper stuffs this into the user variable. */
2011 printstatus(getrval2(tcp));
2026 if (!syserror(tcp)) {
2027 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2028 tprintf("%#lx", tcp->u_arg[0]);
2030 printstatus(status);
2041 return printwaitn(tcp, 3, 0);
2048 return printwaitn(tcp, 4, 0);
2056 return printwaitn(tcp, 4, 1);
2060 #if defined SVR4 || defined LINUX
2062 static const struct xlat waitid_types[] = {
2065 { P_PPID, "P_PPID" },
2067 { P_PGID, "P_PGID" },
2082 { P_LWPID, "P_LWPID" },
2094 if (entering(tcp)) {
2095 printxval(waitid_types, tcp->u_arg[0], "P_???");
2096 tprintf(", %ld, ", tcp->u_arg[1]);
2103 else if (syserror(tcp))
2104 tprintf("%#lx", tcp->u_arg[2]);
2105 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2108 printsiginfo(&si, verbose(tcp));
2111 printflags(wait4_options, tcp->u_arg[3], "W???");
2112 if (tcp->u_nargs > 4) {
2117 else if (tcp->u_error)
2118 tprintf("%#lx", tcp->u_arg[4]);
2120 printrusage(tcp, tcp->u_arg[4]);
2126 #endif /* SVR4 or LINUX */
2133 tprintf("%lu", tcp->u_arg[0]);
2141 struct utsname uname;
2144 if (syserror(tcp) || !verbose(tcp))
2145 tprintf("%#lx", tcp->u_arg[0]);
2146 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2148 else if (!abbrev(tcp)) {
2150 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2151 uname.sysname, uname.nodename);
2152 tprintf("release=\"%s\", version=\"%s\", ",
2153 uname.release, uname.version);
2154 tprintf("machine=\"%s\"", uname.machine);
2157 tprintf(", domainname=\"%s\"", uname.domainname);
2163 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2164 uname.sysname, uname.nodename);
2171 static const struct xlat ptrace_cmds[] = {
2173 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2174 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2175 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2176 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2177 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2178 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2179 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2180 { PTRACE_CONT, "PTRACE_CONT" },
2181 { PTRACE_KILL, "PTRACE_KILL" },
2182 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2183 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2184 { PTRACE_DETACH, "PTRACE_DETACH" },
2185 # ifdef PTRACE_GETREGS
2186 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2188 # ifdef PTRACE_SETREGS
2189 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2191 # ifdef PTRACE_GETFPREGS
2192 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2194 # ifdef PTRACE_SETFPREGS
2195 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2197 # ifdef PTRACE_GETFPXREGS
2198 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2200 # ifdef PTRACE_SETFPXREGS
2201 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2203 # ifdef PTRACE_GETVRREGS
2204 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2206 # ifdef PTRACE_SETVRREGS
2207 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2209 # ifdef PTRACE_SETOPTIONS
2210 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2212 # ifdef PTRACE_GETEVENTMSG
2213 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2215 # ifdef PTRACE_GETSIGINFO
2216 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2218 # ifdef PTRACE_SETSIGINFO
2219 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2221 # ifdef PTRACE_SET_SYSCALL
2222 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2225 { PTRACE_READDATA, "PTRACE_READDATA" },
2226 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2227 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2228 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2229 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2230 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2232 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2233 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2235 { PTRACE_22, "PTRACE_22" },
2236 { PTRACE_23, "PTRACE_3" },
2237 # endif /* !SPARC */
2238 # endif /* SUNOS4 */
2239 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2241 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2243 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2244 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2245 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2247 { PTRACE_26, "PTRACE_26" },
2248 { PTRACE_27, "PTRACE_27" },
2249 { PTRACE_28, "PTRACE_28" },
2251 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2252 # endif /* SUNOS4 */
2254 # else /* FREEBSD */
2256 { PT_TRACE_ME, "PT_TRACE_ME" },
2257 { PT_READ_I, "PT_READ_I" },
2258 { PT_READ_D, "PT_READ_D" },
2259 { PT_WRITE_I, "PT_WRITE_I" },
2260 { PT_WRITE_D, "PT_WRITE_D" },
2262 { PT_READ_U, "PT_READ_U" },
2264 { PT_CONTINUE, "PT_CONTINUE" },
2265 { PT_KILL, "PT_KILL" },
2266 { PT_STEP, "PT_STEP" },
2267 { PT_ATTACH, "PT_ATTACH" },
2268 { PT_DETACH, "PT_DETACH" },
2269 { PT_GETREGS, "PT_GETREGS" },
2270 { PT_SETREGS, "PT_SETREGS" },
2271 { PT_GETFPREGS, "PT_GETFPREGS" },
2272 { PT_SETFPREGS, "PT_SETFPREGS" },
2273 { PT_GETDBREGS, "PT_GETDBREGS" },
2274 { PT_SETDBREGS, "PT_SETDBREGS" },
2275 # endif /* FREEBSD */
2280 # ifdef PTRACE_SETOPTIONS
2281 static const struct xlat ptrace_setoptions_flags[] = {
2282 # ifdef PTRACE_O_TRACESYSGOOD
2283 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2285 # ifdef PTRACE_O_TRACEFORK
2286 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2288 # ifdef PTRACE_O_TRACEVFORK
2289 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2291 # ifdef PTRACE_O_TRACECLONE
2292 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2294 # ifdef PTRACE_O_TRACEEXEC
2295 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2297 # ifdef PTRACE_O_TRACEVFORKDONE
2298 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2300 # ifdef PTRACE_O_TRACEEXIT
2301 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2305 # endif /* PTRACE_SETOPTIONS */
2306 # endif /* !FREEBSD */
2309 const struct xlat struct_user_offsets[] = {
2311 # if defined(S390) || defined(S390X)
2312 { PT_PSWMASK, "psw_mask" },
2313 { PT_PSWADDR, "psw_addr" },
2314 { PT_GPR0, "gpr0" },
2315 { PT_GPR1, "gpr1" },
2316 { PT_GPR2, "gpr2" },
2317 { PT_GPR3, "gpr3" },
2318 { PT_GPR4, "gpr4" },
2319 { PT_GPR5, "gpr5" },
2320 { PT_GPR6, "gpr6" },
2321 { PT_GPR7, "gpr7" },
2322 { PT_GPR8, "gpr8" },
2323 { PT_GPR9, "gpr9" },
2324 { PT_GPR10, "gpr10" },
2325 { PT_GPR11, "gpr11" },
2326 { PT_GPR12, "gpr12" },
2327 { PT_GPR13, "gpr13" },
2328 { PT_GPR14, "gpr14" },
2329 { PT_GPR15, "gpr15" },
2330 { PT_ACR0, "acr0" },
2331 { PT_ACR1, "acr1" },
2332 { PT_ACR2, "acr2" },
2333 { PT_ACR3, "acr3" },
2334 { PT_ACR4, "acr4" },
2335 { PT_ACR5, "acr5" },
2336 { PT_ACR6, "acr6" },
2337 { PT_ACR7, "acr7" },
2338 { PT_ACR8, "acr8" },
2339 { PT_ACR9, "acr9" },
2340 { PT_ACR10, "acr10" },
2341 { PT_ACR11, "acr11" },
2342 { PT_ACR12, "acr12" },
2343 { PT_ACR13, "acr13" },
2344 { PT_ACR14, "acr14" },
2345 { PT_ACR15, "acr15" },
2346 { PT_ORIGGPR2, "orig_gpr2" },
2349 { PT_FPR0_HI, "fpr0.hi" },
2350 { PT_FPR0_LO, "fpr0.lo" },
2351 { PT_FPR1_HI, "fpr1.hi" },
2352 { PT_FPR1_LO, "fpr1.lo" },
2353 { PT_FPR2_HI, "fpr2.hi" },
2354 { PT_FPR2_LO, "fpr2.lo" },
2355 { PT_FPR3_HI, "fpr3.hi" },
2356 { PT_FPR3_LO, "fpr3.lo" },
2357 { PT_FPR4_HI, "fpr4.hi" },
2358 { PT_FPR4_LO, "fpr4.lo" },
2359 { PT_FPR5_HI, "fpr5.hi" },
2360 { PT_FPR5_LO, "fpr5.lo" },
2361 { PT_FPR6_HI, "fpr6.hi" },
2362 { PT_FPR6_LO, "fpr6.lo" },
2363 { PT_FPR7_HI, "fpr7.hi" },
2364 { PT_FPR7_LO, "fpr7.lo" },
2365 { PT_FPR8_HI, "fpr8.hi" },
2366 { PT_FPR8_LO, "fpr8.lo" },
2367 { PT_FPR9_HI, "fpr9.hi" },
2368 { PT_FPR9_LO, "fpr9.lo" },
2369 { PT_FPR10_HI, "fpr10.hi" },
2370 { PT_FPR10_LO, "fpr10.lo" },
2371 { PT_FPR11_HI, "fpr11.hi" },
2372 { PT_FPR11_LO, "fpr11.lo" },
2373 { PT_FPR12_HI, "fpr12.hi" },
2374 { PT_FPR12_LO, "fpr12.lo" },
2375 { PT_FPR13_HI, "fpr13.hi" },
2376 { PT_FPR13_LO, "fpr13.lo" },
2377 { PT_FPR14_HI, "fpr14.hi" },
2378 { PT_FPR14_LO, "fpr14.lo" },
2379 { PT_FPR15_HI, "fpr15.hi" },
2380 { PT_FPR15_LO, "fpr15.lo" },
2383 { PT_FPR0, "fpr0" },
2384 { PT_FPR1, "fpr1" },
2385 { PT_FPR2, "fpr2" },
2386 { PT_FPR3, "fpr3" },
2387 { PT_FPR4, "fpr4" },
2388 { PT_FPR5, "fpr5" },
2389 { PT_FPR6, "fpr6" },
2390 { PT_FPR7, "fpr7" },
2391 { PT_FPR8, "fpr8" },
2392 { PT_FPR9, "fpr9" },
2393 { PT_FPR10, "fpr10" },
2394 { PT_FPR11, "fpr11" },
2395 { PT_FPR12, "fpr12" },
2396 { PT_FPR13, "fpr13" },
2397 { PT_FPR14, "fpr14" },
2398 { PT_FPR15, "fpr15" },
2401 { PT_CR_10, "cr10" },
2402 { PT_CR_11, "cr11" },
2403 { PT_IEEE_IP, "ieee_exception_ip" },
2404 # elif defined(SPARC)
2405 /* XXX No support for these offsets yet. */
2406 # elif defined(HPPA)
2407 /* XXX No support for these offsets yet. */
2408 # elif defined(POWERPC)
2410 # define PT_ORIG_R3 34
2412 # define REGSIZE (sizeof(unsigned long))
2413 { REGSIZE*PT_R0, "r0" },
2414 { REGSIZE*PT_R1, "r1" },
2415 { REGSIZE*PT_R2, "r2" },
2416 { REGSIZE*PT_R3, "r3" },
2417 { REGSIZE*PT_R4, "r4" },
2418 { REGSIZE*PT_R5, "r5" },
2419 { REGSIZE*PT_R6, "r6" },
2420 { REGSIZE*PT_R7, "r7" },
2421 { REGSIZE*PT_R8, "r8" },
2422 { REGSIZE*PT_R9, "r9" },
2423 { REGSIZE*PT_R10, "r10" },
2424 { REGSIZE*PT_R11, "r11" },
2425 { REGSIZE*PT_R12, "r12" },
2426 { REGSIZE*PT_R13, "r13" },
2427 { REGSIZE*PT_R14, "r14" },
2428 { REGSIZE*PT_R15, "r15" },
2429 { REGSIZE*PT_R16, "r16" },
2430 { REGSIZE*PT_R17, "r17" },
2431 { REGSIZE*PT_R18, "r18" },
2432 { REGSIZE*PT_R19, "r19" },
2433 { REGSIZE*PT_R20, "r20" },
2434 { REGSIZE*PT_R21, "r21" },
2435 { REGSIZE*PT_R22, "r22" },
2436 { REGSIZE*PT_R23, "r23" },
2437 { REGSIZE*PT_R24, "r24" },
2438 { REGSIZE*PT_R25, "r25" },
2439 { REGSIZE*PT_R26, "r26" },
2440 { REGSIZE*PT_R27, "r27" },
2441 { REGSIZE*PT_R28, "r28" },
2442 { REGSIZE*PT_R29, "r29" },
2443 { REGSIZE*PT_R30, "r30" },
2444 { REGSIZE*PT_R31, "r31" },
2445 { REGSIZE*PT_NIP, "NIP" },
2446 { REGSIZE*PT_MSR, "MSR" },
2447 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2448 { REGSIZE*PT_CTR, "CTR" },
2449 { REGSIZE*PT_LNK, "LNK" },
2450 { REGSIZE*PT_XER, "XER" },
2451 { REGSIZE*PT_CCR, "CCR" },
2452 { REGSIZE*PT_FPR0, "FPR0" },
2454 # elif defined(ALPHA)
2520 # elif defined(IA64)
2521 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2522 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2523 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2524 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2525 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2526 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2527 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2528 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2529 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2530 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2531 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2532 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2533 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2534 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2535 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2536 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2537 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2538 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2539 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2540 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2541 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2542 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2543 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2544 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2545 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2546 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2547 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2548 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2549 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2550 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2551 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2552 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2554 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2555 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2556 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2557 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2558 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2559 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2560 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2561 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2562 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2563 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2564 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2565 { PT_B4, "b4" }, { PT_B5, "b5" },
2566 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2568 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2569 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2570 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2571 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2572 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2573 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2574 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2575 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2576 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2577 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2578 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2579 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2580 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2581 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2582 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2583 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2584 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2586 { PT_AR_CSD, "ar.csd" },
2589 { PT_AR_SSD, "ar.ssd" },
2591 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2592 # elif defined(I386)
2604 { 4*ORIG_EAX, "4*ORIG_EAX" },
2608 { 4*UESP, "4*UESP" },
2610 # elif defined(X86_64)
2626 { 8*ORIG_RAX, "8*ORIG_RAX" },
2629 { 8*EFLAGS, "8*EFL" },
2632 # elif defined(M68K)
2633 { 4*PT_D1, "4*PT_D1" },
2634 { 4*PT_D2, "4*PT_D2" },
2635 { 4*PT_D3, "4*PT_D3" },
2636 { 4*PT_D4, "4*PT_D4" },
2637 { 4*PT_D5, "4*PT_D5" },
2638 { 4*PT_D6, "4*PT_D6" },
2639 { 4*PT_D7, "4*PT_D7" },
2640 { 4*PT_A0, "4*PT_A0" },
2641 { 4*PT_A1, "4*PT_A1" },
2642 { 4*PT_A2, "4*PT_A2" },
2643 { 4*PT_A3, "4*PT_A3" },
2644 { 4*PT_A4, "4*PT_A4" },
2645 { 4*PT_A5, "4*PT_A5" },
2646 { 4*PT_A6, "4*PT_A6" },
2647 { 4*PT_D0, "4*PT_D0" },
2648 { 4*PT_USP, "4*PT_USP" },
2649 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2650 { 4*PT_SR, "4*PT_SR" },
2651 { 4*PT_PC, "4*PT_PC" },
2653 { 4*REG_REG0, "4*REG_REG0" },
2654 { 4*(REG_REG0+1), "4*REG_REG1" },
2655 { 4*(REG_REG0+2), "4*REG_REG2" },
2656 { 4*(REG_REG0+3), "4*REG_REG3" },
2657 { 4*(REG_REG0+4), "4*REG_REG4" },
2658 { 4*(REG_REG0+5), "4*REG_REG5" },
2659 { 4*(REG_REG0+6), "4*REG_REG6" },
2660 { 4*(REG_REG0+7), "4*REG_REG7" },
2661 { 4*(REG_REG0+8), "4*REG_REG8" },
2662 { 4*(REG_REG0+9), "4*REG_REG9" },
2663 { 4*(REG_REG0+10), "4*REG_REG10" },
2664 { 4*(REG_REG0+11), "4*REG_REG11" },
2665 { 4*(REG_REG0+12), "4*REG_REG12" },
2666 { 4*(REG_REG0+13), "4*REG_REG13" },
2667 { 4*(REG_REG0+14), "4*REG_REG14" },
2668 { 4*REG_REG15, "4*REG_REG15" },
2669 { 4*REG_PC, "4*REG_PC" },
2670 { 4*REG_PR, "4*REG_PR" },
2671 { 4*REG_SR, "4*REG_SR" },
2672 { 4*REG_GBR, "4*REG_GBR" },
2673 { 4*REG_MACH, "4*REG_MACH" },
2674 { 4*REG_MACL, "4*REG_MACL" },
2675 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2676 { 4*REG_FPUL, "4*REG_FPUL" },
2677 { 4*REG_FPREG0, "4*REG_FPREG0" },
2678 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2679 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2680 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2681 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2682 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2683 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2684 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2685 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2686 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2687 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2688 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2689 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2690 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2691 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2692 { 4*REG_FPREG15, "4*REG_FPREG15" },
2694 { 4*REG_XDREG0, "4*REG_XDREG0" },
2695 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2696 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2697 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2698 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2699 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2700 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2701 { 4*REG_XDREG14, "4*REG_XDREG14" },
2703 { 4*REG_FPSCR, "4*REG_FPSCR" },
2704 # elif defined(SH64)
2709 { 16, "syscall no.(L)" },
2710 { 20, "syscall_no.(U)" },
2853 /* This entry is in case pt_regs contains dregs (depends on
2854 the kernel build options). */
2855 { uoff(regs), "offsetof(struct user, regs)" },
2856 { uoff(fpu), "offsetof(struct user, fpu)" },
2858 { uoff(regs.ARM_r0), "r0" },
2859 { uoff(regs.ARM_r1), "r1" },
2860 { uoff(regs.ARM_r2), "r2" },
2861 { uoff(regs.ARM_r3), "r3" },
2862 { uoff(regs.ARM_r4), "r4" },
2863 { uoff(regs.ARM_r5), "r5" },
2864 { uoff(regs.ARM_r6), "r6" },
2865 { uoff(regs.ARM_r7), "r7" },
2866 { uoff(regs.ARM_r8), "r8" },
2867 { uoff(regs.ARM_r9), "r9" },
2868 { uoff(regs.ARM_r10), "r10" },
2869 { uoff(regs.ARM_fp), "fp" },
2870 { uoff(regs.ARM_ip), "ip" },
2871 { uoff(regs.ARM_sp), "sp" },
2872 { uoff(regs.ARM_lr), "lr" },
2873 { uoff(regs.ARM_pc), "pc" },
2874 { uoff(regs.ARM_cpsr), "cpsr" },
2875 # elif defined(AVR32)
2876 { uoff(regs.sr), "sr" },
2877 { uoff(regs.pc), "pc" },
2878 { uoff(regs.lr), "lr" },
2879 { uoff(regs.sp), "sp" },
2880 { uoff(regs.r12), "r12" },
2881 { uoff(regs.r11), "r11" },
2882 { uoff(regs.r10), "r10" },
2883 { uoff(regs.r9), "r9" },
2884 { uoff(regs.r8), "r8" },
2885 { uoff(regs.r7), "r7" },
2886 { uoff(regs.r6), "r6" },
2887 { uoff(regs.r5), "r5" },
2888 { uoff(regs.r4), "r4" },
2889 { uoff(regs.r3), "r3" },
2890 { uoff(regs.r2), "r2" },
2891 { uoff(regs.r1), "r1" },
2892 { uoff(regs.r0), "r0" },
2893 { uoff(regs.r12_orig), "orig_r12" },
2894 # elif defined(MIPS)
2966 # elif defined(TILE)
2967 { PTREGS_OFFSET_REG(0), "r0" },
2968 { PTREGS_OFFSET_REG(1), "r1" },
2969 { PTREGS_OFFSET_REG(2), "r2" },
2970 { PTREGS_OFFSET_REG(3), "r3" },
2971 { PTREGS_OFFSET_REG(4), "r4" },
2972 { PTREGS_OFFSET_REG(5), "r5" },
2973 { PTREGS_OFFSET_REG(6), "r6" },
2974 { PTREGS_OFFSET_REG(7), "r7" },
2975 { PTREGS_OFFSET_REG(8), "r8" },
2976 { PTREGS_OFFSET_REG(9), "r9" },
2977 { PTREGS_OFFSET_REG(10), "r10" },
2978 { PTREGS_OFFSET_REG(11), "r11" },
2979 { PTREGS_OFFSET_REG(12), "r12" },
2980 { PTREGS_OFFSET_REG(13), "r13" },
2981 { PTREGS_OFFSET_REG(14), "r14" },
2982 { PTREGS_OFFSET_REG(15), "r15" },
2983 { PTREGS_OFFSET_REG(16), "r16" },
2984 { PTREGS_OFFSET_REG(17), "r17" },
2985 { PTREGS_OFFSET_REG(18), "r18" },
2986 { PTREGS_OFFSET_REG(19), "r19" },
2987 { PTREGS_OFFSET_REG(20), "r20" },
2988 { PTREGS_OFFSET_REG(21), "r21" },
2989 { PTREGS_OFFSET_REG(22), "r22" },
2990 { PTREGS_OFFSET_REG(23), "r23" },
2991 { PTREGS_OFFSET_REG(24), "r24" },
2992 { PTREGS_OFFSET_REG(25), "r25" },
2993 { PTREGS_OFFSET_REG(26), "r26" },
2994 { PTREGS_OFFSET_REG(27), "r27" },
2995 { PTREGS_OFFSET_REG(28), "r28" },
2996 { PTREGS_OFFSET_REG(29), "r29" },
2997 { PTREGS_OFFSET_REG(30), "r30" },
2998 { PTREGS_OFFSET_REG(31), "r31" },
2999 { PTREGS_OFFSET_REG(32), "r32" },
3000 { PTREGS_OFFSET_REG(33), "r33" },
3001 { PTREGS_OFFSET_REG(34), "r34" },
3002 { PTREGS_OFFSET_REG(35), "r35" },
3003 { PTREGS_OFFSET_REG(36), "r36" },
3004 { PTREGS_OFFSET_REG(37), "r37" },
3005 { PTREGS_OFFSET_REG(38), "r38" },
3006 { PTREGS_OFFSET_REG(39), "r39" },
3007 { PTREGS_OFFSET_REG(40), "r40" },
3008 { PTREGS_OFFSET_REG(41), "r41" },
3009 { PTREGS_OFFSET_REG(42), "r42" },
3010 { PTREGS_OFFSET_REG(43), "r43" },
3011 { PTREGS_OFFSET_REG(44), "r44" },
3012 { PTREGS_OFFSET_REG(45), "r45" },
3013 { PTREGS_OFFSET_REG(46), "r46" },
3014 { PTREGS_OFFSET_REG(47), "r47" },
3015 { PTREGS_OFFSET_REG(48), "r48" },
3016 { PTREGS_OFFSET_REG(49), "r49" },
3017 { PTREGS_OFFSET_REG(50), "r50" },
3018 { PTREGS_OFFSET_REG(51), "r51" },
3019 { PTREGS_OFFSET_REG(52), "r52" },
3020 { PTREGS_OFFSET_TP, "tp" },
3021 { PTREGS_OFFSET_SP, "sp" },
3022 { PTREGS_OFFSET_LR, "lr" },
3023 { PTREGS_OFFSET_PC, "pc" },
3024 { PTREGS_OFFSET_EX1, "ex1" },
3025 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
3026 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
3027 { PTREGS_OFFSET_FLAGS, "flags" },
3030 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3031 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3032 { 4*PT_R13, "4*PT_R13" },
3033 { 4*PT_R12, "4*PT_R12" },
3034 { 4*PT_R11, "4*PT_R11" },
3035 { 4*PT_R10, "4*PT_R10" },
3036 { 4*PT_R9, "4*PT_R9" },
3037 { 4*PT_R8, "4*PT_R8" },
3038 { 4*PT_R7, "4*PT_R7" },
3039 { 4*PT_R6, "4*PT_R6" },
3040 { 4*PT_R5, "4*PT_R5" },
3041 { 4*PT_R4, "4*PT_R4" },
3042 { 4*PT_R3, "4*PT_R3" },
3043 { 4*PT_R2, "4*PT_R2" },
3044 { 4*PT_R1, "4*PT_R1" },
3045 { 4*PT_R0, "4*PT_R0" },
3046 { 4*PT_MOF, "4*PT_MOF" },
3047 { 4*PT_DCCR, "4*PT_DCCR" },
3048 { 4*PT_SRP, "4*PT_SRP" },
3049 { 4*PT_IRP, "4*PT_IRP" },
3050 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3051 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3052 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3053 { 4*PT_USP, "4*PT_USP" },
3056 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3057 { 4*PT_R0, "4*PT_R0" },
3058 { 4*PT_R1, "4*PT_R1" },
3059 { 4*PT_R2, "4*PT_R2" },
3060 { 4*PT_R3, "4*PT_R3" },
3061 { 4*PT_R4, "4*PT_R4" },
3062 { 4*PT_R5, "4*PT_R5" },
3063 { 4*PT_R6, "4*PT_R6" },
3064 { 4*PT_R7, "4*PT_R7" },
3065 { 4*PT_R8, "4*PT_R8" },
3066 { 4*PT_R9, "4*PT_R9" },
3067 { 4*PT_R10, "4*PT_R10" },
3068 { 4*PT_R11, "4*PT_R11" },
3069 { 4*PT_R12, "4*PT_R12" },
3070 { 4*PT_R13, "4*PT_R13" },
3071 { 4*PT_ACR, "4*PT_ACR" },
3072 { 4*PT_SRS, "4*PT_SRS" },
3073 { 4*PT_MOF, "4*PT_MOF" },
3074 { 4*PT_SPC, "4*PT_SPC" },
3075 { 4*PT_CCS, "4*PT_CCS" },
3076 { 4*PT_SRP, "4*PT_SRP" },
3077 { 4*PT_ERP, "4*PT_ERP" },
3078 { 4*PT_EXS, "4*PT_EXS" },
3079 { 4*PT_EDA, "4*PT_EDA" },
3080 { 4*PT_USP, "4*PT_USP" },
3081 { 4*PT_PPC, "4*PT_PPC" },
3082 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3083 { 4*PT_BP+4, "4*PT_BP+4" },
3084 { 4*PT_BP+8, "4*PT_BP+8" },
3085 { 4*PT_BP+12, "4*PT_BP+12" },
3086 { 4*PT_BP+16, "4*PT_BP+16" },
3087 { 4*PT_BP+20, "4*PT_BP+20" },
3088 { 4*PT_BP+24, "4*PT_BP+24" },
3089 { 4*PT_BP+28, "4*PT_BP+28" },
3090 { 4*PT_BP+32, "4*PT_BP+32" },
3091 { 4*PT_BP+36, "4*PT_BP+36" },
3092 { 4*PT_BP+40, "4*PT_BP+40" },
3093 { 4*PT_BP+44, "4*PT_BP+44" },
3094 { 4*PT_BP+48, "4*PT_BP+48" },
3095 { 4*PT_BP+52, "4*PT_BP+52" },
3096 { 4*PT_BP+56, "4*PT_BP+56" },
3099 { PT_GPR(0), "r0" },
3100 { PT_GPR(1), "r1" },
3101 { PT_GPR(2), "r2" },
3102 { PT_GPR(3), "r3" },
3103 { PT_GPR(4), "r4" },
3104 { PT_GPR(5), "r5" },
3105 { PT_GPR(6), "r6" },
3106 { PT_GPR(7), "r7" },
3107 { PT_GPR(8), "r8" },
3108 { PT_GPR(9), "r9" },
3109 { PT_GPR(10), "r10" },
3110 { PT_GPR(11), "r11" },
3111 { PT_GPR(12), "r12" },
3112 { PT_GPR(13), "r13" },
3113 { PT_GPR(14), "r14" },
3114 { PT_GPR(15), "r15" },
3115 { PT_GPR(16), "r16" },
3116 { PT_GPR(17), "r17" },
3117 { PT_GPR(18), "r18" },
3118 { PT_GPR(19), "r19" },
3119 { PT_GPR(20), "r20" },
3120 { PT_GPR(21), "r21" },
3121 { PT_GPR(22), "r22" },
3122 { PT_GPR(23), "r23" },
3123 { PT_GPR(24), "r24" },
3124 { PT_GPR(25), "r25" },
3125 { PT_GPR(26), "r26" },
3126 { PT_GPR(27), "r27" },
3127 { PT_GPR(28), "r28" },
3128 { PT_GPR(29), "r29" },
3129 { PT_GPR(30), "r30" },
3130 { PT_GPR(31), "r31" },
3132 { PT_MSR, "rmsr", },
3133 { PT_EAR, "rear", },
3134 { PT_ESR, "resr", },
3135 { PT_FSR, "rfsr", },
3136 { PT_KERNEL_MODE, "kernel_mode", },
3139 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3140 && !defined(ALPHA) && !defined(IA64) \
3141 && !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
3142 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3143 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3145 # if defined(I386) || defined(X86_64)
3146 { uoff(i387), "offsetof(struct user, i387)" },
3149 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3151 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3152 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3153 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3154 # if !defined(SPARC64)
3155 { uoff(start_code), "offsetof(struct user, start_code)" },
3157 # if defined(AVR32) || defined(SH64)
3158 { uoff(start_data), "offsetof(struct user, start_data)" },
3160 # if !defined(SPARC64)
3161 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3163 { uoff(signal), "offsetof(struct user, signal)" },
3164 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3165 { uoff(reserved), "offsetof(struct user, reserved)" },
3167 # if !defined(SPARC64)
3168 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3170 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3171 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3173 { uoff(magic), "offsetof(struct user, magic)" },
3174 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3175 # if defined(I386) || defined(X86_64)
3176 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3178 # endif /* !defined(many arches) */
3183 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3184 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3185 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3186 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3187 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3188 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3189 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3190 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3191 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3192 { uoff(u_error), "offsetof(struct user, u_error)" },
3193 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3194 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3195 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3196 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3197 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3198 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3199 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3200 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3201 { uoff(u_code), "offsetof(struct user, u_code)" },
3202 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3203 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3204 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3205 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3206 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3207 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3208 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3209 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3210 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3211 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3212 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3213 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3214 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3215 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3216 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3217 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3218 { uoff(u_start), "offsetof(struct user, u_start)" },
3219 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3220 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3221 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3222 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3223 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3224 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3225 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3226 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3227 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3228 # endif /* SUNOS4 */
3230 { sizeof(struct user), "sizeof(struct user)" },
3234 # endif /* !FREEBSD */
3237 sys_ptrace(struct tcb *tcp)
3239 const struct xlat *x;
3242 if (entering(tcp)) {
3243 printxval(ptrace_cmds, tcp->u_arg[0],
3250 tprintf(", %lu, ", tcp->u_arg[1]);
3251 addr = tcp->u_arg[2];
3253 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3254 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3255 for (x = struct_user_offsets; x->str; x++) {
3260 tprintf("%#lx, ", addr);
3261 else if (x->val > addr && x != struct_user_offsets) {
3263 tprintf("%s + %ld, ", x->str, addr - x->val);
3266 tprintf("%s, ", x->str);
3270 tprintf("%#lx, ", tcp->u_arg[2]);
3272 switch (tcp->u_arg[0]) {
3274 case PTRACE_PEEKDATA:
3275 case PTRACE_PEEKTEXT:
3276 case PTRACE_PEEKUSER:
3280 case PTRACE_SINGLESTEP:
3281 case PTRACE_SYSCALL:
3283 printsignal(tcp->u_arg[3]);
3285 # ifdef PTRACE_SETOPTIONS
3286 case PTRACE_SETOPTIONS:
3287 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3290 # ifdef PTRACE_SETSIGINFO
3291 case PTRACE_SETSIGINFO: {
3295 else if (syserror(tcp))
3296 tprintf("%#lx", tcp->u_arg[3]);
3297 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3300 printsiginfo(&si, verbose(tcp));
3304 # ifdef PTRACE_GETSIGINFO
3305 case PTRACE_GETSIGINFO:
3306 /* Don't print anything, do it at syscall return. */
3310 tprintf("%#lx", tcp->u_arg[3]);
3314 switch (tcp->u_arg[0]) {
3315 case PTRACE_PEEKDATA:
3316 case PTRACE_PEEKTEXT:
3317 case PTRACE_PEEKUSER:
3321 printnum(tcp, tcp->u_arg[3], "%#lx");
3324 # ifdef PTRACE_GETSIGINFO
3325 case PTRACE_GETSIGINFO: {
3329 else if (syserror(tcp))
3330 tprintf("%#lx", tcp->u_arg[3]);
3331 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3334 printsiginfo(&si, verbose(tcp));
3342 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3343 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3344 tprintf("%lu, ", tcp->u_arg[3]);
3345 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3346 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3347 tcp->u_arg[0] != PTRACE_READTEXT) {
3348 tprintf("%#lx", tcp->u_arg[3]);
3351 if (tcp->u_arg[0] == PTRACE_READDATA ||
3352 tcp->u_arg[0] == PTRACE_READTEXT) {
3353 tprintf("%lu, ", tcp->u_arg[3]);
3354 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3357 # endif /* SUNOS4 */
3359 tprintf("%lu", tcp->u_arg[3]);
3361 # endif /* FREEBSD */
3368 # ifndef FUTEX_CMP_REQUEUE
3369 # define FUTEX_CMP_REQUEUE 4
3371 # ifndef FUTEX_WAKE_OP
3372 # define FUTEX_WAKE_OP 5
3374 # ifndef FUTEX_LOCK_PI
3375 # define FUTEX_LOCK_PI 6
3376 # define FUTEX_UNLOCK_PI 7
3377 # define FUTEX_TRYLOCK_PI 8
3379 # ifndef FUTEX_WAIT_BITSET
3380 # define FUTEX_WAIT_BITSET 9
3382 # ifndef FUTEX_WAKE_BITSET
3383 # define FUTEX_WAKE_BITSET 10
3385 # ifndef FUTEX_WAIT_REQUEUE_PI
3386 # define FUTEX_WAIT_REQUEUE_PI 11
3388 # ifndef FUTEX_CMP_REQUEUE_PI
3389 # define FUTEX_CMP_REQUEUE_PI 12
3391 # ifndef FUTEX_PRIVATE_FLAG
3392 # define FUTEX_PRIVATE_FLAG 128
3394 # ifndef FUTEX_CLOCK_REALTIME
3395 # define FUTEX_CLOCK_REALTIME 256
3397 static const struct xlat futexops[] = {
3398 { FUTEX_WAIT, "FUTEX_WAIT" },
3399 { FUTEX_WAKE, "FUTEX_WAKE" },
3400 { FUTEX_FD, "FUTEX_FD" },
3401 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3402 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3403 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3404 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3405 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3406 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3407 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3408 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3409 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3410 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3411 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3412 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3413 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3414 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3415 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3416 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3417 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3418 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3419 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3420 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3421 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3422 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3423 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3424 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3425 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3426 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3427 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3430 # ifndef FUTEX_OP_SET
3431 # define FUTEX_OP_SET 0
3432 # define FUTEX_OP_ADD 1
3433 # define FUTEX_OP_OR 2
3434 # define FUTEX_OP_ANDN 3
3435 # define FUTEX_OP_XOR 4
3436 # define FUTEX_OP_CMP_EQ 0
3437 # define FUTEX_OP_CMP_NE 1
3438 # define FUTEX_OP_CMP_LT 2
3439 # define FUTEX_OP_CMP_LE 3
3440 # define FUTEX_OP_CMP_GT 4
3441 # define FUTEX_OP_CMP_GE 5
3443 static const struct xlat futexwakeops[] = {
3444 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3445 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3446 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3447 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3448 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3451 static const struct xlat futexwakecmps[] = {
3452 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3453 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3454 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3455 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3456 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3457 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3462 sys_futex(struct tcb *tcp)
3464 if (entering(tcp)) {
3465 long int cmd = tcp->u_arg[1] & 127;
3466 tprintf("%p, ", (void *) tcp->u_arg[0]);
3467 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3468 tprintf(", %ld", tcp->u_arg[2]);
3469 if (cmd == FUTEX_WAKE_BITSET)
3470 tprintf(", %lx", tcp->u_arg[5]);
3471 else if (cmd == FUTEX_WAIT) {
3473 printtv(tcp, tcp->u_arg[3]);
3474 } else if (cmd == FUTEX_WAIT_BITSET) {
3476 printtv(tcp, tcp->u_arg[3]);
3477 tprintf(", %lx", tcp->u_arg[5]);
3478 } else if (cmd == FUTEX_REQUEUE)
3479 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3480 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3481 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3482 else if (cmd == FUTEX_WAKE_OP) {
3483 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3484 if ((tcp->u_arg[5] >> 28) & 8)
3485 tprintf("FUTEX_OP_OPARG_SHIFT|");
3486 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3487 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3488 if ((tcp->u_arg[5] >> 24) & 8)
3489 tprintf("FUTEX_OP_OPARG_SHIFT|");
3490 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3491 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3492 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3494 printtv(tcp, tcp->u_arg[3]);
3495 tprintf(", %p", (void *) tcp->u_arg[4]);
3502 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3505 unsigned long w, min_len;
3507 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3508 min_len = len - max_strlen * sizeof(w);
3511 for (; len >= sizeof(w) && len > min_len;
3512 len -= sizeof(w), list += sizeof(w)) {
3513 if (umove(tcp, list, &w) < 0)
3524 tprintf("%#lx", list);
3526 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3529 tprintf(first ? "{}" : "}");
3534 sys_sched_setaffinity(struct tcb *tcp)
3536 if (entering(tcp)) {
3537 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3538 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3544 sys_sched_getaffinity(struct tcb *tcp)
3546 if (entering(tcp)) {
3547 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3549 if (tcp->u_rval == -1)
3550 tprintf("%#lx", tcp->u_arg[2]);
3552 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3557 static const struct xlat schedulers[] = {
3558 { SCHED_OTHER, "SCHED_OTHER" },
3559 { SCHED_RR, "SCHED_RR" },
3560 { SCHED_FIFO, "SCHED_FIFO" },
3565 sys_sched_getscheduler(struct tcb *tcp)
3567 if (entering(tcp)) {
3568 tprintf("%d", (int) tcp->u_arg[0]);
3569 } else if (! syserror(tcp)) {
3570 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3571 if (tcp->auxstr != NULL)
3578 sys_sched_setscheduler(struct tcb *tcp)
3580 if (entering(tcp)) {
3581 struct sched_param p;
3582 tprintf("%d, ", (int) tcp->u_arg[0]);
3583 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3584 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3585 tprintf(", %#lx", tcp->u_arg[2]);
3587 tprintf(", { %d }", p.__sched_priority);
3593 sys_sched_getparam(struct tcb *tcp)
3595 if (entering(tcp)) {
3596 tprintf("%d, ", (int) tcp->u_arg[0]);
3598 struct sched_param p;
3599 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3600 tprintf("%#lx", tcp->u_arg[1]);
3602 tprintf("{ %d }", p.__sched_priority);
3608 sys_sched_setparam(struct tcb *tcp)
3610 if (entering(tcp)) {
3611 struct sched_param p;
3612 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3613 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3615 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3621 sys_sched_get_priority_min(struct tcb *tcp)
3623 if (entering(tcp)) {
3624 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3630 # include <asm/prctl.h>
3632 static const struct xlat archvals[] = {
3633 { ARCH_SET_GS, "ARCH_SET_GS" },
3634 { ARCH_SET_FS, "ARCH_SET_FS" },
3635 { ARCH_GET_FS, "ARCH_GET_FS" },
3636 { ARCH_GET_GS, "ARCH_GET_GS" },
3641 sys_arch_prctl(struct tcb *tcp)
3643 if (entering(tcp)) {
3644 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3645 if (tcp->u_arg[0] == ARCH_SET_GS
3646 || tcp->u_arg[0] == ARCH_SET_FS
3648 tprintf(", %#lx", tcp->u_arg[1]);
3651 if (tcp->u_arg[0] == ARCH_GET_GS
3652 || tcp->u_arg[0] == ARCH_GET_FS
3655 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3656 tprintf(", [%#lx]", v);
3658 tprintf(", %#lx", tcp->u_arg[1]);
3663 # endif /* X86_64 */
3667 sys_getcpu(struct tcb *tcp)
3671 if (tcp->u_arg[0] == 0)
3673 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3674 tprintf("%#lx, ", tcp->u_arg[0]);
3676 tprintf("[%u], ", u);
3677 if (tcp->u_arg[1] == 0)
3679 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3680 tprintf("%#lx, ", tcp->u_arg[1]);
3682 tprintf("[%u], ", u);
3683 tprintf("%#lx", tcp->u_arg[2]);