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]);
446 internal_exit(struct tcb *tcp)
449 tcp->flags |= TCB_EXITING;
450 #ifdef __NR_exit_group
451 if (known_scno(tcp) == __NR_exit_group)
452 tcp->flags |= TCB_GROUP_EXITING;
458 /* TCP is creating a child we want to follow.
459 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
460 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
462 fork_tcb(struct tcb *tcp)
464 if (nprocs == tcbtabsize)
467 tcp->flags |= TCB_FOLLOWFORK;
473 sys_fork(struct tcb *tcp)
475 if (exiting(tcp) && !syserror(tcp)) {
477 tcp->auxstr = "child process";
478 return RVAL_UDECIMAL | RVAL_STR;
491 tprintf ("%ld", tcp->u_arg[0]);
493 else if (!syserror(tcp)) {
495 tcp->auxstr = "child process";
496 return RVAL_UDECIMAL | RVAL_STR;
508 struct tcb *tcpchild;
512 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
522 tcpchild = alloctcb(tcp->u_rval);
523 if (proc_open(tcpchild, 2) < 0)
529 #else /* !USE_PROCFS */
533 /* defines copied from linux/sched.h since we can't include that
534 * ourselves (it conflicts with *lots* of libc includes)
536 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
537 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
538 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
539 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
540 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
541 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
542 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
543 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
544 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
545 #define CLONE_THREAD 0x00010000 /* Same thread group? */
546 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
547 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
548 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
549 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
550 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
551 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
552 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
553 #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
554 #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
555 #define CLONE_NEWIPC 0x08000000 /* New ipcs */
556 #define CLONE_NEWUSER 0x10000000 /* New user namespace */
557 #define CLONE_NEWPID 0x20000000 /* New pid namespace */
558 #define CLONE_NEWNET 0x40000000 /* New network namespace */
559 #define CLONE_IO 0x80000000 /* Clone io context */
561 static const struct xlat clone_flags[] = {
562 { CLONE_VM, "CLONE_VM" },
563 { CLONE_FS, "CLONE_FS" },
564 { CLONE_FILES, "CLONE_FILES" },
565 { CLONE_SIGHAND, "CLONE_SIGHAND" },
566 { CLONE_IDLETASK, "CLONE_IDLETASK"},
567 { CLONE_PTRACE, "CLONE_PTRACE" },
568 { CLONE_VFORK, "CLONE_VFORK" },
569 { CLONE_PARENT, "CLONE_PARENT" },
570 { CLONE_THREAD, "CLONE_THREAD" },
571 { CLONE_NEWNS, "CLONE_NEWNS" },
572 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
573 { CLONE_SETTLS, "CLONE_SETTLS" },
574 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
575 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
576 { CLONE_UNTRACED, "CLONE_UNTRACED" },
577 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
578 { CLONE_STOPPED, "CLONE_STOPPED" },
579 { CLONE_NEWUTS, "CLONE_NEWUTS" },
580 { CLONE_NEWIPC, "CLONE_NEWIPC" },
581 { CLONE_NEWUSER, "CLONE_NEWUSER" },
582 { CLONE_NEWPID, "CLONE_NEWPID" },
583 { CLONE_NEWNET, "CLONE_NEWNET" },
584 { CLONE_IO, "CLONE_IO" },
589 # include <asm/ldt.h>
590 # ifdef HAVE_STRUCT_USER_DESC
591 # define modify_ldt_ldt_s user_desc
593 extern void print_ldt_entry();
599 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
600 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
601 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
602 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
603 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
609 # elif defined X86_64 || defined ALPHA
628 const char *sep = "|";
629 unsigned long flags = tcp->u_arg[ARG_FLAGS];
630 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
631 # ifdef ARG_STACKSIZE
632 if (ARG_STACKSIZE != -1)
633 tprintf("stack_size=%#lx, ",
634 tcp->u_arg[ARG_STACKSIZE]);
637 if (!printflags(clone_flags, flags &~ CSIGNAL, NULL))
639 if ((flags & CSIGNAL) != 0)
640 tprintf("%s%s", sep, signame(flags & CSIGNAL));
641 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
642 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
644 if (flags & CLONE_PARENT_SETTID)
645 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
646 if (flags & CLONE_SETTLS) {
648 struct modify_ldt_ldt_s copy;
649 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
650 tprintf(", {entry_number:%d, ",
655 print_ldt_entry(©);
659 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
661 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
662 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
668 sys_unshare(struct tcb *tcp)
671 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
681 return RVAL_UDECIMAL;
686 change_syscall(struct tcb *tcp, int new)
690 /* Attempt to make vfork into fork, which we can follow. */
691 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
694 #elif defined(X86_64)
695 /* Attempt to make vfork into fork, which we can follow. */
696 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
699 #elif defined(POWERPC)
700 if (ptrace(PTRACE_POKEUSER, tcp->pid,
701 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
704 #elif defined(S390) || defined(S390X)
705 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
706 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
710 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
713 #elif defined(SPARC) || defined(SPARC64)
715 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
717 regs.u_regs[U_REG_G1] = new;
718 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
722 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
726 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
730 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
734 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
741 break; /* x86 SYS_fork */
746 fprintf(stderr, "%s: unexpected syscall %d\n",
750 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
752 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
756 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
760 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
764 /* Top half of reg encodes the no. of args n as 0x1n.
765 Assume 0 args as kernel never actually checks... */
766 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
770 #elif defined(CRISV10) || defined(CRISV32)
771 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
775 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
776 # ifndef PTRACE_SET_SYSCALL
777 # define PTRACE_SET_SYSCALL 23
780 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
785 if (ptrace(PTRACE_POKEUSER, tcp->pid,
786 (char*)PTREGS_OFFSET_REG(0),
790 #elif defined(MICROBLAZE)
791 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR(0)), new)<0)
795 #warning Do not know how to handle change_syscall for this architecture
796 #endif /* architecture */
803 handle_new_child(struct tcb *tcp, int pid, int bpt)
805 struct tcb *tcpchild;
807 #ifdef CLONE_PTRACE /* See new setbpt code. */
808 tcpchild = pid2tcb(pid);
809 if (tcpchild != NULL) {
810 /* The child already reported its startup trap
811 before the parent reported its syscall return. */
813 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
814 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
816 [preattached child %d of %d in weird state!]\n",
820 #endif /* CLONE_PTRACE */
823 tcpchild = alloctcb(pid);
827 /* Attach to the new child */
828 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
831 perror("PTRACE_ATTACH");
832 fprintf(stderr, "Too late?\n");
836 #endif /* !CLONE_PTRACE */
841 tcpchild->flags |= TCB_ATTACHED;
842 /* Child has BPT too, must be removed on first occasion. */
844 tcpchild->flags |= TCB_BPTSET;
845 tcpchild->baddr = tcp->baddr;
846 memcpy(tcpchild->inst, tcp->inst,
847 sizeof tcpchild->inst);
849 tcpchild->parent = tcp;
851 if (tcpchild->flags & TCB_SUSPENDED) {
852 /* The child was born suspended, due to our having
853 forced CLONE_PTRACE. */
857 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
858 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
863 Process %u resumed (parent %d ready)\n",
868 fprintf(stderr, "Process %d attached\n", pid);
871 #ifdef TCB_CLONE_THREAD
872 if (sysent[tcp->scno].sys_func == sys_clone)
875 * Save the flags used in this call,
876 * in case we point TCP to our parent below.
878 int call_flags = tcp->u_arg[ARG_FLAGS];
879 if ((tcp->flags & TCB_CLONE_THREAD) &&
880 tcp->parent != NULL) {
881 /* The parent in this clone is itself a
882 thread belonging to another process.
883 There is no meaning to the parentage
884 relationship of the new child with the
885 thread, only with the process. We
886 associate the new thread with our
887 parent. Since this is done for every
888 new thread, there will never be a
889 TCB_CLONE_THREAD process that has
893 tcpchild->parent = tcp;
896 if (call_flags & CLONE_THREAD) {
897 tcpchild->flags |= TCB_CLONE_THREAD;
898 ++tcp->nclone_threads;
900 if ((call_flags & CLONE_PARENT) &&
901 !(call_flags & CLONE_THREAD)) {
903 tcpchild->parent = NULL;
904 if (tcp->parent != NULL) {
906 tcpchild->parent = tcp;
911 #endif /* TCB_CLONE_THREAD */
916 internal_fork(struct tcb *tcp)
918 if ((ptrace_setoptions_followfork
919 & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
920 == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
924 tcp->flags &= ~TCB_FOLLOWFORK;
928 * In occasion of using PTRACE_O_TRACECLONE, we won't see the
929 * new child if clone is called with flag CLONE_UNTRACED, so
930 * we keep the same logic with that option and don't trace it.
932 if ((sysent[tcp->scno].sys_func == sys_clone) &&
933 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
942 if (!(tcp->flags & TCB_FOLLOWFORK))
945 bpt = tcp->flags & TCB_BPTSET;
955 return handle_new_child(tcp, pid, bpt);
966 struct tcb *tcpchild;
971 if (known_scno(tcp) == SYS_vfork) {
972 /* Attempt to make vfork into fork, which we can follow. */
973 if (change_syscall(tcp, SYS_fork) < 0)
978 if (!followfork || dont_follow)
985 int bpt = tcp->flags & TCB_BPTSET;
987 if (!(tcp->flags & TCB_FOLLOWFORK))
997 tcpchild = alloctcb(pid);
1000 /* The child must have run before it can be attached. */
1005 select(0, NULL, NULL, NULL, &tv);
1007 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1008 perror("PTRACE_ATTACH");
1009 fprintf(stderr, "Too late?\n");
1014 /* Try to catch the new process as soon as possible. */
1017 for (i = 0; i < 1024; i++)
1018 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1021 perror("PTRACE_ATTACH");
1022 fprintf(stderr, "Too late?\n");
1027 #endif /* !oldway */
1029 tcpchild->flags |= TCB_ATTACHED;
1030 /* Child has BPT too, must be removed on first occasion */
1032 tcpchild->flags |= TCB_BPTSET;
1033 tcpchild->baddr = tcp->baddr;
1034 memcpy(tcpchild->inst, tcp->inst,
1035 sizeof tcpchild->inst);
1037 tcpchild->parent = tcp;
1040 fprintf(stderr, "Process %d attached\n", pid);
1047 #endif /* !USE_PROCFS */
1049 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1056 return RVAL_UDECIMAL;
1060 #endif /* SUNOS4 || LINUX || FREEBSD */
1064 static char idstr[16];
1071 sprintf(idstr, "ppid %lu", getrval2(tcp));
1072 tcp->auxstr = idstr;
1083 sprintf(idstr, "euid %lu", getrval2(tcp));
1084 tcp->auxstr = idstr;
1095 sprintf(idstr, "egid %lu", getrval2(tcp));
1096 tcp->auxstr = idstr;
1106 int sys_getuid(struct tcb *tcp)
1109 tcp->u_rval = (uid_t) tcp->u_rval;
1110 return RVAL_UDECIMAL;
1113 int sys_setfsuid(struct tcb *tcp)
1116 tprintf("%u", (uid_t) tcp->u_arg[0]);
1118 tcp->u_rval = (uid_t) tcp->u_rval;
1119 return RVAL_UDECIMAL;
1126 if (entering(tcp)) {
1127 tprintf("%u", (uid_t) tcp->u_arg[0]);
1136 if (entering(tcp)) {
1137 tprintf("%u", (gid_t) tcp->u_arg[0]);
1143 sys_getresuid(struct tcb *tcp)
1148 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1149 tcp->u_arg[1], tcp->u_arg[2]);
1151 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1152 tprintf("%#lx, ", tcp->u_arg[0]);
1154 tprintf("[%lu], ", (unsigned long) uid);
1155 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1156 tprintf("%#lx, ", tcp->u_arg[1]);
1158 tprintf("[%lu], ", (unsigned long) uid);
1159 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1160 tprintf("%#lx", tcp->u_arg[2]);
1162 tprintf("[%lu]", (unsigned long) uid);
1175 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1176 tcp->u_arg[1], tcp->u_arg[2]);
1178 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1179 tprintf("%#lx, ", tcp->u_arg[0]);
1181 tprintf("[%lu], ", (unsigned long) gid);
1182 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1183 tprintf("%#lx, ", tcp->u_arg[1]);
1185 tprintf("[%lu], ", (unsigned long) gid);
1186 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1187 tprintf("%#lx", tcp->u_arg[2]);
1189 tprintf("[%lu]", (unsigned long) gid);
1201 if (entering(tcp)) {
1202 printuid("", tcp->u_arg[0]);
1203 printuid(", ", tcp->u_arg[1]);
1212 if (entering(tcp)) {
1213 printuid("", tcp->u_arg[0]);
1214 printuid(", ", tcp->u_arg[1]);
1219 #if defined(LINUX) || defined(FREEBSD)
1224 if (entering(tcp)) {
1225 printuid("", tcp->u_arg[0]);
1226 printuid(", ", tcp->u_arg[1]);
1227 printuid(", ", tcp->u_arg[2]);
1235 if (entering(tcp)) {
1236 printuid("", tcp->u_arg[0]);
1237 printuid(", ", tcp->u_arg[1]);
1238 printuid(", ", tcp->u_arg[2]);
1243 #endif /* LINUX || FREEBSD */
1249 if (entering(tcp)) {
1250 unsigned long len, size, start, cur, end, abbrev_end;
1254 len = tcp->u_arg[0];
1255 tprintf("%lu, ", len);
1260 start = tcp->u_arg[1];
1265 size = len * sizeof(gid);
1267 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1268 tprintf("%#lx", start);
1272 abbrev_end = start + max_strlen * sizeof(gid);
1273 if (abbrev_end < start)
1279 for (cur = start; cur < end; cur += sizeof(gid)) {
1282 if (cur >= abbrev_end) {
1286 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1291 tprintf("%lu", (unsigned long) gid);
1295 tprintf(" %#lx", tcp->u_arg[1]);
1306 if (entering(tcp)) {
1307 len = tcp->u_arg[0];
1308 tprintf("%lu, ", len);
1310 unsigned long size, start, cur, end, abbrev_end;
1319 start = tcp->u_arg[1];
1324 if (tcp->u_arg[0] == 0) {
1325 tprintf("%#lx", start);
1328 size = len * sizeof(gid);
1330 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1331 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]);
1366 sys_setgroups32(tcp)
1369 if (entering(tcp)) {
1370 unsigned long len, size, start, cur, end, abbrev_end;
1374 len = tcp->u_arg[0];
1375 tprintf("%lu, ", len);
1380 start = tcp->u_arg[1];
1385 size = len * sizeof(gid);
1387 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1388 tprintf("%#lx", start);
1392 abbrev_end = start + max_strlen * sizeof(gid);
1393 if (abbrev_end < start)
1399 for (cur = start; cur < end; cur += sizeof(gid)) {
1402 if (cur >= abbrev_end) {
1406 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1411 tprintf("%lu", (unsigned long) gid);
1415 tprintf(" %#lx", tcp->u_arg[1]);
1421 sys_getgroups32(tcp)
1426 if (entering(tcp)) {
1427 len = tcp->u_arg[0];
1428 tprintf("%lu, ", len);
1430 unsigned long size, start, cur, end, abbrev_end;
1439 start = tcp->u_arg[1];
1444 size = len * sizeof(gid);
1446 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1447 size / sizeof(gid) != len || end < start) {
1448 tprintf("%#lx", start);
1452 abbrev_end = start + max_strlen * sizeof(gid);
1453 if (abbrev_end < start)
1459 for (cur = start; cur < end; cur += sizeof(gid)) {
1462 if (cur >= abbrev_end) {
1466 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1471 tprintf("%lu", (unsigned long) gid);
1475 tprintf(" %#lx", tcp->u_arg[1]);
1481 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1486 if (entering(tcp)) {
1488 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1493 #endif /* ALPHA || SUNOS4 || SVR4 */
1499 if (entering(tcp)) {
1501 tprintf("%lu", tcp->u_arg[0]);
1511 if (entering(tcp)) {
1512 tprintf("%lu", tcp->u_arg[0]);
1528 if (entering(tcp)) {
1529 tprintf("%lu", tcp->u_arg[0]);
1538 if (entering(tcp)) {
1539 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1546 #include <sys/privilege.h>
1549 static const struct xlat procpriv_cmds [] = {
1550 { SETPRV, "SETPRV" },
1551 { CLRPRV, "CLRPRV" },
1552 { PUTPRV, "PUTPRV" },
1553 { GETPRV, "GETPRV" },
1554 { CNTPRV, "CNTPRV" },
1559 static const struct xlat procpriv_priv [] = {
1560 { P_OWNER, "P_OWNER" },
1561 { P_AUDIT, "P_AUDIT" },
1562 { P_COMPAT, "P_COMPAT" },
1563 { P_DACREAD, "P_DACREAD" },
1564 { P_DACWRITE, "P_DACWRITE" },
1566 { P_FILESYS, "P_FILESYS" },
1567 { P_MACREAD, "P_MACREAD" },
1568 { P_MACWRITE, "P_MACWRITE" },
1569 { P_MOUNT, "P_MOUNT" },
1570 { P_MULTIDIR, "P_MULTIDIR" },
1571 { P_SETPLEVEL, "P_SETPLEVEL" },
1572 { P_SETSPRIV, "P_SETSPRIV" },
1573 { P_SETUID, "P_SETUID" },
1574 { P_SYSOPS, "P_SYSOPS" },
1575 { P_SETUPRIV, "P_SETUPRIV" },
1576 { P_DRIVER, "P_DRIVER" },
1577 { P_RTIME, "P_RTIME" },
1578 { P_MACUPGRADE, "P_MACUPGRADE" },
1579 { P_FSYSRANGE, "P_FSYSRANGE" },
1580 { P_SETFLEVEL, "P_SETFLEVEL" },
1581 { P_AUDITWR, "P_AUDITWR" },
1582 { P_TSHAR, "P_TSHAR" },
1583 { P_PLOCK, "P_PLOCK" },
1584 { P_CORE, "P_CORE" },
1585 { P_LOADMOD, "P_LOADMOD" },
1586 { P_BIND, "P_BIND" },
1587 { P_ALLPRIVS, "P_ALLPRIVS" },
1592 static const struct xlat procpriv_type [] = {
1593 { PS_FIX, "PS_FIX" },
1594 { PS_INH, "PS_INH" },
1595 { PS_MAX, "PS_MAX" },
1596 { PS_WKG, "PS_WKG" },
1602 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1605 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1606 int dots = len > max;
1609 if (len > max) len = max;
1612 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1614 tprintf ("%#lx", addr);
1620 for (i = 0; i < len; ++i) {
1623 if (i) tprintf (", ");
1625 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1626 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1628 tprintf ("%s|%s", t, p);
1631 tprintf ("%#lx", buf [i]);
1635 if (dots) tprintf (" ...");
1645 if (entering(tcp)) {
1646 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1647 switch (tcp->u_arg[0]) {
1649 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1657 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1658 tprintf (", %ld", tcp->u_arg[2]);
1661 else if (tcp->u_arg[0] == GETPRV) {
1662 if (syserror (tcp)) {
1663 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1667 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1668 tprintf (", %ld", tcp->u_arg[2]);
1675 #endif /* UNIXWARE */
1679 printargv(struct tcb *tcp, long addr)
1684 char data[sizeof(long)];
1690 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1691 if (umoven(tcp, addr, personality_wordsize[current_personality],
1693 tprintf("%#lx", addr);
1696 if (personality_wordsize[current_personality] == 4)
1701 printstr(tcp, cp.p64, -1);
1702 addr += personality_wordsize[current_personality];
1705 tprintf("%s...", sep);
1709 printargc(const char *fmt, struct tcb *tcp, long addr)
1714 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1715 addr += sizeof(char *);
1717 tprintf(fmt, count, count == 1 ? "" : "s");
1720 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1722 sys_execv(struct tcb *tcp)
1724 if (entering(tcp)) {
1725 printpath(tcp, tcp->u_arg[0]);
1727 tprintf(", %#lx", tcp->u_arg[1]);
1730 printargv(tcp, tcp->u_arg[1]);
1736 #endif /* SPARC || SPARC64 || SUNOS4 */
1739 sys_execve(struct tcb *tcp)
1741 if (entering(tcp)) {
1742 printpath(tcp, tcp->u_arg[0]);
1744 tprintf(", %#lx", tcp->u_arg[1]);
1747 printargv(tcp, tcp->u_arg[1]);
1751 tprintf(", %#lx", tcp->u_arg[2]);
1752 else if (abbrev(tcp))
1753 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1756 printargv(tcp, tcp->u_arg[2]);
1765 int sys_rexecve(tcp)
1768 if (entering (tcp)) {
1770 tprintf (", %ld", tcp->u_arg[3]);
1778 internal_exec(struct tcb *tcp)
1781 if (exiting(tcp) && !syserror(tcp) && followfork)
1784 #if defined LINUX && defined TCB_WAITEXECVE
1785 if (exiting(tcp) && syserror(tcp))
1786 tcp->flags &= ~TCB_WAITEXECVE;
1788 /* Maybe we have post-execve SIGTRAP suppressed? */
1789 if (!(ptrace_setoptions_for_all & PTRACE_O_TRACEEXEC))
1790 tcp->flags |= TCB_WAITEXECVE; /* no */
1792 #endif /* LINUX && TCB_WAITEXECVE */
1798 #define __WNOTHREAD 0x20000000
1801 #define __WALL 0x40000000
1804 #define __WCLONE 0x80000000
1808 static const struct xlat wait4_options[] = {
1809 { WNOHANG, "WNOHANG" },
1811 { WUNTRACED, "WUNTRACED" },
1814 { WEXITED, "WEXITED" },
1817 { WTRAPPED, "WTRAPPED" },
1820 { WSTOPPED, "WSTOPPED" },
1823 { WCONTINUED, "WCONTINUED" },
1826 { WNOWAIT, "WNOWAIT" },
1829 { __WCLONE, "__WCLONE" },
1832 { __WALL, "__WALL" },
1835 { __WNOTHREAD, "__WNOTHREAD" },
1840 #if !defined WCOREFLAG && defined WCOREFLG
1841 # define WCOREFLAG WCOREFLG
1844 # define WCOREFLAG 0x80
1847 # define WCOREDUMP(status) ((status) & 0200)
1852 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1855 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1865 * Here is a tricky presentation problem. This solution
1866 * is still not entirely satisfactory but since there
1867 * are no wait status constructors it will have to do.
1869 if (WIFSTOPPED(status)) {
1870 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1871 signame(WSTOPSIG(status)));
1872 status &= ~W_STOPCODE(WSTOPSIG(status));
1874 else if (WIFSIGNALED(status)) {
1875 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1876 signame(WTERMSIG(status)),
1877 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1878 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1880 else if (WIFEXITED(status)) {
1881 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1882 WEXITSTATUS(status));
1884 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1887 tprintf("[%#x]", status);
1894 tprintf(" | %#x]", status);
1900 printwaitn(struct tcb *tcp, int n, int bitness)
1907 if (entering(tcp)) {
1909 /* On Linux, kernel-side pid_t is typedef'ed to int
1910 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1911 * pid argument to int on 64bit arches, producing,
1912 * for example, wait4(4294967295, ...) instead of -1
1913 * in strace. We have to use int here, not long.
1915 int pid = tcp->u_arg[0];
1916 tprintf("%d, ", pid);
1919 * Sign-extend a 32-bit value when that's what it is.
1921 long pid = tcp->u_arg[0];
1922 if (personality_wordsize[current_personality] < sizeof pid)
1923 pid = (long) (int) pid;
1924 tprintf("%ld, ", pid);
1930 else if (syserror(tcp) || tcp->u_rval == 0)
1931 tprintf("%#lx", tcp->u_arg[1]);
1932 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1938 printstatus(status);
1941 printflags(wait4_options, tcp->u_arg[2], "W???");
1948 else if (tcp->u_rval > 0) {
1951 printrusage32(tcp, tcp->u_arg[3]);
1954 printrusage(tcp, tcp->u_arg[3]);
1958 else if (tcp->u_rval > 0 && exited)
1959 printrusage(tcp, tcp->u_arg[3]);
1962 tprintf("%#lx", tcp->u_arg[3]);
1969 internal_wait(tcp, flagarg)
1975 #ifdef TCB_CLONE_THREAD
1976 if (tcp->flags & TCB_CLONE_THREAD)
1977 /* The children we wait for are our parent's children. */
1978 got_kids = (tcp->parent->nchildren
1979 > tcp->parent->nclone_threads);
1981 got_kids = (tcp->nchildren > tcp->nclone_threads);
1983 got_kids = tcp->nchildren > 0;
1986 if (entering(tcp) && got_kids) {
1987 /* There are children that this parent should block for.
1988 But ptrace made us the parent of the traced children
1989 and the real parent will get ECHILD from the wait call.
1991 XXX If we attached with strace -f -p PID, then there
1992 may be untraced dead children the parent could be reaping
1993 now, but we make him block. */
1995 /* ??? WTA: fix bug with hanging children */
1997 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1999 * There are traced children. We'll make the parent
2000 * block to avoid a false ECHILD error due to our
2001 * ptrace having stolen the children. However,
2002 * we shouldn't block if there are zombies to reap.
2003 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2005 struct tcb *child = NULL;
2006 if (tcp->nzombies > 0 &&
2007 (tcp->u_arg[0] == -1 ||
2008 (child = pid2tcb(tcp->u_arg[0])) == NULL))
2010 if (tcp->u_arg[0] > 0) {
2012 * If the parent waits for a specified child
2013 * PID, then it must get ECHILD right away
2014 * if that PID is not one of its children.
2015 * Make sure that the requested PID matches
2016 * one of the parent's children that we are
2017 * tracing, and don't suspend it otherwise.
2020 child = pid2tcb(tcp->u_arg[0]);
2021 if (child == NULL || child->parent != (
2022 #ifdef TCB_CLONE_THREAD
2023 (tcp->flags & TCB_CLONE_THREAD)
2027 (child->flags & TCB_EXITING))
2030 tcp->flags |= TCB_SUSPENDED;
2031 tcp->waitpid = tcp->u_arg[0];
2032 #ifdef TCB_CLONE_THREAD
2033 if (tcp->flags & TCB_CLONE_THREAD)
2034 tcp->parent->nclone_waiting++;
2038 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2039 if (tcp->u_arg[flagarg] & WNOHANG) {
2040 /* We must force a fake result of 0 instead of
2041 the ECHILD error. */
2042 return force_result(tcp, 0, 0);
2045 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2046 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2048 * We just reaped a child we don't know about,
2049 * presumably a zombie we already droptcb'd.
2063 /* The library wrapper stuffs this into the user variable. */
2065 printstatus(getrval2(tcp));
2080 if (!syserror(tcp)) {
2081 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2082 tprintf("%#lx", tcp->u_arg[0]);
2084 printstatus(status);
2095 return printwaitn(tcp, 3, 0);
2102 return printwaitn(tcp, 4, 0);
2110 return printwaitn(tcp, 4, 1);
2114 #if defined SVR4 || defined LINUX
2116 static const struct xlat waitid_types[] = {
2119 { P_PPID, "P_PPID" },
2121 { P_PGID, "P_PGID" },
2136 { P_LWPID, "P_LWPID" },
2142 sys_waitid(struct tcb *tcp)
2146 if (entering(tcp)) {
2147 printxval(waitid_types, tcp->u_arg[0], "P_???");
2148 tprintf(", %ld, ", tcp->u_arg[1]);
2154 else if (syserror(tcp))
2155 tprintf("%#lx", tcp->u_arg[2]);
2156 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2159 printsiginfo(&si, verbose(tcp));
2162 printflags(wait4_options, tcp->u_arg[3], "W???");
2163 if (tcp->u_nargs > 4) {
2168 else if (tcp->u_error)
2169 tprintf("%#lx", tcp->u_arg[4]);
2171 printrusage(tcp, tcp->u_arg[4]);
2177 #endif /* SVR4 or LINUX */
2184 tprintf("%lu", tcp->u_arg[0]);
2192 struct utsname uname;
2195 if (syserror(tcp) || !verbose(tcp))
2196 tprintf("%#lx", tcp->u_arg[0]);
2197 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2199 else if (!abbrev(tcp)) {
2201 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2202 uname.sysname, uname.nodename);
2203 tprintf("release=\"%s\", version=\"%s\", ",
2204 uname.release, uname.version);
2205 tprintf("machine=\"%s\"", uname.machine);
2208 tprintf(", domainname=\"%s\"", uname.domainname);
2214 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2215 uname.sysname, uname.nodename);
2222 static const struct xlat ptrace_cmds[] = {
2224 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2225 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2226 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2227 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2228 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2229 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2230 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2231 { PTRACE_CONT, "PTRACE_CONT" },
2232 { PTRACE_KILL, "PTRACE_KILL" },
2233 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2234 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2235 { PTRACE_DETACH, "PTRACE_DETACH" },
2236 # ifdef PTRACE_GETREGS
2237 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2239 # ifdef PTRACE_SETREGS
2240 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2242 # ifdef PTRACE_GETFPREGS
2243 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2245 # ifdef PTRACE_SETFPREGS
2246 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2248 # ifdef PTRACE_GETFPXREGS
2249 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2251 # ifdef PTRACE_SETFPXREGS
2252 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2254 # ifdef PTRACE_GETVRREGS
2255 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2257 # ifdef PTRACE_SETVRREGS
2258 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2260 # ifdef PTRACE_SETOPTIONS
2261 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2263 # ifdef PTRACE_GETEVENTMSG
2264 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2266 # ifdef PTRACE_GETSIGINFO
2267 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2269 # ifdef PTRACE_SETSIGINFO
2270 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2272 # ifdef PTRACE_GETREGSET
2273 { PTRACE_GETREGSET, "PTRACE_GETREGSET", },
2275 # ifdef PTRACE_SETREGSET
2276 { PTRACE_SETREGSET, "PTRACE_SETREGSET", },
2278 # ifdef PTRACE_SET_SYSCALL
2279 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2282 { PTRACE_READDATA, "PTRACE_READDATA" },
2283 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2284 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2285 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2286 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2287 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2289 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2290 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2292 { PTRACE_22, "PTRACE_22" },
2293 { PTRACE_23, "PTRACE_3" },
2294 # endif /* !SPARC */
2295 # endif /* SUNOS4 */
2296 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2298 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2300 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2301 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2302 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2304 { PTRACE_26, "PTRACE_26" },
2305 { PTRACE_27, "PTRACE_27" },
2306 { PTRACE_28, "PTRACE_28" },
2308 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2309 # endif /* SUNOS4 */
2311 # else /* FREEBSD */
2313 { PT_TRACE_ME, "PT_TRACE_ME" },
2314 { PT_READ_I, "PT_READ_I" },
2315 { PT_READ_D, "PT_READ_D" },
2316 { PT_WRITE_I, "PT_WRITE_I" },
2317 { PT_WRITE_D, "PT_WRITE_D" },
2319 { PT_READ_U, "PT_READ_U" },
2321 { PT_CONTINUE, "PT_CONTINUE" },
2322 { PT_KILL, "PT_KILL" },
2323 { PT_STEP, "PT_STEP" },
2324 { PT_ATTACH, "PT_ATTACH" },
2325 { PT_DETACH, "PT_DETACH" },
2326 { PT_GETREGS, "PT_GETREGS" },
2327 { PT_SETREGS, "PT_SETREGS" },
2328 { PT_GETFPREGS, "PT_GETFPREGS" },
2329 { PT_SETFPREGS, "PT_SETFPREGS" },
2330 { PT_GETDBREGS, "PT_GETDBREGS" },
2331 { PT_SETDBREGS, "PT_SETDBREGS" },
2332 # endif /* FREEBSD */
2337 # ifdef PTRACE_SETOPTIONS
2338 static const struct xlat ptrace_setoptions_flags[] = {
2339 # ifdef PTRACE_O_TRACESYSGOOD
2340 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2342 # ifdef PTRACE_O_TRACEFORK
2343 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2345 # ifdef PTRACE_O_TRACEVFORK
2346 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2348 # ifdef PTRACE_O_TRACECLONE
2349 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2351 # ifdef PTRACE_O_TRACEEXEC
2352 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2354 # ifdef PTRACE_O_TRACEVFORKDONE
2355 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2357 # ifdef PTRACE_O_TRACEEXIT
2358 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2362 # endif /* PTRACE_SETOPTIONS */
2363 # endif /* !FREEBSD */
2366 const struct xlat struct_user_offsets[] = {
2368 # if defined(S390) || defined(S390X)
2369 { PT_PSWMASK, "psw_mask" },
2370 { PT_PSWADDR, "psw_addr" },
2371 { PT_GPR0, "gpr0" },
2372 { PT_GPR1, "gpr1" },
2373 { PT_GPR2, "gpr2" },
2374 { PT_GPR3, "gpr3" },
2375 { PT_GPR4, "gpr4" },
2376 { PT_GPR5, "gpr5" },
2377 { PT_GPR6, "gpr6" },
2378 { PT_GPR7, "gpr7" },
2379 { PT_GPR8, "gpr8" },
2380 { PT_GPR9, "gpr9" },
2381 { PT_GPR10, "gpr10" },
2382 { PT_GPR11, "gpr11" },
2383 { PT_GPR12, "gpr12" },
2384 { PT_GPR13, "gpr13" },
2385 { PT_GPR14, "gpr14" },
2386 { PT_GPR15, "gpr15" },
2387 { PT_ACR0, "acr0" },
2388 { PT_ACR1, "acr1" },
2389 { PT_ACR2, "acr2" },
2390 { PT_ACR3, "acr3" },
2391 { PT_ACR4, "acr4" },
2392 { PT_ACR5, "acr5" },
2393 { PT_ACR6, "acr6" },
2394 { PT_ACR7, "acr7" },
2395 { PT_ACR8, "acr8" },
2396 { PT_ACR9, "acr9" },
2397 { PT_ACR10, "acr10" },
2398 { PT_ACR11, "acr11" },
2399 { PT_ACR12, "acr12" },
2400 { PT_ACR13, "acr13" },
2401 { PT_ACR14, "acr14" },
2402 { PT_ACR15, "acr15" },
2403 { PT_ORIGGPR2, "orig_gpr2" },
2406 { PT_FPR0_HI, "fpr0.hi" },
2407 { PT_FPR0_LO, "fpr0.lo" },
2408 { PT_FPR1_HI, "fpr1.hi" },
2409 { PT_FPR1_LO, "fpr1.lo" },
2410 { PT_FPR2_HI, "fpr2.hi" },
2411 { PT_FPR2_LO, "fpr2.lo" },
2412 { PT_FPR3_HI, "fpr3.hi" },
2413 { PT_FPR3_LO, "fpr3.lo" },
2414 { PT_FPR4_HI, "fpr4.hi" },
2415 { PT_FPR4_LO, "fpr4.lo" },
2416 { PT_FPR5_HI, "fpr5.hi" },
2417 { PT_FPR5_LO, "fpr5.lo" },
2418 { PT_FPR6_HI, "fpr6.hi" },
2419 { PT_FPR6_LO, "fpr6.lo" },
2420 { PT_FPR7_HI, "fpr7.hi" },
2421 { PT_FPR7_LO, "fpr7.lo" },
2422 { PT_FPR8_HI, "fpr8.hi" },
2423 { PT_FPR8_LO, "fpr8.lo" },
2424 { PT_FPR9_HI, "fpr9.hi" },
2425 { PT_FPR9_LO, "fpr9.lo" },
2426 { PT_FPR10_HI, "fpr10.hi" },
2427 { PT_FPR10_LO, "fpr10.lo" },
2428 { PT_FPR11_HI, "fpr11.hi" },
2429 { PT_FPR11_LO, "fpr11.lo" },
2430 { PT_FPR12_HI, "fpr12.hi" },
2431 { PT_FPR12_LO, "fpr12.lo" },
2432 { PT_FPR13_HI, "fpr13.hi" },
2433 { PT_FPR13_LO, "fpr13.lo" },
2434 { PT_FPR14_HI, "fpr14.hi" },
2435 { PT_FPR14_LO, "fpr14.lo" },
2436 { PT_FPR15_HI, "fpr15.hi" },
2437 { PT_FPR15_LO, "fpr15.lo" },
2440 { PT_FPR0, "fpr0" },
2441 { PT_FPR1, "fpr1" },
2442 { PT_FPR2, "fpr2" },
2443 { PT_FPR3, "fpr3" },
2444 { PT_FPR4, "fpr4" },
2445 { PT_FPR5, "fpr5" },
2446 { PT_FPR6, "fpr6" },
2447 { PT_FPR7, "fpr7" },
2448 { PT_FPR8, "fpr8" },
2449 { PT_FPR9, "fpr9" },
2450 { PT_FPR10, "fpr10" },
2451 { PT_FPR11, "fpr11" },
2452 { PT_FPR12, "fpr12" },
2453 { PT_FPR13, "fpr13" },
2454 { PT_FPR14, "fpr14" },
2455 { PT_FPR15, "fpr15" },
2458 { PT_CR_10, "cr10" },
2459 { PT_CR_11, "cr11" },
2460 { PT_IEEE_IP, "ieee_exception_ip" },
2461 # elif defined(SPARC)
2462 /* XXX No support for these offsets yet. */
2463 # elif defined(HPPA)
2464 /* XXX No support for these offsets yet. */
2465 # elif defined(POWERPC)
2467 # define PT_ORIG_R3 34
2469 # define REGSIZE (sizeof(unsigned long))
2470 { REGSIZE*PT_R0, "r0" },
2471 { REGSIZE*PT_R1, "r1" },
2472 { REGSIZE*PT_R2, "r2" },
2473 { REGSIZE*PT_R3, "r3" },
2474 { REGSIZE*PT_R4, "r4" },
2475 { REGSIZE*PT_R5, "r5" },
2476 { REGSIZE*PT_R6, "r6" },
2477 { REGSIZE*PT_R7, "r7" },
2478 { REGSIZE*PT_R8, "r8" },
2479 { REGSIZE*PT_R9, "r9" },
2480 { REGSIZE*PT_R10, "r10" },
2481 { REGSIZE*PT_R11, "r11" },
2482 { REGSIZE*PT_R12, "r12" },
2483 { REGSIZE*PT_R13, "r13" },
2484 { REGSIZE*PT_R14, "r14" },
2485 { REGSIZE*PT_R15, "r15" },
2486 { REGSIZE*PT_R16, "r16" },
2487 { REGSIZE*PT_R17, "r17" },
2488 { REGSIZE*PT_R18, "r18" },
2489 { REGSIZE*PT_R19, "r19" },
2490 { REGSIZE*PT_R20, "r20" },
2491 { REGSIZE*PT_R21, "r21" },
2492 { REGSIZE*PT_R22, "r22" },
2493 { REGSIZE*PT_R23, "r23" },
2494 { REGSIZE*PT_R24, "r24" },
2495 { REGSIZE*PT_R25, "r25" },
2496 { REGSIZE*PT_R26, "r26" },
2497 { REGSIZE*PT_R27, "r27" },
2498 { REGSIZE*PT_R28, "r28" },
2499 { REGSIZE*PT_R29, "r29" },
2500 { REGSIZE*PT_R30, "r30" },
2501 { REGSIZE*PT_R31, "r31" },
2502 { REGSIZE*PT_NIP, "NIP" },
2503 { REGSIZE*PT_MSR, "MSR" },
2504 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2505 { REGSIZE*PT_CTR, "CTR" },
2506 { REGSIZE*PT_LNK, "LNK" },
2507 { REGSIZE*PT_XER, "XER" },
2508 { REGSIZE*PT_CCR, "CCR" },
2509 { REGSIZE*PT_FPR0, "FPR0" },
2511 # elif defined(ALPHA)
2577 # elif defined(IA64)
2578 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2579 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2580 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2581 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2582 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2583 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2584 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2585 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2586 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2587 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2588 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2589 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2590 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2591 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2592 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2593 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2594 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2595 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2596 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2597 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2598 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2599 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2600 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2601 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2602 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2603 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2604 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2605 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2606 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2607 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2608 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2609 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2611 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2612 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2613 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2614 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2615 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2616 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2617 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2618 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2619 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2620 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2621 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2622 { PT_B4, "b4" }, { PT_B5, "b5" },
2623 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2625 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2626 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2627 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2628 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2629 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2630 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2631 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2632 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2633 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2634 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2635 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2636 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2637 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2638 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2639 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2640 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2641 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2643 { PT_AR_CSD, "ar.csd" },
2646 { PT_AR_SSD, "ar.ssd" },
2648 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2649 # elif defined(I386)
2661 { 4*ORIG_EAX, "4*ORIG_EAX" },
2665 { 4*UESP, "4*UESP" },
2667 # elif defined(X86_64)
2683 { 8*ORIG_RAX, "8*ORIG_RAX" },
2686 { 8*EFLAGS, "8*EFL" },
2689 # elif defined(M68K)
2690 { 4*PT_D1, "4*PT_D1" },
2691 { 4*PT_D2, "4*PT_D2" },
2692 { 4*PT_D3, "4*PT_D3" },
2693 { 4*PT_D4, "4*PT_D4" },
2694 { 4*PT_D5, "4*PT_D5" },
2695 { 4*PT_D6, "4*PT_D6" },
2696 { 4*PT_D7, "4*PT_D7" },
2697 { 4*PT_A0, "4*PT_A0" },
2698 { 4*PT_A1, "4*PT_A1" },
2699 { 4*PT_A2, "4*PT_A2" },
2700 { 4*PT_A3, "4*PT_A3" },
2701 { 4*PT_A4, "4*PT_A4" },
2702 { 4*PT_A5, "4*PT_A5" },
2703 { 4*PT_A6, "4*PT_A6" },
2704 { 4*PT_D0, "4*PT_D0" },
2705 { 4*PT_USP, "4*PT_USP" },
2706 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2707 { 4*PT_SR, "4*PT_SR" },
2708 { 4*PT_PC, "4*PT_PC" },
2710 { 4*REG_REG0, "4*REG_REG0" },
2711 { 4*(REG_REG0+1), "4*REG_REG1" },
2712 { 4*(REG_REG0+2), "4*REG_REG2" },
2713 { 4*(REG_REG0+3), "4*REG_REG3" },
2714 { 4*(REG_REG0+4), "4*REG_REG4" },
2715 { 4*(REG_REG0+5), "4*REG_REG5" },
2716 { 4*(REG_REG0+6), "4*REG_REG6" },
2717 { 4*(REG_REG0+7), "4*REG_REG7" },
2718 { 4*(REG_REG0+8), "4*REG_REG8" },
2719 { 4*(REG_REG0+9), "4*REG_REG9" },
2720 { 4*(REG_REG0+10), "4*REG_REG10" },
2721 { 4*(REG_REG0+11), "4*REG_REG11" },
2722 { 4*(REG_REG0+12), "4*REG_REG12" },
2723 { 4*(REG_REG0+13), "4*REG_REG13" },
2724 { 4*(REG_REG0+14), "4*REG_REG14" },
2725 { 4*REG_REG15, "4*REG_REG15" },
2726 { 4*REG_PC, "4*REG_PC" },
2727 { 4*REG_PR, "4*REG_PR" },
2728 { 4*REG_SR, "4*REG_SR" },
2729 { 4*REG_GBR, "4*REG_GBR" },
2730 { 4*REG_MACH, "4*REG_MACH" },
2731 { 4*REG_MACL, "4*REG_MACL" },
2732 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2733 { 4*REG_FPUL, "4*REG_FPUL" },
2734 { 4*REG_FPREG0, "4*REG_FPREG0" },
2735 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2736 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2737 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2738 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2739 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2740 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2741 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2742 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2743 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2744 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2745 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2746 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2747 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2748 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2749 { 4*REG_FPREG15, "4*REG_FPREG15" },
2751 { 4*REG_XDREG0, "4*REG_XDREG0" },
2752 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2753 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2754 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2755 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2756 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2757 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2758 { 4*REG_XDREG14, "4*REG_XDREG14" },
2760 { 4*REG_FPSCR, "4*REG_FPSCR" },
2761 # elif defined(SH64)
2766 { 16, "syscall no.(L)" },
2767 { 20, "syscall_no.(U)" },
2910 /* This entry is in case pt_regs contains dregs (depends on
2911 the kernel build options). */
2912 { uoff(regs), "offsetof(struct user, regs)" },
2913 { uoff(fpu), "offsetof(struct user, fpu)" },
2915 { uoff(regs.ARM_r0), "r0" },
2916 { uoff(regs.ARM_r1), "r1" },
2917 { uoff(regs.ARM_r2), "r2" },
2918 { uoff(regs.ARM_r3), "r3" },
2919 { uoff(regs.ARM_r4), "r4" },
2920 { uoff(regs.ARM_r5), "r5" },
2921 { uoff(regs.ARM_r6), "r6" },
2922 { uoff(regs.ARM_r7), "r7" },
2923 { uoff(regs.ARM_r8), "r8" },
2924 { uoff(regs.ARM_r9), "r9" },
2925 { uoff(regs.ARM_r10), "r10" },
2926 { uoff(regs.ARM_fp), "fp" },
2927 { uoff(regs.ARM_ip), "ip" },
2928 { uoff(regs.ARM_sp), "sp" },
2929 { uoff(regs.ARM_lr), "lr" },
2930 { uoff(regs.ARM_pc), "pc" },
2931 { uoff(regs.ARM_cpsr), "cpsr" },
2932 # elif defined(AVR32)
2933 { uoff(regs.sr), "sr" },
2934 { uoff(regs.pc), "pc" },
2935 { uoff(regs.lr), "lr" },
2936 { uoff(regs.sp), "sp" },
2937 { uoff(regs.r12), "r12" },
2938 { uoff(regs.r11), "r11" },
2939 { uoff(regs.r10), "r10" },
2940 { uoff(regs.r9), "r9" },
2941 { uoff(regs.r8), "r8" },
2942 { uoff(regs.r7), "r7" },
2943 { uoff(regs.r6), "r6" },
2944 { uoff(regs.r5), "r5" },
2945 { uoff(regs.r4), "r4" },
2946 { uoff(regs.r3), "r3" },
2947 { uoff(regs.r2), "r2" },
2948 { uoff(regs.r1), "r1" },
2949 { uoff(regs.r0), "r0" },
2950 { uoff(regs.r12_orig), "orig_r12" },
2951 # elif defined(MIPS)
3023 # elif defined(TILE)
3024 { PTREGS_OFFSET_REG(0), "r0" },
3025 { PTREGS_OFFSET_REG(1), "r1" },
3026 { PTREGS_OFFSET_REG(2), "r2" },
3027 { PTREGS_OFFSET_REG(3), "r3" },
3028 { PTREGS_OFFSET_REG(4), "r4" },
3029 { PTREGS_OFFSET_REG(5), "r5" },
3030 { PTREGS_OFFSET_REG(6), "r6" },
3031 { PTREGS_OFFSET_REG(7), "r7" },
3032 { PTREGS_OFFSET_REG(8), "r8" },
3033 { PTREGS_OFFSET_REG(9), "r9" },
3034 { PTREGS_OFFSET_REG(10), "r10" },
3035 { PTREGS_OFFSET_REG(11), "r11" },
3036 { PTREGS_OFFSET_REG(12), "r12" },
3037 { PTREGS_OFFSET_REG(13), "r13" },
3038 { PTREGS_OFFSET_REG(14), "r14" },
3039 { PTREGS_OFFSET_REG(15), "r15" },
3040 { PTREGS_OFFSET_REG(16), "r16" },
3041 { PTREGS_OFFSET_REG(17), "r17" },
3042 { PTREGS_OFFSET_REG(18), "r18" },
3043 { PTREGS_OFFSET_REG(19), "r19" },
3044 { PTREGS_OFFSET_REG(20), "r20" },
3045 { PTREGS_OFFSET_REG(21), "r21" },
3046 { PTREGS_OFFSET_REG(22), "r22" },
3047 { PTREGS_OFFSET_REG(23), "r23" },
3048 { PTREGS_OFFSET_REG(24), "r24" },
3049 { PTREGS_OFFSET_REG(25), "r25" },
3050 { PTREGS_OFFSET_REG(26), "r26" },
3051 { PTREGS_OFFSET_REG(27), "r27" },
3052 { PTREGS_OFFSET_REG(28), "r28" },
3053 { PTREGS_OFFSET_REG(29), "r29" },
3054 { PTREGS_OFFSET_REG(30), "r30" },
3055 { PTREGS_OFFSET_REG(31), "r31" },
3056 { PTREGS_OFFSET_REG(32), "r32" },
3057 { PTREGS_OFFSET_REG(33), "r33" },
3058 { PTREGS_OFFSET_REG(34), "r34" },
3059 { PTREGS_OFFSET_REG(35), "r35" },
3060 { PTREGS_OFFSET_REG(36), "r36" },
3061 { PTREGS_OFFSET_REG(37), "r37" },
3062 { PTREGS_OFFSET_REG(38), "r38" },
3063 { PTREGS_OFFSET_REG(39), "r39" },
3064 { PTREGS_OFFSET_REG(40), "r40" },
3065 { PTREGS_OFFSET_REG(41), "r41" },
3066 { PTREGS_OFFSET_REG(42), "r42" },
3067 { PTREGS_OFFSET_REG(43), "r43" },
3068 { PTREGS_OFFSET_REG(44), "r44" },
3069 { PTREGS_OFFSET_REG(45), "r45" },
3070 { PTREGS_OFFSET_REG(46), "r46" },
3071 { PTREGS_OFFSET_REG(47), "r47" },
3072 { PTREGS_OFFSET_REG(48), "r48" },
3073 { PTREGS_OFFSET_REG(49), "r49" },
3074 { PTREGS_OFFSET_REG(50), "r50" },
3075 { PTREGS_OFFSET_REG(51), "r51" },
3076 { PTREGS_OFFSET_REG(52), "r52" },
3077 { PTREGS_OFFSET_TP, "tp" },
3078 { PTREGS_OFFSET_SP, "sp" },
3079 { PTREGS_OFFSET_LR, "lr" },
3080 { PTREGS_OFFSET_PC, "pc" },
3081 { PTREGS_OFFSET_EX1, "ex1" },
3082 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
3083 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
3084 { PTREGS_OFFSET_FLAGS, "flags" },
3087 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3088 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3089 { 4*PT_R13, "4*PT_R13" },
3090 { 4*PT_R12, "4*PT_R12" },
3091 { 4*PT_R11, "4*PT_R11" },
3092 { 4*PT_R10, "4*PT_R10" },
3093 { 4*PT_R9, "4*PT_R9" },
3094 { 4*PT_R8, "4*PT_R8" },
3095 { 4*PT_R7, "4*PT_R7" },
3096 { 4*PT_R6, "4*PT_R6" },
3097 { 4*PT_R5, "4*PT_R5" },
3098 { 4*PT_R4, "4*PT_R4" },
3099 { 4*PT_R3, "4*PT_R3" },
3100 { 4*PT_R2, "4*PT_R2" },
3101 { 4*PT_R1, "4*PT_R1" },
3102 { 4*PT_R0, "4*PT_R0" },
3103 { 4*PT_MOF, "4*PT_MOF" },
3104 { 4*PT_DCCR, "4*PT_DCCR" },
3105 { 4*PT_SRP, "4*PT_SRP" },
3106 { 4*PT_IRP, "4*PT_IRP" },
3107 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3108 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3109 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3110 { 4*PT_USP, "4*PT_USP" },
3113 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3114 { 4*PT_R0, "4*PT_R0" },
3115 { 4*PT_R1, "4*PT_R1" },
3116 { 4*PT_R2, "4*PT_R2" },
3117 { 4*PT_R3, "4*PT_R3" },
3118 { 4*PT_R4, "4*PT_R4" },
3119 { 4*PT_R5, "4*PT_R5" },
3120 { 4*PT_R6, "4*PT_R6" },
3121 { 4*PT_R7, "4*PT_R7" },
3122 { 4*PT_R8, "4*PT_R8" },
3123 { 4*PT_R9, "4*PT_R9" },
3124 { 4*PT_R10, "4*PT_R10" },
3125 { 4*PT_R11, "4*PT_R11" },
3126 { 4*PT_R12, "4*PT_R12" },
3127 { 4*PT_R13, "4*PT_R13" },
3128 { 4*PT_ACR, "4*PT_ACR" },
3129 { 4*PT_SRS, "4*PT_SRS" },
3130 { 4*PT_MOF, "4*PT_MOF" },
3131 { 4*PT_SPC, "4*PT_SPC" },
3132 { 4*PT_CCS, "4*PT_CCS" },
3133 { 4*PT_SRP, "4*PT_SRP" },
3134 { 4*PT_ERP, "4*PT_ERP" },
3135 { 4*PT_EXS, "4*PT_EXS" },
3136 { 4*PT_EDA, "4*PT_EDA" },
3137 { 4*PT_USP, "4*PT_USP" },
3138 { 4*PT_PPC, "4*PT_PPC" },
3139 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3140 { 4*PT_BP+4, "4*PT_BP+4" },
3141 { 4*PT_BP+8, "4*PT_BP+8" },
3142 { 4*PT_BP+12, "4*PT_BP+12" },
3143 { 4*PT_BP+16, "4*PT_BP+16" },
3144 { 4*PT_BP+20, "4*PT_BP+20" },
3145 { 4*PT_BP+24, "4*PT_BP+24" },
3146 { 4*PT_BP+28, "4*PT_BP+28" },
3147 { 4*PT_BP+32, "4*PT_BP+32" },
3148 { 4*PT_BP+36, "4*PT_BP+36" },
3149 { 4*PT_BP+40, "4*PT_BP+40" },
3150 { 4*PT_BP+44, "4*PT_BP+44" },
3151 { 4*PT_BP+48, "4*PT_BP+48" },
3152 { 4*PT_BP+52, "4*PT_BP+52" },
3153 { 4*PT_BP+56, "4*PT_BP+56" },
3156 { PT_GPR(0), "r0" },
3157 { PT_GPR(1), "r1" },
3158 { PT_GPR(2), "r2" },
3159 { PT_GPR(3), "r3" },
3160 { PT_GPR(4), "r4" },
3161 { PT_GPR(5), "r5" },
3162 { PT_GPR(6), "r6" },
3163 { PT_GPR(7), "r7" },
3164 { PT_GPR(8), "r8" },
3165 { PT_GPR(9), "r9" },
3166 { PT_GPR(10), "r10" },
3167 { PT_GPR(11), "r11" },
3168 { PT_GPR(12), "r12" },
3169 { PT_GPR(13), "r13" },
3170 { PT_GPR(14), "r14" },
3171 { PT_GPR(15), "r15" },
3172 { PT_GPR(16), "r16" },
3173 { PT_GPR(17), "r17" },
3174 { PT_GPR(18), "r18" },
3175 { PT_GPR(19), "r19" },
3176 { PT_GPR(20), "r20" },
3177 { PT_GPR(21), "r21" },
3178 { PT_GPR(22), "r22" },
3179 { PT_GPR(23), "r23" },
3180 { PT_GPR(24), "r24" },
3181 { PT_GPR(25), "r25" },
3182 { PT_GPR(26), "r26" },
3183 { PT_GPR(27), "r27" },
3184 { PT_GPR(28), "r28" },
3185 { PT_GPR(29), "r29" },
3186 { PT_GPR(30), "r30" },
3187 { PT_GPR(31), "r31" },
3189 { PT_MSR, "rmsr", },
3190 { PT_EAR, "rear", },
3191 { PT_ESR, "resr", },
3192 { PT_FSR, "rfsr", },
3193 { PT_KERNEL_MODE, "kernel_mode", },
3196 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3197 && !defined(ALPHA) && !defined(IA64) \
3198 && !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
3199 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3200 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3202 # if defined(I386) || defined(X86_64)
3203 { uoff(i387), "offsetof(struct user, i387)" },
3206 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3208 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3209 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3210 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3211 # if !defined(SPARC64)
3212 { uoff(start_code), "offsetof(struct user, start_code)" },
3214 # if defined(AVR32) || defined(SH64)
3215 { uoff(start_data), "offsetof(struct user, start_data)" },
3217 # if !defined(SPARC64)
3218 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3220 { uoff(signal), "offsetof(struct user, signal)" },
3221 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3222 { uoff(reserved), "offsetof(struct user, reserved)" },
3224 # if !defined(SPARC64)
3225 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3227 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3228 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3230 { uoff(magic), "offsetof(struct user, magic)" },
3231 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3232 # if defined(I386) || defined(X86_64)
3233 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3235 # endif /* !defined(many arches) */
3240 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3241 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3242 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3243 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3244 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3245 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3246 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3247 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3248 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3249 { uoff(u_error), "offsetof(struct user, u_error)" },
3250 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3251 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3252 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3253 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3254 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3255 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3256 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3257 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3258 { uoff(u_code), "offsetof(struct user, u_code)" },
3259 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3260 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3261 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3262 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3263 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3264 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3265 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3266 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3267 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3268 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3269 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3270 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3271 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3272 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3273 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3274 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3275 { uoff(u_start), "offsetof(struct user, u_start)" },
3276 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3277 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3278 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3279 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3280 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3281 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3282 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3283 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3284 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3285 # endif /* SUNOS4 */
3287 { sizeof(struct user), "sizeof(struct user)" },
3291 # endif /* !FREEBSD */
3294 sys_ptrace(struct tcb *tcp)
3296 const struct xlat *x;
3299 if (entering(tcp)) {
3300 printxval(ptrace_cmds, tcp->u_arg[0],
3307 tprintf(", %lu, ", tcp->u_arg[1]);
3308 addr = tcp->u_arg[2];
3310 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3311 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3312 for (x = struct_user_offsets; x->str; x++) {
3317 tprintf("%#lx, ", addr);
3318 else if (x->val > addr && x != struct_user_offsets) {
3320 tprintf("%s + %ld, ", x->str, addr - x->val);
3323 tprintf("%s, ", x->str);
3327 tprintf("%#lx, ", tcp->u_arg[2]);
3329 switch (tcp->u_arg[0]) {
3331 case PTRACE_PEEKDATA:
3332 case PTRACE_PEEKTEXT:
3333 case PTRACE_PEEKUSER:
3337 case PTRACE_SINGLESTEP:
3338 case PTRACE_SYSCALL:
3340 printsignal(tcp->u_arg[3]);
3342 # ifdef PTRACE_SETOPTIONS
3343 case PTRACE_SETOPTIONS:
3344 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3347 # ifdef PTRACE_SETSIGINFO
3348 case PTRACE_SETSIGINFO: {
3352 else if (syserror(tcp))
3353 tprintf("%#lx", tcp->u_arg[3]);
3354 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3357 printsiginfo(&si, verbose(tcp));
3361 # ifdef PTRACE_GETSIGINFO
3362 case PTRACE_GETSIGINFO:
3363 /* Don't print anything, do it at syscall return. */
3367 tprintf("%#lx", tcp->u_arg[3]);
3371 switch (tcp->u_arg[0]) {
3372 case PTRACE_PEEKDATA:
3373 case PTRACE_PEEKTEXT:
3374 case PTRACE_PEEKUSER:
3378 printnum(tcp, tcp->u_arg[3], "%#lx");
3381 # ifdef PTRACE_GETSIGINFO
3382 case PTRACE_GETSIGINFO: {
3386 else if (syserror(tcp))
3387 tprintf("%#lx", tcp->u_arg[3]);
3388 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3391 printsiginfo(&si, verbose(tcp));
3399 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3400 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3401 tprintf("%lu, ", tcp->u_arg[3]);
3402 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3403 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3404 tcp->u_arg[0] != PTRACE_READTEXT) {
3405 tprintf("%#lx", tcp->u_arg[3]);
3408 if (tcp->u_arg[0] == PTRACE_READDATA ||
3409 tcp->u_arg[0] == PTRACE_READTEXT) {
3410 tprintf("%lu, ", tcp->u_arg[3]);
3411 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3414 # endif /* SUNOS4 */
3416 tprintf("%lu", tcp->u_arg[3]);
3418 # endif /* FREEBSD */
3425 # ifndef FUTEX_CMP_REQUEUE
3426 # define FUTEX_CMP_REQUEUE 4
3428 # ifndef FUTEX_WAKE_OP
3429 # define FUTEX_WAKE_OP 5
3431 # ifndef FUTEX_LOCK_PI
3432 # define FUTEX_LOCK_PI 6
3433 # define FUTEX_UNLOCK_PI 7
3434 # define FUTEX_TRYLOCK_PI 8
3436 # ifndef FUTEX_WAIT_BITSET
3437 # define FUTEX_WAIT_BITSET 9
3439 # ifndef FUTEX_WAKE_BITSET
3440 # define FUTEX_WAKE_BITSET 10
3442 # ifndef FUTEX_WAIT_REQUEUE_PI
3443 # define FUTEX_WAIT_REQUEUE_PI 11
3445 # ifndef FUTEX_CMP_REQUEUE_PI
3446 # define FUTEX_CMP_REQUEUE_PI 12
3448 # ifndef FUTEX_PRIVATE_FLAG
3449 # define FUTEX_PRIVATE_FLAG 128
3451 # ifndef FUTEX_CLOCK_REALTIME
3452 # define FUTEX_CLOCK_REALTIME 256
3454 static const struct xlat futexops[] = {
3455 { FUTEX_WAIT, "FUTEX_WAIT" },
3456 { FUTEX_WAKE, "FUTEX_WAKE" },
3457 { FUTEX_FD, "FUTEX_FD" },
3458 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3459 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3460 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3461 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3462 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3463 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3464 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3465 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3466 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3467 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3468 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3469 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3470 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3471 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3472 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3473 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3474 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3475 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3476 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3477 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3478 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3479 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3480 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3481 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3482 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3483 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3484 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3487 # ifndef FUTEX_OP_SET
3488 # define FUTEX_OP_SET 0
3489 # define FUTEX_OP_ADD 1
3490 # define FUTEX_OP_OR 2
3491 # define FUTEX_OP_ANDN 3
3492 # define FUTEX_OP_XOR 4
3493 # define FUTEX_OP_CMP_EQ 0
3494 # define FUTEX_OP_CMP_NE 1
3495 # define FUTEX_OP_CMP_LT 2
3496 # define FUTEX_OP_CMP_LE 3
3497 # define FUTEX_OP_CMP_GT 4
3498 # define FUTEX_OP_CMP_GE 5
3500 static const struct xlat futexwakeops[] = {
3501 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3502 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3503 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3504 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3505 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3508 static const struct xlat futexwakecmps[] = {
3509 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3510 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3511 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3512 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3513 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3514 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3519 sys_futex(struct tcb *tcp)
3521 if (entering(tcp)) {
3522 long int cmd = tcp->u_arg[1] & 127;
3523 tprintf("%p, ", (void *) tcp->u_arg[0]);
3524 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3525 tprintf(", %ld", tcp->u_arg[2]);
3526 if (cmd == FUTEX_WAKE_BITSET)
3527 tprintf(", %lx", tcp->u_arg[5]);
3528 else if (cmd == FUTEX_WAIT) {
3530 printtv(tcp, tcp->u_arg[3]);
3531 } else if (cmd == FUTEX_WAIT_BITSET) {
3533 printtv(tcp, tcp->u_arg[3]);
3534 tprintf(", %lx", tcp->u_arg[5]);
3535 } else if (cmd == FUTEX_REQUEUE)
3536 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3537 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3538 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3539 else if (cmd == FUTEX_WAKE_OP) {
3540 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3541 if ((tcp->u_arg[5] >> 28) & 8)
3542 tprintf("FUTEX_OP_OPARG_SHIFT|");
3543 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3544 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3545 if ((tcp->u_arg[5] >> 24) & 8)
3546 tprintf("FUTEX_OP_OPARG_SHIFT|");
3547 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3548 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3549 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3551 printtv(tcp, tcp->u_arg[3]);
3552 tprintf(", %p", (void *) tcp->u_arg[4]);
3559 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3562 unsigned long w, min_len;
3564 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3565 min_len = len - max_strlen * sizeof(w);
3568 for (; len >= sizeof(w) && len > min_len;
3569 len -= sizeof(w), list += sizeof(w)) {
3570 if (umove(tcp, list, &w) < 0)
3581 tprintf("%#lx", list);
3583 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3586 tprintf(first ? "{}" : "}");
3591 sys_sched_setaffinity(struct tcb *tcp)
3593 if (entering(tcp)) {
3594 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3595 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3601 sys_sched_getaffinity(struct tcb *tcp)
3603 if (entering(tcp)) {
3604 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3606 if (tcp->u_rval == -1)
3607 tprintf("%#lx", tcp->u_arg[2]);
3609 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3614 static const struct xlat schedulers[] = {
3615 { SCHED_OTHER, "SCHED_OTHER" },
3616 { SCHED_RR, "SCHED_RR" },
3617 { SCHED_FIFO, "SCHED_FIFO" },
3622 sys_sched_getscheduler(struct tcb *tcp)
3624 if (entering(tcp)) {
3625 tprintf("%d", (int) tcp->u_arg[0]);
3626 } else if (! syserror(tcp)) {
3627 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3628 if (tcp->auxstr != NULL)
3635 sys_sched_setscheduler(struct tcb *tcp)
3637 if (entering(tcp)) {
3638 struct sched_param p;
3639 tprintf("%d, ", (int) tcp->u_arg[0]);
3640 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3641 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3642 tprintf(", %#lx", tcp->u_arg[2]);
3644 tprintf(", { %d }", p.__sched_priority);
3650 sys_sched_getparam(struct tcb *tcp)
3652 if (entering(tcp)) {
3653 tprintf("%d, ", (int) tcp->u_arg[0]);
3655 struct sched_param p;
3656 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3657 tprintf("%#lx", tcp->u_arg[1]);
3659 tprintf("{ %d }", p.__sched_priority);
3665 sys_sched_setparam(struct tcb *tcp)
3667 if (entering(tcp)) {
3668 struct sched_param p;
3669 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3670 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3672 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3678 sys_sched_get_priority_min(struct tcb *tcp)
3680 if (entering(tcp)) {
3681 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3687 # include <asm/prctl.h>
3689 static const struct xlat archvals[] = {
3690 { ARCH_SET_GS, "ARCH_SET_GS" },
3691 { ARCH_SET_FS, "ARCH_SET_FS" },
3692 { ARCH_GET_FS, "ARCH_GET_FS" },
3693 { ARCH_GET_GS, "ARCH_GET_GS" },
3698 sys_arch_prctl(struct tcb *tcp)
3700 if (entering(tcp)) {
3701 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3702 if (tcp->u_arg[0] == ARCH_SET_GS
3703 || tcp->u_arg[0] == ARCH_SET_FS
3705 tprintf(", %#lx", tcp->u_arg[1]);
3708 if (tcp->u_arg[0] == ARCH_GET_GS
3709 || tcp->u_arg[0] == ARCH_GET_FS
3712 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3713 tprintf(", [%#lx]", v);
3715 tprintf(", %#lx", tcp->u_arg[1]);
3720 # endif /* X86_64 */
3724 sys_getcpu(struct tcb *tcp)
3728 if (tcp->u_arg[0] == 0)
3730 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3731 tprintf("%#lx, ", tcp->u_arg[0]);
3733 tprintf("[%u], ", u);
3734 if (tcp->u_arg[1] == 0)
3736 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3737 tprintf("%#lx, ", tcp->u_arg[1]);
3739 tprintf("[%u], ", u);
3740 tprintf("%#lx", tcp->u_arg[2]);