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 extern int force_result();
1985 return force_result(tcp, 0, 0);
1988 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1989 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1991 * We just reaped a child we don't know about,
1992 * presumably a zombie we already droptcb'd.
2006 /* The library wrapper stuffs this into the user variable. */
2008 printstatus(getrval2(tcp));
2023 if (!syserror(tcp)) {
2024 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2025 tprintf("%#lx", tcp->u_arg[0]);
2027 printstatus(status);
2038 return printwaitn(tcp, 3, 0);
2045 return printwaitn(tcp, 4, 0);
2053 return printwaitn(tcp, 4, 1);
2057 #if defined SVR4 || defined LINUX
2059 static const struct xlat waitid_types[] = {
2062 { P_PPID, "P_PPID" },
2064 { P_PGID, "P_PGID" },
2079 { P_LWPID, "P_LWPID" },
2091 if (entering(tcp)) {
2092 printxval(waitid_types, tcp->u_arg[0], "P_???");
2093 tprintf(", %ld, ", tcp->u_arg[1]);
2100 else if (syserror(tcp))
2101 tprintf("%#lx", tcp->u_arg[2]);
2102 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2105 printsiginfo(&si, verbose(tcp));
2108 printflags(wait4_options, tcp->u_arg[3], "W???");
2109 if (tcp->u_nargs > 4) {
2114 else if (tcp->u_error)
2115 tprintf("%#lx", tcp->u_arg[4]);
2117 printrusage(tcp, tcp->u_arg[4]);
2123 #endif /* SVR4 or LINUX */
2130 tprintf("%lu", tcp->u_arg[0]);
2138 struct utsname uname;
2141 if (syserror(tcp) || !verbose(tcp))
2142 tprintf("%#lx", tcp->u_arg[0]);
2143 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2145 else if (!abbrev(tcp)) {
2147 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2148 uname.sysname, uname.nodename);
2149 tprintf("release=\"%s\", version=\"%s\", ",
2150 uname.release, uname.version);
2151 tprintf("machine=\"%s\"", uname.machine);
2154 tprintf(", domainname=\"%s\"", uname.domainname);
2160 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2161 uname.sysname, uname.nodename);
2168 static const struct xlat ptrace_cmds[] = {
2170 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2171 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2172 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2173 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2174 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2175 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2176 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2177 { PTRACE_CONT, "PTRACE_CONT" },
2178 { PTRACE_KILL, "PTRACE_KILL" },
2179 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2180 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2181 { PTRACE_DETACH, "PTRACE_DETACH" },
2182 # ifdef PTRACE_GETREGS
2183 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2185 # ifdef PTRACE_SETREGS
2186 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2188 # ifdef PTRACE_GETFPREGS
2189 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2191 # ifdef PTRACE_SETFPREGS
2192 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2194 # ifdef PTRACE_GETFPXREGS
2195 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2197 # ifdef PTRACE_SETFPXREGS
2198 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2200 # ifdef PTRACE_GETVRREGS
2201 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2203 # ifdef PTRACE_SETVRREGS
2204 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2206 # ifdef PTRACE_SETOPTIONS
2207 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2209 # ifdef PTRACE_GETEVENTMSG
2210 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2212 # ifdef PTRACE_GETSIGINFO
2213 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2215 # ifdef PTRACE_SETSIGINFO
2216 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2218 # ifdef PTRACE_SET_SYSCALL
2219 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2222 { PTRACE_READDATA, "PTRACE_READDATA" },
2223 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2224 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2225 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2226 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2227 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2229 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2230 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2232 { PTRACE_22, "PTRACE_22" },
2233 { PTRACE_23, "PTRACE_3" },
2234 # endif /* !SPARC */
2235 # endif /* SUNOS4 */
2236 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2238 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2240 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2241 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2242 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2244 { PTRACE_26, "PTRACE_26" },
2245 { PTRACE_27, "PTRACE_27" },
2246 { PTRACE_28, "PTRACE_28" },
2248 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2249 # endif /* SUNOS4 */
2251 # else /* FREEBSD */
2253 { PT_TRACE_ME, "PT_TRACE_ME" },
2254 { PT_READ_I, "PT_READ_I" },
2255 { PT_READ_D, "PT_READ_D" },
2256 { PT_WRITE_I, "PT_WRITE_I" },
2257 { PT_WRITE_D, "PT_WRITE_D" },
2259 { PT_READ_U, "PT_READ_U" },
2261 { PT_CONTINUE, "PT_CONTINUE" },
2262 { PT_KILL, "PT_KILL" },
2263 { PT_STEP, "PT_STEP" },
2264 { PT_ATTACH, "PT_ATTACH" },
2265 { PT_DETACH, "PT_DETACH" },
2266 { PT_GETREGS, "PT_GETREGS" },
2267 { PT_SETREGS, "PT_SETREGS" },
2268 { PT_GETFPREGS, "PT_GETFPREGS" },
2269 { PT_SETFPREGS, "PT_SETFPREGS" },
2270 { PT_GETDBREGS, "PT_GETDBREGS" },
2271 { PT_SETDBREGS, "PT_SETDBREGS" },
2272 # endif /* FREEBSD */
2277 # ifdef PTRACE_SETOPTIONS
2278 static const struct xlat ptrace_setoptions_flags[] = {
2279 # ifdef PTRACE_O_TRACESYSGOOD
2280 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2282 # ifdef PTRACE_O_TRACEFORK
2283 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2285 # ifdef PTRACE_O_TRACEVFORK
2286 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2288 # ifdef PTRACE_O_TRACECLONE
2289 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2291 # ifdef PTRACE_O_TRACEEXEC
2292 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2294 # ifdef PTRACE_O_TRACEVFORKDONE
2295 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2297 # ifdef PTRACE_O_TRACEEXIT
2298 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2302 # endif /* PTRACE_SETOPTIONS */
2303 # endif /* !FREEBSD */
2306 const struct xlat struct_user_offsets[] = {
2308 # if defined(S390) || defined(S390X)
2309 { PT_PSWMASK, "psw_mask" },
2310 { PT_PSWADDR, "psw_addr" },
2311 { PT_GPR0, "gpr0" },
2312 { PT_GPR1, "gpr1" },
2313 { PT_GPR2, "gpr2" },
2314 { PT_GPR3, "gpr3" },
2315 { PT_GPR4, "gpr4" },
2316 { PT_GPR5, "gpr5" },
2317 { PT_GPR6, "gpr6" },
2318 { PT_GPR7, "gpr7" },
2319 { PT_GPR8, "gpr8" },
2320 { PT_GPR9, "gpr9" },
2321 { PT_GPR10, "gpr10" },
2322 { PT_GPR11, "gpr11" },
2323 { PT_GPR12, "gpr12" },
2324 { PT_GPR13, "gpr13" },
2325 { PT_GPR14, "gpr14" },
2326 { PT_GPR15, "gpr15" },
2327 { PT_ACR0, "acr0" },
2328 { PT_ACR1, "acr1" },
2329 { PT_ACR2, "acr2" },
2330 { PT_ACR3, "acr3" },
2331 { PT_ACR4, "acr4" },
2332 { PT_ACR5, "acr5" },
2333 { PT_ACR6, "acr6" },
2334 { PT_ACR7, "acr7" },
2335 { PT_ACR8, "acr8" },
2336 { PT_ACR9, "acr9" },
2337 { PT_ACR10, "acr10" },
2338 { PT_ACR11, "acr11" },
2339 { PT_ACR12, "acr12" },
2340 { PT_ACR13, "acr13" },
2341 { PT_ACR14, "acr14" },
2342 { PT_ACR15, "acr15" },
2343 { PT_ORIGGPR2, "orig_gpr2" },
2346 { PT_FPR0_HI, "fpr0.hi" },
2347 { PT_FPR0_LO, "fpr0.lo" },
2348 { PT_FPR1_HI, "fpr1.hi" },
2349 { PT_FPR1_LO, "fpr1.lo" },
2350 { PT_FPR2_HI, "fpr2.hi" },
2351 { PT_FPR2_LO, "fpr2.lo" },
2352 { PT_FPR3_HI, "fpr3.hi" },
2353 { PT_FPR3_LO, "fpr3.lo" },
2354 { PT_FPR4_HI, "fpr4.hi" },
2355 { PT_FPR4_LO, "fpr4.lo" },
2356 { PT_FPR5_HI, "fpr5.hi" },
2357 { PT_FPR5_LO, "fpr5.lo" },
2358 { PT_FPR6_HI, "fpr6.hi" },
2359 { PT_FPR6_LO, "fpr6.lo" },
2360 { PT_FPR7_HI, "fpr7.hi" },
2361 { PT_FPR7_LO, "fpr7.lo" },
2362 { PT_FPR8_HI, "fpr8.hi" },
2363 { PT_FPR8_LO, "fpr8.lo" },
2364 { PT_FPR9_HI, "fpr9.hi" },
2365 { PT_FPR9_LO, "fpr9.lo" },
2366 { PT_FPR10_HI, "fpr10.hi" },
2367 { PT_FPR10_LO, "fpr10.lo" },
2368 { PT_FPR11_HI, "fpr11.hi" },
2369 { PT_FPR11_LO, "fpr11.lo" },
2370 { PT_FPR12_HI, "fpr12.hi" },
2371 { PT_FPR12_LO, "fpr12.lo" },
2372 { PT_FPR13_HI, "fpr13.hi" },
2373 { PT_FPR13_LO, "fpr13.lo" },
2374 { PT_FPR14_HI, "fpr14.hi" },
2375 { PT_FPR14_LO, "fpr14.lo" },
2376 { PT_FPR15_HI, "fpr15.hi" },
2377 { PT_FPR15_LO, "fpr15.lo" },
2380 { PT_FPR0, "fpr0" },
2381 { PT_FPR1, "fpr1" },
2382 { PT_FPR2, "fpr2" },
2383 { PT_FPR3, "fpr3" },
2384 { PT_FPR4, "fpr4" },
2385 { PT_FPR5, "fpr5" },
2386 { PT_FPR6, "fpr6" },
2387 { PT_FPR7, "fpr7" },
2388 { PT_FPR8, "fpr8" },
2389 { PT_FPR9, "fpr9" },
2390 { PT_FPR10, "fpr10" },
2391 { PT_FPR11, "fpr11" },
2392 { PT_FPR12, "fpr12" },
2393 { PT_FPR13, "fpr13" },
2394 { PT_FPR14, "fpr14" },
2395 { PT_FPR15, "fpr15" },
2398 { PT_CR_10, "cr10" },
2399 { PT_CR_11, "cr11" },
2400 { PT_IEEE_IP, "ieee_exception_ip" },
2401 # elif defined(SPARC)
2402 /* XXX No support for these offsets yet. */
2403 # elif defined(HPPA)
2404 /* XXX No support for these offsets yet. */
2405 # elif defined(POWERPC)
2407 # define PT_ORIG_R3 34
2409 # define REGSIZE (sizeof(unsigned long))
2410 { REGSIZE*PT_R0, "r0" },
2411 { REGSIZE*PT_R1, "r1" },
2412 { REGSIZE*PT_R2, "r2" },
2413 { REGSIZE*PT_R3, "r3" },
2414 { REGSIZE*PT_R4, "r4" },
2415 { REGSIZE*PT_R5, "r5" },
2416 { REGSIZE*PT_R6, "r6" },
2417 { REGSIZE*PT_R7, "r7" },
2418 { REGSIZE*PT_R8, "r8" },
2419 { REGSIZE*PT_R9, "r9" },
2420 { REGSIZE*PT_R10, "r10" },
2421 { REGSIZE*PT_R11, "r11" },
2422 { REGSIZE*PT_R12, "r12" },
2423 { REGSIZE*PT_R13, "r13" },
2424 { REGSIZE*PT_R14, "r14" },
2425 { REGSIZE*PT_R15, "r15" },
2426 { REGSIZE*PT_R16, "r16" },
2427 { REGSIZE*PT_R17, "r17" },
2428 { REGSIZE*PT_R18, "r18" },
2429 { REGSIZE*PT_R19, "r19" },
2430 { REGSIZE*PT_R20, "r20" },
2431 { REGSIZE*PT_R21, "r21" },
2432 { REGSIZE*PT_R22, "r22" },
2433 { REGSIZE*PT_R23, "r23" },
2434 { REGSIZE*PT_R24, "r24" },
2435 { REGSIZE*PT_R25, "r25" },
2436 { REGSIZE*PT_R26, "r26" },
2437 { REGSIZE*PT_R27, "r27" },
2438 { REGSIZE*PT_R28, "r28" },
2439 { REGSIZE*PT_R29, "r29" },
2440 { REGSIZE*PT_R30, "r30" },
2441 { REGSIZE*PT_R31, "r31" },
2442 { REGSIZE*PT_NIP, "NIP" },
2443 { REGSIZE*PT_MSR, "MSR" },
2444 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2445 { REGSIZE*PT_CTR, "CTR" },
2446 { REGSIZE*PT_LNK, "LNK" },
2447 { REGSIZE*PT_XER, "XER" },
2448 { REGSIZE*PT_CCR, "CCR" },
2449 { REGSIZE*PT_FPR0, "FPR0" },
2451 # elif defined(ALPHA)
2517 # elif defined(IA64)
2518 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2519 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2520 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2521 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2522 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2523 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2524 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2525 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2526 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2527 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2528 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2529 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2530 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2531 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2532 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2533 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2534 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2535 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2536 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2537 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2538 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2539 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2540 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2541 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2542 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2543 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2544 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2545 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2546 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2547 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2548 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2549 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2551 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2552 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2553 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2554 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2555 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2556 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2557 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2558 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2559 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2560 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2561 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2562 { PT_B4, "b4" }, { PT_B5, "b5" },
2563 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2565 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2566 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2567 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2568 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2569 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2570 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2571 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2572 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2573 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2574 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2575 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2576 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2577 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2578 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2579 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2580 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2581 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2583 { PT_AR_CSD, "ar.csd" },
2586 { PT_AR_SSD, "ar.ssd" },
2588 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2589 # elif defined(I386)
2601 { 4*ORIG_EAX, "4*ORIG_EAX" },
2605 { 4*UESP, "4*UESP" },
2607 # elif defined(X86_64)
2623 { 8*ORIG_RAX, "8*ORIG_RAX" },
2626 { 8*EFLAGS, "8*EFL" },
2629 # elif defined(M68K)
2630 { 4*PT_D1, "4*PT_D1" },
2631 { 4*PT_D2, "4*PT_D2" },
2632 { 4*PT_D3, "4*PT_D3" },
2633 { 4*PT_D4, "4*PT_D4" },
2634 { 4*PT_D5, "4*PT_D5" },
2635 { 4*PT_D6, "4*PT_D6" },
2636 { 4*PT_D7, "4*PT_D7" },
2637 { 4*PT_A0, "4*PT_A0" },
2638 { 4*PT_A1, "4*PT_A1" },
2639 { 4*PT_A2, "4*PT_A2" },
2640 { 4*PT_A3, "4*PT_A3" },
2641 { 4*PT_A4, "4*PT_A4" },
2642 { 4*PT_A5, "4*PT_A5" },
2643 { 4*PT_A6, "4*PT_A6" },
2644 { 4*PT_D0, "4*PT_D0" },
2645 { 4*PT_USP, "4*PT_USP" },
2646 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2647 { 4*PT_SR, "4*PT_SR" },
2648 { 4*PT_PC, "4*PT_PC" },
2650 { 4*REG_REG0, "4*REG_REG0" },
2651 { 4*(REG_REG0+1), "4*REG_REG1" },
2652 { 4*(REG_REG0+2), "4*REG_REG2" },
2653 { 4*(REG_REG0+3), "4*REG_REG3" },
2654 { 4*(REG_REG0+4), "4*REG_REG4" },
2655 { 4*(REG_REG0+5), "4*REG_REG5" },
2656 { 4*(REG_REG0+6), "4*REG_REG6" },
2657 { 4*(REG_REG0+7), "4*REG_REG7" },
2658 { 4*(REG_REG0+8), "4*REG_REG8" },
2659 { 4*(REG_REG0+9), "4*REG_REG9" },
2660 { 4*(REG_REG0+10), "4*REG_REG10" },
2661 { 4*(REG_REG0+11), "4*REG_REG11" },
2662 { 4*(REG_REG0+12), "4*REG_REG12" },
2663 { 4*(REG_REG0+13), "4*REG_REG13" },
2664 { 4*(REG_REG0+14), "4*REG_REG14" },
2665 { 4*REG_REG15, "4*REG_REG15" },
2666 { 4*REG_PC, "4*REG_PC" },
2667 { 4*REG_PR, "4*REG_PR" },
2668 { 4*REG_SR, "4*REG_SR" },
2669 { 4*REG_GBR, "4*REG_GBR" },
2670 { 4*REG_MACH, "4*REG_MACH" },
2671 { 4*REG_MACL, "4*REG_MACL" },
2672 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2673 { 4*REG_FPUL, "4*REG_FPUL" },
2674 { 4*REG_FPREG0, "4*REG_FPREG0" },
2675 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2676 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2677 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2678 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2679 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2680 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2681 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2682 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2683 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2684 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2685 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2686 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2687 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2688 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2689 { 4*REG_FPREG15, "4*REG_FPREG15" },
2691 { 4*REG_XDREG0, "4*REG_XDREG0" },
2692 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2693 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2694 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2695 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2696 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2697 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2698 { 4*REG_XDREG14, "4*REG_XDREG14" },
2700 { 4*REG_FPSCR, "4*REG_FPSCR" },
2701 # elif defined(SH64)
2706 { 16, "syscall no.(L)" },
2707 { 20, "syscall_no.(U)" },
2850 /* This entry is in case pt_regs contains dregs (depends on
2851 the kernel build options). */
2852 { uoff(regs), "offsetof(struct user, regs)" },
2853 { uoff(fpu), "offsetof(struct user, fpu)" },
2855 { uoff(regs.ARM_r0), "r0" },
2856 { uoff(regs.ARM_r1), "r1" },
2857 { uoff(regs.ARM_r2), "r2" },
2858 { uoff(regs.ARM_r3), "r3" },
2859 { uoff(regs.ARM_r4), "r4" },
2860 { uoff(regs.ARM_r5), "r5" },
2861 { uoff(regs.ARM_r6), "r6" },
2862 { uoff(regs.ARM_r7), "r7" },
2863 { uoff(regs.ARM_r8), "r8" },
2864 { uoff(regs.ARM_r9), "r9" },
2865 { uoff(regs.ARM_r10), "r10" },
2866 { uoff(regs.ARM_fp), "fp" },
2867 { uoff(regs.ARM_ip), "ip" },
2868 { uoff(regs.ARM_sp), "sp" },
2869 { uoff(regs.ARM_lr), "lr" },
2870 { uoff(regs.ARM_pc), "pc" },
2871 { uoff(regs.ARM_cpsr), "cpsr" },
2872 # elif defined(AVR32)
2873 { uoff(regs.sr), "sr" },
2874 { uoff(regs.pc), "pc" },
2875 { uoff(regs.lr), "lr" },
2876 { uoff(regs.sp), "sp" },
2877 { uoff(regs.r12), "r12" },
2878 { uoff(regs.r11), "r11" },
2879 { uoff(regs.r10), "r10" },
2880 { uoff(regs.r9), "r9" },
2881 { uoff(regs.r8), "r8" },
2882 { uoff(regs.r7), "r7" },
2883 { uoff(regs.r6), "r6" },
2884 { uoff(regs.r5), "r5" },
2885 { uoff(regs.r4), "r4" },
2886 { uoff(regs.r3), "r3" },
2887 { uoff(regs.r2), "r2" },
2888 { uoff(regs.r1), "r1" },
2889 { uoff(regs.r0), "r0" },
2890 { uoff(regs.r12_orig), "orig_r12" },
2891 # elif defined(MIPS)
2963 # elif defined(TILE)
2964 { PTREGS_OFFSET_REG(0), "r0" },
2965 { PTREGS_OFFSET_REG(1), "r1" },
2966 { PTREGS_OFFSET_REG(2), "r2" },
2967 { PTREGS_OFFSET_REG(3), "r3" },
2968 { PTREGS_OFFSET_REG(4), "r4" },
2969 { PTREGS_OFFSET_REG(5), "r5" },
2970 { PTREGS_OFFSET_REG(6), "r6" },
2971 { PTREGS_OFFSET_REG(7), "r7" },
2972 { PTREGS_OFFSET_REG(8), "r8" },
2973 { PTREGS_OFFSET_REG(9), "r9" },
2974 { PTREGS_OFFSET_REG(10), "r10" },
2975 { PTREGS_OFFSET_REG(11), "r11" },
2976 { PTREGS_OFFSET_REG(12), "r12" },
2977 { PTREGS_OFFSET_REG(13), "r13" },
2978 { PTREGS_OFFSET_REG(14), "r14" },
2979 { PTREGS_OFFSET_REG(15), "r15" },
2980 { PTREGS_OFFSET_REG(16), "r16" },
2981 { PTREGS_OFFSET_REG(17), "r17" },
2982 { PTREGS_OFFSET_REG(18), "r18" },
2983 { PTREGS_OFFSET_REG(19), "r19" },
2984 { PTREGS_OFFSET_REG(20), "r20" },
2985 { PTREGS_OFFSET_REG(21), "r21" },
2986 { PTREGS_OFFSET_REG(22), "r22" },
2987 { PTREGS_OFFSET_REG(23), "r23" },
2988 { PTREGS_OFFSET_REG(24), "r24" },
2989 { PTREGS_OFFSET_REG(25), "r25" },
2990 { PTREGS_OFFSET_REG(26), "r26" },
2991 { PTREGS_OFFSET_REG(27), "r27" },
2992 { PTREGS_OFFSET_REG(28), "r28" },
2993 { PTREGS_OFFSET_REG(29), "r29" },
2994 { PTREGS_OFFSET_REG(30), "r30" },
2995 { PTREGS_OFFSET_REG(31), "r31" },
2996 { PTREGS_OFFSET_REG(32), "r32" },
2997 { PTREGS_OFFSET_REG(33), "r33" },
2998 { PTREGS_OFFSET_REG(34), "r34" },
2999 { PTREGS_OFFSET_REG(35), "r35" },
3000 { PTREGS_OFFSET_REG(36), "r36" },
3001 { PTREGS_OFFSET_REG(37), "r37" },
3002 { PTREGS_OFFSET_REG(38), "r38" },
3003 { PTREGS_OFFSET_REG(39), "r39" },
3004 { PTREGS_OFFSET_REG(40), "r40" },
3005 { PTREGS_OFFSET_REG(41), "r41" },
3006 { PTREGS_OFFSET_REG(42), "r42" },
3007 { PTREGS_OFFSET_REG(43), "r43" },
3008 { PTREGS_OFFSET_REG(44), "r44" },
3009 { PTREGS_OFFSET_REG(45), "r45" },
3010 { PTREGS_OFFSET_REG(46), "r46" },
3011 { PTREGS_OFFSET_REG(47), "r47" },
3012 { PTREGS_OFFSET_REG(48), "r48" },
3013 { PTREGS_OFFSET_REG(49), "r49" },
3014 { PTREGS_OFFSET_REG(50), "r50" },
3015 { PTREGS_OFFSET_REG(51), "r51" },
3016 { PTREGS_OFFSET_REG(52), "r52" },
3017 { PTREGS_OFFSET_TP, "tp" },
3018 { PTREGS_OFFSET_SP, "sp" },
3019 { PTREGS_OFFSET_LR, "lr" },
3020 { PTREGS_OFFSET_PC, "pc" },
3021 { PTREGS_OFFSET_EX1, "ex1" },
3022 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
3023 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
3024 { PTREGS_OFFSET_FLAGS, "flags" },
3027 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3028 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3029 { 4*PT_R13, "4*PT_R13" },
3030 { 4*PT_R12, "4*PT_R12" },
3031 { 4*PT_R11, "4*PT_R11" },
3032 { 4*PT_R10, "4*PT_R10" },
3033 { 4*PT_R9, "4*PT_R9" },
3034 { 4*PT_R8, "4*PT_R8" },
3035 { 4*PT_R7, "4*PT_R7" },
3036 { 4*PT_R6, "4*PT_R6" },
3037 { 4*PT_R5, "4*PT_R5" },
3038 { 4*PT_R4, "4*PT_R4" },
3039 { 4*PT_R3, "4*PT_R3" },
3040 { 4*PT_R2, "4*PT_R2" },
3041 { 4*PT_R1, "4*PT_R1" },
3042 { 4*PT_R0, "4*PT_R0" },
3043 { 4*PT_MOF, "4*PT_MOF" },
3044 { 4*PT_DCCR, "4*PT_DCCR" },
3045 { 4*PT_SRP, "4*PT_SRP" },
3046 { 4*PT_IRP, "4*PT_IRP" },
3047 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3048 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3049 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3050 { 4*PT_USP, "4*PT_USP" },
3053 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3054 { 4*PT_R0, "4*PT_R0" },
3055 { 4*PT_R1, "4*PT_R1" },
3056 { 4*PT_R2, "4*PT_R2" },
3057 { 4*PT_R3, "4*PT_R3" },
3058 { 4*PT_R4, "4*PT_R4" },
3059 { 4*PT_R5, "4*PT_R5" },
3060 { 4*PT_R6, "4*PT_R6" },
3061 { 4*PT_R7, "4*PT_R7" },
3062 { 4*PT_R8, "4*PT_R8" },
3063 { 4*PT_R9, "4*PT_R9" },
3064 { 4*PT_R10, "4*PT_R10" },
3065 { 4*PT_R11, "4*PT_R11" },
3066 { 4*PT_R12, "4*PT_R12" },
3067 { 4*PT_R13, "4*PT_R13" },
3068 { 4*PT_ACR, "4*PT_ACR" },
3069 { 4*PT_SRS, "4*PT_SRS" },
3070 { 4*PT_MOF, "4*PT_MOF" },
3071 { 4*PT_SPC, "4*PT_SPC" },
3072 { 4*PT_CCS, "4*PT_CCS" },
3073 { 4*PT_SRP, "4*PT_SRP" },
3074 { 4*PT_ERP, "4*PT_ERP" },
3075 { 4*PT_EXS, "4*PT_EXS" },
3076 { 4*PT_EDA, "4*PT_EDA" },
3077 { 4*PT_USP, "4*PT_USP" },
3078 { 4*PT_PPC, "4*PT_PPC" },
3079 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3080 { 4*PT_BP+4, "4*PT_BP+4" },
3081 { 4*PT_BP+8, "4*PT_BP+8" },
3082 { 4*PT_BP+12, "4*PT_BP+12" },
3083 { 4*PT_BP+16, "4*PT_BP+16" },
3084 { 4*PT_BP+20, "4*PT_BP+20" },
3085 { 4*PT_BP+24, "4*PT_BP+24" },
3086 { 4*PT_BP+28, "4*PT_BP+28" },
3087 { 4*PT_BP+32, "4*PT_BP+32" },
3088 { 4*PT_BP+36, "4*PT_BP+36" },
3089 { 4*PT_BP+40, "4*PT_BP+40" },
3090 { 4*PT_BP+44, "4*PT_BP+44" },
3091 { 4*PT_BP+48, "4*PT_BP+48" },
3092 { 4*PT_BP+52, "4*PT_BP+52" },
3093 { 4*PT_BP+56, "4*PT_BP+56" },
3096 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3097 && !defined(ALPHA) && !defined(IA64) \
3098 && !defined(CRISV10) && !defined(CRISV32)
3099 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3100 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3102 # if defined(I386) || defined(X86_64)
3103 { uoff(i387), "offsetof(struct user, i387)" },
3106 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3108 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3109 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3110 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3111 # if !defined(SPARC64)
3112 { uoff(start_code), "offsetof(struct user, start_code)" },
3114 # if defined(AVR32) || defined(SH64)
3115 { uoff(start_data), "offsetof(struct user, start_data)" },
3117 # if !defined(SPARC64)
3118 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3120 { uoff(signal), "offsetof(struct user, signal)" },
3121 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3122 { uoff(reserved), "offsetof(struct user, reserved)" },
3124 # if !defined(SPARC64)
3125 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3127 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3128 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3130 { uoff(magic), "offsetof(struct user, magic)" },
3131 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3132 # if defined(I386) || defined(X86_64)
3133 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3135 # endif /* !defined(many arches) */
3140 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3141 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3142 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3143 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3144 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3145 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3146 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3147 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3148 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3149 { uoff(u_error), "offsetof(struct user, u_error)" },
3150 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3151 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3152 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3153 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3154 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3155 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3156 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3157 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3158 { uoff(u_code), "offsetof(struct user, u_code)" },
3159 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3160 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3161 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3162 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3163 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3164 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3165 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3166 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3167 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3168 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3169 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3170 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3171 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3172 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3173 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3174 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3175 { uoff(u_start), "offsetof(struct user, u_start)" },
3176 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3177 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3178 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3179 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3180 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3181 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3182 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3183 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3184 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3185 # endif /* SUNOS4 */
3187 { sizeof(struct user), "sizeof(struct user)" },
3191 # endif /* !FREEBSD */
3194 sys_ptrace(struct tcb *tcp)
3196 const struct xlat *x;
3199 if (entering(tcp)) {
3200 printxval(ptrace_cmds, tcp->u_arg[0],
3207 tprintf(", %lu, ", tcp->u_arg[1]);
3208 addr = tcp->u_arg[2];
3210 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3211 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3212 for (x = struct_user_offsets; x->str; x++) {
3217 tprintf("%#lx, ", addr);
3218 else if (x->val > addr && x != struct_user_offsets) {
3220 tprintf("%s + %ld, ", x->str, addr - x->val);
3223 tprintf("%s, ", x->str);
3227 tprintf("%#lx, ", tcp->u_arg[2]);
3229 switch (tcp->u_arg[0]) {
3231 case PTRACE_PEEKDATA:
3232 case PTRACE_PEEKTEXT:
3233 case PTRACE_PEEKUSER:
3237 case PTRACE_SINGLESTEP:
3238 case PTRACE_SYSCALL:
3240 printsignal(tcp->u_arg[3]);
3242 # ifdef PTRACE_SETOPTIONS
3243 case PTRACE_SETOPTIONS:
3244 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3247 # ifdef PTRACE_SETSIGINFO
3248 case PTRACE_SETSIGINFO: {
3252 else if (syserror(tcp))
3253 tprintf("%#lx", tcp->u_arg[3]);
3254 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3257 printsiginfo(&si, verbose(tcp));
3261 # ifdef PTRACE_GETSIGINFO
3262 case PTRACE_GETSIGINFO:
3263 /* Don't print anything, do it at syscall return. */
3267 tprintf("%#lx", tcp->u_arg[3]);
3271 switch (tcp->u_arg[0]) {
3272 case PTRACE_PEEKDATA:
3273 case PTRACE_PEEKTEXT:
3274 case PTRACE_PEEKUSER:
3278 printnum(tcp, tcp->u_arg[3], "%#lx");
3281 # ifdef PTRACE_GETSIGINFO
3282 case PTRACE_GETSIGINFO: {
3286 else if (syserror(tcp))
3287 tprintf("%#lx", tcp->u_arg[3]);
3288 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3291 printsiginfo(&si, verbose(tcp));
3299 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3300 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3301 tprintf("%lu, ", tcp->u_arg[3]);
3302 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3303 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3304 tcp->u_arg[0] != PTRACE_READTEXT) {
3305 tprintf("%#lx", tcp->u_arg[3]);
3308 if (tcp->u_arg[0] == PTRACE_READDATA ||
3309 tcp->u_arg[0] == PTRACE_READTEXT) {
3310 tprintf("%lu, ", tcp->u_arg[3]);
3311 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3314 # endif /* SUNOS4 */
3316 tprintf("%lu", tcp->u_arg[3]);
3318 # endif /* FREEBSD */
3325 # ifndef FUTEX_CMP_REQUEUE
3326 # define FUTEX_CMP_REQUEUE 4
3328 # ifndef FUTEX_WAKE_OP
3329 # define FUTEX_WAKE_OP 5
3331 # ifndef FUTEX_LOCK_PI
3332 # define FUTEX_LOCK_PI 6
3333 # define FUTEX_UNLOCK_PI 7
3334 # define FUTEX_TRYLOCK_PI 8
3336 # ifndef FUTEX_WAIT_BITSET
3337 # define FUTEX_WAIT_BITSET 9
3339 # ifndef FUTEX_WAKE_BITSET
3340 # define FUTEX_WAKE_BITSET 10
3342 # ifndef FUTEX_WAIT_REQUEUE_PI
3343 # define FUTEX_WAIT_REQUEUE_PI 11
3345 # ifndef FUTEX_CMP_REQUEUE_PI
3346 # define FUTEX_CMP_REQUEUE_PI 12
3348 # ifndef FUTEX_PRIVATE_FLAG
3349 # define FUTEX_PRIVATE_FLAG 128
3351 # ifndef FUTEX_CLOCK_REALTIME
3352 # define FUTEX_CLOCK_REALTIME 256
3354 static const struct xlat futexops[] = {
3355 { FUTEX_WAIT, "FUTEX_WAIT" },
3356 { FUTEX_WAKE, "FUTEX_WAKE" },
3357 { FUTEX_FD, "FUTEX_FD" },
3358 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3359 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3360 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3361 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3362 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3363 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3364 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3365 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3366 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3367 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3368 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3369 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3370 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3371 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3372 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3373 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3374 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3375 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3376 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3377 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3378 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3379 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3380 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3381 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3382 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3383 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3384 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3387 # ifndef FUTEX_OP_SET
3388 # define FUTEX_OP_SET 0
3389 # define FUTEX_OP_ADD 1
3390 # define FUTEX_OP_OR 2
3391 # define FUTEX_OP_ANDN 3
3392 # define FUTEX_OP_XOR 4
3393 # define FUTEX_OP_CMP_EQ 0
3394 # define FUTEX_OP_CMP_NE 1
3395 # define FUTEX_OP_CMP_LT 2
3396 # define FUTEX_OP_CMP_LE 3
3397 # define FUTEX_OP_CMP_GT 4
3398 # define FUTEX_OP_CMP_GE 5
3400 static const struct xlat futexwakeops[] = {
3401 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3402 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3403 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3404 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3405 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3408 static const struct xlat futexwakecmps[] = {
3409 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3410 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3411 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3412 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3413 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3414 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3419 sys_futex(struct tcb *tcp)
3421 if (entering(tcp)) {
3422 long int cmd = tcp->u_arg[1] & 127;
3423 tprintf("%p, ", (void *) tcp->u_arg[0]);
3424 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3425 tprintf(", %ld", tcp->u_arg[2]);
3426 if (cmd == FUTEX_WAKE_BITSET)
3427 tprintf(", %lx", tcp->u_arg[5]);
3428 else if (cmd == FUTEX_WAIT) {
3430 printtv(tcp, tcp->u_arg[3]);
3431 } else if (cmd == FUTEX_WAIT_BITSET) {
3433 printtv(tcp, tcp->u_arg[3]);
3434 tprintf(", %lx", tcp->u_arg[5]);
3435 } else if (cmd == FUTEX_REQUEUE)
3436 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3437 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3438 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3439 else if (cmd == FUTEX_WAKE_OP) {
3440 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3441 if ((tcp->u_arg[5] >> 28) & 8)
3442 tprintf("FUTEX_OP_OPARG_SHIFT|");
3443 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3444 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3445 if ((tcp->u_arg[5] >> 24) & 8)
3446 tprintf("FUTEX_OP_OPARG_SHIFT|");
3447 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3448 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3449 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3451 printtv(tcp, tcp->u_arg[3]);
3452 tprintf(", %p", (void *) tcp->u_arg[4]);
3459 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3462 unsigned long w, min_len;
3464 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3465 min_len = len - max_strlen * sizeof(w);
3468 for (; len >= sizeof(w) && len > min_len;
3469 len -= sizeof(w), list += sizeof(w)) {
3470 if (umove(tcp, list, &w) < 0)
3481 tprintf("%#lx", list);
3483 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3486 tprintf(first ? "{}" : "}");
3491 sys_sched_setaffinity(struct tcb *tcp)
3493 if (entering(tcp)) {
3494 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3495 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3501 sys_sched_getaffinity(struct tcb *tcp)
3503 if (entering(tcp)) {
3504 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3506 if (tcp->u_rval == -1)
3507 tprintf("%#lx", tcp->u_arg[2]);
3509 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3514 static const struct xlat schedulers[] = {
3515 { SCHED_OTHER, "SCHED_OTHER" },
3516 { SCHED_RR, "SCHED_RR" },
3517 { SCHED_FIFO, "SCHED_FIFO" },
3522 sys_sched_getscheduler(struct tcb *tcp)
3524 if (entering(tcp)) {
3525 tprintf("%d", (int) tcp->u_arg[0]);
3526 } else if (! syserror(tcp)) {
3527 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3528 if (tcp->auxstr != NULL)
3535 sys_sched_setscheduler(struct tcb *tcp)
3537 if (entering(tcp)) {
3538 struct sched_param p;
3539 tprintf("%d, ", (int) tcp->u_arg[0]);
3540 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3541 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3542 tprintf(", %#lx", tcp->u_arg[2]);
3544 tprintf(", { %d }", p.__sched_priority);
3550 sys_sched_getparam(struct tcb *tcp)
3552 if (entering(tcp)) {
3553 tprintf("%d, ", (int) tcp->u_arg[0]);
3555 struct sched_param p;
3556 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3557 tprintf("%#lx", tcp->u_arg[1]);
3559 tprintf("{ %d }", p.__sched_priority);
3565 sys_sched_setparam(struct tcb *tcp)
3567 if (entering(tcp)) {
3568 struct sched_param p;
3569 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3570 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3572 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3578 sys_sched_get_priority_min(struct tcb *tcp)
3580 if (entering(tcp)) {
3581 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3587 # include <asm/prctl.h>
3589 static const struct xlat archvals[] = {
3590 { ARCH_SET_GS, "ARCH_SET_GS" },
3591 { ARCH_SET_FS, "ARCH_SET_FS" },
3592 { ARCH_GET_FS, "ARCH_GET_FS" },
3593 { ARCH_GET_GS, "ARCH_GET_GS" },
3598 sys_arch_prctl(struct tcb *tcp)
3600 if (entering(tcp)) {
3601 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3602 if (tcp->u_arg[0] == ARCH_SET_GS
3603 || tcp->u_arg[0] == ARCH_SET_FS
3605 tprintf(", %#lx", tcp->u_arg[1]);
3608 if (tcp->u_arg[0] == ARCH_GET_GS
3609 || tcp->u_arg[0] == ARCH_GET_FS
3612 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3613 tprintf(", [%#lx]", v);
3615 tprintf(", %#lx", tcp->u_arg[1]);
3620 # endif /* X86_64 */
3624 sys_getcpu(struct tcb *tcp)
3628 if (tcp->u_arg[0] == 0)
3630 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3631 tprintf("%#lx, ", tcp->u_arg[0]);
3633 tprintf("[%u], ", u);
3634 if (tcp->u_arg[1] == 0)
3636 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3637 tprintf("%#lx, ", tcp->u_arg[1]);
3639 tprintf("[%u], ", u);
3640 tprintf("%#lx", tcp->u_arg[2]);