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>
60 #if defined (SPARC) || defined (SPARC64)
61 # define fpq kernel_fpq
63 # define fpu kernel_fpu
64 #endif /* SPARC || SPARC64 */
66 #if defined (SPARC) || defined (SPARC64)
70 #endif /* SPARC || SPARC64 */
71 #endif /* HAVE_ASM_REG_H */
75 #ifndef PTRACE_PEEKUSR
76 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
78 #ifndef PTRACE_POKEUSR
79 # define PTRACE_POKEUSR PTRACE_POKEUSER
83 #ifdef HAVE_LINUX_PTRACE_H
85 # ifdef HAVE_STRUCT_IA64_FPREG
86 # define ia64_fpreg XXX_ia64_fpreg
88 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89 # define pt_all_user_regs XXX_pt_all_user_regs
91 #include <linux/ptrace.h>
93 # undef pt_all_user_regs
96 #if defined (LINUX) && defined (SPARC64)
98 # undef PTRACE_GETREGS
99 # define PTRACE_GETREGS PTRACE_GETREGS64
100 # undef PTRACE_SETREGS
101 # define PTRACE_SETREGS PTRACE_SETREGS64
102 #endif /* LINUX && SPARC64 */
104 #ifdef HAVE_LINUX_FUTEX_H
105 #include <linux/futex.h>
109 # define FUTEX_WAIT 0
112 # define FUTEX_WAKE 1
117 # ifndef FUTEX_REQUEUE
118 # define FUTEX_REQUEUE 3
124 #include <asm/posix_types.h>
126 #define GETGROUPS_T __kernel_gid_t
128 #define GETGROUPS32_T __kernel_gid32_t
131 #if defined(LINUX) && defined(IA64)
132 # include <asm/ptrace_offsets.h>
133 # include <asm/rse.h>
137 #include <sys/prctl.h>
141 #define WCOREDUMP(status) ((status) & 0200)
144 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
145 #if defined(HAVE_PRCTL)
146 static const struct xlat prctl_options[] = {
148 { PR_MAXPROCS, "PR_MAXPROCS" },
151 { PR_ISBLOCKED, "PR_ISBLOCKED" },
153 #ifdef PR_SETSTACKSIZE
154 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
156 #ifdef PR_GETSTACKSIZE
157 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
160 { PR_MAXPPROCS, "PR_MAXPPROCS" },
162 #ifdef PR_UNBLKONEXEC
163 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
166 { PR_ATOMICSIM, "PR_ATOMICSIM" },
169 { PR_SETEXITSIG, "PR_SETEXITSIG" },
172 { PR_RESIDENT, "PR_RESIDENT" },
175 { PR_ATTACHADDR, "PR_ATTACHADDR" },
178 { PR_DETACHADDR, "PR_DETACHADDR" },
181 { PR_TERMCHILD, "PR_TERMCHILD" },
184 { PR_GETSHMASK, "PR_GETSHMASK" },
187 { PR_GETNSHARE, "PR_GETNSHARE" },
190 { PR_COREPID, "PR_COREPID" },
192 #ifdef PR_ATTACHADDRPERM
193 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
195 #ifdef PR_PTHREADEXIT
196 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
198 #ifdef PR_SET_PDEATHSIG
199 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
201 #ifdef PR_GET_PDEATHSIG
202 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
204 #ifdef PR_GET_DUMPABLE
205 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
207 #ifdef PR_SET_DUMPABLE
208 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
210 #ifdef PR_GET_UNALIGN
211 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
213 #ifdef PR_SET_UNALIGN
214 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
216 #ifdef PR_GET_KEEPCAPS
217 { PR_GET_KEEPCAPS, "PR_GET_KEEPCAPS" },
219 #ifdef PR_SET_KEEPCAPS
220 { PR_SET_KEEPCAPS, "PR_SET_KEEPCAPS" },
223 { PR_GET_FPEMU, "PR_GET_FPEMU" },
226 { PR_SET_FPEMU, "PR_SET_FPEMU" },
229 { PR_GET_FPEXC, "PR_GET_FPEXC" },
232 { PR_SET_FPEXC, "PR_SET_FPEXC" },
235 { PR_GET_TIMING, "PR_GET_TIMING" },
238 { PR_SET_TIMING, "PR_SET_TIMING" },
241 { PR_SET_NAME, "PR_SET_NAME" },
244 { PR_GET_NAME, "PR_GET_NAME" },
247 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
250 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
252 #ifdef PR_GET_SECCOMP
253 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
255 #ifdef PR_SET_SECCOMP
256 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
259 { PR_GET_TSC, "PR_GET_TSC" },
262 { PR_SET_TSC, "PR_SET_TSC" },
264 #ifdef PR_GET_SECUREBITS
265 { PR_GET_SECUREBITS, "PR_GET_SECUREBITS" },
267 #ifdef PR_SET_SECUREBITS
268 { PR_SET_SECUREBITS, "PR_SET_SECUREBITS" },
275 unalignctl_string (unsigned int ctl)
280 #ifdef PR_UNALIGN_NOPRINT
281 case PR_UNALIGN_NOPRINT:
284 #ifdef PR_UNALIGN_SIGBUS
285 case PR_UNALIGN_SIGBUS:
291 sprintf(buf, "%x", ctl);
303 printxval(prctl_options, tcp->u_arg[0], "PR_???");
304 switch (tcp->u_arg[0]) {
309 #ifdef PR_SET_PDEATHSIG
310 case PR_SET_PDEATHSIG:
311 tprintf(", %lu", tcp->u_arg[1]);
314 #ifdef PR_GET_PDEATHSIG
315 case PR_GET_PDEATHSIG:
318 #ifdef PR_SET_DUMPABLE
319 case PR_SET_DUMPABLE:
320 tprintf(", %lu", tcp->u_arg[1]);
323 #ifdef PR_GET_DUMPABLE
324 case PR_GET_DUMPABLE:
327 #ifdef PR_SET_UNALIGN
329 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
332 #ifdef PR_GET_UNALIGN
334 tprintf(", %#lx", tcp->u_arg[1]);
337 #ifdef PR_SET_KEEPCAPS
338 case PR_SET_KEEPCAPS:
339 tprintf(", %lu", tcp->u_arg[1]);
342 #ifdef PR_GET_KEEPCAPS
343 case PR_GET_KEEPCAPS:
347 for (i = 1; i < tcp->u_nargs; i++)
348 tprintf(", %#lx", tcp->u_arg[i]);
352 switch (tcp->u_arg[0]) {
353 #ifdef PR_GET_PDEATHSIG
354 case PR_GET_PDEATHSIG:
355 if (umove(tcp, tcp->u_arg[1], &i) < 0)
356 tprintf(", %#lx", tcp->u_arg[1]);
358 tprintf(", {%u}", i);
361 #ifdef PR_GET_DUMPABLE
362 case PR_GET_DUMPABLE:
363 return RVAL_UDECIMAL;
365 #ifdef PR_GET_UNALIGN
367 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
369 tcp->auxstr = unalignctl_string(i);
372 #ifdef PR_GET_KEEPCAPS
373 case PR_GET_KEEPCAPS:
374 return RVAL_UDECIMAL;
383 #endif /* HAVE_PRCTL */
385 #if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
394 #endif /* FREEBSD || SUNOS4 || SVR4 */
401 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
402 tprintf(", %lu", tcp->u_arg[1]);
407 #if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
414 tprintf("%#lx", tcp->u_arg[0]);
416 printpath(tcp, tcp->u_arg[0]);
417 tprintf(", %lu", tcp->u_arg[1]);
421 #endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
424 sys_setdomainname(tcp)
428 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
429 tprintf(", %lu", tcp->u_arg[1]);
437 sys_getdomainname(tcp)
442 tprintf("%#lx", tcp->u_arg[0]);
444 printpath(tcp, tcp->u_arg[0]);
445 tprintf(", %lu", tcp->u_arg[1]);
456 fprintf(stderr, "_exit returned!\n");
459 /* special case: we stop tracing this process, finish line now */
460 tprintf("%ld) ", tcp->u_arg[0]);
472 tcp->flags |= TCB_EXITING;
473 #ifdef __NR_exit_group
476 if (tcp->scno == 252)
477 tcp->flags |= TCB_GROUP_EXITING;
480 if (known_scno(tcp) == __NR_exit_group)
481 tcp->flags |= TCB_GROUP_EXITING;
487 /* TCP is creating a child we want to follow.
488 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
489 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
491 fork_tcb(struct tcb *tcp)
493 if (nprocs == tcbtabsize)
496 tcp->flags |= TCB_FOLLOWFORK;
502 sys_fork(struct tcb *tcp)
504 if (exiting(tcp) && !syserror(tcp)) {
506 tcp->auxstr = "child process";
507 return RVAL_UDECIMAL | RVAL_STR;
520 tprintf ("%ld", tcp->u_arg[0]);
522 else if (!syserror(tcp)) {
524 tcp->auxstr = "child process";
525 return RVAL_UDECIMAL | RVAL_STR;
537 struct tcb *tcpchild;
541 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
551 tcpchild = alloctcb(tcp->u_rval);
552 if (proc_open(tcpchild, 2) < 0)
558 #else /* !USE_PROCFS */
562 /* defines copied from linux/sched.h since we can't include that
563 * ourselves (it conflicts with *lots* of libc includes)
565 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
566 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
567 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
568 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
569 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
570 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
571 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
572 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
573 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
574 #define CLONE_THREAD 0x00010000 /* Same thread group? */
575 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
576 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
577 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
578 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
579 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
580 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
581 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
582 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
584 static const struct xlat clone_flags[] = {
585 { CLONE_VM, "CLONE_VM" },
586 { CLONE_FS, "CLONE_FS" },
587 { CLONE_FILES, "CLONE_FILES" },
588 { CLONE_SIGHAND, "CLONE_SIGHAND" },
589 { CLONE_IDLETASK, "CLONE_IDLETASK"},
590 { CLONE_PTRACE, "CLONE_PTRACE" },
591 { CLONE_VFORK, "CLONE_VFORK" },
592 { CLONE_PARENT, "CLONE_PARENT" },
593 { CLONE_THREAD, "CLONE_THREAD" },
594 { CLONE_NEWNS, "CLONE_NEWNS" },
595 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
596 { CLONE_SETTLS, "CLONE_SETTLS" },
597 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
598 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
599 { CLONE_DETACHED, "CLONE_DETACHED" },
600 { CLONE_UNTRACED, "CLONE_UNTRACED" },
601 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
606 # include <asm/ldt.h>
607 # ifdef HAVE_STRUCT_USER_DESC
608 # define modify_ldt_ldt_s user_desc
610 extern void print_ldt_entry();
616 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
617 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
618 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
619 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
620 # elif defined S390 || defined S390X
626 # elif defined X86_64 || defined ALPHA
645 unsigned long flags = tcp->u_arg[ARG_FLAGS];
646 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
647 # ifdef ARG_STACKSIZE
648 if (ARG_STACKSIZE != -1)
649 tprintf("stack_size=%#lx, ",
650 tcp->u_arg[ARG_STACKSIZE]);
653 printflags(clone_flags, flags &~ CSIGNAL, NULL);
654 if ((flags & CSIGNAL) != 0)
655 tprintf("|%s", signame(flags & CSIGNAL));
656 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
657 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
659 if (flags & CLONE_PARENT_SETTID)
660 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
661 if (flags & CLONE_SETTLS) {
663 struct modify_ldt_ldt_s copy;
664 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
665 tprintf(", {entry_number:%d, ",
670 print_ldt_entry(©);
674 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
676 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
677 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
683 sys_unshare(struct tcb *tcp)
686 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
696 return RVAL_UDECIMAL;
701 change_syscall(struct tcb *tcp, int new)
705 /* Attempt to make vfork into fork, which we can follow. */
706 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
709 #elif defined(X86_64)
710 /* Attempt to make vfork into fork, which we can follow. */
711 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
714 #elif defined(POWERPC)
715 if (ptrace(PTRACE_POKEUSER, tcp->pid,
716 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
719 #elif defined(S390) || defined(S390X)
720 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
721 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
725 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
728 #elif defined(SPARC) || defined(SPARC64)
730 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
733 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
737 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
741 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
745 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
752 break; /* x86 SYS_fork */
757 fprintf(stderr, "%s: unexpected syscall %d\n",
761 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
763 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
767 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
771 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
775 /* Top half of reg encodes the no. of args n as 0x1n.
776 Assume 0 args as kernel never actually checks... */
777 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
782 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
783 # ifndef PTRACE_SET_SYSCALL
784 # define PTRACE_SET_SYSCALL 23
787 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
792 #warning Do not know how to handle change_syscall for this architecture
793 #endif /* architecture */
806 unsigned long *bsp, *ap;
808 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
811 ap = ia64_rse_skip_regs(bsp, argnum);
813 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
820 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
824 #elif defined(X86_64)
826 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
830 #elif defined(POWERPC)
832 #define PT_ORIG_R3 34
835 ptrace(PTRACE_POKEUSER, tcp->pid,
836 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
845 ptrace(PTRACE_POKEUSER, tcp->pid,
846 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
850 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
853 ptrace(PTRACE_POKEDATA, tcp->pid,
854 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
859 #elif defined(S390) || defined(S390X)
862 ptrace(PTRACE_POKEUSER, tcp->pid,
863 (char *) (argnum==0 ? PT_ORIGGPR2 :
864 PT_GPR2 + argnum*sizeof(long)),
872 # warning Sorry, setargs not implemented for this architecture.
878 #if defined SYS_clone || defined SYS_clone2
880 internal_clone(struct tcb *tcp)
882 struct tcb *tcpchild;
892 bpt = tcp->flags & TCB_BPTSET;
894 if (!(tcp->flags & TCB_FOLLOWFORK))
904 /* Should not happen, but bugs often cause bogus value here */
906 || (sizeof(pid) != sizeof(tcp->u_rval) && pid != tcp->u_rval)
910 fprintf(stderr, "bogus clone() return value %lx!\n", tcp->u_rval);
914 #ifdef CLONE_PTRACE /* See new setbpt code. */
915 tcpchild = pid2tcb(pid);
916 if (tcpchild != NULL) {
917 /* The child already reported its startup trap
918 before the parent reported its syscall return. */
920 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
921 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
923 [preattached child %d of %d in weird state!]\n",
930 tcpchild = alloctcb(pid);
934 /* Attach to the new child */
935 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
938 perror("PTRACE_ATTACH");
939 fprintf(stderr, "Too late?\n");
948 tcpchild->flags |= TCB_ATTACHED;
949 /* Child has BPT too, must be removed on first occasion. */
951 tcpchild->flags |= TCB_BPTSET;
952 tcpchild->baddr = tcp->baddr;
953 memcpy(tcpchild->inst, tcp->inst,
954 sizeof tcpchild->inst);
956 tcpchild->parent = tcp;
958 if (tcpchild->flags & TCB_SUSPENDED) {
959 /* The child was born suspended, due to our having
960 forced CLONE_PTRACE. */
964 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
965 /* TCB_SUSPENDED tasks are not collected by waitpid
966 * loop, and left stopped. Restart it:
968 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
973 Process %u resumed (parent %d ready)\n",
978 fprintf(stderr, "Process %d attached\n", pid);
981 #ifdef TCB_CLONE_THREAD
984 * Save the flags used in this call,
985 * in case we point TCP to our parent below.
987 int call_flags = tcp->u_arg[ARG_FLAGS];
988 if ((tcp->flags & TCB_CLONE_THREAD) &&
989 tcp->parent != NULL) {
990 /* The parent in this clone is itself a
991 thread belonging to another process.
992 There is no meaning to the parentage
993 relationship of the new child with the
994 thread, only with the process. We
995 associate the new thread with our
996 parent. Since this is done for every
997 new thread, there will never be a
998 TCB_CLONE_THREAD process that has
1002 tcpchild->parent = tcp;
1005 if (call_flags & CLONE_THREAD) {
1006 tcpchild->flags |= TCB_CLONE_THREAD;
1007 ++tcp->nclone_threads;
1009 if (call_flags & CLONE_DETACHED) {
1010 tcpchild->flags |= TCB_CLONE_DETACHED;
1011 ++tcp->nclone_detached;
1025 /* We do special magic with clone for any clone or fork. */
1026 return internal_clone(tcp);
1029 struct tcb *tcpchild;
1031 int dont_follow = 0;
1034 if (known_scno(tcp) == SYS_vfork) {
1035 /* Attempt to make vfork into fork, which we can follow. */
1036 if (change_syscall(tcp, SYS_fork) < 0)
1040 if (entering(tcp)) {
1041 if (!followfork || dont_follow)
1044 if (setbpt(tcp) < 0)
1048 int bpt = tcp->flags & TCB_BPTSET;
1050 if (!(tcp->flags & TCB_FOLLOWFORK))
1060 tcpchild = alloctcb(pid);
1063 /* The child must have run before it can be attached. */
1064 /* This must be a bug in the parisc kernel, but I havn't
1065 * identified it yet. Seems to be an issue associated
1066 * with attaching to a process (which sends it a signal)
1067 * before that process has ever been scheduled. When
1068 * debugging, I started seeing crashes in
1069 * arch/parisc/kernel/signal.c:do_signal(), apparently
1070 * caused by r8 getting corrupt over the dequeue_signal()
1071 * call. Didn't make much sense though...
1077 select(0, NULL, NULL, NULL, &tv);
1080 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1081 perror("PTRACE_ATTACH");
1082 fprintf(stderr, "Too late?\n");
1089 /* The child must have run before it can be attached. */
1094 select(0, NULL, NULL, NULL, &tv);
1096 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1097 perror("PTRACE_ATTACH");
1098 fprintf(stderr, "Too late?\n");
1103 /* Try to catch the new process as soon as possible. */
1106 for (i = 0; i < 1024; i++)
1107 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1110 perror("PTRACE_ATTACH");
1111 fprintf(stderr, "Too late?\n");
1116 #endif /* !oldway */
1118 tcpchild->flags |= TCB_ATTACHED;
1119 /* Child has BPT too, must be removed on first occasion */
1121 tcpchild->flags |= TCB_BPTSET;
1122 tcpchild->baddr = tcp->baddr;
1123 memcpy(tcpchild->inst, tcp->inst,
1124 sizeof tcpchild->inst);
1126 tcpchild->parent = tcp;
1129 fprintf(stderr, "Process %d attached\n", pid);
1135 #endif /* !USE_PROCFS */
1137 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1144 return RVAL_UDECIMAL;
1148 #endif /* SUNOS4 || LINUX || FREEBSD */
1152 static char idstr[16];
1159 sprintf(idstr, "ppid %lu", getrval2(tcp));
1160 tcp->auxstr = idstr;
1171 sprintf(idstr, "euid %lu", getrval2(tcp));
1172 tcp->auxstr = idstr;
1183 sprintf(idstr, "egid %lu", getrval2(tcp));
1184 tcp->auxstr = idstr;
1198 if (entering(tcp)) {
1199 tprintf("%u", (uid_t) tcp->u_arg[0]);
1208 if (entering(tcp)) {
1209 tprintf("%u", (gid_t) tcp->u_arg[0]);
1221 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1222 tcp->u_arg[1], tcp->u_arg[2]);
1224 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1225 tprintf("%#lx, ", tcp->u_arg[0]);
1227 tprintf("[%lu], ", (unsigned long) uid);
1228 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1229 tprintf("%#lx, ", tcp->u_arg[1]);
1231 tprintf("[%lu], ", (unsigned long) uid);
1232 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1233 tprintf("%#lx", tcp->u_arg[2]);
1235 tprintf("[%lu]", (unsigned long) uid);
1248 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1249 tcp->u_arg[1], tcp->u_arg[2]);
1251 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1252 tprintf("%#lx, ", tcp->u_arg[0]);
1254 tprintf("[%lu], ", (unsigned long) gid);
1255 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1256 tprintf("%#lx, ", tcp->u_arg[1]);
1258 tprintf("[%lu], ", (unsigned long) gid);
1259 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1260 tprintf("%#lx", tcp->u_arg[2]);
1262 tprintf("[%lu]", (unsigned long) gid);
1274 if (entering(tcp)) {
1275 printuid("", tcp->u_arg[0]);
1276 printuid(", ", tcp->u_arg[1]);
1285 if (entering(tcp)) {
1286 printuid("", tcp->u_arg[0]);
1287 printuid(", ", tcp->u_arg[1]);
1292 #if defined(LINUX) || defined(FREEBSD)
1297 if (entering(tcp)) {
1298 printuid("", tcp->u_arg[0]);
1299 printuid(", ", tcp->u_arg[1]);
1300 printuid(", ", tcp->u_arg[2]);
1308 if (entering(tcp)) {
1309 printuid("", tcp->u_arg[0]);
1310 printuid(", ", tcp->u_arg[1]);
1311 printuid(", ", tcp->u_arg[2]);
1316 #endif /* LINUX || FREEBSD */
1322 if (entering(tcp)) {
1323 unsigned long len, size, start, cur, end, abbrev_end;
1327 len = tcp->u_arg[0];
1328 tprintf("%lu, ", len);
1333 start = tcp->u_arg[1];
1338 size = len * sizeof(gid);
1340 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1341 tprintf("%#lx", start);
1345 abbrev_end = start + max_strlen * sizeof(gid);
1346 if (abbrev_end < start)
1352 for (cur = start; cur < end; cur += sizeof(gid)) {
1355 if (cur >= abbrev_end) {
1359 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1364 tprintf("%lu", (unsigned long) gid);
1368 tprintf(" %#lx", tcp->u_arg[1]);
1379 if (entering(tcp)) {
1380 len = tcp->u_arg[0];
1381 tprintf("%lu, ", len);
1383 unsigned long size, start, cur, end, abbrev_end;
1392 start = tcp->u_arg[1];
1397 if (tcp->u_arg[0] == 0) {
1398 tprintf("%#lx", start);
1401 size = len * sizeof(gid);
1403 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1404 size / sizeof(gid) != len || end < start) {
1405 tprintf("%#lx", start);
1409 abbrev_end = start + max_strlen * sizeof(gid);
1410 if (abbrev_end < start)
1416 for (cur = start; cur < end; cur += sizeof(gid)) {
1419 if (cur >= abbrev_end) {
1423 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1428 tprintf("%lu", (unsigned long) gid);
1432 tprintf(" %#lx", tcp->u_arg[1]);
1439 sys_setgroups32(tcp)
1442 if (entering(tcp)) {
1443 unsigned long len, size, start, cur, end, abbrev_end;
1447 len = tcp->u_arg[0];
1448 tprintf("%lu, ", len);
1453 start = tcp->u_arg[1];
1458 size = len * sizeof(gid);
1460 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1461 tprintf("%#lx", start);
1465 abbrev_end = start + max_strlen * sizeof(gid);
1466 if (abbrev_end < start)
1472 for (cur = start; cur < end; cur += sizeof(gid)) {
1475 if (cur >= abbrev_end) {
1479 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1484 tprintf("%lu", (unsigned long) gid);
1488 tprintf(" %#lx", tcp->u_arg[1]);
1494 sys_getgroups32(tcp)
1499 if (entering(tcp)) {
1500 len = tcp->u_arg[0];
1501 tprintf("%lu, ", len);
1503 unsigned long size, start, cur, end, abbrev_end;
1512 start = tcp->u_arg[1];
1517 size = len * sizeof(gid);
1519 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1520 size / sizeof(gid) != len || end < start) {
1521 tprintf("%#lx", start);
1525 abbrev_end = start + max_strlen * sizeof(gid);
1526 if (abbrev_end < start)
1532 for (cur = start; cur < end; cur += sizeof(gid)) {
1535 if (cur >= abbrev_end) {
1539 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1544 tprintf("%lu", (unsigned long) gid);
1548 tprintf(" %#lx", tcp->u_arg[1]);
1554 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1559 if (entering(tcp)) {
1561 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1566 #endif /* ALPHA || SUNOS4 || SVR4 */
1572 if (entering(tcp)) {
1574 tprintf("%lu", tcp->u_arg[0]);
1584 if (entering(tcp)) {
1585 tprintf("%lu", tcp->u_arg[0]);
1601 if (entering(tcp)) {
1602 tprintf("%lu", tcp->u_arg[0]);
1611 if (entering(tcp)) {
1612 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1619 #include <sys/privilege.h>
1622 static const struct xlat procpriv_cmds [] = {
1623 { SETPRV, "SETPRV" },
1624 { CLRPRV, "CLRPRV" },
1625 { PUTPRV, "PUTPRV" },
1626 { GETPRV, "GETPRV" },
1627 { CNTPRV, "CNTPRV" },
1632 static const struct xlat procpriv_priv [] = {
1633 { P_OWNER, "P_OWNER" },
1634 { P_AUDIT, "P_AUDIT" },
1635 { P_COMPAT, "P_COMPAT" },
1636 { P_DACREAD, "P_DACREAD" },
1637 { P_DACWRITE, "P_DACWRITE" },
1639 { P_FILESYS, "P_FILESYS" },
1640 { P_MACREAD, "P_MACREAD" },
1641 { P_MACWRITE, "P_MACWRITE" },
1642 { P_MOUNT, "P_MOUNT" },
1643 { P_MULTIDIR, "P_MULTIDIR" },
1644 { P_SETPLEVEL, "P_SETPLEVEL" },
1645 { P_SETSPRIV, "P_SETSPRIV" },
1646 { P_SETUID, "P_SETUID" },
1647 { P_SYSOPS, "P_SYSOPS" },
1648 { P_SETUPRIV, "P_SETUPRIV" },
1649 { P_DRIVER, "P_DRIVER" },
1650 { P_RTIME, "P_RTIME" },
1651 { P_MACUPGRADE, "P_MACUPGRADE" },
1652 { P_FSYSRANGE, "P_FSYSRANGE" },
1653 { P_SETFLEVEL, "P_SETFLEVEL" },
1654 { P_AUDITWR, "P_AUDITWR" },
1655 { P_TSHAR, "P_TSHAR" },
1656 { P_PLOCK, "P_PLOCK" },
1657 { P_CORE, "P_CORE" },
1658 { P_LOADMOD, "P_LOADMOD" },
1659 { P_BIND, "P_BIND" },
1660 { P_ALLPRIVS, "P_ALLPRIVS" },
1665 static const struct xlat procpriv_type [] = {
1666 { PS_FIX, "PS_FIX" },
1667 { PS_INH, "PS_INH" },
1668 { PS_MAX, "PS_MAX" },
1669 { PS_WKG, "PS_WKG" },
1675 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1678 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1679 int dots = len > max;
1682 if (len > max) len = max;
1685 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1687 tprintf ("%#lx", addr);
1693 for (i = 0; i < len; ++i) {
1696 if (i) tprintf (", ");
1698 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1699 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1701 tprintf ("%s|%s", t, p);
1704 tprintf ("%#lx", buf [i]);
1708 if (dots) tprintf (" ...");
1718 if (entering(tcp)) {
1719 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1720 switch (tcp->u_arg[0]) {
1722 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1730 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1731 tprintf (", %ld", tcp->u_arg[2]);
1734 else if (tcp->u_arg[0] == GETPRV) {
1735 if (syserror (tcp)) {
1736 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1740 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1741 tprintf (", %ld", tcp->u_arg[2]);
1752 printargv(tcp, addr)
1759 char data[sizeof(long)];
1765 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1766 if (umoven(tcp, addr, personality_wordsize[current_personality],
1768 tprintf("%#lx", addr);
1771 if (personality_wordsize[current_personality] == 4)
1776 printstr(tcp, cp.p64, -1);
1777 addr += personality_wordsize[current_personality];
1780 tprintf("%s...", sep);
1784 printargc(fmt, tcp, addr)
1792 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1793 addr += sizeof(char *);
1795 tprintf(fmt, count, count == 1 ? "" : "s");
1798 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1803 if (entering(tcp)) {
1804 printpath(tcp, tcp->u_arg[0]);
1806 tprintf(", %#lx", tcp->u_arg[1]);
1808 else if (abbrev(tcp))
1809 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1813 printargv(tcp, tcp->u_arg[1]);
1819 #endif /* SPARC || SPARC64 || SUNOS4 */
1825 if (entering(tcp)) {
1826 printpath(tcp, tcp->u_arg[0]);
1828 tprintf(", %#lx", tcp->u_arg[1]);
1830 else if (abbrev(tcp))
1831 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1835 printargv(tcp, tcp->u_arg[1]);
1839 tprintf(", %#lx", tcp->u_arg[2]);
1840 else if (abbrev(tcp))
1841 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1844 printargv(tcp, tcp->u_arg[2]);
1853 int sys_rexecve(tcp)
1856 if (entering (tcp)) {
1858 tprintf (", %ld", tcp->u_arg[3]);
1870 if (exiting(tcp) && !syserror(tcp) && followfork)
1873 #if defined LINUX && defined TCB_WAITEXECVE
1874 if (exiting(tcp) && syserror(tcp))
1875 tcp->flags &= ~TCB_WAITEXECVE;
1877 tcp->flags |= TCB_WAITEXECVE;
1878 #endif /* LINUX && TCB_WAITEXECVE */
1884 #define __WNOTHREAD 0x20000000
1887 #define __WALL 0x40000000
1890 #define __WCLONE 0x80000000
1894 static const struct xlat wait4_options[] = {
1895 { WNOHANG, "WNOHANG" },
1897 { WUNTRACED, "WUNTRACED" },
1900 { WEXITED, "WEXITED" },
1903 { WTRAPPED, "WTRAPPED" },
1906 { WSTOPPED, "WSTOPPED" },
1909 { WCONTINUED, "WCONTINUED" },
1912 { WNOWAIT, "WNOWAIT" },
1915 { __WCLONE, "__WCLONE" },
1918 { __WALL, "__WALL" },
1921 { __WNOTHREAD, "__WNOTHREAD" },
1926 #if !defined WCOREFLAG && defined WCOREFLG
1927 # define WCOREFLAG WCOREFLG
1930 #define WCOREFLAG 0x80
1934 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1937 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1947 * Here is a tricky presentation problem. This solution
1948 * is still not entirely satisfactory but since there
1949 * are no wait status constructors it will have to do.
1951 if (WIFSTOPPED(status)) {
1952 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1953 signame(WSTOPSIG(status)));
1954 status &= ~W_STOPCODE(WSTOPSIG(status));
1956 else if (WIFSIGNALED(status)) {
1957 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1958 signame(WTERMSIG(status)),
1959 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1960 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1962 else if (WIFEXITED(status)) {
1963 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1964 WEXITSTATUS(status));
1966 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1969 tprintf("[%#x]", status);
1976 tprintf(" | %#x]", status);
1982 printwaitn(struct tcb *tcp, int n, int bitness)
1987 if (entering(tcp)) {
1989 * Sign-extend a 32-bit value when that's what it is.
1991 * NB: On Linux, kernel-side pid_t is typedef'ed to int
1992 * on all arches; also, glibc-2.8 truncates wait3 and wait4
1993 * pid argument to int on 64bit arches, producing,
1994 * for example, wait4(4294967295, ...) instead of -1
1996 * Therefore, maybe it makes sense to *unconditionally*
1997 * widen int to long here...
1999 long pid = tcp->u_arg[0];
2000 if (personality_wordsize[current_personality] < sizeof pid)
2001 pid = (long) (int) pid;
2002 tprintf("%ld, ", pid);
2007 else if (syserror(tcp) || tcp->u_rval == 0)
2008 tprintf("%#lx", tcp->u_arg[1]);
2009 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2012 exited = printstatus(status);
2015 printflags(wait4_options, tcp->u_arg[2], "W???");
2022 else if (tcp->u_rval > 0) {
2025 printrusage32(tcp, tcp->u_arg[3]);
2028 printrusage(tcp, tcp->u_arg[3]);
2032 else if (tcp->u_rval > 0 && exited)
2033 printrusage(tcp, tcp->u_arg[3]);
2036 tprintf("%#lx", tcp->u_arg[3]);
2043 internal_wait(tcp, flagarg)
2049 #ifdef TCB_CLONE_THREAD
2050 if (tcp->flags & TCB_CLONE_THREAD)
2051 /* The children we wait for are our parent's children. */
2052 got_kids = (tcp->parent->nchildren
2053 > tcp->parent->nclone_detached);
2055 got_kids = (tcp->nchildren > tcp->nclone_detached);
2057 got_kids = tcp->nchildren > 0;
2060 if (entering(tcp) && got_kids) {
2061 /* There are children that this parent should block for.
2062 But ptrace made us the parent of the traced children
2063 and the real parent will get ECHILD from the wait call.
2065 XXX If we attached with strace -f -p PID, then there
2066 may be untraced dead children the parent could be reaping
2067 now, but we make him block. */
2069 /* ??? WTA: fix bug with hanging children */
2071 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
2073 * There are traced children. We'll make the parent
2074 * block to avoid a false ECHILD error due to our
2075 * ptrace having stolen the children. However,
2076 * we shouldn't block if there are zombies to reap.
2077 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2079 struct tcb *child = NULL;
2080 if (tcp->nzombies > 0 &&
2081 (tcp->u_arg[0] == -1 ||
2082 (child = pid2tcb(tcp->u_arg[0])) == NULL))
2084 if (tcp->u_arg[0] > 0) {
2086 * If the parent waits for a specified child
2087 * PID, then it must get ECHILD right away
2088 * if that PID is not one of its children.
2089 * Make sure that the requested PID matches
2090 * one of the parent's children that we are
2091 * tracing, and don't suspend it otherwise.
2094 child = pid2tcb(tcp->u_arg[0]);
2095 if (child == NULL || child->parent != (
2096 #ifdef TCB_CLONE_THREAD
2097 (tcp->flags & TCB_CLONE_THREAD)
2101 (child->flags & TCB_EXITING))
2104 tcp->flags |= TCB_SUSPENDED;
2105 tcp->waitpid = tcp->u_arg[0];
2106 #ifdef TCB_CLONE_THREAD
2107 if (tcp->flags & TCB_CLONE_THREAD)
2108 tcp->parent->nclone_waiting++;
2112 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2113 if (tcp->u_arg[flagarg] & WNOHANG) {
2114 /* We must force a fake result of 0 instead of
2115 the ECHILD error. */
2116 extern int force_result();
2117 return force_result(tcp, 0, 0);
2120 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2121 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2123 * We just reaped a child we don't know about,
2124 * presumably a zombie we already droptcb'd.
2138 /* The library wrapper stuffs this into the user variable. */
2140 printstatus(getrval2(tcp));
2155 if (!syserror(tcp)) {
2156 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2157 tprintf("%#lx", tcp->u_arg[0]);
2159 printstatus(status);
2170 return printwaitn(tcp, 3, 0);
2177 return printwaitn(tcp, 4, 0);
2185 return printwaitn(tcp, 4, 1);
2189 #if defined SVR4 || defined LINUX
2191 static const struct xlat waitid_types[] = {
2194 { P_PPID, "P_PPID" },
2196 { P_PGID, "P_PGID" },
2211 { P_LWPID, "P_LWPID" },
2223 if (entering(tcp)) {
2224 printxval(waitid_types, tcp->u_arg[0], "P_???");
2225 tprintf(", %ld, ", tcp->u_arg[1]);
2232 else if (syserror(tcp))
2233 tprintf("%#lx", tcp->u_arg[2]);
2234 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2237 printsiginfo(&si, verbose(tcp));
2240 printflags(wait4_options, tcp->u_arg[3], "W???");
2241 if (tcp->u_nargs > 4) {
2246 else if (tcp->u_error)
2247 tprintf("%#lx", tcp->u_arg[4]);
2249 printrusage(tcp, tcp->u_arg[4]);
2255 #endif /* SVR4 or LINUX */
2262 tprintf("%lu", tcp->u_arg[0]);
2270 struct utsname uname;
2273 if (syserror(tcp) || !verbose(tcp))
2274 tprintf("%#lx", tcp->u_arg[0]);
2275 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2277 else if (!abbrev(tcp)) {
2279 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2280 uname.sysname, uname.nodename);
2281 tprintf("release=\"%s\", version=\"%s\", ",
2282 uname.release, uname.version);
2283 tprintf("machine=\"%s\"", uname.machine);
2286 tprintf(", domainname=\"%s\"", uname.domainname);
2287 #endif /* __GLIBC__ */
2292 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2293 uname.sysname, uname.nodename);
2300 static const struct xlat ptrace_cmds[] = {
2302 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2303 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2304 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2305 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2306 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2307 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2308 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2309 { PTRACE_CONT, "PTRACE_CONT" },
2310 { PTRACE_KILL, "PTRACE_KILL" },
2311 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2312 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2313 { PTRACE_DETACH, "PTRACE_DETACH" },
2314 #ifdef PTRACE_GETREGS
2315 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2317 #ifdef PTRACE_SETREGS
2318 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2320 #ifdef PTRACE_GETFPREGS
2321 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2323 #ifdef PTRACE_SETFPREGS
2324 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2326 #ifdef PTRACE_GETFPXREGS
2327 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2329 #ifdef PTRACE_SETFPXREGS
2330 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2332 #ifdef PTRACE_GETVRREGS
2333 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2335 #ifdef PTRACE_SETVRREGS
2336 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2338 #ifdef PTRACE_SETOPTIONS
2339 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2341 #ifdef PTRACE_GETEVENTMSG
2342 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2344 #ifdef PTRACE_GETSIGINFO
2345 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2347 #ifdef PTRACE_SETSIGINFO
2348 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2351 { PTRACE_READDATA, "PTRACE_READDATA" },
2352 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2353 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2354 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2355 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2356 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2358 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2359 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2361 { PTRACE_22, "PTRACE_PTRACE_22" },
2362 { PTRACE_23, "PTRACE_PTRACE_23" },
2365 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2367 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2369 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2370 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2371 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2373 { PTRACE_26, "PTRACE_26" },
2374 { PTRACE_27, "PTRACE_27" },
2375 { PTRACE_28, "PTRACE_28" },
2377 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2382 { PT_TRACE_ME, "PT_TRACE_ME" },
2383 { PT_READ_I, "PT_READ_I" },
2384 { PT_READ_D, "PT_READ_D" },
2385 { PT_WRITE_I, "PT_WRITE_I" },
2386 { PT_WRITE_D, "PT_WRITE_D" },
2388 { PT_READ_U, "PT_READ_U" },
2390 { PT_CONTINUE, "PT_CONTINUE" },
2391 { PT_KILL, "PT_KILL" },
2392 { PT_STEP, "PT_STEP" },
2393 { PT_ATTACH, "PT_ATTACH" },
2394 { PT_DETACH, "PT_DETACH" },
2395 { PT_GETREGS, "PT_GETREGS" },
2396 { PT_SETREGS, "PT_SETREGS" },
2397 { PT_GETFPREGS, "PT_GETFPREGS" },
2398 { PT_SETFPREGS, "PT_SETFPREGS" },
2399 { PT_GETDBREGS, "PT_GETDBREGS" },
2400 { PT_SETDBREGS, "PT_SETDBREGS" },
2401 #endif /* FREEBSD */
2406 #ifdef PTRACE_SETOPTIONS
2407 static const struct xlat ptrace_setoptions_flags[] = {
2408 #ifdef PTRACE_O_TRACESYSGOOD
2409 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2411 #ifdef PTRACE_O_TRACEFORK
2412 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2414 #ifdef PTRACE_O_TRACEVFORK
2415 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2417 #ifdef PTRACE_O_TRACECLONE
2418 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2420 #ifdef PTRACE_O_TRACEEXEC
2421 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2423 #ifdef PTRACE_O_TRACEVFORKDONE
2424 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2426 #ifdef PTRACE_O_TRACEEXIT
2427 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2435 const struct xlat struct_user_offsets[] = {
2437 #if defined(S390) || defined(S390X)
2438 { PT_PSWMASK, "psw_mask" },
2439 { PT_PSWADDR, "psw_addr" },
2440 { PT_GPR0, "gpr0" },
2441 { PT_GPR1, "gpr1" },
2442 { PT_GPR2, "gpr2" },
2443 { PT_GPR3, "gpr3" },
2444 { PT_GPR4, "gpr4" },
2445 { PT_GPR5, "gpr5" },
2446 { PT_GPR6, "gpr6" },
2447 { PT_GPR7, "gpr7" },
2448 { PT_GPR8, "gpr8" },
2449 { PT_GPR9, "gpr9" },
2450 { PT_GPR10, "gpr10" },
2451 { PT_GPR11, "gpr11" },
2452 { PT_GPR12, "gpr12" },
2453 { PT_GPR13, "gpr13" },
2454 { PT_GPR14, "gpr14" },
2455 { PT_GPR15, "gpr15" },
2456 { PT_ACR0, "acr0" },
2457 { PT_ACR1, "acr1" },
2458 { PT_ACR2, "acr2" },
2459 { PT_ACR3, "acr3" },
2460 { PT_ACR4, "acr4" },
2461 { PT_ACR5, "acr5" },
2462 { PT_ACR6, "acr6" },
2463 { PT_ACR7, "acr7" },
2464 { PT_ACR8, "acr8" },
2465 { PT_ACR9, "acr9" },
2466 { PT_ACR10, "acr10" },
2467 { PT_ACR11, "acr11" },
2468 { PT_ACR12, "acr12" },
2469 { PT_ACR13, "acr13" },
2470 { PT_ACR14, "acr14" },
2471 { PT_ACR15, "acr15" },
2472 { PT_ORIGGPR2, "orig_gpr2" },
2475 { PT_FPR0_HI, "fpr0.hi" },
2476 { PT_FPR0_LO, "fpr0.lo" },
2477 { PT_FPR1_HI, "fpr1.hi" },
2478 { PT_FPR1_LO, "fpr1.lo" },
2479 { PT_FPR2_HI, "fpr2.hi" },
2480 { PT_FPR2_LO, "fpr2.lo" },
2481 { PT_FPR3_HI, "fpr3.hi" },
2482 { PT_FPR3_LO, "fpr3.lo" },
2483 { PT_FPR4_HI, "fpr4.hi" },
2484 { PT_FPR4_LO, "fpr4.lo" },
2485 { PT_FPR5_HI, "fpr5.hi" },
2486 { PT_FPR5_LO, "fpr5.lo" },
2487 { PT_FPR6_HI, "fpr6.hi" },
2488 { PT_FPR6_LO, "fpr6.lo" },
2489 { PT_FPR7_HI, "fpr7.hi" },
2490 { PT_FPR7_LO, "fpr7.lo" },
2491 { PT_FPR8_HI, "fpr8.hi" },
2492 { PT_FPR8_LO, "fpr8.lo" },
2493 { PT_FPR9_HI, "fpr9.hi" },
2494 { PT_FPR9_LO, "fpr9.lo" },
2495 { PT_FPR10_HI, "fpr10.hi" },
2496 { PT_FPR10_LO, "fpr10.lo" },
2497 { PT_FPR11_HI, "fpr11.hi" },
2498 { PT_FPR11_LO, "fpr11.lo" },
2499 { PT_FPR12_HI, "fpr12.hi" },
2500 { PT_FPR12_LO, "fpr12.lo" },
2501 { PT_FPR13_HI, "fpr13.hi" },
2502 { PT_FPR13_LO, "fpr13.lo" },
2503 { PT_FPR14_HI, "fpr14.hi" },
2504 { PT_FPR14_LO, "fpr14.lo" },
2505 { PT_FPR15_HI, "fpr15.hi" },
2506 { PT_FPR15_LO, "fpr15.lo" },
2509 { PT_FPR0, "fpr0" },
2510 { PT_FPR1, "fpr1" },
2511 { PT_FPR2, "fpr2" },
2512 { PT_FPR3, "fpr3" },
2513 { PT_FPR4, "fpr4" },
2514 { PT_FPR5, "fpr5" },
2515 { PT_FPR6, "fpr6" },
2516 { PT_FPR7, "fpr7" },
2517 { PT_FPR8, "fpr8" },
2518 { PT_FPR9, "fpr9" },
2519 { PT_FPR10, "fpr10" },
2520 { PT_FPR11, "fpr11" },
2521 { PT_FPR12, "fpr12" },
2522 { PT_FPR13, "fpr13" },
2523 { PT_FPR14, "fpr14" },
2524 { PT_FPR15, "fpr15" },
2527 { PT_CR_10, "cr10" },
2528 { PT_CR_11, "cr11" },
2529 { PT_IEEE_IP, "ieee_exception_ip" },
2532 /* XXX No support for these offsets yet. */
2534 /* XXX No support for these offsets yet. */
2535 #elif defined(POWERPC)
2537 #define PT_ORIG_R3 34
2539 #define REGSIZE (sizeof(unsigned long))
2540 { REGSIZE*PT_R0, "r0" },
2541 { REGSIZE*PT_R1, "r1" },
2542 { REGSIZE*PT_R2, "r2" },
2543 { REGSIZE*PT_R3, "r3" },
2544 { REGSIZE*PT_R4, "r4" },
2545 { REGSIZE*PT_R5, "r5" },
2546 { REGSIZE*PT_R6, "r6" },
2547 { REGSIZE*PT_R7, "r7" },
2548 { REGSIZE*PT_R8, "r8" },
2549 { REGSIZE*PT_R9, "r9" },
2550 { REGSIZE*PT_R10, "r10" },
2551 { REGSIZE*PT_R11, "r11" },
2552 { REGSIZE*PT_R12, "r12" },
2553 { REGSIZE*PT_R13, "r13" },
2554 { REGSIZE*PT_R14, "r14" },
2555 { REGSIZE*PT_R15, "r15" },
2556 { REGSIZE*PT_R16, "r16" },
2557 { REGSIZE*PT_R17, "r17" },
2558 { REGSIZE*PT_R18, "r18" },
2559 { REGSIZE*PT_R19, "r19" },
2560 { REGSIZE*PT_R20, "r20" },
2561 { REGSIZE*PT_R21, "r21" },
2562 { REGSIZE*PT_R22, "r22" },
2563 { REGSIZE*PT_R23, "r23" },
2564 { REGSIZE*PT_R24, "r24" },
2565 { REGSIZE*PT_R25, "r25" },
2566 { REGSIZE*PT_R26, "r26" },
2567 { REGSIZE*PT_R27, "r27" },
2568 { REGSIZE*PT_R28, "r28" },
2569 { REGSIZE*PT_R29, "r29" },
2570 { REGSIZE*PT_R30, "r30" },
2571 { REGSIZE*PT_R31, "r31" },
2572 { REGSIZE*PT_NIP, "NIP" },
2573 { REGSIZE*PT_MSR, "MSR" },
2574 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2575 { REGSIZE*PT_CTR, "CTR" },
2576 { REGSIZE*PT_LNK, "LNK" },
2577 { REGSIZE*PT_XER, "XER" },
2578 { REGSIZE*PT_CCR, "CCR" },
2579 { REGSIZE*PT_FPR0, "FPR0" },
2650 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2651 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2652 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2653 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2654 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2655 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2656 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2657 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2658 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2659 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2660 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2661 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2662 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2663 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2664 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2665 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2666 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2667 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2668 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2669 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2670 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2671 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2672 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2673 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2674 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2675 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2676 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2677 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2678 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2679 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2680 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2681 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2683 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2684 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2685 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2686 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2687 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2688 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2689 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2690 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2691 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2692 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2693 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2694 { PT_B4, "b4" }, { PT_B5, "b5" },
2695 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2697 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2698 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2699 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2700 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2701 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2702 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2703 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2704 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2705 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2706 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2707 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2708 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2709 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2710 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2711 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2712 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2713 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2715 { PT_AR_CSD, "ar.csd" },
2718 { PT_AR_SSD, "ar.ssd" },
2720 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2734 { 4*ORIG_EAX, "4*ORIG_EAX" },
2738 { 4*UESP, "4*UESP" },
2763 { 8*ORIG_RAX, "8*ORIG_RAX" },
2766 { 8*EFLAGS, "8*EFL" },
2771 { 4*PT_D1, "4*PT_D1" },
2772 { 4*PT_D2, "4*PT_D2" },
2773 { 4*PT_D3, "4*PT_D3" },
2774 { 4*PT_D4, "4*PT_D4" },
2775 { 4*PT_D5, "4*PT_D5" },
2776 { 4*PT_D6, "4*PT_D6" },
2777 { 4*PT_D7, "4*PT_D7" },
2778 { 4*PT_A0, "4*PT_A0" },
2779 { 4*PT_A1, "4*PT_A1" },
2780 { 4*PT_A2, "4*PT_A2" },
2781 { 4*PT_A3, "4*PT_A3" },
2782 { 4*PT_A4, "4*PT_A4" },
2783 { 4*PT_A5, "4*PT_A5" },
2784 { 4*PT_A6, "4*PT_A6" },
2785 { 4*PT_D0, "4*PT_D0" },
2786 { 4*PT_USP, "4*PT_USP" },
2787 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2788 { 4*PT_SR, "4*PT_SR" },
2789 { 4*PT_PC, "4*PT_PC" },
2793 { 4*REG_REG0, "4*REG_REG0" },
2794 { 4*(REG_REG0+1), "4*REG_REG1" },
2795 { 4*(REG_REG0+2), "4*REG_REG2" },
2796 { 4*(REG_REG0+3), "4*REG_REG3" },
2797 { 4*(REG_REG0+4), "4*REG_REG4" },
2798 { 4*(REG_REG0+5), "4*REG_REG5" },
2799 { 4*(REG_REG0+6), "4*REG_REG6" },
2800 { 4*(REG_REG0+7), "4*REG_REG7" },
2801 { 4*(REG_REG0+8), "4*REG_REG8" },
2802 { 4*(REG_REG0+9), "4*REG_REG9" },
2803 { 4*(REG_REG0+10), "4*REG_REG10" },
2804 { 4*(REG_REG0+11), "4*REG_REG11" },
2805 { 4*(REG_REG0+12), "4*REG_REG12" },
2806 { 4*(REG_REG0+13), "4*REG_REG13" },
2807 { 4*(REG_REG0+14), "4*REG_REG14" },
2808 { 4*REG_REG15, "4*REG_REG15" },
2809 { 4*REG_PC, "4*REG_PC" },
2810 { 4*REG_PR, "4*REG_PR" },
2811 { 4*REG_SR, "4*REG_SR" },
2812 { 4*REG_GBR, "4*REG_GBR" },
2813 { 4*REG_MACH, "4*REG_MACH" },
2814 { 4*REG_MACL, "4*REG_MACL" },
2815 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2816 { 4*REG_FPUL, "4*REG_FPUL" },
2817 { 4*REG_FPREG0, "4*REG_FPREG0" },
2818 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2819 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2820 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2821 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2822 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2823 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2824 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2825 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2826 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2827 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2828 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2829 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2830 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2831 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2832 { 4*REG_FPREG15, "4*REG_FPREG15" },
2834 { 4*REG_XDREG0, "4*REG_XDREG0" },
2835 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2836 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2837 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2838 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2839 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2840 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2841 { 4*REG_XDREG14, "4*REG_XDREG14" },
2843 { 4*REG_FPSCR, "4*REG_FPSCR" },
2850 { 16, "syscall no.(L)" },
2851 { 20, "syscall_no.(U)" },
2994 /* This entry is in case pt_regs contains dregs (depends on
2995 the kernel build options). */
2996 { uoff(regs), "offsetof(struct user, regs)" },
2997 { uoff(fpu), "offsetof(struct user, fpu)" },
3000 { uoff(regs.ARM_r0), "r0" },
3001 { uoff(regs.ARM_r1), "r1" },
3002 { uoff(regs.ARM_r2), "r2" },
3003 { uoff(regs.ARM_r3), "r3" },
3004 { uoff(regs.ARM_r4), "r4" },
3005 { uoff(regs.ARM_r5), "r5" },
3006 { uoff(regs.ARM_r6), "r6" },
3007 { uoff(regs.ARM_r7), "r7" },
3008 { uoff(regs.ARM_r8), "r8" },
3009 { uoff(regs.ARM_r9), "r9" },
3010 { uoff(regs.ARM_r10), "r10" },
3011 { uoff(regs.ARM_fp), "fp" },
3012 { uoff(regs.ARM_ip), "ip" },
3013 { uoff(regs.ARM_sp), "sp" },
3014 { uoff(regs.ARM_lr), "lr" },
3015 { uoff(regs.ARM_pc), "pc" },
3016 { uoff(regs.ARM_cpsr), "cpsr" },
3093 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
3094 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3096 #if defined(I386) || defined(X86_64)
3097 { uoff(i387), "offsetof(struct user, i387)" },
3100 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3103 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3104 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3105 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3106 #if !defined(SPARC64)
3107 { uoff(start_code), "offsetof(struct user, start_code)" },
3110 { uoff(start_data), "offsetof(struct user, start_data)" },
3112 #if !defined(SPARC64)
3113 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3115 { uoff(signal), "offsetof(struct user, signal)" },
3116 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
3117 { uoff(reserved), "offsetof(struct user, reserved)" },
3119 #if !defined(SPARC64)
3120 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3122 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
3123 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3125 { uoff(magic), "offsetof(struct user, magic)" },
3126 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3127 #if defined(I386) || defined(X86_64)
3128 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3132 #endif /* !POWERPC/!SPARC */
3135 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3136 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3137 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3138 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3139 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3140 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3141 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3142 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3143 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3144 { uoff(u_error), "offsetof(struct user, u_error)" },
3145 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3146 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3147 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3148 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3149 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3150 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3151 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3152 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3153 { uoff(u_code), "offsetof(struct user, u_code)" },
3154 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3155 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3156 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3157 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3158 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3159 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3160 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3161 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3162 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3163 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3164 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3165 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3166 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3167 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3168 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3169 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3170 { uoff(u_start), "offsetof(struct user, u_start)" },
3171 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3172 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3173 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3174 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3175 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3176 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3177 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3178 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3179 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3182 { sizeof(struct user), "sizeof(struct user)" },
3192 const struct xlat *x;
3195 if (entering(tcp)) {
3196 printxval(ptrace_cmds, tcp->u_arg[0],
3203 tprintf(", %lu, ", tcp->u_arg[1]);
3204 addr = tcp->u_arg[2];
3206 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3207 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3208 for (x = struct_user_offsets; x->str; x++) {
3213 tprintf("%#lx, ", addr);
3214 else if (x->val > addr && x != struct_user_offsets) {
3216 tprintf("%s + %ld, ", x->str, addr - x->val);
3219 tprintf("%s, ", x->str);
3223 tprintf("%#lx, ", tcp->u_arg[2]);
3225 switch (tcp->u_arg[0]) {
3227 case PTRACE_PEEKDATA:
3228 case PTRACE_PEEKTEXT:
3229 case PTRACE_PEEKUSER:
3233 case PTRACE_SINGLESTEP:
3234 case PTRACE_SYSCALL:
3236 printsignal(tcp->u_arg[3]);
3238 #ifdef PTRACE_SETOPTIONS
3239 case PTRACE_SETOPTIONS:
3240 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3243 #ifdef PTRACE_SETSIGINFO
3244 case PTRACE_SETSIGINFO: {
3248 else if (syserror(tcp))
3249 tprintf("%#lx", tcp->u_arg[3]);
3250 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3253 printsiginfo(&si, verbose(tcp));
3257 #ifdef PTRACE_GETSIGINFO
3258 case PTRACE_GETSIGINFO:
3259 /* Don't print anything, do it at syscall return. */
3263 tprintf("%#lx", tcp->u_arg[3]);
3267 switch (tcp->u_arg[0]) {
3268 case PTRACE_PEEKDATA:
3269 case PTRACE_PEEKTEXT:
3270 case PTRACE_PEEKUSER:
3274 printnum(tcp, tcp->u_arg[3], "%#lx");
3277 #ifdef PTRACE_GETSIGINFO
3278 case PTRACE_GETSIGINFO: {
3282 else if (syserror(tcp))
3283 tprintf("%#lx", tcp->u_arg[3]);
3284 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3287 printsiginfo(&si, verbose(tcp));
3295 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3296 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3297 tprintf("%lu, ", tcp->u_arg[3]);
3298 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3299 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3300 tcp->u_arg[0] != PTRACE_READTEXT) {
3301 tprintf("%#lx", tcp->u_arg[3]);
3304 if (tcp->u_arg[0] == PTRACE_READDATA ||
3305 tcp->u_arg[0] == PTRACE_READTEXT) {
3306 tprintf("%lu, ", tcp->u_arg[3]);
3307 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3312 tprintf("%lu", tcp->u_arg[3]);
3314 #endif /* FREEBSD */
3321 # ifndef FUTEX_CMP_REQUEUE
3322 # define FUTEX_CMP_REQUEUE 4
3324 # ifndef FUTEX_WAKE_OP
3325 # define FUTEX_WAKE_OP 5
3327 # ifndef FUTEX_LOCK_PI
3328 # define FUTEX_LOCK_PI 6
3329 # define FUTEX_UNLOCK_PI 7
3330 # define FUTEX_TRYLOCK_PI 8
3332 # ifndef FUTEX_WAIT_BITSET
3333 # define FUTEX_WAIT_BITSET 9
3335 # ifndef FUTEX_WAKE_BITSET
3336 # define FUTEX_WAKE_BITSET 10
3338 # ifndef FUTEX_PRIVATE_FLAG
3339 # define FUTEX_PRIVATE_FLAG 128
3341 static const struct xlat futexops[] = {
3342 { FUTEX_WAIT, "FUTEX_WAIT" },
3343 { FUTEX_WAKE, "FUTEX_WAKE" },
3344 { FUTEX_FD, "FUTEX_FD" },
3345 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3346 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3347 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3348 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3349 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3350 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3351 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3352 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3353 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3354 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3355 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3356 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3357 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3358 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3359 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3360 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3361 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3362 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3363 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3366 #ifndef FUTEX_OP_SET
3367 # define FUTEX_OP_SET 0
3368 # define FUTEX_OP_ADD 1
3369 # define FUTEX_OP_OR 2
3370 # define FUTEX_OP_ANDN 3
3371 # define FUTEX_OP_XOR 4
3372 # define FUTEX_OP_CMP_EQ 0
3373 # define FUTEX_OP_CMP_NE 1
3374 # define FUTEX_OP_CMP_LT 2
3375 # define FUTEX_OP_CMP_LE 3
3376 # define FUTEX_OP_CMP_GT 4
3377 # define FUTEX_OP_CMP_GE 5
3379 static const struct xlat futexwakeops[] = {
3380 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3381 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3382 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3383 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3384 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3387 static const struct xlat futexwakecmps[] = {
3388 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3389 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3390 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3391 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3392 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3393 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3401 if (entering(tcp)) {
3402 long int cmd = tcp->u_arg[1] & 127;
3403 tprintf("%p, ", (void *) tcp->u_arg[0]);
3404 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3405 tprintf(", %ld", tcp->u_arg[2]);
3406 if (cmd == FUTEX_WAKE_BITSET)
3407 tprintf(", %lx", tcp->u_arg[5]);
3408 else if (cmd == FUTEX_WAIT) {
3410 printtv(tcp, tcp->u_arg[3]);
3411 } else if (cmd == FUTEX_WAIT_BITSET) {
3413 printtv(tcp, tcp->u_arg[3]);
3414 tprintf(", %lx", tcp->u_arg[5]);
3415 } else if (cmd == FUTEX_REQUEUE)
3416 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3417 else if (cmd == FUTEX_CMP_REQUEUE)
3418 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3419 else if (cmd == FUTEX_WAKE_OP) {
3420 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3421 if ((tcp->u_arg[5] >> 28) & 8)
3422 tprintf("FUTEX_OP_OPARG_SHIFT|");
3423 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3424 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3425 if ((tcp->u_arg[5] >> 24) & 8)
3426 tprintf("FUTEX_OP_OPARG_SHIFT|");
3427 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3428 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3435 print_affinitylist(tcp, list, len)
3442 while (len >= sizeof (unsigned long)) {
3444 umove(tcp, list, &w);
3445 tprintf("%s %lx", first ? "" : ",", w);
3447 len -= sizeof (unsigned long);
3448 list += sizeof(unsigned long);
3454 sys_sched_setaffinity(tcp)
3457 if (entering(tcp)) {
3458 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3459 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3465 sys_sched_getaffinity(tcp)
3468 if (entering(tcp)) {
3469 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3471 if (tcp->u_rval == -1)
3472 tprintf("%#lx", tcp->u_arg[2]);
3474 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3479 static const struct xlat schedulers[] = {
3480 { SCHED_OTHER, "SCHED_OTHER" },
3481 { SCHED_RR, "SCHED_RR" },
3482 { SCHED_FIFO, "SCHED_FIFO" },
3487 sys_sched_getscheduler(tcp)
3490 if (entering(tcp)) {
3491 tprintf("%d", (int) tcp->u_arg[0]);
3492 } else if (! syserror(tcp)) {
3493 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3494 if (tcp->auxstr != NULL)
3501 sys_sched_setscheduler(tcp)
3504 if (entering(tcp)) {
3505 struct sched_param p;
3506 tprintf("%d, ", (int) tcp->u_arg[0]);
3507 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3508 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3509 tprintf(", %#lx", tcp->u_arg[2]);
3511 tprintf(", { %d }", p.__sched_priority);
3517 sys_sched_getparam(tcp)
3520 if (entering(tcp)) {
3521 tprintf("%d, ", (int) tcp->u_arg[0]);
3523 struct sched_param p;
3524 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3525 tprintf("%#lx", tcp->u_arg[1]);
3527 tprintf("{ %d }", p.__sched_priority);
3533 sys_sched_setparam(tcp)
3536 if (entering(tcp)) {
3537 struct sched_param p;
3538 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3539 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3541 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3547 sys_sched_get_priority_min(tcp)
3550 if (entering(tcp)) {
3551 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3557 #include <asm/prctl.h>
3559 static const struct xlat archvals[] = {
3560 { ARCH_SET_GS, "ARCH_SET_GS" },
3561 { ARCH_SET_FS, "ARCH_SET_FS" },
3562 { ARCH_GET_FS, "ARCH_GET_FS" },
3563 { ARCH_GET_GS, "ARCH_GET_GS" },
3571 if (entering(tcp)) {
3572 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3573 if (tcp->u_arg[0] == ARCH_SET_GS
3574 || tcp->u_arg[0] == ARCH_SET_FS)
3575 tprintf(", %#lx", tcp->u_arg[1]);
3577 if (tcp->u_arg[0] == ARCH_GET_GS
3578 || tcp->u_arg[0] == ARCH_GET_FS) {
3580 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3581 tprintf(", [%#lx]", v);
3583 tprintf(", %#lx", tcp->u_arg[1]);
3597 if (tcp->u_arg[0] == 0)
3599 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3600 tprintf("%#lx, ", tcp->u_arg[0]);
3602 tprintf("[%u], ", u);
3603 if (tcp->u_arg[1] == 0)
3605 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3606 tprintf("%#lx, ", tcp->u_arg[1]);
3608 tprintf("[%u], ", u);
3609 tprintf("%#lx", tcp->u_arg[2]);