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),
784 #warning Do not know how to handle change_syscall for this architecture
785 #endif /* architecture */
792 internal_fork(struct tcb *tcp)
801 struct tcb *tcpchild;
805 if (!(tcp->flags & TCB_FOLLOWFORK))
808 bpt = tcp->flags & TCB_BPTSET;
818 #ifdef CLONE_PTRACE /* See new setbpt code. */
819 tcpchild = pid2tcb(pid);
820 if (tcpchild != NULL) {
821 /* The child already reported its startup trap
822 before the parent reported its syscall return. */
824 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
825 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
827 [preattached child %d of %d in weird state!]\n",
831 #endif /* CLONE_PTRACE */
834 tcpchild = alloctcb(pid);
838 /* Attach to the new child */
839 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
842 perror("PTRACE_ATTACH");
843 fprintf(stderr, "Too late?\n");
847 #endif /* !CLONE_PTRACE */
852 tcpchild->flags |= TCB_ATTACHED;
853 /* Child has BPT too, must be removed on first occasion. */
855 tcpchild->flags |= TCB_BPTSET;
856 tcpchild->baddr = tcp->baddr;
857 memcpy(tcpchild->inst, tcp->inst,
858 sizeof tcpchild->inst);
860 tcpchild->parent = tcp;
862 if (tcpchild->flags & TCB_SUSPENDED) {
863 /* The child was born suspended, due to our having
864 forced CLONE_PTRACE. */
868 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
869 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
874 Process %u resumed (parent %d ready)\n",
879 fprintf(stderr, "Process %d attached\n", pid);
882 #ifdef TCB_CLONE_THREAD
885 * Save the flags used in this call,
886 * in case we point TCP to our parent below.
888 int call_flags = tcp->u_arg[ARG_FLAGS];
889 if ((tcp->flags & TCB_CLONE_THREAD) &&
890 tcp->parent != NULL) {
891 /* The parent in this clone is itself a
892 thread belonging to another process.
893 There is no meaning to the parentage
894 relationship of the new child with the
895 thread, only with the process. We
896 associate the new thread with our
897 parent. Since this is done for every
898 new thread, there will never be a
899 TCB_CLONE_THREAD process that has
903 tcpchild->parent = tcp;
906 if (call_flags & CLONE_THREAD) {
907 tcpchild->flags |= TCB_CLONE_THREAD;
908 ++tcp->nclone_threads;
910 if (call_flags & CLONE_DETACHED) {
911 tcpchild->flags |= TCB_CLONE_DETACHED;
912 ++tcp->nclone_detached;
915 #endif /* TCB_CLONE_THREAD */
926 struct tcb *tcpchild;
931 if (known_scno(tcp) == SYS_vfork) {
932 /* Attempt to make vfork into fork, which we can follow. */
933 if (change_syscall(tcp, SYS_fork) < 0)
938 if (!followfork || dont_follow)
945 int bpt = tcp->flags & TCB_BPTSET;
947 if (!(tcp->flags & TCB_FOLLOWFORK))
957 tcpchild = alloctcb(pid);
960 /* The child must have run before it can be attached. */
965 select(0, NULL, NULL, NULL, &tv);
967 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
968 perror("PTRACE_ATTACH");
969 fprintf(stderr, "Too late?\n");
974 /* Try to catch the new process as soon as possible. */
977 for (i = 0; i < 1024; i++)
978 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
981 perror("PTRACE_ATTACH");
982 fprintf(stderr, "Too late?\n");
989 tcpchild->flags |= TCB_ATTACHED;
990 /* Child has BPT too, must be removed on first occasion */
992 tcpchild->flags |= TCB_BPTSET;
993 tcpchild->baddr = tcp->baddr;
994 memcpy(tcpchild->inst, tcp->inst,
995 sizeof tcpchild->inst);
997 tcpchild->parent = tcp;
1000 fprintf(stderr, "Process %d attached\n", pid);
1007 #endif /* !USE_PROCFS */
1009 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1016 return RVAL_UDECIMAL;
1020 #endif /* SUNOS4 || LINUX || FREEBSD */
1024 static char idstr[16];
1031 sprintf(idstr, "ppid %lu", getrval2(tcp));
1032 tcp->auxstr = idstr;
1043 sprintf(idstr, "euid %lu", getrval2(tcp));
1044 tcp->auxstr = idstr;
1055 sprintf(idstr, "egid %lu", getrval2(tcp));
1056 tcp->auxstr = idstr;
1070 if (entering(tcp)) {
1071 tprintf("%u", (uid_t) tcp->u_arg[0]);
1080 if (entering(tcp)) {
1081 tprintf("%u", (gid_t) tcp->u_arg[0]);
1087 sys_getresuid(struct tcb *tcp)
1092 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1093 tcp->u_arg[1], tcp->u_arg[2]);
1095 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1096 tprintf("%#lx, ", tcp->u_arg[0]);
1098 tprintf("[%lu], ", (unsigned long) uid);
1099 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1100 tprintf("%#lx, ", tcp->u_arg[1]);
1102 tprintf("[%lu], ", (unsigned long) uid);
1103 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1104 tprintf("%#lx", tcp->u_arg[2]);
1106 tprintf("[%lu]", (unsigned long) uid);
1119 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1120 tcp->u_arg[1], tcp->u_arg[2]);
1122 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1123 tprintf("%#lx, ", tcp->u_arg[0]);
1125 tprintf("[%lu], ", (unsigned long) gid);
1126 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1127 tprintf("%#lx, ", tcp->u_arg[1]);
1129 tprintf("[%lu], ", (unsigned long) gid);
1130 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1131 tprintf("%#lx", tcp->u_arg[2]);
1133 tprintf("[%lu]", (unsigned long) gid);
1145 if (entering(tcp)) {
1146 printuid("", tcp->u_arg[0]);
1147 printuid(", ", tcp->u_arg[1]);
1156 if (entering(tcp)) {
1157 printuid("", tcp->u_arg[0]);
1158 printuid(", ", tcp->u_arg[1]);
1163 #if defined(LINUX) || defined(FREEBSD)
1168 if (entering(tcp)) {
1169 printuid("", tcp->u_arg[0]);
1170 printuid(", ", tcp->u_arg[1]);
1171 printuid(", ", tcp->u_arg[2]);
1179 if (entering(tcp)) {
1180 printuid("", tcp->u_arg[0]);
1181 printuid(", ", tcp->u_arg[1]);
1182 printuid(", ", tcp->u_arg[2]);
1187 #endif /* LINUX || FREEBSD */
1193 if (entering(tcp)) {
1194 unsigned long len, size, start, cur, end, abbrev_end;
1198 len = tcp->u_arg[0];
1199 tprintf("%lu, ", len);
1204 start = tcp->u_arg[1];
1209 size = len * sizeof(gid);
1211 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1212 tprintf("%#lx", start);
1216 abbrev_end = start + max_strlen * sizeof(gid);
1217 if (abbrev_end < start)
1223 for (cur = start; cur < end; cur += sizeof(gid)) {
1226 if (cur >= abbrev_end) {
1230 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1235 tprintf("%lu", (unsigned long) gid);
1239 tprintf(" %#lx", tcp->u_arg[1]);
1250 if (entering(tcp)) {
1251 len = tcp->u_arg[0];
1252 tprintf("%lu, ", len);
1254 unsigned long size, start, cur, end, abbrev_end;
1263 start = tcp->u_arg[1];
1268 if (tcp->u_arg[0] == 0) {
1269 tprintf("%#lx", start);
1272 size = len * sizeof(gid);
1274 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1275 size / sizeof(gid) != len || end < start) {
1276 tprintf("%#lx", start);
1280 abbrev_end = start + max_strlen * sizeof(gid);
1281 if (abbrev_end < start)
1287 for (cur = start; cur < end; cur += sizeof(gid)) {
1290 if (cur >= abbrev_end) {
1294 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1299 tprintf("%lu", (unsigned long) gid);
1303 tprintf(" %#lx", tcp->u_arg[1]);
1310 sys_setgroups32(tcp)
1313 if (entering(tcp)) {
1314 unsigned long len, size, start, cur, end, abbrev_end;
1318 len = tcp->u_arg[0];
1319 tprintf("%lu, ", len);
1324 start = tcp->u_arg[1];
1329 size = len * sizeof(gid);
1331 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1332 tprintf("%#lx", start);
1336 abbrev_end = start + max_strlen * sizeof(gid);
1337 if (abbrev_end < start)
1343 for (cur = start; cur < end; cur += sizeof(gid)) {
1346 if (cur >= abbrev_end) {
1350 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1355 tprintf("%lu", (unsigned long) gid);
1359 tprintf(" %#lx", tcp->u_arg[1]);
1365 sys_getgroups32(tcp)
1370 if (entering(tcp)) {
1371 len = tcp->u_arg[0];
1372 tprintf("%lu, ", len);
1374 unsigned long size, start, cur, end, abbrev_end;
1383 start = tcp->u_arg[1];
1388 size = len * sizeof(gid);
1390 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1391 size / sizeof(gid) != len || end < start) {
1392 tprintf("%#lx", start);
1396 abbrev_end = start + max_strlen * sizeof(gid);
1397 if (abbrev_end < start)
1403 for (cur = start; cur < end; cur += sizeof(gid)) {
1406 if (cur >= abbrev_end) {
1410 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1415 tprintf("%lu", (unsigned long) gid);
1419 tprintf(" %#lx", tcp->u_arg[1]);
1425 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1430 if (entering(tcp)) {
1432 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1437 #endif /* ALPHA || SUNOS4 || SVR4 */
1443 if (entering(tcp)) {
1445 tprintf("%lu", tcp->u_arg[0]);
1455 if (entering(tcp)) {
1456 tprintf("%lu", tcp->u_arg[0]);
1472 if (entering(tcp)) {
1473 tprintf("%lu", tcp->u_arg[0]);
1482 if (entering(tcp)) {
1483 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1490 #include <sys/privilege.h>
1493 static const struct xlat procpriv_cmds [] = {
1494 { SETPRV, "SETPRV" },
1495 { CLRPRV, "CLRPRV" },
1496 { PUTPRV, "PUTPRV" },
1497 { GETPRV, "GETPRV" },
1498 { CNTPRV, "CNTPRV" },
1503 static const struct xlat procpriv_priv [] = {
1504 { P_OWNER, "P_OWNER" },
1505 { P_AUDIT, "P_AUDIT" },
1506 { P_COMPAT, "P_COMPAT" },
1507 { P_DACREAD, "P_DACREAD" },
1508 { P_DACWRITE, "P_DACWRITE" },
1510 { P_FILESYS, "P_FILESYS" },
1511 { P_MACREAD, "P_MACREAD" },
1512 { P_MACWRITE, "P_MACWRITE" },
1513 { P_MOUNT, "P_MOUNT" },
1514 { P_MULTIDIR, "P_MULTIDIR" },
1515 { P_SETPLEVEL, "P_SETPLEVEL" },
1516 { P_SETSPRIV, "P_SETSPRIV" },
1517 { P_SETUID, "P_SETUID" },
1518 { P_SYSOPS, "P_SYSOPS" },
1519 { P_SETUPRIV, "P_SETUPRIV" },
1520 { P_DRIVER, "P_DRIVER" },
1521 { P_RTIME, "P_RTIME" },
1522 { P_MACUPGRADE, "P_MACUPGRADE" },
1523 { P_FSYSRANGE, "P_FSYSRANGE" },
1524 { P_SETFLEVEL, "P_SETFLEVEL" },
1525 { P_AUDITWR, "P_AUDITWR" },
1526 { P_TSHAR, "P_TSHAR" },
1527 { P_PLOCK, "P_PLOCK" },
1528 { P_CORE, "P_CORE" },
1529 { P_LOADMOD, "P_LOADMOD" },
1530 { P_BIND, "P_BIND" },
1531 { P_ALLPRIVS, "P_ALLPRIVS" },
1536 static const struct xlat procpriv_type [] = {
1537 { PS_FIX, "PS_FIX" },
1538 { PS_INH, "PS_INH" },
1539 { PS_MAX, "PS_MAX" },
1540 { PS_WKG, "PS_WKG" },
1546 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1549 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1550 int dots = len > max;
1553 if (len > max) len = max;
1556 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1558 tprintf ("%#lx", addr);
1564 for (i = 0; i < len; ++i) {
1567 if (i) tprintf (", ");
1569 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1570 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1572 tprintf ("%s|%s", t, p);
1575 tprintf ("%#lx", buf [i]);
1579 if (dots) tprintf (" ...");
1589 if (entering(tcp)) {
1590 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1591 switch (tcp->u_arg[0]) {
1593 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1601 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1602 tprintf (", %ld", tcp->u_arg[2]);
1605 else if (tcp->u_arg[0] == GETPRV) {
1606 if (syserror (tcp)) {
1607 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1611 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1612 tprintf (", %ld", tcp->u_arg[2]);
1619 #endif /* UNIXWARE */
1623 printargv(tcp, addr)
1630 char data[sizeof(long)];
1636 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1637 if (umoven(tcp, addr, personality_wordsize[current_personality],
1639 tprintf("%#lx", addr);
1642 if (personality_wordsize[current_personality] == 4)
1647 printstr(tcp, cp.p64, -1);
1648 addr += personality_wordsize[current_personality];
1651 tprintf("%s...", sep);
1655 printargc(fmt, tcp, addr)
1663 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1664 addr += sizeof(char *);
1666 tprintf(fmt, count, count == 1 ? "" : "s");
1669 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1671 sys_execv(struct tcb *tcp)
1673 if (entering(tcp)) {
1674 printpath(tcp, tcp->u_arg[0]);
1676 tprintf(", %#lx", tcp->u_arg[1]);
1679 printargv(tcp, tcp->u_arg[1]);
1685 #endif /* SPARC || SPARC64 || SUNOS4 */
1688 sys_execve(struct tcb *tcp)
1690 if (entering(tcp)) {
1691 printpath(tcp, tcp->u_arg[0]);
1693 tprintf(", %#lx", tcp->u_arg[1]);
1696 printargv(tcp, tcp->u_arg[1]);
1700 tprintf(", %#lx", tcp->u_arg[2]);
1701 else if (abbrev(tcp))
1702 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1705 printargv(tcp, tcp->u_arg[2]);
1714 int sys_rexecve(tcp)
1717 if (entering (tcp)) {
1719 tprintf (", %ld", tcp->u_arg[3]);
1731 if (exiting(tcp) && !syserror(tcp) && followfork)
1734 #if defined LINUX && defined TCB_WAITEXECVE
1735 if (exiting(tcp) && syserror(tcp))
1736 tcp->flags &= ~TCB_WAITEXECVE;
1738 tcp->flags |= TCB_WAITEXECVE;
1739 #endif /* LINUX && TCB_WAITEXECVE */
1745 #define __WNOTHREAD 0x20000000
1748 #define __WALL 0x40000000
1751 #define __WCLONE 0x80000000
1755 static const struct xlat wait4_options[] = {
1756 { WNOHANG, "WNOHANG" },
1758 { WUNTRACED, "WUNTRACED" },
1761 { WEXITED, "WEXITED" },
1764 { WTRAPPED, "WTRAPPED" },
1767 { WSTOPPED, "WSTOPPED" },
1770 { WCONTINUED, "WCONTINUED" },
1773 { WNOWAIT, "WNOWAIT" },
1776 { __WCLONE, "__WCLONE" },
1779 { __WALL, "__WALL" },
1782 { __WNOTHREAD, "__WNOTHREAD" },
1787 #if !defined WCOREFLAG && defined WCOREFLG
1788 # define WCOREFLAG WCOREFLG
1791 # define WCOREFLAG 0x80
1794 # define WCOREDUMP(status) ((status) & 0200)
1799 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1802 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1812 * Here is a tricky presentation problem. This solution
1813 * is still not entirely satisfactory but since there
1814 * are no wait status constructors it will have to do.
1816 if (WIFSTOPPED(status)) {
1817 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1818 signame(WSTOPSIG(status)));
1819 status &= ~W_STOPCODE(WSTOPSIG(status));
1821 else if (WIFSIGNALED(status)) {
1822 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1823 signame(WTERMSIG(status)),
1824 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1825 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1827 else if (WIFEXITED(status)) {
1828 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1829 WEXITSTATUS(status));
1831 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1834 tprintf("[%#x]", status);
1841 tprintf(" | %#x]", status);
1847 printwaitn(struct tcb *tcp, int n, int bitness)
1852 if (entering(tcp)) {
1854 /* On Linux, kernel-side pid_t is typedef'ed to int
1855 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1856 * pid argument to int on 64bit arches, producing,
1857 * for example, wait4(4294967295, ...) instead of -1
1858 * in strace. We have to use int here, not long.
1860 int pid = tcp->u_arg[0];
1861 tprintf("%d, ", pid);
1864 * Sign-extend a 32-bit value when that's what it is.
1866 long pid = tcp->u_arg[0];
1867 if (personality_wordsize[current_personality] < sizeof pid)
1868 pid = (long) (int) pid;
1869 tprintf("%ld, ", pid);
1875 else if (syserror(tcp) || tcp->u_rval == 0)
1876 tprintf("%#lx", tcp->u_arg[1]);
1877 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1880 exited = printstatus(status);
1883 printflags(wait4_options, tcp->u_arg[2], "W???");
1890 else if (tcp->u_rval > 0) {
1893 printrusage32(tcp, tcp->u_arg[3]);
1896 printrusage(tcp, tcp->u_arg[3]);
1900 else if (tcp->u_rval > 0 && exited)
1901 printrusage(tcp, tcp->u_arg[3]);
1904 tprintf("%#lx", tcp->u_arg[3]);
1911 internal_wait(tcp, flagarg)
1917 #ifdef TCB_CLONE_THREAD
1918 if (tcp->flags & TCB_CLONE_THREAD)
1919 /* The children we wait for are our parent's children. */
1920 got_kids = (tcp->parent->nchildren
1921 > tcp->parent->nclone_detached);
1923 got_kids = (tcp->nchildren > tcp->nclone_detached);
1925 got_kids = tcp->nchildren > 0;
1928 if (entering(tcp) && got_kids) {
1929 /* There are children that this parent should block for.
1930 But ptrace made us the parent of the traced children
1931 and the real parent will get ECHILD from the wait call.
1933 XXX If we attached with strace -f -p PID, then there
1934 may be untraced dead children the parent could be reaping
1935 now, but we make him block. */
1937 /* ??? WTA: fix bug with hanging children */
1939 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1941 * There are traced children. We'll make the parent
1942 * block to avoid a false ECHILD error due to our
1943 * ptrace having stolen the children. However,
1944 * we shouldn't block if there are zombies to reap.
1945 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1947 struct tcb *child = NULL;
1948 if (tcp->nzombies > 0 &&
1949 (tcp->u_arg[0] == -1 ||
1950 (child = pid2tcb(tcp->u_arg[0])) == NULL))
1952 if (tcp->u_arg[0] > 0) {
1954 * If the parent waits for a specified child
1955 * PID, then it must get ECHILD right away
1956 * if that PID is not one of its children.
1957 * Make sure that the requested PID matches
1958 * one of the parent's children that we are
1959 * tracing, and don't suspend it otherwise.
1962 child = pid2tcb(tcp->u_arg[0]);
1963 if (child == NULL || child->parent != (
1964 #ifdef TCB_CLONE_THREAD
1965 (tcp->flags & TCB_CLONE_THREAD)
1969 (child->flags & TCB_EXITING))
1972 tcp->flags |= TCB_SUSPENDED;
1973 tcp->waitpid = tcp->u_arg[0];
1974 #ifdef TCB_CLONE_THREAD
1975 if (tcp->flags & TCB_CLONE_THREAD)
1976 tcp->parent->nclone_waiting++;
1980 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1981 if (tcp->u_arg[flagarg] & WNOHANG) {
1982 /* We must force a fake result of 0 instead of
1983 the ECHILD error. */
1984 return force_result(tcp, 0, 0);
1987 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1988 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1990 * We just reaped a child we don't know about,
1991 * presumably a zombie we already droptcb'd.
2005 /* The library wrapper stuffs this into the user variable. */
2007 printstatus(getrval2(tcp));
2022 if (!syserror(tcp)) {
2023 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2024 tprintf("%#lx", tcp->u_arg[0]);
2026 printstatus(status);
2037 return printwaitn(tcp, 3, 0);
2044 return printwaitn(tcp, 4, 0);
2052 return printwaitn(tcp, 4, 1);
2056 #if defined SVR4 || defined LINUX
2058 static const struct xlat waitid_types[] = {
2061 { P_PPID, "P_PPID" },
2063 { P_PGID, "P_PGID" },
2078 { P_LWPID, "P_LWPID" },
2090 if (entering(tcp)) {
2091 printxval(waitid_types, tcp->u_arg[0], "P_???");
2092 tprintf(", %ld, ", tcp->u_arg[1]);
2099 else if (syserror(tcp))
2100 tprintf("%#lx", tcp->u_arg[2]);
2101 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2104 printsiginfo(&si, verbose(tcp));
2107 printflags(wait4_options, tcp->u_arg[3], "W???");
2108 if (tcp->u_nargs > 4) {
2113 else if (tcp->u_error)
2114 tprintf("%#lx", tcp->u_arg[4]);
2116 printrusage(tcp, tcp->u_arg[4]);
2122 #endif /* SVR4 or LINUX */
2129 tprintf("%lu", tcp->u_arg[0]);
2137 struct utsname uname;
2140 if (syserror(tcp) || !verbose(tcp))
2141 tprintf("%#lx", tcp->u_arg[0]);
2142 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2144 else if (!abbrev(tcp)) {
2146 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2147 uname.sysname, uname.nodename);
2148 tprintf("release=\"%s\", version=\"%s\", ",
2149 uname.release, uname.version);
2150 tprintf("machine=\"%s\"", uname.machine);
2153 tprintf(", domainname=\"%s\"", uname.domainname);
2159 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2160 uname.sysname, uname.nodename);
2167 static const struct xlat ptrace_cmds[] = {
2169 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2170 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2171 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2172 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2173 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2174 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2175 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2176 { PTRACE_CONT, "PTRACE_CONT" },
2177 { PTRACE_KILL, "PTRACE_KILL" },
2178 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2179 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2180 { PTRACE_DETACH, "PTRACE_DETACH" },
2181 # ifdef PTRACE_GETREGS
2182 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2184 # ifdef PTRACE_SETREGS
2185 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2187 # ifdef PTRACE_GETFPREGS
2188 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2190 # ifdef PTRACE_SETFPREGS
2191 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2193 # ifdef PTRACE_GETFPXREGS
2194 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2196 # ifdef PTRACE_SETFPXREGS
2197 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2199 # ifdef PTRACE_GETVRREGS
2200 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2202 # ifdef PTRACE_SETVRREGS
2203 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2205 # ifdef PTRACE_SETOPTIONS
2206 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2208 # ifdef PTRACE_GETEVENTMSG
2209 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2211 # ifdef PTRACE_GETSIGINFO
2212 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2214 # ifdef PTRACE_SETSIGINFO
2215 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2217 # ifdef PTRACE_SET_SYSCALL
2218 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2221 { PTRACE_READDATA, "PTRACE_READDATA" },
2222 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2223 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2224 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2225 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2226 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2228 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2229 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2231 { PTRACE_22, "PTRACE_22" },
2232 { PTRACE_23, "PTRACE_3" },
2233 # endif /* !SPARC */
2234 # endif /* SUNOS4 */
2235 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2237 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2239 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2240 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2241 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2243 { PTRACE_26, "PTRACE_26" },
2244 { PTRACE_27, "PTRACE_27" },
2245 { PTRACE_28, "PTRACE_28" },
2247 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2248 # endif /* SUNOS4 */
2250 # else /* FREEBSD */
2252 { PT_TRACE_ME, "PT_TRACE_ME" },
2253 { PT_READ_I, "PT_READ_I" },
2254 { PT_READ_D, "PT_READ_D" },
2255 { PT_WRITE_I, "PT_WRITE_I" },
2256 { PT_WRITE_D, "PT_WRITE_D" },
2258 { PT_READ_U, "PT_READ_U" },
2260 { PT_CONTINUE, "PT_CONTINUE" },
2261 { PT_KILL, "PT_KILL" },
2262 { PT_STEP, "PT_STEP" },
2263 { PT_ATTACH, "PT_ATTACH" },
2264 { PT_DETACH, "PT_DETACH" },
2265 { PT_GETREGS, "PT_GETREGS" },
2266 { PT_SETREGS, "PT_SETREGS" },
2267 { PT_GETFPREGS, "PT_GETFPREGS" },
2268 { PT_SETFPREGS, "PT_SETFPREGS" },
2269 { PT_GETDBREGS, "PT_GETDBREGS" },
2270 { PT_SETDBREGS, "PT_SETDBREGS" },
2271 # endif /* FREEBSD */
2276 # ifdef PTRACE_SETOPTIONS
2277 static const struct xlat ptrace_setoptions_flags[] = {
2278 # ifdef PTRACE_O_TRACESYSGOOD
2279 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2281 # ifdef PTRACE_O_TRACEFORK
2282 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2284 # ifdef PTRACE_O_TRACEVFORK
2285 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2287 # ifdef PTRACE_O_TRACECLONE
2288 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2290 # ifdef PTRACE_O_TRACEEXEC
2291 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2293 # ifdef PTRACE_O_TRACEVFORKDONE
2294 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2296 # ifdef PTRACE_O_TRACEEXIT
2297 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2301 # endif /* PTRACE_SETOPTIONS */
2302 # endif /* !FREEBSD */
2305 const struct xlat struct_user_offsets[] = {
2307 # if defined(S390) || defined(S390X)
2308 { PT_PSWMASK, "psw_mask" },
2309 { PT_PSWADDR, "psw_addr" },
2310 { PT_GPR0, "gpr0" },
2311 { PT_GPR1, "gpr1" },
2312 { PT_GPR2, "gpr2" },
2313 { PT_GPR3, "gpr3" },
2314 { PT_GPR4, "gpr4" },
2315 { PT_GPR5, "gpr5" },
2316 { PT_GPR6, "gpr6" },
2317 { PT_GPR7, "gpr7" },
2318 { PT_GPR8, "gpr8" },
2319 { PT_GPR9, "gpr9" },
2320 { PT_GPR10, "gpr10" },
2321 { PT_GPR11, "gpr11" },
2322 { PT_GPR12, "gpr12" },
2323 { PT_GPR13, "gpr13" },
2324 { PT_GPR14, "gpr14" },
2325 { PT_GPR15, "gpr15" },
2326 { PT_ACR0, "acr0" },
2327 { PT_ACR1, "acr1" },
2328 { PT_ACR2, "acr2" },
2329 { PT_ACR3, "acr3" },
2330 { PT_ACR4, "acr4" },
2331 { PT_ACR5, "acr5" },
2332 { PT_ACR6, "acr6" },
2333 { PT_ACR7, "acr7" },
2334 { PT_ACR8, "acr8" },
2335 { PT_ACR9, "acr9" },
2336 { PT_ACR10, "acr10" },
2337 { PT_ACR11, "acr11" },
2338 { PT_ACR12, "acr12" },
2339 { PT_ACR13, "acr13" },
2340 { PT_ACR14, "acr14" },
2341 { PT_ACR15, "acr15" },
2342 { PT_ORIGGPR2, "orig_gpr2" },
2345 { PT_FPR0_HI, "fpr0.hi" },
2346 { PT_FPR0_LO, "fpr0.lo" },
2347 { PT_FPR1_HI, "fpr1.hi" },
2348 { PT_FPR1_LO, "fpr1.lo" },
2349 { PT_FPR2_HI, "fpr2.hi" },
2350 { PT_FPR2_LO, "fpr2.lo" },
2351 { PT_FPR3_HI, "fpr3.hi" },
2352 { PT_FPR3_LO, "fpr3.lo" },
2353 { PT_FPR4_HI, "fpr4.hi" },
2354 { PT_FPR4_LO, "fpr4.lo" },
2355 { PT_FPR5_HI, "fpr5.hi" },
2356 { PT_FPR5_LO, "fpr5.lo" },
2357 { PT_FPR6_HI, "fpr6.hi" },
2358 { PT_FPR6_LO, "fpr6.lo" },
2359 { PT_FPR7_HI, "fpr7.hi" },
2360 { PT_FPR7_LO, "fpr7.lo" },
2361 { PT_FPR8_HI, "fpr8.hi" },
2362 { PT_FPR8_LO, "fpr8.lo" },
2363 { PT_FPR9_HI, "fpr9.hi" },
2364 { PT_FPR9_LO, "fpr9.lo" },
2365 { PT_FPR10_HI, "fpr10.hi" },
2366 { PT_FPR10_LO, "fpr10.lo" },
2367 { PT_FPR11_HI, "fpr11.hi" },
2368 { PT_FPR11_LO, "fpr11.lo" },
2369 { PT_FPR12_HI, "fpr12.hi" },
2370 { PT_FPR12_LO, "fpr12.lo" },
2371 { PT_FPR13_HI, "fpr13.hi" },
2372 { PT_FPR13_LO, "fpr13.lo" },
2373 { PT_FPR14_HI, "fpr14.hi" },
2374 { PT_FPR14_LO, "fpr14.lo" },
2375 { PT_FPR15_HI, "fpr15.hi" },
2376 { PT_FPR15_LO, "fpr15.lo" },
2379 { PT_FPR0, "fpr0" },
2380 { PT_FPR1, "fpr1" },
2381 { PT_FPR2, "fpr2" },
2382 { PT_FPR3, "fpr3" },
2383 { PT_FPR4, "fpr4" },
2384 { PT_FPR5, "fpr5" },
2385 { PT_FPR6, "fpr6" },
2386 { PT_FPR7, "fpr7" },
2387 { PT_FPR8, "fpr8" },
2388 { PT_FPR9, "fpr9" },
2389 { PT_FPR10, "fpr10" },
2390 { PT_FPR11, "fpr11" },
2391 { PT_FPR12, "fpr12" },
2392 { PT_FPR13, "fpr13" },
2393 { PT_FPR14, "fpr14" },
2394 { PT_FPR15, "fpr15" },
2397 { PT_CR_10, "cr10" },
2398 { PT_CR_11, "cr11" },
2399 { PT_IEEE_IP, "ieee_exception_ip" },
2400 # elif defined(SPARC)
2401 /* XXX No support for these offsets yet. */
2402 # elif defined(HPPA)
2403 /* XXX No support for these offsets yet. */
2404 # elif defined(POWERPC)
2406 # define PT_ORIG_R3 34
2408 # define REGSIZE (sizeof(unsigned long))
2409 { REGSIZE*PT_R0, "r0" },
2410 { REGSIZE*PT_R1, "r1" },
2411 { REGSIZE*PT_R2, "r2" },
2412 { REGSIZE*PT_R3, "r3" },
2413 { REGSIZE*PT_R4, "r4" },
2414 { REGSIZE*PT_R5, "r5" },
2415 { REGSIZE*PT_R6, "r6" },
2416 { REGSIZE*PT_R7, "r7" },
2417 { REGSIZE*PT_R8, "r8" },
2418 { REGSIZE*PT_R9, "r9" },
2419 { REGSIZE*PT_R10, "r10" },
2420 { REGSIZE*PT_R11, "r11" },
2421 { REGSIZE*PT_R12, "r12" },
2422 { REGSIZE*PT_R13, "r13" },
2423 { REGSIZE*PT_R14, "r14" },
2424 { REGSIZE*PT_R15, "r15" },
2425 { REGSIZE*PT_R16, "r16" },
2426 { REGSIZE*PT_R17, "r17" },
2427 { REGSIZE*PT_R18, "r18" },
2428 { REGSIZE*PT_R19, "r19" },
2429 { REGSIZE*PT_R20, "r20" },
2430 { REGSIZE*PT_R21, "r21" },
2431 { REGSIZE*PT_R22, "r22" },
2432 { REGSIZE*PT_R23, "r23" },
2433 { REGSIZE*PT_R24, "r24" },
2434 { REGSIZE*PT_R25, "r25" },
2435 { REGSIZE*PT_R26, "r26" },
2436 { REGSIZE*PT_R27, "r27" },
2437 { REGSIZE*PT_R28, "r28" },
2438 { REGSIZE*PT_R29, "r29" },
2439 { REGSIZE*PT_R30, "r30" },
2440 { REGSIZE*PT_R31, "r31" },
2441 { REGSIZE*PT_NIP, "NIP" },
2442 { REGSIZE*PT_MSR, "MSR" },
2443 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2444 { REGSIZE*PT_CTR, "CTR" },
2445 { REGSIZE*PT_LNK, "LNK" },
2446 { REGSIZE*PT_XER, "XER" },
2447 { REGSIZE*PT_CCR, "CCR" },
2448 { REGSIZE*PT_FPR0, "FPR0" },
2450 # elif defined(ALPHA)
2516 # elif defined(IA64)
2517 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2518 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2519 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2520 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2521 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2522 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2523 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2524 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2525 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2526 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2527 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2528 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2529 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2530 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2531 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2532 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2533 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2534 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2535 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2536 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2537 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2538 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2539 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2540 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2541 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2542 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2543 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2544 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2545 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2546 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2547 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2548 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2550 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2551 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2552 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2553 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2554 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2555 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2556 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2557 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2558 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2559 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2560 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2561 { PT_B4, "b4" }, { PT_B5, "b5" },
2562 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2564 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2565 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2566 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2567 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2568 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2569 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2570 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2571 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2572 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2573 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2574 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2575 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2576 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2577 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2578 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2579 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2580 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2582 { PT_AR_CSD, "ar.csd" },
2585 { PT_AR_SSD, "ar.ssd" },
2587 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2588 # elif defined(I386)
2600 { 4*ORIG_EAX, "4*ORIG_EAX" },
2604 { 4*UESP, "4*UESP" },
2606 # elif defined(X86_64)
2622 { 8*ORIG_RAX, "8*ORIG_RAX" },
2625 { 8*EFLAGS, "8*EFL" },
2628 # elif defined(M68K)
2629 { 4*PT_D1, "4*PT_D1" },
2630 { 4*PT_D2, "4*PT_D2" },
2631 { 4*PT_D3, "4*PT_D3" },
2632 { 4*PT_D4, "4*PT_D4" },
2633 { 4*PT_D5, "4*PT_D5" },
2634 { 4*PT_D6, "4*PT_D6" },
2635 { 4*PT_D7, "4*PT_D7" },
2636 { 4*PT_A0, "4*PT_A0" },
2637 { 4*PT_A1, "4*PT_A1" },
2638 { 4*PT_A2, "4*PT_A2" },
2639 { 4*PT_A3, "4*PT_A3" },
2640 { 4*PT_A4, "4*PT_A4" },
2641 { 4*PT_A5, "4*PT_A5" },
2642 { 4*PT_A6, "4*PT_A6" },
2643 { 4*PT_D0, "4*PT_D0" },
2644 { 4*PT_USP, "4*PT_USP" },
2645 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2646 { 4*PT_SR, "4*PT_SR" },
2647 { 4*PT_PC, "4*PT_PC" },
2649 { 4*REG_REG0, "4*REG_REG0" },
2650 { 4*(REG_REG0+1), "4*REG_REG1" },
2651 { 4*(REG_REG0+2), "4*REG_REG2" },
2652 { 4*(REG_REG0+3), "4*REG_REG3" },
2653 { 4*(REG_REG0+4), "4*REG_REG4" },
2654 { 4*(REG_REG0+5), "4*REG_REG5" },
2655 { 4*(REG_REG0+6), "4*REG_REG6" },
2656 { 4*(REG_REG0+7), "4*REG_REG7" },
2657 { 4*(REG_REG0+8), "4*REG_REG8" },
2658 { 4*(REG_REG0+9), "4*REG_REG9" },
2659 { 4*(REG_REG0+10), "4*REG_REG10" },
2660 { 4*(REG_REG0+11), "4*REG_REG11" },
2661 { 4*(REG_REG0+12), "4*REG_REG12" },
2662 { 4*(REG_REG0+13), "4*REG_REG13" },
2663 { 4*(REG_REG0+14), "4*REG_REG14" },
2664 { 4*REG_REG15, "4*REG_REG15" },
2665 { 4*REG_PC, "4*REG_PC" },
2666 { 4*REG_PR, "4*REG_PR" },
2667 { 4*REG_SR, "4*REG_SR" },
2668 { 4*REG_GBR, "4*REG_GBR" },
2669 { 4*REG_MACH, "4*REG_MACH" },
2670 { 4*REG_MACL, "4*REG_MACL" },
2671 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2672 { 4*REG_FPUL, "4*REG_FPUL" },
2673 { 4*REG_FPREG0, "4*REG_FPREG0" },
2674 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2675 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2676 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2677 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2678 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2679 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2680 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2681 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2682 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2683 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2684 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2685 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2686 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2687 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2688 { 4*REG_FPREG15, "4*REG_FPREG15" },
2690 { 4*REG_XDREG0, "4*REG_XDREG0" },
2691 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2692 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2693 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2694 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2695 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2696 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2697 { 4*REG_XDREG14, "4*REG_XDREG14" },
2699 { 4*REG_FPSCR, "4*REG_FPSCR" },
2700 # elif defined(SH64)
2705 { 16, "syscall no.(L)" },
2706 { 20, "syscall_no.(U)" },
2849 /* This entry is in case pt_regs contains dregs (depends on
2850 the kernel build options). */
2851 { uoff(regs), "offsetof(struct user, regs)" },
2852 { uoff(fpu), "offsetof(struct user, fpu)" },
2854 { uoff(regs.ARM_r0), "r0" },
2855 { uoff(regs.ARM_r1), "r1" },
2856 { uoff(regs.ARM_r2), "r2" },
2857 { uoff(regs.ARM_r3), "r3" },
2858 { uoff(regs.ARM_r4), "r4" },
2859 { uoff(regs.ARM_r5), "r5" },
2860 { uoff(regs.ARM_r6), "r6" },
2861 { uoff(regs.ARM_r7), "r7" },
2862 { uoff(regs.ARM_r8), "r8" },
2863 { uoff(regs.ARM_r9), "r9" },
2864 { uoff(regs.ARM_r10), "r10" },
2865 { uoff(regs.ARM_fp), "fp" },
2866 { uoff(regs.ARM_ip), "ip" },
2867 { uoff(regs.ARM_sp), "sp" },
2868 { uoff(regs.ARM_lr), "lr" },
2869 { uoff(regs.ARM_pc), "pc" },
2870 { uoff(regs.ARM_cpsr), "cpsr" },
2871 # elif defined(AVR32)
2872 { uoff(regs.sr), "sr" },
2873 { uoff(regs.pc), "pc" },
2874 { uoff(regs.lr), "lr" },
2875 { uoff(regs.sp), "sp" },
2876 { uoff(regs.r12), "r12" },
2877 { uoff(regs.r11), "r11" },
2878 { uoff(regs.r10), "r10" },
2879 { uoff(regs.r9), "r9" },
2880 { uoff(regs.r8), "r8" },
2881 { uoff(regs.r7), "r7" },
2882 { uoff(regs.r6), "r6" },
2883 { uoff(regs.r5), "r5" },
2884 { uoff(regs.r4), "r4" },
2885 { uoff(regs.r3), "r3" },
2886 { uoff(regs.r2), "r2" },
2887 { uoff(regs.r1), "r1" },
2888 { uoff(regs.r0), "r0" },
2889 { uoff(regs.r12_orig), "orig_r12" },
2890 # elif defined(MIPS)
2962 # elif defined(TILE)
2963 { PTREGS_OFFSET_REG(0), "r0" },
2964 { PTREGS_OFFSET_REG(1), "r1" },
2965 { PTREGS_OFFSET_REG(2), "r2" },
2966 { PTREGS_OFFSET_REG(3), "r3" },
2967 { PTREGS_OFFSET_REG(4), "r4" },
2968 { PTREGS_OFFSET_REG(5), "r5" },
2969 { PTREGS_OFFSET_REG(6), "r6" },
2970 { PTREGS_OFFSET_REG(7), "r7" },
2971 { PTREGS_OFFSET_REG(8), "r8" },
2972 { PTREGS_OFFSET_REG(9), "r9" },
2973 { PTREGS_OFFSET_REG(10), "r10" },
2974 { PTREGS_OFFSET_REG(11), "r11" },
2975 { PTREGS_OFFSET_REG(12), "r12" },
2976 { PTREGS_OFFSET_REG(13), "r13" },
2977 { PTREGS_OFFSET_REG(14), "r14" },
2978 { PTREGS_OFFSET_REG(15), "r15" },
2979 { PTREGS_OFFSET_REG(16), "r16" },
2980 { PTREGS_OFFSET_REG(17), "r17" },
2981 { PTREGS_OFFSET_REG(18), "r18" },
2982 { PTREGS_OFFSET_REG(19), "r19" },
2983 { PTREGS_OFFSET_REG(20), "r20" },
2984 { PTREGS_OFFSET_REG(21), "r21" },
2985 { PTREGS_OFFSET_REG(22), "r22" },
2986 { PTREGS_OFFSET_REG(23), "r23" },
2987 { PTREGS_OFFSET_REG(24), "r24" },
2988 { PTREGS_OFFSET_REG(25), "r25" },
2989 { PTREGS_OFFSET_REG(26), "r26" },
2990 { PTREGS_OFFSET_REG(27), "r27" },
2991 { PTREGS_OFFSET_REG(28), "r28" },
2992 { PTREGS_OFFSET_REG(29), "r29" },
2993 { PTREGS_OFFSET_REG(30), "r30" },
2994 { PTREGS_OFFSET_REG(31), "r31" },
2995 { PTREGS_OFFSET_REG(32), "r32" },
2996 { PTREGS_OFFSET_REG(33), "r33" },
2997 { PTREGS_OFFSET_REG(34), "r34" },
2998 { PTREGS_OFFSET_REG(35), "r35" },
2999 { PTREGS_OFFSET_REG(36), "r36" },
3000 { PTREGS_OFFSET_REG(37), "r37" },
3001 { PTREGS_OFFSET_REG(38), "r38" },
3002 { PTREGS_OFFSET_REG(39), "r39" },
3003 { PTREGS_OFFSET_REG(40), "r40" },
3004 { PTREGS_OFFSET_REG(41), "r41" },
3005 { PTREGS_OFFSET_REG(42), "r42" },
3006 { PTREGS_OFFSET_REG(43), "r43" },
3007 { PTREGS_OFFSET_REG(44), "r44" },
3008 { PTREGS_OFFSET_REG(45), "r45" },
3009 { PTREGS_OFFSET_REG(46), "r46" },
3010 { PTREGS_OFFSET_REG(47), "r47" },
3011 { PTREGS_OFFSET_REG(48), "r48" },
3012 { PTREGS_OFFSET_REG(49), "r49" },
3013 { PTREGS_OFFSET_REG(50), "r50" },
3014 { PTREGS_OFFSET_REG(51), "r51" },
3015 { PTREGS_OFFSET_REG(52), "r52" },
3016 { PTREGS_OFFSET_TP, "tp" },
3017 { PTREGS_OFFSET_SP, "sp" },
3018 { PTREGS_OFFSET_LR, "lr" },
3019 { PTREGS_OFFSET_PC, "pc" },
3020 { PTREGS_OFFSET_EX1, "ex1" },
3021 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
3022 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
3023 { PTREGS_OFFSET_FLAGS, "flags" },
3026 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3027 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3028 { 4*PT_R13, "4*PT_R13" },
3029 { 4*PT_R12, "4*PT_R12" },
3030 { 4*PT_R11, "4*PT_R11" },
3031 { 4*PT_R10, "4*PT_R10" },
3032 { 4*PT_R9, "4*PT_R9" },
3033 { 4*PT_R8, "4*PT_R8" },
3034 { 4*PT_R7, "4*PT_R7" },
3035 { 4*PT_R6, "4*PT_R6" },
3036 { 4*PT_R5, "4*PT_R5" },
3037 { 4*PT_R4, "4*PT_R4" },
3038 { 4*PT_R3, "4*PT_R3" },
3039 { 4*PT_R2, "4*PT_R2" },
3040 { 4*PT_R1, "4*PT_R1" },
3041 { 4*PT_R0, "4*PT_R0" },
3042 { 4*PT_MOF, "4*PT_MOF" },
3043 { 4*PT_DCCR, "4*PT_DCCR" },
3044 { 4*PT_SRP, "4*PT_SRP" },
3045 { 4*PT_IRP, "4*PT_IRP" },
3046 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3047 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3048 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3049 { 4*PT_USP, "4*PT_USP" },
3052 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3053 { 4*PT_R0, "4*PT_R0" },
3054 { 4*PT_R1, "4*PT_R1" },
3055 { 4*PT_R2, "4*PT_R2" },
3056 { 4*PT_R3, "4*PT_R3" },
3057 { 4*PT_R4, "4*PT_R4" },
3058 { 4*PT_R5, "4*PT_R5" },
3059 { 4*PT_R6, "4*PT_R6" },
3060 { 4*PT_R7, "4*PT_R7" },
3061 { 4*PT_R8, "4*PT_R8" },
3062 { 4*PT_R9, "4*PT_R9" },
3063 { 4*PT_R10, "4*PT_R10" },
3064 { 4*PT_R11, "4*PT_R11" },
3065 { 4*PT_R12, "4*PT_R12" },
3066 { 4*PT_R13, "4*PT_R13" },
3067 { 4*PT_ACR, "4*PT_ACR" },
3068 { 4*PT_SRS, "4*PT_SRS" },
3069 { 4*PT_MOF, "4*PT_MOF" },
3070 { 4*PT_SPC, "4*PT_SPC" },
3071 { 4*PT_CCS, "4*PT_CCS" },
3072 { 4*PT_SRP, "4*PT_SRP" },
3073 { 4*PT_ERP, "4*PT_ERP" },
3074 { 4*PT_EXS, "4*PT_EXS" },
3075 { 4*PT_EDA, "4*PT_EDA" },
3076 { 4*PT_USP, "4*PT_USP" },
3077 { 4*PT_PPC, "4*PT_PPC" },
3078 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3079 { 4*PT_BP+4, "4*PT_BP+4" },
3080 { 4*PT_BP+8, "4*PT_BP+8" },
3081 { 4*PT_BP+12, "4*PT_BP+12" },
3082 { 4*PT_BP+16, "4*PT_BP+16" },
3083 { 4*PT_BP+20, "4*PT_BP+20" },
3084 { 4*PT_BP+24, "4*PT_BP+24" },
3085 { 4*PT_BP+28, "4*PT_BP+28" },
3086 { 4*PT_BP+32, "4*PT_BP+32" },
3087 { 4*PT_BP+36, "4*PT_BP+36" },
3088 { 4*PT_BP+40, "4*PT_BP+40" },
3089 { 4*PT_BP+44, "4*PT_BP+44" },
3090 { 4*PT_BP+48, "4*PT_BP+48" },
3091 { 4*PT_BP+52, "4*PT_BP+52" },
3092 { 4*PT_BP+56, "4*PT_BP+56" },
3095 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3096 && !defined(ALPHA) && !defined(IA64) \
3097 && !defined(CRISV10) && !defined(CRISV32)
3098 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3099 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3101 # if defined(I386) || defined(X86_64)
3102 { uoff(i387), "offsetof(struct user, i387)" },
3105 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3107 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3108 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3109 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3110 # if !defined(SPARC64)
3111 { uoff(start_code), "offsetof(struct user, start_code)" },
3113 # if defined(AVR32) || defined(SH64)
3114 { uoff(start_data), "offsetof(struct user, start_data)" },
3116 # if !defined(SPARC64)
3117 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3119 { uoff(signal), "offsetof(struct user, signal)" },
3120 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3121 { uoff(reserved), "offsetof(struct user, reserved)" },
3123 # if !defined(SPARC64)
3124 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3126 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3127 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3129 { uoff(magic), "offsetof(struct user, magic)" },
3130 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3131 # if defined(I386) || defined(X86_64)
3132 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3134 # endif /* !defined(many arches) */
3139 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3140 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3141 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3142 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3143 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3144 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3145 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3146 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3147 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3148 { uoff(u_error), "offsetof(struct user, u_error)" },
3149 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3150 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3151 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3152 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3153 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3154 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3155 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3156 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3157 { uoff(u_code), "offsetof(struct user, u_code)" },
3158 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3159 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3160 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3161 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3162 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3163 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3164 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3165 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3166 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3167 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3168 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3169 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3170 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3171 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3172 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3173 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3174 { uoff(u_start), "offsetof(struct user, u_start)" },
3175 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3176 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3177 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3178 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3179 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3180 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3181 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3182 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3183 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3184 # endif /* SUNOS4 */
3186 { sizeof(struct user), "sizeof(struct user)" },
3190 # endif /* !FREEBSD */
3193 sys_ptrace(struct tcb *tcp)
3195 const struct xlat *x;
3198 if (entering(tcp)) {
3199 printxval(ptrace_cmds, tcp->u_arg[0],
3206 tprintf(", %lu, ", tcp->u_arg[1]);
3207 addr = tcp->u_arg[2];
3209 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3210 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3211 for (x = struct_user_offsets; x->str; x++) {
3216 tprintf("%#lx, ", addr);
3217 else if (x->val > addr && x != struct_user_offsets) {
3219 tprintf("%s + %ld, ", x->str, addr - x->val);
3222 tprintf("%s, ", x->str);
3226 tprintf("%#lx, ", tcp->u_arg[2]);
3228 switch (tcp->u_arg[0]) {
3230 case PTRACE_PEEKDATA:
3231 case PTRACE_PEEKTEXT:
3232 case PTRACE_PEEKUSER:
3236 case PTRACE_SINGLESTEP:
3237 case PTRACE_SYSCALL:
3239 printsignal(tcp->u_arg[3]);
3241 # ifdef PTRACE_SETOPTIONS
3242 case PTRACE_SETOPTIONS:
3243 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3246 # ifdef PTRACE_SETSIGINFO
3247 case PTRACE_SETSIGINFO: {
3251 else if (syserror(tcp))
3252 tprintf("%#lx", tcp->u_arg[3]);
3253 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3256 printsiginfo(&si, verbose(tcp));
3260 # ifdef PTRACE_GETSIGINFO
3261 case PTRACE_GETSIGINFO:
3262 /* Don't print anything, do it at syscall return. */
3266 tprintf("%#lx", tcp->u_arg[3]);
3270 switch (tcp->u_arg[0]) {
3271 case PTRACE_PEEKDATA:
3272 case PTRACE_PEEKTEXT:
3273 case PTRACE_PEEKUSER:
3277 printnum(tcp, tcp->u_arg[3], "%#lx");
3280 # ifdef PTRACE_GETSIGINFO
3281 case PTRACE_GETSIGINFO: {
3285 else if (syserror(tcp))
3286 tprintf("%#lx", tcp->u_arg[3]);
3287 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3290 printsiginfo(&si, verbose(tcp));
3298 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3299 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3300 tprintf("%lu, ", tcp->u_arg[3]);
3301 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3302 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3303 tcp->u_arg[0] != PTRACE_READTEXT) {
3304 tprintf("%#lx", tcp->u_arg[3]);
3307 if (tcp->u_arg[0] == PTRACE_READDATA ||
3308 tcp->u_arg[0] == PTRACE_READTEXT) {
3309 tprintf("%lu, ", tcp->u_arg[3]);
3310 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3313 # endif /* SUNOS4 */
3315 tprintf("%lu", tcp->u_arg[3]);
3317 # endif /* FREEBSD */
3324 # ifndef FUTEX_CMP_REQUEUE
3325 # define FUTEX_CMP_REQUEUE 4
3327 # ifndef FUTEX_WAKE_OP
3328 # define FUTEX_WAKE_OP 5
3330 # ifndef FUTEX_LOCK_PI
3331 # define FUTEX_LOCK_PI 6
3332 # define FUTEX_UNLOCK_PI 7
3333 # define FUTEX_TRYLOCK_PI 8
3335 # ifndef FUTEX_WAIT_BITSET
3336 # define FUTEX_WAIT_BITSET 9
3338 # ifndef FUTEX_WAKE_BITSET
3339 # define FUTEX_WAKE_BITSET 10
3341 # ifndef FUTEX_WAIT_REQUEUE_PI
3342 # define FUTEX_WAIT_REQUEUE_PI 11
3344 # ifndef FUTEX_CMP_REQUEUE_PI
3345 # define FUTEX_CMP_REQUEUE_PI 12
3347 # ifndef FUTEX_PRIVATE_FLAG
3348 # define FUTEX_PRIVATE_FLAG 128
3350 # ifndef FUTEX_CLOCK_REALTIME
3351 # define FUTEX_CLOCK_REALTIME 256
3353 static const struct xlat futexops[] = {
3354 { FUTEX_WAIT, "FUTEX_WAIT" },
3355 { FUTEX_WAKE, "FUTEX_WAKE" },
3356 { FUTEX_FD, "FUTEX_FD" },
3357 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3358 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3359 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3360 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3361 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3362 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3363 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3364 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3365 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3366 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3367 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3368 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3369 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3370 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3371 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3372 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3373 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3374 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3375 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3376 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3377 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3378 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3379 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3380 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3381 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3382 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3383 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3386 # ifndef FUTEX_OP_SET
3387 # define FUTEX_OP_SET 0
3388 # define FUTEX_OP_ADD 1
3389 # define FUTEX_OP_OR 2
3390 # define FUTEX_OP_ANDN 3
3391 # define FUTEX_OP_XOR 4
3392 # define FUTEX_OP_CMP_EQ 0
3393 # define FUTEX_OP_CMP_NE 1
3394 # define FUTEX_OP_CMP_LT 2
3395 # define FUTEX_OP_CMP_LE 3
3396 # define FUTEX_OP_CMP_GT 4
3397 # define FUTEX_OP_CMP_GE 5
3399 static const struct xlat futexwakeops[] = {
3400 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3401 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3402 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3403 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3404 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3407 static const struct xlat futexwakecmps[] = {
3408 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3409 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3410 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3411 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3412 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3413 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3418 sys_futex(struct tcb *tcp)
3420 if (entering(tcp)) {
3421 long int cmd = tcp->u_arg[1] & 127;
3422 tprintf("%p, ", (void *) tcp->u_arg[0]);
3423 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3424 tprintf(", %ld", tcp->u_arg[2]);
3425 if (cmd == FUTEX_WAKE_BITSET)
3426 tprintf(", %lx", tcp->u_arg[5]);
3427 else if (cmd == FUTEX_WAIT) {
3429 printtv(tcp, tcp->u_arg[3]);
3430 } else if (cmd == FUTEX_WAIT_BITSET) {
3432 printtv(tcp, tcp->u_arg[3]);
3433 tprintf(", %lx", tcp->u_arg[5]);
3434 } else if (cmd == FUTEX_REQUEUE)
3435 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3436 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3437 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3438 else if (cmd == FUTEX_WAKE_OP) {
3439 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3440 if ((tcp->u_arg[5] >> 28) & 8)
3441 tprintf("FUTEX_OP_OPARG_SHIFT|");
3442 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3443 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3444 if ((tcp->u_arg[5] >> 24) & 8)
3445 tprintf("FUTEX_OP_OPARG_SHIFT|");
3446 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3447 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3448 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3450 printtv(tcp, tcp->u_arg[3]);
3451 tprintf(", %p", (void *) tcp->u_arg[4]);
3458 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3461 unsigned long w, min_len;
3463 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3464 min_len = len - max_strlen * sizeof(w);
3467 for (; len >= sizeof(w) && len > min_len;
3468 len -= sizeof(w), list += sizeof(w)) {
3469 if (umove(tcp, list, &w) < 0)
3480 tprintf("%#lx", list);
3482 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3485 tprintf(first ? "{}" : "}");
3490 sys_sched_setaffinity(struct tcb *tcp)
3492 if (entering(tcp)) {
3493 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3494 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3500 sys_sched_getaffinity(struct tcb *tcp)
3502 if (entering(tcp)) {
3503 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3505 if (tcp->u_rval == -1)
3506 tprintf("%#lx", tcp->u_arg[2]);
3508 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3513 static const struct xlat schedulers[] = {
3514 { SCHED_OTHER, "SCHED_OTHER" },
3515 { SCHED_RR, "SCHED_RR" },
3516 { SCHED_FIFO, "SCHED_FIFO" },
3521 sys_sched_getscheduler(struct tcb *tcp)
3523 if (entering(tcp)) {
3524 tprintf("%d", (int) tcp->u_arg[0]);
3525 } else if (! syserror(tcp)) {
3526 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3527 if (tcp->auxstr != NULL)
3534 sys_sched_setscheduler(struct tcb *tcp)
3536 if (entering(tcp)) {
3537 struct sched_param p;
3538 tprintf("%d, ", (int) tcp->u_arg[0]);
3539 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3540 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3541 tprintf(", %#lx", tcp->u_arg[2]);
3543 tprintf(", { %d }", p.__sched_priority);
3549 sys_sched_getparam(struct tcb *tcp)
3551 if (entering(tcp)) {
3552 tprintf("%d, ", (int) tcp->u_arg[0]);
3554 struct sched_param p;
3555 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3556 tprintf("%#lx", tcp->u_arg[1]);
3558 tprintf("{ %d }", p.__sched_priority);
3564 sys_sched_setparam(struct tcb *tcp)
3566 if (entering(tcp)) {
3567 struct sched_param p;
3568 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3569 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3571 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3577 sys_sched_get_priority_min(struct tcb *tcp)
3579 if (entering(tcp)) {
3580 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3586 # include <asm/prctl.h>
3588 static const struct xlat archvals[] = {
3589 { ARCH_SET_GS, "ARCH_SET_GS" },
3590 { ARCH_SET_FS, "ARCH_SET_FS" },
3591 { ARCH_GET_FS, "ARCH_GET_FS" },
3592 { ARCH_GET_GS, "ARCH_GET_GS" },
3597 sys_arch_prctl(struct tcb *tcp)
3599 if (entering(tcp)) {
3600 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3601 if (tcp->u_arg[0] == ARCH_SET_GS
3602 || tcp->u_arg[0] == ARCH_SET_FS
3604 tprintf(", %#lx", tcp->u_arg[1]);
3607 if (tcp->u_arg[0] == ARCH_GET_GS
3608 || tcp->u_arg[0] == ARCH_GET_FS
3611 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3612 tprintf(", [%#lx]", v);
3614 tprintf(", %#lx", tcp->u_arg[1]);
3619 # endif /* X86_64 */
3623 sys_getcpu(struct tcb *tcp)
3627 if (tcp->u_arg[0] == 0)
3629 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3630 tprintf("%#lx, ", tcp->u_arg[0]);
3632 tprintf("[%u], ", u);
3633 if (tcp->u_arg[1] == 0)
3635 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3636 tprintf("%#lx, ", tcp->u_arg[1]);
3638 tprintf("[%u], ", u);
3639 tprintf("%#lx", tcp->u_arg[2]);