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_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
559 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
561 static const struct xlat clone_flags[] = {
562 { CLONE_VM, "CLONE_VM" },
563 { CLONE_FS, "CLONE_FS" },
564 { CLONE_FILES, "CLONE_FILES" },
565 { CLONE_SIGHAND, "CLONE_SIGHAND" },
566 { CLONE_IDLETASK, "CLONE_IDLETASK"},
567 { CLONE_PTRACE, "CLONE_PTRACE" },
568 { CLONE_VFORK, "CLONE_VFORK" },
569 { CLONE_PARENT, "CLONE_PARENT" },
570 { CLONE_THREAD, "CLONE_THREAD" },
571 { CLONE_NEWNS, "CLONE_NEWNS" },
572 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
573 { CLONE_SETTLS, "CLONE_SETTLS" },
574 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
575 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
576 { CLONE_UNTRACED, "CLONE_UNTRACED" },
577 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
582 # include <asm/ldt.h>
583 # ifdef HAVE_STRUCT_USER_DESC
584 # define modify_ldt_ldt_s user_desc
586 extern void print_ldt_entry();
592 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
593 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
594 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
595 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
596 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
602 # elif defined X86_64 || defined ALPHA
621 const char *sep = "|";
622 unsigned long flags = tcp->u_arg[ARG_FLAGS];
623 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
624 # ifdef ARG_STACKSIZE
625 if (ARG_STACKSIZE != -1)
626 tprintf("stack_size=%#lx, ",
627 tcp->u_arg[ARG_STACKSIZE]);
630 if (!printflags(clone_flags, flags &~ CSIGNAL, NULL))
632 if ((flags & CSIGNAL) != 0)
633 tprintf("%s%s", sep, 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)
799 tcp->flags &= ~TCB_FOLLOWFORK;
803 * In occasion of using PTRACE_O_TRACECLONE, we won't see the
804 * new child if clone is called with flag CLONE_UNTRACED, so
805 * we keep the same logic with that option and don't trace it.
807 if ((sysent[tcp->scno].sys_func == sys_clone) &&
808 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
814 struct tcb *tcpchild;
818 if (!(tcp->flags & TCB_FOLLOWFORK))
821 bpt = tcp->flags & TCB_BPTSET;
831 #ifdef CLONE_PTRACE /* See new setbpt code. */
832 tcpchild = pid2tcb(pid);
833 if (tcpchild != NULL) {
834 /* The child already reported its startup trap
835 before the parent reported its syscall return. */
837 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
838 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
840 [preattached child %d of %d in weird state!]\n",
844 #endif /* CLONE_PTRACE */
847 tcpchild = alloctcb(pid);
851 /* Attach to the new child */
852 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
855 perror("PTRACE_ATTACH");
856 fprintf(stderr, "Too late?\n");
860 #endif /* !CLONE_PTRACE */
865 tcpchild->flags |= TCB_ATTACHED;
866 /* Child has BPT too, must be removed on first occasion. */
868 tcpchild->flags |= TCB_BPTSET;
869 tcpchild->baddr = tcp->baddr;
870 memcpy(tcpchild->inst, tcp->inst,
871 sizeof tcpchild->inst);
873 tcpchild->parent = tcp;
875 if (tcpchild->flags & TCB_SUSPENDED) {
876 /* The child was born suspended, due to our having
877 forced CLONE_PTRACE. */
881 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
882 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
887 Process %u resumed (parent %d ready)\n",
892 fprintf(stderr, "Process %d attached\n", pid);
895 #ifdef TCB_CLONE_THREAD
898 * Save the flags used in this call,
899 * in case we point TCP to our parent below.
901 int call_flags = tcp->u_arg[ARG_FLAGS];
902 if ((tcp->flags & TCB_CLONE_THREAD) &&
903 tcp->parent != NULL) {
904 /* The parent in this clone is itself a
905 thread belonging to another process.
906 There is no meaning to the parentage
907 relationship of the new child with the
908 thread, only with the process. We
909 associate the new thread with our
910 parent. Since this is done for every
911 new thread, there will never be a
912 TCB_CLONE_THREAD process that has
916 tcpchild->parent = tcp;
919 if (call_flags & CLONE_THREAD) {
920 tcpchild->flags |= TCB_CLONE_THREAD;
921 ++tcp->nclone_threads;
923 if ((call_flags & CLONE_PARENT) &&
924 !(call_flags & CLONE_THREAD)) {
926 tcpchild->parent = NULL;
927 if (tcp->parent != NULL) {
929 tcpchild->parent = tcp;
934 #endif /* TCB_CLONE_THREAD */
945 struct tcb *tcpchild;
950 if (known_scno(tcp) == SYS_vfork) {
951 /* Attempt to make vfork into fork, which we can follow. */
952 if (change_syscall(tcp, SYS_fork) < 0)
957 if (!followfork || dont_follow)
964 int bpt = tcp->flags & TCB_BPTSET;
966 if (!(tcp->flags & TCB_FOLLOWFORK))
976 tcpchild = alloctcb(pid);
979 /* The child must have run before it can be attached. */
984 select(0, NULL, NULL, NULL, &tv);
986 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
987 perror("PTRACE_ATTACH");
988 fprintf(stderr, "Too late?\n");
993 /* Try to catch the new process as soon as possible. */
996 for (i = 0; i < 1024; i++)
997 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1000 perror("PTRACE_ATTACH");
1001 fprintf(stderr, "Too late?\n");
1006 #endif /* !oldway */
1008 tcpchild->flags |= TCB_ATTACHED;
1009 /* Child has BPT too, must be removed on first occasion */
1011 tcpchild->flags |= TCB_BPTSET;
1012 tcpchild->baddr = tcp->baddr;
1013 memcpy(tcpchild->inst, tcp->inst,
1014 sizeof tcpchild->inst);
1016 tcpchild->parent = tcp;
1019 fprintf(stderr, "Process %d attached\n", pid);
1026 #endif /* !USE_PROCFS */
1028 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1035 return RVAL_UDECIMAL;
1039 #endif /* SUNOS4 || LINUX || FREEBSD */
1043 static char idstr[16];
1050 sprintf(idstr, "ppid %lu", getrval2(tcp));
1051 tcp->auxstr = idstr;
1062 sprintf(idstr, "euid %lu", getrval2(tcp));
1063 tcp->auxstr = idstr;
1074 sprintf(idstr, "egid %lu", getrval2(tcp));
1075 tcp->auxstr = idstr;
1089 if (entering(tcp)) {
1090 tprintf("%u", (uid_t) tcp->u_arg[0]);
1099 if (entering(tcp)) {
1100 tprintf("%u", (gid_t) tcp->u_arg[0]);
1106 sys_getresuid(struct tcb *tcp)
1111 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1112 tcp->u_arg[1], tcp->u_arg[2]);
1114 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1115 tprintf("%#lx, ", tcp->u_arg[0]);
1117 tprintf("[%lu], ", (unsigned long) uid);
1118 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1119 tprintf("%#lx, ", tcp->u_arg[1]);
1121 tprintf("[%lu], ", (unsigned long) uid);
1122 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1123 tprintf("%#lx", tcp->u_arg[2]);
1125 tprintf("[%lu]", (unsigned long) uid);
1138 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1139 tcp->u_arg[1], tcp->u_arg[2]);
1141 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1142 tprintf("%#lx, ", tcp->u_arg[0]);
1144 tprintf("[%lu], ", (unsigned long) gid);
1145 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1146 tprintf("%#lx, ", tcp->u_arg[1]);
1148 tprintf("[%lu], ", (unsigned long) gid);
1149 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1150 tprintf("%#lx", tcp->u_arg[2]);
1152 tprintf("[%lu]", (unsigned long) gid);
1164 if (entering(tcp)) {
1165 printuid("", tcp->u_arg[0]);
1166 printuid(", ", tcp->u_arg[1]);
1175 if (entering(tcp)) {
1176 printuid("", tcp->u_arg[0]);
1177 printuid(", ", tcp->u_arg[1]);
1182 #if defined(LINUX) || defined(FREEBSD)
1187 if (entering(tcp)) {
1188 printuid("", tcp->u_arg[0]);
1189 printuid(", ", tcp->u_arg[1]);
1190 printuid(", ", tcp->u_arg[2]);
1198 if (entering(tcp)) {
1199 printuid("", tcp->u_arg[0]);
1200 printuid(", ", tcp->u_arg[1]);
1201 printuid(", ", tcp->u_arg[2]);
1206 #endif /* LINUX || FREEBSD */
1212 if (entering(tcp)) {
1213 unsigned long len, size, start, cur, end, abbrev_end;
1217 len = tcp->u_arg[0];
1218 tprintf("%lu, ", len);
1223 start = tcp->u_arg[1];
1228 size = len * sizeof(gid);
1230 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1231 tprintf("%#lx", start);
1235 abbrev_end = start + max_strlen * sizeof(gid);
1236 if (abbrev_end < start)
1242 for (cur = start; cur < end; cur += sizeof(gid)) {
1245 if (cur >= abbrev_end) {
1249 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1254 tprintf("%lu", (unsigned long) gid);
1258 tprintf(" %#lx", tcp->u_arg[1]);
1269 if (entering(tcp)) {
1270 len = tcp->u_arg[0];
1271 tprintf("%lu, ", len);
1273 unsigned long size, start, cur, end, abbrev_end;
1282 start = tcp->u_arg[1];
1287 if (tcp->u_arg[0] == 0) {
1288 tprintf("%#lx", start);
1291 size = len * sizeof(gid);
1293 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1294 size / sizeof(gid) != len || end < start) {
1295 tprintf("%#lx", start);
1299 abbrev_end = start + max_strlen * sizeof(gid);
1300 if (abbrev_end < start)
1306 for (cur = start; cur < end; cur += sizeof(gid)) {
1309 if (cur >= abbrev_end) {
1313 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1318 tprintf("%lu", (unsigned long) gid);
1322 tprintf(" %#lx", tcp->u_arg[1]);
1329 sys_setgroups32(tcp)
1332 if (entering(tcp)) {
1333 unsigned long len, size, start, cur, end, abbrev_end;
1337 len = tcp->u_arg[0];
1338 tprintf("%lu, ", len);
1343 start = tcp->u_arg[1];
1348 size = len * sizeof(gid);
1350 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1351 tprintf("%#lx", start);
1355 abbrev_end = start + max_strlen * sizeof(gid);
1356 if (abbrev_end < start)
1362 for (cur = start; cur < end; cur += sizeof(gid)) {
1365 if (cur >= abbrev_end) {
1369 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1374 tprintf("%lu", (unsigned long) gid);
1378 tprintf(" %#lx", tcp->u_arg[1]);
1384 sys_getgroups32(tcp)
1389 if (entering(tcp)) {
1390 len = tcp->u_arg[0];
1391 tprintf("%lu, ", len);
1393 unsigned long size, start, cur, end, abbrev_end;
1402 start = tcp->u_arg[1];
1407 size = len * sizeof(gid);
1409 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1410 size / sizeof(gid) != len || end < start) {
1411 tprintf("%#lx", start);
1415 abbrev_end = start + max_strlen * sizeof(gid);
1416 if (abbrev_end < start)
1422 for (cur = start; cur < end; cur += sizeof(gid)) {
1425 if (cur >= abbrev_end) {
1429 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1434 tprintf("%lu", (unsigned long) gid);
1438 tprintf(" %#lx", tcp->u_arg[1]);
1444 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1449 if (entering(tcp)) {
1451 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1456 #endif /* ALPHA || SUNOS4 || SVR4 */
1462 if (entering(tcp)) {
1464 tprintf("%lu", tcp->u_arg[0]);
1474 if (entering(tcp)) {
1475 tprintf("%lu", tcp->u_arg[0]);
1491 if (entering(tcp)) {
1492 tprintf("%lu", tcp->u_arg[0]);
1501 if (entering(tcp)) {
1502 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1509 #include <sys/privilege.h>
1512 static const struct xlat procpriv_cmds [] = {
1513 { SETPRV, "SETPRV" },
1514 { CLRPRV, "CLRPRV" },
1515 { PUTPRV, "PUTPRV" },
1516 { GETPRV, "GETPRV" },
1517 { CNTPRV, "CNTPRV" },
1522 static const struct xlat procpriv_priv [] = {
1523 { P_OWNER, "P_OWNER" },
1524 { P_AUDIT, "P_AUDIT" },
1525 { P_COMPAT, "P_COMPAT" },
1526 { P_DACREAD, "P_DACREAD" },
1527 { P_DACWRITE, "P_DACWRITE" },
1529 { P_FILESYS, "P_FILESYS" },
1530 { P_MACREAD, "P_MACREAD" },
1531 { P_MACWRITE, "P_MACWRITE" },
1532 { P_MOUNT, "P_MOUNT" },
1533 { P_MULTIDIR, "P_MULTIDIR" },
1534 { P_SETPLEVEL, "P_SETPLEVEL" },
1535 { P_SETSPRIV, "P_SETSPRIV" },
1536 { P_SETUID, "P_SETUID" },
1537 { P_SYSOPS, "P_SYSOPS" },
1538 { P_SETUPRIV, "P_SETUPRIV" },
1539 { P_DRIVER, "P_DRIVER" },
1540 { P_RTIME, "P_RTIME" },
1541 { P_MACUPGRADE, "P_MACUPGRADE" },
1542 { P_FSYSRANGE, "P_FSYSRANGE" },
1543 { P_SETFLEVEL, "P_SETFLEVEL" },
1544 { P_AUDITWR, "P_AUDITWR" },
1545 { P_TSHAR, "P_TSHAR" },
1546 { P_PLOCK, "P_PLOCK" },
1547 { P_CORE, "P_CORE" },
1548 { P_LOADMOD, "P_LOADMOD" },
1549 { P_BIND, "P_BIND" },
1550 { P_ALLPRIVS, "P_ALLPRIVS" },
1555 static const struct xlat procpriv_type [] = {
1556 { PS_FIX, "PS_FIX" },
1557 { PS_INH, "PS_INH" },
1558 { PS_MAX, "PS_MAX" },
1559 { PS_WKG, "PS_WKG" },
1565 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1568 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1569 int dots = len > max;
1572 if (len > max) len = max;
1575 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1577 tprintf ("%#lx", addr);
1583 for (i = 0; i < len; ++i) {
1586 if (i) tprintf (", ");
1588 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1589 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1591 tprintf ("%s|%s", t, p);
1594 tprintf ("%#lx", buf [i]);
1598 if (dots) tprintf (" ...");
1608 if (entering(tcp)) {
1609 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1610 switch (tcp->u_arg[0]) {
1612 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1620 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1621 tprintf (", %ld", tcp->u_arg[2]);
1624 else if (tcp->u_arg[0] == GETPRV) {
1625 if (syserror (tcp)) {
1626 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1630 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1631 tprintf (", %ld", tcp->u_arg[2]);
1638 #endif /* UNIXWARE */
1642 printargv(struct tcb *tcp, long addr)
1647 char data[sizeof(long)];
1653 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1654 if (umoven(tcp, addr, personality_wordsize[current_personality],
1656 tprintf("%#lx", addr);
1659 if (personality_wordsize[current_personality] == 4)
1664 printstr(tcp, cp.p64, -1);
1665 addr += personality_wordsize[current_personality];
1668 tprintf("%s...", sep);
1672 printargc(const char *fmt, struct tcb *tcp, long addr)
1677 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1678 addr += sizeof(char *);
1680 tprintf(fmt, count, count == 1 ? "" : "s");
1683 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1685 sys_execv(struct tcb *tcp)
1687 if (entering(tcp)) {
1688 printpath(tcp, tcp->u_arg[0]);
1690 tprintf(", %#lx", tcp->u_arg[1]);
1693 printargv(tcp, tcp->u_arg[1]);
1699 #endif /* SPARC || SPARC64 || SUNOS4 */
1702 sys_execve(struct tcb *tcp)
1704 if (entering(tcp)) {
1705 printpath(tcp, tcp->u_arg[0]);
1707 tprintf(", %#lx", tcp->u_arg[1]);
1710 printargv(tcp, tcp->u_arg[1]);
1714 tprintf(", %#lx", tcp->u_arg[2]);
1715 else if (abbrev(tcp))
1716 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1719 printargv(tcp, tcp->u_arg[2]);
1728 int sys_rexecve(tcp)
1731 if (entering (tcp)) {
1733 tprintf (", %ld", tcp->u_arg[3]);
1745 if (exiting(tcp) && !syserror(tcp) && followfork)
1748 #if defined LINUX && defined TCB_WAITEXECVE
1749 if (exiting(tcp) && syserror(tcp))
1750 tcp->flags &= ~TCB_WAITEXECVE;
1752 tcp->flags |= TCB_WAITEXECVE;
1753 #endif /* LINUX && TCB_WAITEXECVE */
1759 #define __WNOTHREAD 0x20000000
1762 #define __WALL 0x40000000
1765 #define __WCLONE 0x80000000
1769 static const struct xlat wait4_options[] = {
1770 { WNOHANG, "WNOHANG" },
1772 { WUNTRACED, "WUNTRACED" },
1775 { WEXITED, "WEXITED" },
1778 { WTRAPPED, "WTRAPPED" },
1781 { WSTOPPED, "WSTOPPED" },
1784 { WCONTINUED, "WCONTINUED" },
1787 { WNOWAIT, "WNOWAIT" },
1790 { __WCLONE, "__WCLONE" },
1793 { __WALL, "__WALL" },
1796 { __WNOTHREAD, "__WNOTHREAD" },
1801 #if !defined WCOREFLAG && defined WCOREFLG
1802 # define WCOREFLAG WCOREFLG
1805 # define WCOREFLAG 0x80
1808 # define WCOREDUMP(status) ((status) & 0200)
1813 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1816 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1826 * Here is a tricky presentation problem. This solution
1827 * is still not entirely satisfactory but since there
1828 * are no wait status constructors it will have to do.
1830 if (WIFSTOPPED(status)) {
1831 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1832 signame(WSTOPSIG(status)));
1833 status &= ~W_STOPCODE(WSTOPSIG(status));
1835 else if (WIFSIGNALED(status)) {
1836 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1837 signame(WTERMSIG(status)),
1838 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1839 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1841 else if (WIFEXITED(status)) {
1842 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1843 WEXITSTATUS(status));
1845 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1848 tprintf("[%#x]", status);
1855 tprintf(" | %#x]", status);
1861 printwaitn(struct tcb *tcp, int n, int bitness)
1866 if (entering(tcp)) {
1868 /* On Linux, kernel-side pid_t is typedef'ed to int
1869 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1870 * pid argument to int on 64bit arches, producing,
1871 * for example, wait4(4294967295, ...) instead of -1
1872 * in strace. We have to use int here, not long.
1874 int pid = tcp->u_arg[0];
1875 tprintf("%d, ", pid);
1878 * Sign-extend a 32-bit value when that's what it is.
1880 long pid = tcp->u_arg[0];
1881 if (personality_wordsize[current_personality] < sizeof pid)
1882 pid = (long) (int) pid;
1883 tprintf("%ld, ", pid);
1889 else if (syserror(tcp) || tcp->u_rval == 0)
1890 tprintf("%#lx", tcp->u_arg[1]);
1891 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1894 exited = printstatus(status);
1897 printflags(wait4_options, tcp->u_arg[2], "W???");
1904 else if (tcp->u_rval > 0) {
1907 printrusage32(tcp, tcp->u_arg[3]);
1910 printrusage(tcp, tcp->u_arg[3]);
1914 else if (tcp->u_rval > 0 && exited)
1915 printrusage(tcp, tcp->u_arg[3]);
1918 tprintf("%#lx", tcp->u_arg[3]);
1925 internal_wait(tcp, flagarg)
1931 #ifdef TCB_CLONE_THREAD
1932 if (tcp->flags & TCB_CLONE_THREAD)
1933 /* The children we wait for are our parent's children. */
1934 got_kids = (tcp->parent->nchildren
1935 > tcp->parent->nclone_threads);
1937 got_kids = (tcp->nchildren > tcp->nclone_threads);
1939 got_kids = tcp->nchildren > 0;
1942 if (entering(tcp) && got_kids) {
1943 /* There are children that this parent should block for.
1944 But ptrace made us the parent of the traced children
1945 and the real parent will get ECHILD from the wait call.
1947 XXX If we attached with strace -f -p PID, then there
1948 may be untraced dead children the parent could be reaping
1949 now, but we make him block. */
1951 /* ??? WTA: fix bug with hanging children */
1953 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1955 * There are traced children. We'll make the parent
1956 * block to avoid a false ECHILD error due to our
1957 * ptrace having stolen the children. However,
1958 * we shouldn't block if there are zombies to reap.
1959 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1961 struct tcb *child = NULL;
1962 if (tcp->nzombies > 0 &&
1963 (tcp->u_arg[0] == -1 ||
1964 (child = pid2tcb(tcp->u_arg[0])) == NULL))
1966 if (tcp->u_arg[0] > 0) {
1968 * If the parent waits for a specified child
1969 * PID, then it must get ECHILD right away
1970 * if that PID is not one of its children.
1971 * Make sure that the requested PID matches
1972 * one of the parent's children that we are
1973 * tracing, and don't suspend it otherwise.
1976 child = pid2tcb(tcp->u_arg[0]);
1977 if (child == NULL || child->parent != (
1978 #ifdef TCB_CLONE_THREAD
1979 (tcp->flags & TCB_CLONE_THREAD)
1983 (child->flags & TCB_EXITING))
1986 tcp->flags |= TCB_SUSPENDED;
1987 tcp->waitpid = tcp->u_arg[0];
1988 #ifdef TCB_CLONE_THREAD
1989 if (tcp->flags & TCB_CLONE_THREAD)
1990 tcp->parent->nclone_waiting++;
1994 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1995 if (tcp->u_arg[flagarg] & WNOHANG) {
1996 /* We must force a fake result of 0 instead of
1997 the ECHILD error. */
1998 return force_result(tcp, 0, 0);
2001 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2002 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2004 * We just reaped a child we don't know about,
2005 * presumably a zombie we already droptcb'd.
2019 /* The library wrapper stuffs this into the user variable. */
2021 printstatus(getrval2(tcp));
2036 if (!syserror(tcp)) {
2037 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2038 tprintf("%#lx", tcp->u_arg[0]);
2040 printstatus(status);
2051 return printwaitn(tcp, 3, 0);
2058 return printwaitn(tcp, 4, 0);
2066 return printwaitn(tcp, 4, 1);
2070 #if defined SVR4 || defined LINUX
2072 static const struct xlat waitid_types[] = {
2075 { P_PPID, "P_PPID" },
2077 { P_PGID, "P_PGID" },
2092 { P_LWPID, "P_LWPID" },
2098 sys_waitid(struct tcb *tcp)
2102 if (entering(tcp)) {
2103 printxval(waitid_types, tcp->u_arg[0], "P_???");
2104 tprintf(", %ld, ", tcp->u_arg[1]);
2110 else if (syserror(tcp))
2111 tprintf("%#lx", tcp->u_arg[2]);
2112 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2115 printsiginfo(&si, verbose(tcp));
2118 printflags(wait4_options, tcp->u_arg[3], "W???");
2119 if (tcp->u_nargs > 4) {
2124 else if (tcp->u_error)
2125 tprintf("%#lx", tcp->u_arg[4]);
2127 printrusage(tcp, tcp->u_arg[4]);
2133 #endif /* SVR4 or LINUX */
2140 tprintf("%lu", tcp->u_arg[0]);
2148 struct utsname uname;
2151 if (syserror(tcp) || !verbose(tcp))
2152 tprintf("%#lx", tcp->u_arg[0]);
2153 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2155 else if (!abbrev(tcp)) {
2157 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2158 uname.sysname, uname.nodename);
2159 tprintf("release=\"%s\", version=\"%s\", ",
2160 uname.release, uname.version);
2161 tprintf("machine=\"%s\"", uname.machine);
2164 tprintf(", domainname=\"%s\"", uname.domainname);
2170 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2171 uname.sysname, uname.nodename);
2178 static const struct xlat ptrace_cmds[] = {
2180 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2181 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2182 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2183 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2184 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2185 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2186 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2187 { PTRACE_CONT, "PTRACE_CONT" },
2188 { PTRACE_KILL, "PTRACE_KILL" },
2189 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2190 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2191 { PTRACE_DETACH, "PTRACE_DETACH" },
2192 # ifdef PTRACE_GETREGS
2193 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2195 # ifdef PTRACE_SETREGS
2196 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2198 # ifdef PTRACE_GETFPREGS
2199 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2201 # ifdef PTRACE_SETFPREGS
2202 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2204 # ifdef PTRACE_GETFPXREGS
2205 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2207 # ifdef PTRACE_SETFPXREGS
2208 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2210 # ifdef PTRACE_GETVRREGS
2211 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2213 # ifdef PTRACE_SETVRREGS
2214 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2216 # ifdef PTRACE_SETOPTIONS
2217 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2219 # ifdef PTRACE_GETEVENTMSG
2220 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2222 # ifdef PTRACE_GETSIGINFO
2223 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2225 # ifdef PTRACE_SETSIGINFO
2226 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2228 # ifdef PTRACE_SET_SYSCALL
2229 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2232 { PTRACE_READDATA, "PTRACE_READDATA" },
2233 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2234 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2235 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2236 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2237 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2239 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2240 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2242 { PTRACE_22, "PTRACE_22" },
2243 { PTRACE_23, "PTRACE_3" },
2244 # endif /* !SPARC */
2245 # endif /* SUNOS4 */
2246 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2248 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2250 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2251 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2252 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2254 { PTRACE_26, "PTRACE_26" },
2255 { PTRACE_27, "PTRACE_27" },
2256 { PTRACE_28, "PTRACE_28" },
2258 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2259 # endif /* SUNOS4 */
2261 # else /* FREEBSD */
2263 { PT_TRACE_ME, "PT_TRACE_ME" },
2264 { PT_READ_I, "PT_READ_I" },
2265 { PT_READ_D, "PT_READ_D" },
2266 { PT_WRITE_I, "PT_WRITE_I" },
2267 { PT_WRITE_D, "PT_WRITE_D" },
2269 { PT_READ_U, "PT_READ_U" },
2271 { PT_CONTINUE, "PT_CONTINUE" },
2272 { PT_KILL, "PT_KILL" },
2273 { PT_STEP, "PT_STEP" },
2274 { PT_ATTACH, "PT_ATTACH" },
2275 { PT_DETACH, "PT_DETACH" },
2276 { PT_GETREGS, "PT_GETREGS" },
2277 { PT_SETREGS, "PT_SETREGS" },
2278 { PT_GETFPREGS, "PT_GETFPREGS" },
2279 { PT_SETFPREGS, "PT_SETFPREGS" },
2280 { PT_GETDBREGS, "PT_GETDBREGS" },
2281 { PT_SETDBREGS, "PT_SETDBREGS" },
2282 # endif /* FREEBSD */
2287 # ifdef PTRACE_SETOPTIONS
2288 static const struct xlat ptrace_setoptions_flags[] = {
2289 # ifdef PTRACE_O_TRACESYSGOOD
2290 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2292 # ifdef PTRACE_O_TRACEFORK
2293 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2295 # ifdef PTRACE_O_TRACEVFORK
2296 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2298 # ifdef PTRACE_O_TRACECLONE
2299 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2301 # ifdef PTRACE_O_TRACEEXEC
2302 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2304 # ifdef PTRACE_O_TRACEVFORKDONE
2305 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2307 # ifdef PTRACE_O_TRACEEXIT
2308 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2312 # endif /* PTRACE_SETOPTIONS */
2313 # endif /* !FREEBSD */
2316 const struct xlat struct_user_offsets[] = {
2318 # if defined(S390) || defined(S390X)
2319 { PT_PSWMASK, "psw_mask" },
2320 { PT_PSWADDR, "psw_addr" },
2321 { PT_GPR0, "gpr0" },
2322 { PT_GPR1, "gpr1" },
2323 { PT_GPR2, "gpr2" },
2324 { PT_GPR3, "gpr3" },
2325 { PT_GPR4, "gpr4" },
2326 { PT_GPR5, "gpr5" },
2327 { PT_GPR6, "gpr6" },
2328 { PT_GPR7, "gpr7" },
2329 { PT_GPR8, "gpr8" },
2330 { PT_GPR9, "gpr9" },
2331 { PT_GPR10, "gpr10" },
2332 { PT_GPR11, "gpr11" },
2333 { PT_GPR12, "gpr12" },
2334 { PT_GPR13, "gpr13" },
2335 { PT_GPR14, "gpr14" },
2336 { PT_GPR15, "gpr15" },
2337 { PT_ACR0, "acr0" },
2338 { PT_ACR1, "acr1" },
2339 { PT_ACR2, "acr2" },
2340 { PT_ACR3, "acr3" },
2341 { PT_ACR4, "acr4" },
2342 { PT_ACR5, "acr5" },
2343 { PT_ACR6, "acr6" },
2344 { PT_ACR7, "acr7" },
2345 { PT_ACR8, "acr8" },
2346 { PT_ACR9, "acr9" },
2347 { PT_ACR10, "acr10" },
2348 { PT_ACR11, "acr11" },
2349 { PT_ACR12, "acr12" },
2350 { PT_ACR13, "acr13" },
2351 { PT_ACR14, "acr14" },
2352 { PT_ACR15, "acr15" },
2353 { PT_ORIGGPR2, "orig_gpr2" },
2356 { PT_FPR0_HI, "fpr0.hi" },
2357 { PT_FPR0_LO, "fpr0.lo" },
2358 { PT_FPR1_HI, "fpr1.hi" },
2359 { PT_FPR1_LO, "fpr1.lo" },
2360 { PT_FPR2_HI, "fpr2.hi" },
2361 { PT_FPR2_LO, "fpr2.lo" },
2362 { PT_FPR3_HI, "fpr3.hi" },
2363 { PT_FPR3_LO, "fpr3.lo" },
2364 { PT_FPR4_HI, "fpr4.hi" },
2365 { PT_FPR4_LO, "fpr4.lo" },
2366 { PT_FPR5_HI, "fpr5.hi" },
2367 { PT_FPR5_LO, "fpr5.lo" },
2368 { PT_FPR6_HI, "fpr6.hi" },
2369 { PT_FPR6_LO, "fpr6.lo" },
2370 { PT_FPR7_HI, "fpr7.hi" },
2371 { PT_FPR7_LO, "fpr7.lo" },
2372 { PT_FPR8_HI, "fpr8.hi" },
2373 { PT_FPR8_LO, "fpr8.lo" },
2374 { PT_FPR9_HI, "fpr9.hi" },
2375 { PT_FPR9_LO, "fpr9.lo" },
2376 { PT_FPR10_HI, "fpr10.hi" },
2377 { PT_FPR10_LO, "fpr10.lo" },
2378 { PT_FPR11_HI, "fpr11.hi" },
2379 { PT_FPR11_LO, "fpr11.lo" },
2380 { PT_FPR12_HI, "fpr12.hi" },
2381 { PT_FPR12_LO, "fpr12.lo" },
2382 { PT_FPR13_HI, "fpr13.hi" },
2383 { PT_FPR13_LO, "fpr13.lo" },
2384 { PT_FPR14_HI, "fpr14.hi" },
2385 { PT_FPR14_LO, "fpr14.lo" },
2386 { PT_FPR15_HI, "fpr15.hi" },
2387 { PT_FPR15_LO, "fpr15.lo" },
2390 { PT_FPR0, "fpr0" },
2391 { PT_FPR1, "fpr1" },
2392 { PT_FPR2, "fpr2" },
2393 { PT_FPR3, "fpr3" },
2394 { PT_FPR4, "fpr4" },
2395 { PT_FPR5, "fpr5" },
2396 { PT_FPR6, "fpr6" },
2397 { PT_FPR7, "fpr7" },
2398 { PT_FPR8, "fpr8" },
2399 { PT_FPR9, "fpr9" },
2400 { PT_FPR10, "fpr10" },
2401 { PT_FPR11, "fpr11" },
2402 { PT_FPR12, "fpr12" },
2403 { PT_FPR13, "fpr13" },
2404 { PT_FPR14, "fpr14" },
2405 { PT_FPR15, "fpr15" },
2408 { PT_CR_10, "cr10" },
2409 { PT_CR_11, "cr11" },
2410 { PT_IEEE_IP, "ieee_exception_ip" },
2411 # elif defined(SPARC)
2412 /* XXX No support for these offsets yet. */
2413 # elif defined(HPPA)
2414 /* XXX No support for these offsets yet. */
2415 # elif defined(POWERPC)
2417 # define PT_ORIG_R3 34
2419 # define REGSIZE (sizeof(unsigned long))
2420 { REGSIZE*PT_R0, "r0" },
2421 { REGSIZE*PT_R1, "r1" },
2422 { REGSIZE*PT_R2, "r2" },
2423 { REGSIZE*PT_R3, "r3" },
2424 { REGSIZE*PT_R4, "r4" },
2425 { REGSIZE*PT_R5, "r5" },
2426 { REGSIZE*PT_R6, "r6" },
2427 { REGSIZE*PT_R7, "r7" },
2428 { REGSIZE*PT_R8, "r8" },
2429 { REGSIZE*PT_R9, "r9" },
2430 { REGSIZE*PT_R10, "r10" },
2431 { REGSIZE*PT_R11, "r11" },
2432 { REGSIZE*PT_R12, "r12" },
2433 { REGSIZE*PT_R13, "r13" },
2434 { REGSIZE*PT_R14, "r14" },
2435 { REGSIZE*PT_R15, "r15" },
2436 { REGSIZE*PT_R16, "r16" },
2437 { REGSIZE*PT_R17, "r17" },
2438 { REGSIZE*PT_R18, "r18" },
2439 { REGSIZE*PT_R19, "r19" },
2440 { REGSIZE*PT_R20, "r20" },
2441 { REGSIZE*PT_R21, "r21" },
2442 { REGSIZE*PT_R22, "r22" },
2443 { REGSIZE*PT_R23, "r23" },
2444 { REGSIZE*PT_R24, "r24" },
2445 { REGSIZE*PT_R25, "r25" },
2446 { REGSIZE*PT_R26, "r26" },
2447 { REGSIZE*PT_R27, "r27" },
2448 { REGSIZE*PT_R28, "r28" },
2449 { REGSIZE*PT_R29, "r29" },
2450 { REGSIZE*PT_R30, "r30" },
2451 { REGSIZE*PT_R31, "r31" },
2452 { REGSIZE*PT_NIP, "NIP" },
2453 { REGSIZE*PT_MSR, "MSR" },
2454 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2455 { REGSIZE*PT_CTR, "CTR" },
2456 { REGSIZE*PT_LNK, "LNK" },
2457 { REGSIZE*PT_XER, "XER" },
2458 { REGSIZE*PT_CCR, "CCR" },
2459 { REGSIZE*PT_FPR0, "FPR0" },
2461 # elif defined(ALPHA)
2527 # elif defined(IA64)
2528 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2529 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2530 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2531 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2532 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2533 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2534 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2535 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2536 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2537 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2538 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2539 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2540 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2541 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2542 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2543 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2544 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2545 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2546 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2547 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2548 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2549 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2550 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2551 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2552 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2553 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2554 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2555 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2556 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2557 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2558 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2559 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2561 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2562 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2563 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2564 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2565 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2566 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2567 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2568 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2569 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2570 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2571 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2572 { PT_B4, "b4" }, { PT_B5, "b5" },
2573 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2575 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2576 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2577 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2578 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2579 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2580 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2581 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2582 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2583 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2584 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2585 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2586 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2587 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2588 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2589 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2590 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2591 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2593 { PT_AR_CSD, "ar.csd" },
2596 { PT_AR_SSD, "ar.ssd" },
2598 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2599 # elif defined(I386)
2611 { 4*ORIG_EAX, "4*ORIG_EAX" },
2615 { 4*UESP, "4*UESP" },
2617 # elif defined(X86_64)
2633 { 8*ORIG_RAX, "8*ORIG_RAX" },
2636 { 8*EFLAGS, "8*EFL" },
2639 # elif defined(M68K)
2640 { 4*PT_D1, "4*PT_D1" },
2641 { 4*PT_D2, "4*PT_D2" },
2642 { 4*PT_D3, "4*PT_D3" },
2643 { 4*PT_D4, "4*PT_D4" },
2644 { 4*PT_D5, "4*PT_D5" },
2645 { 4*PT_D6, "4*PT_D6" },
2646 { 4*PT_D7, "4*PT_D7" },
2647 { 4*PT_A0, "4*PT_A0" },
2648 { 4*PT_A1, "4*PT_A1" },
2649 { 4*PT_A2, "4*PT_A2" },
2650 { 4*PT_A3, "4*PT_A3" },
2651 { 4*PT_A4, "4*PT_A4" },
2652 { 4*PT_A5, "4*PT_A5" },
2653 { 4*PT_A6, "4*PT_A6" },
2654 { 4*PT_D0, "4*PT_D0" },
2655 { 4*PT_USP, "4*PT_USP" },
2656 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2657 { 4*PT_SR, "4*PT_SR" },
2658 { 4*PT_PC, "4*PT_PC" },
2660 { 4*REG_REG0, "4*REG_REG0" },
2661 { 4*(REG_REG0+1), "4*REG_REG1" },
2662 { 4*(REG_REG0+2), "4*REG_REG2" },
2663 { 4*(REG_REG0+3), "4*REG_REG3" },
2664 { 4*(REG_REG0+4), "4*REG_REG4" },
2665 { 4*(REG_REG0+5), "4*REG_REG5" },
2666 { 4*(REG_REG0+6), "4*REG_REG6" },
2667 { 4*(REG_REG0+7), "4*REG_REG7" },
2668 { 4*(REG_REG0+8), "4*REG_REG8" },
2669 { 4*(REG_REG0+9), "4*REG_REG9" },
2670 { 4*(REG_REG0+10), "4*REG_REG10" },
2671 { 4*(REG_REG0+11), "4*REG_REG11" },
2672 { 4*(REG_REG0+12), "4*REG_REG12" },
2673 { 4*(REG_REG0+13), "4*REG_REG13" },
2674 { 4*(REG_REG0+14), "4*REG_REG14" },
2675 { 4*REG_REG15, "4*REG_REG15" },
2676 { 4*REG_PC, "4*REG_PC" },
2677 { 4*REG_PR, "4*REG_PR" },
2678 { 4*REG_SR, "4*REG_SR" },
2679 { 4*REG_GBR, "4*REG_GBR" },
2680 { 4*REG_MACH, "4*REG_MACH" },
2681 { 4*REG_MACL, "4*REG_MACL" },
2682 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2683 { 4*REG_FPUL, "4*REG_FPUL" },
2684 { 4*REG_FPREG0, "4*REG_FPREG0" },
2685 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2686 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2687 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2688 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2689 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2690 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2691 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2692 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2693 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2694 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2695 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2696 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2697 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2698 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2699 { 4*REG_FPREG15, "4*REG_FPREG15" },
2701 { 4*REG_XDREG0, "4*REG_XDREG0" },
2702 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2703 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2704 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2705 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2706 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2707 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2708 { 4*REG_XDREG14, "4*REG_XDREG14" },
2710 { 4*REG_FPSCR, "4*REG_FPSCR" },
2711 # elif defined(SH64)
2716 { 16, "syscall no.(L)" },
2717 { 20, "syscall_no.(U)" },
2860 /* This entry is in case pt_regs contains dregs (depends on
2861 the kernel build options). */
2862 { uoff(regs), "offsetof(struct user, regs)" },
2863 { uoff(fpu), "offsetof(struct user, fpu)" },
2865 { uoff(regs.ARM_r0), "r0" },
2866 { uoff(regs.ARM_r1), "r1" },
2867 { uoff(regs.ARM_r2), "r2" },
2868 { uoff(regs.ARM_r3), "r3" },
2869 { uoff(regs.ARM_r4), "r4" },
2870 { uoff(regs.ARM_r5), "r5" },
2871 { uoff(regs.ARM_r6), "r6" },
2872 { uoff(regs.ARM_r7), "r7" },
2873 { uoff(regs.ARM_r8), "r8" },
2874 { uoff(regs.ARM_r9), "r9" },
2875 { uoff(regs.ARM_r10), "r10" },
2876 { uoff(regs.ARM_fp), "fp" },
2877 { uoff(regs.ARM_ip), "ip" },
2878 { uoff(regs.ARM_sp), "sp" },
2879 { uoff(regs.ARM_lr), "lr" },
2880 { uoff(regs.ARM_pc), "pc" },
2881 { uoff(regs.ARM_cpsr), "cpsr" },
2882 # elif defined(AVR32)
2883 { uoff(regs.sr), "sr" },
2884 { uoff(regs.pc), "pc" },
2885 { uoff(regs.lr), "lr" },
2886 { uoff(regs.sp), "sp" },
2887 { uoff(regs.r12), "r12" },
2888 { uoff(regs.r11), "r11" },
2889 { uoff(regs.r10), "r10" },
2890 { uoff(regs.r9), "r9" },
2891 { uoff(regs.r8), "r8" },
2892 { uoff(regs.r7), "r7" },
2893 { uoff(regs.r6), "r6" },
2894 { uoff(regs.r5), "r5" },
2895 { uoff(regs.r4), "r4" },
2896 { uoff(regs.r3), "r3" },
2897 { uoff(regs.r2), "r2" },
2898 { uoff(regs.r1), "r1" },
2899 { uoff(regs.r0), "r0" },
2900 { uoff(regs.r12_orig), "orig_r12" },
2901 # elif defined(MIPS)
2973 # elif defined(TILE)
2974 { PTREGS_OFFSET_REG(0), "r0" },
2975 { PTREGS_OFFSET_REG(1), "r1" },
2976 { PTREGS_OFFSET_REG(2), "r2" },
2977 { PTREGS_OFFSET_REG(3), "r3" },
2978 { PTREGS_OFFSET_REG(4), "r4" },
2979 { PTREGS_OFFSET_REG(5), "r5" },
2980 { PTREGS_OFFSET_REG(6), "r6" },
2981 { PTREGS_OFFSET_REG(7), "r7" },
2982 { PTREGS_OFFSET_REG(8), "r8" },
2983 { PTREGS_OFFSET_REG(9), "r9" },
2984 { PTREGS_OFFSET_REG(10), "r10" },
2985 { PTREGS_OFFSET_REG(11), "r11" },
2986 { PTREGS_OFFSET_REG(12), "r12" },
2987 { PTREGS_OFFSET_REG(13), "r13" },
2988 { PTREGS_OFFSET_REG(14), "r14" },
2989 { PTREGS_OFFSET_REG(15), "r15" },
2990 { PTREGS_OFFSET_REG(16), "r16" },
2991 { PTREGS_OFFSET_REG(17), "r17" },
2992 { PTREGS_OFFSET_REG(18), "r18" },
2993 { PTREGS_OFFSET_REG(19), "r19" },
2994 { PTREGS_OFFSET_REG(20), "r20" },
2995 { PTREGS_OFFSET_REG(21), "r21" },
2996 { PTREGS_OFFSET_REG(22), "r22" },
2997 { PTREGS_OFFSET_REG(23), "r23" },
2998 { PTREGS_OFFSET_REG(24), "r24" },
2999 { PTREGS_OFFSET_REG(25), "r25" },
3000 { PTREGS_OFFSET_REG(26), "r26" },
3001 { PTREGS_OFFSET_REG(27), "r27" },
3002 { PTREGS_OFFSET_REG(28), "r28" },
3003 { PTREGS_OFFSET_REG(29), "r29" },
3004 { PTREGS_OFFSET_REG(30), "r30" },
3005 { PTREGS_OFFSET_REG(31), "r31" },
3006 { PTREGS_OFFSET_REG(32), "r32" },
3007 { PTREGS_OFFSET_REG(33), "r33" },
3008 { PTREGS_OFFSET_REG(34), "r34" },
3009 { PTREGS_OFFSET_REG(35), "r35" },
3010 { PTREGS_OFFSET_REG(36), "r36" },
3011 { PTREGS_OFFSET_REG(37), "r37" },
3012 { PTREGS_OFFSET_REG(38), "r38" },
3013 { PTREGS_OFFSET_REG(39), "r39" },
3014 { PTREGS_OFFSET_REG(40), "r40" },
3015 { PTREGS_OFFSET_REG(41), "r41" },
3016 { PTREGS_OFFSET_REG(42), "r42" },
3017 { PTREGS_OFFSET_REG(43), "r43" },
3018 { PTREGS_OFFSET_REG(44), "r44" },
3019 { PTREGS_OFFSET_REG(45), "r45" },
3020 { PTREGS_OFFSET_REG(46), "r46" },
3021 { PTREGS_OFFSET_REG(47), "r47" },
3022 { PTREGS_OFFSET_REG(48), "r48" },
3023 { PTREGS_OFFSET_REG(49), "r49" },
3024 { PTREGS_OFFSET_REG(50), "r50" },
3025 { PTREGS_OFFSET_REG(51), "r51" },
3026 { PTREGS_OFFSET_REG(52), "r52" },
3027 { PTREGS_OFFSET_TP, "tp" },
3028 { PTREGS_OFFSET_SP, "sp" },
3029 { PTREGS_OFFSET_LR, "lr" },
3030 { PTREGS_OFFSET_PC, "pc" },
3031 { PTREGS_OFFSET_EX1, "ex1" },
3032 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
3033 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
3034 { PTREGS_OFFSET_FLAGS, "flags" },
3037 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3038 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3039 { 4*PT_R13, "4*PT_R13" },
3040 { 4*PT_R12, "4*PT_R12" },
3041 { 4*PT_R11, "4*PT_R11" },
3042 { 4*PT_R10, "4*PT_R10" },
3043 { 4*PT_R9, "4*PT_R9" },
3044 { 4*PT_R8, "4*PT_R8" },
3045 { 4*PT_R7, "4*PT_R7" },
3046 { 4*PT_R6, "4*PT_R6" },
3047 { 4*PT_R5, "4*PT_R5" },
3048 { 4*PT_R4, "4*PT_R4" },
3049 { 4*PT_R3, "4*PT_R3" },
3050 { 4*PT_R2, "4*PT_R2" },
3051 { 4*PT_R1, "4*PT_R1" },
3052 { 4*PT_R0, "4*PT_R0" },
3053 { 4*PT_MOF, "4*PT_MOF" },
3054 { 4*PT_DCCR, "4*PT_DCCR" },
3055 { 4*PT_SRP, "4*PT_SRP" },
3056 { 4*PT_IRP, "4*PT_IRP" },
3057 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3058 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3059 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3060 { 4*PT_USP, "4*PT_USP" },
3063 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3064 { 4*PT_R0, "4*PT_R0" },
3065 { 4*PT_R1, "4*PT_R1" },
3066 { 4*PT_R2, "4*PT_R2" },
3067 { 4*PT_R3, "4*PT_R3" },
3068 { 4*PT_R4, "4*PT_R4" },
3069 { 4*PT_R5, "4*PT_R5" },
3070 { 4*PT_R6, "4*PT_R6" },
3071 { 4*PT_R7, "4*PT_R7" },
3072 { 4*PT_R8, "4*PT_R8" },
3073 { 4*PT_R9, "4*PT_R9" },
3074 { 4*PT_R10, "4*PT_R10" },
3075 { 4*PT_R11, "4*PT_R11" },
3076 { 4*PT_R12, "4*PT_R12" },
3077 { 4*PT_R13, "4*PT_R13" },
3078 { 4*PT_ACR, "4*PT_ACR" },
3079 { 4*PT_SRS, "4*PT_SRS" },
3080 { 4*PT_MOF, "4*PT_MOF" },
3081 { 4*PT_SPC, "4*PT_SPC" },
3082 { 4*PT_CCS, "4*PT_CCS" },
3083 { 4*PT_SRP, "4*PT_SRP" },
3084 { 4*PT_ERP, "4*PT_ERP" },
3085 { 4*PT_EXS, "4*PT_EXS" },
3086 { 4*PT_EDA, "4*PT_EDA" },
3087 { 4*PT_USP, "4*PT_USP" },
3088 { 4*PT_PPC, "4*PT_PPC" },
3089 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3090 { 4*PT_BP+4, "4*PT_BP+4" },
3091 { 4*PT_BP+8, "4*PT_BP+8" },
3092 { 4*PT_BP+12, "4*PT_BP+12" },
3093 { 4*PT_BP+16, "4*PT_BP+16" },
3094 { 4*PT_BP+20, "4*PT_BP+20" },
3095 { 4*PT_BP+24, "4*PT_BP+24" },
3096 { 4*PT_BP+28, "4*PT_BP+28" },
3097 { 4*PT_BP+32, "4*PT_BP+32" },
3098 { 4*PT_BP+36, "4*PT_BP+36" },
3099 { 4*PT_BP+40, "4*PT_BP+40" },
3100 { 4*PT_BP+44, "4*PT_BP+44" },
3101 { 4*PT_BP+48, "4*PT_BP+48" },
3102 { 4*PT_BP+52, "4*PT_BP+52" },
3103 { 4*PT_BP+56, "4*PT_BP+56" },
3106 { PT_GPR(0), "r0" },
3107 { PT_GPR(1), "r1" },
3108 { PT_GPR(2), "r2" },
3109 { PT_GPR(3), "r3" },
3110 { PT_GPR(4), "r4" },
3111 { PT_GPR(5), "r5" },
3112 { PT_GPR(6), "r6" },
3113 { PT_GPR(7), "r7" },
3114 { PT_GPR(8), "r8" },
3115 { PT_GPR(9), "r9" },
3116 { PT_GPR(10), "r10" },
3117 { PT_GPR(11), "r11" },
3118 { PT_GPR(12), "r12" },
3119 { PT_GPR(13), "r13" },
3120 { PT_GPR(14), "r14" },
3121 { PT_GPR(15), "r15" },
3122 { PT_GPR(16), "r16" },
3123 { PT_GPR(17), "r17" },
3124 { PT_GPR(18), "r18" },
3125 { PT_GPR(19), "r19" },
3126 { PT_GPR(20), "r20" },
3127 { PT_GPR(21), "r21" },
3128 { PT_GPR(22), "r22" },
3129 { PT_GPR(23), "r23" },
3130 { PT_GPR(24), "r24" },
3131 { PT_GPR(25), "r25" },
3132 { PT_GPR(26), "r26" },
3133 { PT_GPR(27), "r27" },
3134 { PT_GPR(28), "r28" },
3135 { PT_GPR(29), "r29" },
3136 { PT_GPR(30), "r30" },
3137 { PT_GPR(31), "r31" },
3139 { PT_MSR, "rmsr", },
3140 { PT_EAR, "rear", },
3141 { PT_ESR, "resr", },
3142 { PT_FSR, "rfsr", },
3143 { PT_KERNEL_MODE, "kernel_mode", },
3146 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3147 && !defined(ALPHA) && !defined(IA64) \
3148 && !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
3149 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3150 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3152 # if defined(I386) || defined(X86_64)
3153 { uoff(i387), "offsetof(struct user, i387)" },
3156 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3158 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3159 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3160 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3161 # if !defined(SPARC64)
3162 { uoff(start_code), "offsetof(struct user, start_code)" },
3164 # if defined(AVR32) || defined(SH64)
3165 { uoff(start_data), "offsetof(struct user, start_data)" },
3167 # if !defined(SPARC64)
3168 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3170 { uoff(signal), "offsetof(struct user, signal)" },
3171 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3172 { uoff(reserved), "offsetof(struct user, reserved)" },
3174 # if !defined(SPARC64)
3175 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3177 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3178 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3180 { uoff(magic), "offsetof(struct user, magic)" },
3181 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3182 # if defined(I386) || defined(X86_64)
3183 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3185 # endif /* !defined(many arches) */
3190 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3191 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3192 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3193 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3194 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3195 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3196 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3197 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3198 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3199 { uoff(u_error), "offsetof(struct user, u_error)" },
3200 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3201 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3202 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3203 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3204 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3205 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3206 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3207 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3208 { uoff(u_code), "offsetof(struct user, u_code)" },
3209 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3210 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3211 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3212 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3213 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3214 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3215 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3216 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3217 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3218 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3219 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3220 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3221 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3222 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3223 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3224 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3225 { uoff(u_start), "offsetof(struct user, u_start)" },
3226 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3227 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3228 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3229 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3230 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3231 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3232 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3233 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3234 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3235 # endif /* SUNOS4 */
3237 { sizeof(struct user), "sizeof(struct user)" },
3241 # endif /* !FREEBSD */
3244 sys_ptrace(struct tcb *tcp)
3246 const struct xlat *x;
3249 if (entering(tcp)) {
3250 printxval(ptrace_cmds, tcp->u_arg[0],
3257 tprintf(", %lu, ", tcp->u_arg[1]);
3258 addr = tcp->u_arg[2];
3260 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3261 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3262 for (x = struct_user_offsets; x->str; x++) {
3267 tprintf("%#lx, ", addr);
3268 else if (x->val > addr && x != struct_user_offsets) {
3270 tprintf("%s + %ld, ", x->str, addr - x->val);
3273 tprintf("%s, ", x->str);
3277 tprintf("%#lx, ", tcp->u_arg[2]);
3279 switch (tcp->u_arg[0]) {
3281 case PTRACE_PEEKDATA:
3282 case PTRACE_PEEKTEXT:
3283 case PTRACE_PEEKUSER:
3287 case PTRACE_SINGLESTEP:
3288 case PTRACE_SYSCALL:
3290 printsignal(tcp->u_arg[3]);
3292 # ifdef PTRACE_SETOPTIONS
3293 case PTRACE_SETOPTIONS:
3294 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3297 # ifdef PTRACE_SETSIGINFO
3298 case PTRACE_SETSIGINFO: {
3302 else if (syserror(tcp))
3303 tprintf("%#lx", tcp->u_arg[3]);
3304 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3307 printsiginfo(&si, verbose(tcp));
3311 # ifdef PTRACE_GETSIGINFO
3312 case PTRACE_GETSIGINFO:
3313 /* Don't print anything, do it at syscall return. */
3317 tprintf("%#lx", tcp->u_arg[3]);
3321 switch (tcp->u_arg[0]) {
3322 case PTRACE_PEEKDATA:
3323 case PTRACE_PEEKTEXT:
3324 case PTRACE_PEEKUSER:
3328 printnum(tcp, tcp->u_arg[3], "%#lx");
3331 # ifdef PTRACE_GETSIGINFO
3332 case PTRACE_GETSIGINFO: {
3336 else if (syserror(tcp))
3337 tprintf("%#lx", tcp->u_arg[3]);
3338 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3341 printsiginfo(&si, verbose(tcp));
3349 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3350 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3351 tprintf("%lu, ", tcp->u_arg[3]);
3352 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3353 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3354 tcp->u_arg[0] != PTRACE_READTEXT) {
3355 tprintf("%#lx", tcp->u_arg[3]);
3358 if (tcp->u_arg[0] == PTRACE_READDATA ||
3359 tcp->u_arg[0] == PTRACE_READTEXT) {
3360 tprintf("%lu, ", tcp->u_arg[3]);
3361 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3364 # endif /* SUNOS4 */
3366 tprintf("%lu", tcp->u_arg[3]);
3368 # endif /* FREEBSD */
3375 # ifndef FUTEX_CMP_REQUEUE
3376 # define FUTEX_CMP_REQUEUE 4
3378 # ifndef FUTEX_WAKE_OP
3379 # define FUTEX_WAKE_OP 5
3381 # ifndef FUTEX_LOCK_PI
3382 # define FUTEX_LOCK_PI 6
3383 # define FUTEX_UNLOCK_PI 7
3384 # define FUTEX_TRYLOCK_PI 8
3386 # ifndef FUTEX_WAIT_BITSET
3387 # define FUTEX_WAIT_BITSET 9
3389 # ifndef FUTEX_WAKE_BITSET
3390 # define FUTEX_WAKE_BITSET 10
3392 # ifndef FUTEX_WAIT_REQUEUE_PI
3393 # define FUTEX_WAIT_REQUEUE_PI 11
3395 # ifndef FUTEX_CMP_REQUEUE_PI
3396 # define FUTEX_CMP_REQUEUE_PI 12
3398 # ifndef FUTEX_PRIVATE_FLAG
3399 # define FUTEX_PRIVATE_FLAG 128
3401 # ifndef FUTEX_CLOCK_REALTIME
3402 # define FUTEX_CLOCK_REALTIME 256
3404 static const struct xlat futexops[] = {
3405 { FUTEX_WAIT, "FUTEX_WAIT" },
3406 { FUTEX_WAKE, "FUTEX_WAKE" },
3407 { FUTEX_FD, "FUTEX_FD" },
3408 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3409 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3410 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3411 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3412 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3413 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3414 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3415 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3416 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3417 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3418 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3419 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3420 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3421 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3422 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3423 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3424 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3425 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3426 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3427 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3428 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3429 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3430 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3431 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3432 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3433 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3434 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3437 # ifndef FUTEX_OP_SET
3438 # define FUTEX_OP_SET 0
3439 # define FUTEX_OP_ADD 1
3440 # define FUTEX_OP_OR 2
3441 # define FUTEX_OP_ANDN 3
3442 # define FUTEX_OP_XOR 4
3443 # define FUTEX_OP_CMP_EQ 0
3444 # define FUTEX_OP_CMP_NE 1
3445 # define FUTEX_OP_CMP_LT 2
3446 # define FUTEX_OP_CMP_LE 3
3447 # define FUTEX_OP_CMP_GT 4
3448 # define FUTEX_OP_CMP_GE 5
3450 static const struct xlat futexwakeops[] = {
3451 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3452 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3453 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3454 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3455 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3458 static const struct xlat futexwakecmps[] = {
3459 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3460 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3461 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3462 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3463 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3464 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3469 sys_futex(struct tcb *tcp)
3471 if (entering(tcp)) {
3472 long int cmd = tcp->u_arg[1] & 127;
3473 tprintf("%p, ", (void *) tcp->u_arg[0]);
3474 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3475 tprintf(", %ld", tcp->u_arg[2]);
3476 if (cmd == FUTEX_WAKE_BITSET)
3477 tprintf(", %lx", tcp->u_arg[5]);
3478 else if (cmd == FUTEX_WAIT) {
3480 printtv(tcp, tcp->u_arg[3]);
3481 } else if (cmd == FUTEX_WAIT_BITSET) {
3483 printtv(tcp, tcp->u_arg[3]);
3484 tprintf(", %lx", tcp->u_arg[5]);
3485 } else if (cmd == FUTEX_REQUEUE)
3486 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3487 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3488 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3489 else if (cmd == FUTEX_WAKE_OP) {
3490 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3491 if ((tcp->u_arg[5] >> 28) & 8)
3492 tprintf("FUTEX_OP_OPARG_SHIFT|");
3493 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3494 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3495 if ((tcp->u_arg[5] >> 24) & 8)
3496 tprintf("FUTEX_OP_OPARG_SHIFT|");
3497 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3498 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3499 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3501 printtv(tcp, tcp->u_arg[3]);
3502 tprintf(", %p", (void *) tcp->u_arg[4]);
3509 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3512 unsigned long w, min_len;
3514 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3515 min_len = len - max_strlen * sizeof(w);
3518 for (; len >= sizeof(w) && len > min_len;
3519 len -= sizeof(w), list += sizeof(w)) {
3520 if (umove(tcp, list, &w) < 0)
3531 tprintf("%#lx", list);
3533 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3536 tprintf(first ? "{}" : "}");
3541 sys_sched_setaffinity(struct tcb *tcp)
3543 if (entering(tcp)) {
3544 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3545 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3551 sys_sched_getaffinity(struct tcb *tcp)
3553 if (entering(tcp)) {
3554 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3556 if (tcp->u_rval == -1)
3557 tprintf("%#lx", tcp->u_arg[2]);
3559 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3564 static const struct xlat schedulers[] = {
3565 { SCHED_OTHER, "SCHED_OTHER" },
3566 { SCHED_RR, "SCHED_RR" },
3567 { SCHED_FIFO, "SCHED_FIFO" },
3572 sys_sched_getscheduler(struct tcb *tcp)
3574 if (entering(tcp)) {
3575 tprintf("%d", (int) tcp->u_arg[0]);
3576 } else if (! syserror(tcp)) {
3577 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3578 if (tcp->auxstr != NULL)
3585 sys_sched_setscheduler(struct tcb *tcp)
3587 if (entering(tcp)) {
3588 struct sched_param p;
3589 tprintf("%d, ", (int) tcp->u_arg[0]);
3590 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3591 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3592 tprintf(", %#lx", tcp->u_arg[2]);
3594 tprintf(", { %d }", p.__sched_priority);
3600 sys_sched_getparam(struct tcb *tcp)
3602 if (entering(tcp)) {
3603 tprintf("%d, ", (int) tcp->u_arg[0]);
3605 struct sched_param p;
3606 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3607 tprintf("%#lx", tcp->u_arg[1]);
3609 tprintf("{ %d }", p.__sched_priority);
3615 sys_sched_setparam(struct tcb *tcp)
3617 if (entering(tcp)) {
3618 struct sched_param p;
3619 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3620 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3622 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3628 sys_sched_get_priority_min(struct tcb *tcp)
3630 if (entering(tcp)) {
3631 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3637 # include <asm/prctl.h>
3639 static const struct xlat archvals[] = {
3640 { ARCH_SET_GS, "ARCH_SET_GS" },
3641 { ARCH_SET_FS, "ARCH_SET_FS" },
3642 { ARCH_GET_FS, "ARCH_GET_FS" },
3643 { ARCH_GET_GS, "ARCH_GET_GS" },
3648 sys_arch_prctl(struct tcb *tcp)
3650 if (entering(tcp)) {
3651 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3652 if (tcp->u_arg[0] == ARCH_SET_GS
3653 || tcp->u_arg[0] == ARCH_SET_FS
3655 tprintf(", %#lx", tcp->u_arg[1]);
3658 if (tcp->u_arg[0] == ARCH_GET_GS
3659 || tcp->u_arg[0] == ARCH_GET_FS
3662 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3663 tprintf(", [%#lx]", v);
3665 tprintf(", %#lx", tcp->u_arg[1]);
3670 # endif /* X86_64 */
3674 sys_getcpu(struct tcb *tcp)
3678 if (tcp->u_arg[0] == 0)
3680 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3681 tprintf("%#lx, ", tcp->u_arg[0]);
3683 tprintf("[%u], ", u);
3684 if (tcp->u_arg[1] == 0)
3686 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3687 tprintf("%#lx, ", tcp->u_arg[1]);
3689 tprintf("[%u], ", u);
3690 tprintf("%#lx", tcp->u_arg[2]);