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) {
494 if (expand_tcbtab()) {
495 tcp->flags &= ~TCB_FOLLOWFORK;
500 tcp->flags |= TCB_FOLLOWFORK;
510 if (exiting(tcp) && !syserror(tcp)) {
512 tcp->auxstr = "child process";
513 return RVAL_UDECIMAL | RVAL_STR;
526 tprintf ("%ld", tcp->u_arg[0]);
528 else if (!syserror(tcp)) {
530 tcp->auxstr = "child process";
531 return RVAL_UDECIMAL | RVAL_STR;
543 struct tcb *tcpchild;
547 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
558 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL)
560 if (proc_open(tcpchild, 2) < 0)
566 #else /* !USE_PROCFS */
570 /* defines copied from linux/sched.h since we can't include that
571 * ourselves (it conflicts with *lots* of libc includes)
573 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
574 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
575 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
576 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
577 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
578 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
579 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
580 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
581 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
582 #define CLONE_THREAD 0x00010000 /* Same thread group? */
583 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
584 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
585 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
586 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
587 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
588 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
589 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
590 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
592 static const struct xlat clone_flags[] = {
593 { CLONE_VM, "CLONE_VM" },
594 { CLONE_FS, "CLONE_FS" },
595 { CLONE_FILES, "CLONE_FILES" },
596 { CLONE_SIGHAND, "CLONE_SIGHAND" },
597 { CLONE_IDLETASK, "CLONE_IDLETASK"},
598 { CLONE_PTRACE, "CLONE_PTRACE" },
599 { CLONE_VFORK, "CLONE_VFORK" },
600 { CLONE_PARENT, "CLONE_PARENT" },
601 { CLONE_THREAD, "CLONE_THREAD" },
602 { CLONE_NEWNS, "CLONE_NEWNS" },
603 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
604 { CLONE_SETTLS, "CLONE_SETTLS" },
605 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
606 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
607 { CLONE_DETACHED, "CLONE_DETACHED" },
608 { CLONE_UNTRACED, "CLONE_UNTRACED" },
609 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
614 # include <asm/ldt.h>
615 # ifdef HAVE_STRUCT_USER_DESC
616 # define modify_ldt_ldt_s user_desc
618 extern void print_ldt_entry();
624 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
625 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
626 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
627 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
628 # elif defined S390 || defined S390X
634 # elif defined X86_64 || defined ALPHA
653 unsigned long flags = tcp->u_arg[ARG_FLAGS];
654 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
655 # ifdef ARG_STACKSIZE
656 if (ARG_STACKSIZE != -1)
657 tprintf("stack_size=%#lx, ",
658 tcp->u_arg[ARG_STACKSIZE]);
661 printflags(clone_flags, flags &~ CSIGNAL, NULL);
662 if ((flags & CSIGNAL) != 0)
663 tprintf("|%s", signame(flags & CSIGNAL));
664 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
665 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
667 if (flags & CLONE_PARENT_SETTID)
668 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
669 if (flags & CLONE_SETTLS) {
671 struct modify_ldt_ldt_s copy;
672 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
673 tprintf(", {entry_number:%d, ",
678 print_ldt_entry(©);
682 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
684 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
685 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
691 sys_unshare(struct tcb *tcp)
694 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
704 return RVAL_UDECIMAL;
709 change_syscall(tcp, new)
715 /* Attempt to make vfork into fork, which we can follow. */
716 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
719 #elif defined(X86_64)
720 /* Attempt to make vfork into fork, which we can follow. */
721 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
724 #elif defined(POWERPC)
725 if (ptrace(PTRACE_POKEUSER, tcp->pid,
726 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
729 #elif defined(S390) || defined(S390X)
730 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
731 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
735 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
738 #elif defined(SPARC) || defined(SPARC64)
740 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
743 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
747 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
751 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
755 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
761 case 2: break; /* x86 SYS_fork */
762 case SYS_clone: new = 120; break;
764 fprintf(stderr, "%s: unexpected syscall %d\n",
768 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
770 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
774 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
778 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
782 /* Top half of reg encodes the no. of args n as 0x1n.
783 Assume 0 args as kernel never actually checks... */
784 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
789 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
790 # ifndef PTRACE_SET_SYSCALL
791 # define PTRACE_SET_SYSCALL 23
794 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new) != 0)
799 #warning Do not know how to handle change_syscall for this architecture
800 #endif /* architecture */
813 unsigned long *bsp, *ap;
815 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
818 ap = ia64_rse_skip_regs(bsp, argnum);
820 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
827 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
831 #elif defined(X86_64)
833 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
837 #elif defined(POWERPC)
839 #define PT_ORIG_R3 34
842 ptrace(PTRACE_POKEUSER, tcp->pid,
843 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
852 ptrace(PTRACE_POKEUSER, tcp->pid,
853 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
857 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
860 ptrace(PTRACE_POKEDATA, tcp->pid,
861 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
866 #elif defined(S390) || defined(S390X)
869 ptrace(PTRACE_POKEUSER, tcp->pid,
870 (char *) (argnum==0 ? PT_ORIGGPR2 :
871 PT_GPR2 + argnum*sizeof(long)),
879 # warning Sorry, setargs not implemented for this architecture.
885 #if defined SYS_clone || defined SYS_clone2
890 struct tcb *tcpchild;
900 int bpt = tcp->flags & TCB_BPTSET;
902 if (!(tcp->flags & TCB_FOLLOWFORK))
913 #ifdef CLONE_PTRACE /* See new setbpt code. */
914 tcpchild = pid2tcb(pid);
915 if (tcpchild != NULL) {
916 /* The child already reported its startup trap
917 before the parent reported its syscall return. */
919 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
920 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
922 [preattached child %d of %d in weird state!]\n",
927 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
930 kill(pid, SIGKILL); /* XXX */
935 /* Attach to the new child */
936 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
939 perror("PTRACE_ATTACH");
940 fprintf(stderr, "Too late?\n");
949 tcpchild->flags |= TCB_ATTACHED;
950 /* Child has BPT too, must be removed on first occasion. */
952 tcpchild->flags |= TCB_BPTSET;
953 tcpchild->baddr = tcp->baddr;
954 memcpy(tcpchild->inst, tcp->inst,
955 sizeof tcpchild->inst);
957 tcpchild->parent = tcp;
959 if (tcpchild->flags & TCB_SUSPENDED) {
960 /* The child was born suspended, due to our having
961 forced CLONE_PTRACE. */
965 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
966 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
971 Process %u resumed (parent %d ready)\n",
976 fprintf(stderr, "Process %d attached\n", pid);
979 #ifdef TCB_CLONE_THREAD
982 * Save the flags used in this call,
983 * in case we point TCP to our parent below.
985 int call_flags = tcp->u_arg[ARG_FLAGS];
986 if ((tcp->flags & TCB_CLONE_THREAD) &&
987 tcp->parent != NULL) {
988 /* The parent in this clone is itself a
989 thread belonging to another process.
990 There is no meaning to the parentage
991 relationship of the new child with the
992 thread, only with the process. We
993 associate the new thread with our
994 parent. Since this is done for every
995 new thread, there will never be a
996 TCB_CLONE_THREAD process that has
1000 tcpchild->parent = tcp;
1003 if (call_flags & CLONE_THREAD) {
1004 tcpchild->flags |= TCB_CLONE_THREAD;
1005 ++tcp->nclone_threads;
1007 if (call_flags & CLONE_DETACHED) {
1008 tcpchild->flags |= TCB_CLONE_DETACHED;
1009 ++tcp->nclone_detached;
1024 /* We do special magic with clone for any clone or fork. */
1025 return internal_clone(tcp);
1028 struct tcb *tcpchild;
1030 int dont_follow = 0;
1033 if (known_scno(tcp) == SYS_vfork) {
1034 /* Attempt to make vfork into fork, which we can follow. */
1035 if (change_syscall(tcp, SYS_fork) < 0)
1039 if (entering(tcp)) {
1040 if (!followfork || dont_follow)
1044 if (setbpt(tcp) < 0)
1048 int bpt = tcp->flags & TCB_BPTSET;
1050 if (!(tcp->flags & TCB_FOLLOWFORK))
1059 if (fork_tcb(tcp) || (tcpchild = alloctcb(pid)) == NULL) {
1060 kill(pid, SIGKILL); /* XXX */
1065 /* The child must have run before it can be attached. */
1066 /* This must be a bug in the parisc kernel, but I havn't
1067 * identified it yet. Seems to be an issue associated
1068 * with attaching to a process (which sends it a signal)
1069 * before that process has ever been scheduled. When
1070 * debugging, I started seeing crashes in
1071 * arch/parisc/kernel/signal.c:do_signal(), apparently
1072 * caused by r8 getting corrupt over the dequeue_signal()
1073 * call. Didn't make much sense though...
1079 select(0, NULL, NULL, NULL, &tv);
1082 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1083 perror("PTRACE_ATTACH");
1084 fprintf(stderr, "Too late?\n");
1091 /* The child must have run before it can be attached. */
1096 select(0, NULL, NULL, NULL, &tv);
1098 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1099 perror("PTRACE_ATTACH");
1100 fprintf(stderr, "Too late?\n");
1105 /* Try to catch the new process as soon as possible. */
1108 for (i = 0; i < 1024; i++)
1109 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1112 perror("PTRACE_ATTACH");
1113 fprintf(stderr, "Too late?\n");
1118 #endif /* !oldway */
1120 tcpchild->flags |= TCB_ATTACHED;
1121 /* Child has BPT too, must be removed on first occasion */
1123 tcpchild->flags |= TCB_BPTSET;
1124 tcpchild->baddr = tcp->baddr;
1125 memcpy(tcpchild->inst, tcp->inst,
1126 sizeof tcpchild->inst);
1128 tcpchild->parent = tcp;
1131 fprintf(stderr, "Process %d attached\n", pid);
1137 #endif /* !USE_PROCFS */
1139 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1146 return RVAL_UDECIMAL;
1150 #endif /* SUNOS4 || LINUX || FREEBSD */
1154 static char idstr[16];
1161 sprintf(idstr, "ppid %lu", getrval2(tcp));
1162 tcp->auxstr = idstr;
1173 sprintf(idstr, "euid %lu", getrval2(tcp));
1174 tcp->auxstr = idstr;
1185 sprintf(idstr, "egid %lu", getrval2(tcp));
1186 tcp->auxstr = idstr;
1200 if (entering(tcp)) {
1201 tprintf("%u", (uid_t) tcp->u_arg[0]);
1210 if (entering(tcp)) {
1211 tprintf("%u", (gid_t) tcp->u_arg[0]);
1223 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1224 tcp->u_arg[1], tcp->u_arg[2]);
1226 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1227 tprintf("%#lx, ", tcp->u_arg[0]);
1229 tprintf("[%lu], ", (unsigned long) uid);
1230 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1231 tprintf("%#lx, ", tcp->u_arg[1]);
1233 tprintf("[%lu], ", (unsigned long) uid);
1234 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1235 tprintf("%#lx", tcp->u_arg[2]);
1237 tprintf("[%lu]", (unsigned long) uid);
1250 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1251 tcp->u_arg[1], tcp->u_arg[2]);
1253 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1254 tprintf("%#lx, ", tcp->u_arg[0]);
1256 tprintf("[%lu], ", (unsigned long) gid);
1257 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1258 tprintf("%#lx, ", tcp->u_arg[1]);
1260 tprintf("[%lu], ", (unsigned long) gid);
1261 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1262 tprintf("%#lx", tcp->u_arg[2]);
1264 tprintf("[%lu]", (unsigned long) gid);
1276 if (entering(tcp)) {
1277 printuid("", tcp->u_arg[0]);
1278 printuid(", ", tcp->u_arg[1]);
1287 if (entering(tcp)) {
1288 printuid("", tcp->u_arg[0]);
1289 printuid(", ", tcp->u_arg[1]);
1294 #if defined(LINUX) || defined(FREEBSD)
1299 if (entering(tcp)) {
1300 printuid("", tcp->u_arg[0]);
1301 printuid(", ", tcp->u_arg[1]);
1302 printuid(", ", tcp->u_arg[2]);
1310 if (entering(tcp)) {
1311 printuid("", tcp->u_arg[0]);
1312 printuid(", ", tcp->u_arg[1]);
1313 printuid(", ", tcp->u_arg[2]);
1318 #endif /* LINUX || FREEBSD */
1324 if (entering(tcp)) {
1325 unsigned long len, size, start, cur, end, abbrev_end;
1329 len = tcp->u_arg[0];
1330 tprintf("%lu, ", len);
1335 start = tcp->u_arg[1];
1340 size = len * sizeof(gid);
1342 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1343 tprintf("%#lx", start);
1347 abbrev_end = start + max_strlen * sizeof(gid);
1348 if (abbrev_end < start)
1354 for (cur = start; cur < end; cur += sizeof(gid)) {
1357 if (cur >= abbrev_end) {
1361 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1366 tprintf("%lu", (unsigned long) gid);
1370 tprintf(" %#lx", tcp->u_arg[1]);
1381 if (entering(tcp)) {
1382 len = tcp->u_arg[0];
1383 tprintf("%lu, ", len);
1385 unsigned long size, start, cur, end, abbrev_end;
1394 start = tcp->u_arg[1];
1399 if (tcp->u_arg[0] == 0) {
1400 tprintf("%#lx", start);
1403 size = len * sizeof(gid);
1405 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1406 size / sizeof(gid) != len || end < start) {
1407 tprintf("%#lx", start);
1411 abbrev_end = start + max_strlen * sizeof(gid);
1412 if (abbrev_end < start)
1418 for (cur = start; cur < end; cur += sizeof(gid)) {
1421 if (cur >= abbrev_end) {
1425 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1430 tprintf("%lu", (unsigned long) gid);
1434 tprintf(" %#lx", tcp->u_arg[1]);
1441 sys_setgroups32(tcp)
1444 if (entering(tcp)) {
1445 unsigned long len, size, start, cur, end, abbrev_end;
1449 len = tcp->u_arg[0];
1450 tprintf("%lu, ", len);
1455 start = tcp->u_arg[1];
1460 size = len * sizeof(gid);
1462 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1463 tprintf("%#lx", start);
1467 abbrev_end = start + max_strlen * sizeof(gid);
1468 if (abbrev_end < start)
1474 for (cur = start; cur < end; cur += sizeof(gid)) {
1477 if (cur >= abbrev_end) {
1481 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1486 tprintf("%lu", (unsigned long) gid);
1490 tprintf(" %#lx", tcp->u_arg[1]);
1496 sys_getgroups32(tcp)
1501 if (entering(tcp)) {
1502 len = tcp->u_arg[0];
1503 tprintf("%lu, ", len);
1505 unsigned long size, start, cur, end, abbrev_end;
1514 start = tcp->u_arg[1];
1519 size = len * sizeof(gid);
1521 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1522 size / sizeof(gid) != len || end < start) {
1523 tprintf("%#lx", start);
1527 abbrev_end = start + max_strlen * sizeof(gid);
1528 if (abbrev_end < start)
1534 for (cur = start; cur < end; cur += sizeof(gid)) {
1537 if (cur >= abbrev_end) {
1541 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1546 tprintf("%lu", (unsigned long) gid);
1550 tprintf(" %#lx", tcp->u_arg[1]);
1556 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1561 if (entering(tcp)) {
1563 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1568 #endif /* ALPHA || SUNOS4 || SVR4 */
1574 if (entering(tcp)) {
1576 tprintf("%lu", tcp->u_arg[0]);
1586 if (entering(tcp)) {
1587 tprintf("%lu", tcp->u_arg[0]);
1603 if (entering(tcp)) {
1604 tprintf("%lu", tcp->u_arg[0]);
1613 if (entering(tcp)) {
1614 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1621 #include <sys/privilege.h>
1624 static const struct xlat procpriv_cmds [] = {
1625 { SETPRV, "SETPRV" },
1626 { CLRPRV, "CLRPRV" },
1627 { PUTPRV, "PUTPRV" },
1628 { GETPRV, "GETPRV" },
1629 { CNTPRV, "CNTPRV" },
1634 static const struct xlat procpriv_priv [] = {
1635 { P_OWNER, "P_OWNER" },
1636 { P_AUDIT, "P_AUDIT" },
1637 { P_COMPAT, "P_COMPAT" },
1638 { P_DACREAD, "P_DACREAD" },
1639 { P_DACWRITE, "P_DACWRITE" },
1641 { P_FILESYS, "P_FILESYS" },
1642 { P_MACREAD, "P_MACREAD" },
1643 { P_MACWRITE, "P_MACWRITE" },
1644 { P_MOUNT, "P_MOUNT" },
1645 { P_MULTIDIR, "P_MULTIDIR" },
1646 { P_SETPLEVEL, "P_SETPLEVEL" },
1647 { P_SETSPRIV, "P_SETSPRIV" },
1648 { P_SETUID, "P_SETUID" },
1649 { P_SYSOPS, "P_SYSOPS" },
1650 { P_SETUPRIV, "P_SETUPRIV" },
1651 { P_DRIVER, "P_DRIVER" },
1652 { P_RTIME, "P_RTIME" },
1653 { P_MACUPGRADE, "P_MACUPGRADE" },
1654 { P_FSYSRANGE, "P_FSYSRANGE" },
1655 { P_SETFLEVEL, "P_SETFLEVEL" },
1656 { P_AUDITWR, "P_AUDITWR" },
1657 { P_TSHAR, "P_TSHAR" },
1658 { P_PLOCK, "P_PLOCK" },
1659 { P_CORE, "P_CORE" },
1660 { P_LOADMOD, "P_LOADMOD" },
1661 { P_BIND, "P_BIND" },
1662 { P_ALLPRIVS, "P_ALLPRIVS" },
1667 static const struct xlat procpriv_type [] = {
1668 { PS_FIX, "PS_FIX" },
1669 { PS_INH, "PS_INH" },
1670 { PS_MAX, "PS_MAX" },
1671 { PS_WKG, "PS_WKG" },
1677 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1680 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1681 int dots = len > max;
1684 if (len > max) len = max;
1687 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1689 tprintf ("%#lx", addr);
1695 for (i = 0; i < len; ++i) {
1698 if (i) tprintf (", ");
1700 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1701 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1703 tprintf ("%s|%s", t, p);
1706 tprintf ("%#lx", buf [i]);
1710 if (dots) tprintf (" ...");
1720 if (entering(tcp)) {
1721 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1722 switch (tcp->u_arg[0]) {
1724 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1732 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1733 tprintf (", %ld", tcp->u_arg[2]);
1736 else if (tcp->u_arg[0] == GETPRV) {
1737 if (syserror (tcp)) {
1738 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1742 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1743 tprintf (", %ld", tcp->u_arg[2]);
1754 printargv(tcp, addr)
1761 char data[sizeof(long)];
1767 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1768 if (umoven(tcp, addr, personality_wordsize[current_personality],
1770 tprintf("%#lx", addr);
1773 if (personality_wordsize[current_personality] == 4)
1778 printstr(tcp, cp.p64, -1);
1779 addr += personality_wordsize[current_personality];
1782 tprintf("%s...", sep);
1786 printargc(fmt, tcp, addr)
1794 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1795 addr += sizeof(char *);
1797 tprintf(fmt, count, count == 1 ? "" : "s");
1800 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1805 if (entering(tcp)) {
1806 printpath(tcp, tcp->u_arg[0]);
1808 tprintf(", %#lx", tcp->u_arg[1]);
1810 else if (abbrev(tcp))
1811 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1815 printargv(tcp, tcp->u_arg[1]);
1821 #endif /* SPARC || SPARC64 || SUNOS4 */
1827 if (entering(tcp)) {
1828 printpath(tcp, tcp->u_arg[0]);
1830 tprintf(", %#lx", tcp->u_arg[1]);
1832 else if (abbrev(tcp))
1833 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1837 printargv(tcp, tcp->u_arg[1]);
1841 tprintf(", %#lx", tcp->u_arg[2]);
1842 else if (abbrev(tcp))
1843 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1846 printargv(tcp, tcp->u_arg[2]);
1855 int sys_rexecve(tcp)
1858 if (entering (tcp)) {
1860 tprintf (", %ld", tcp->u_arg[3]);
1872 if (exiting(tcp) && !syserror(tcp) && followfork)
1875 #if defined LINUX && defined TCB_WAITEXECVE
1876 if (exiting(tcp) && syserror(tcp))
1877 tcp->flags &= ~TCB_WAITEXECVE;
1879 tcp->flags |= TCB_WAITEXECVE;
1880 #endif /* LINUX && TCB_WAITEXECVE */
1886 #define __WNOTHREAD 0x20000000
1889 #define __WALL 0x40000000
1892 #define __WCLONE 0x80000000
1896 static const struct xlat wait4_options[] = {
1897 { WNOHANG, "WNOHANG" },
1899 { WUNTRACED, "WUNTRACED" },
1902 { WEXITED, "WEXITED" },
1905 { WTRAPPED, "WTRAPPED" },
1908 { WSTOPPED, "WSTOPPED" },
1911 { WCONTINUED, "WCONTINUED" },
1914 { WNOWAIT, "WNOWAIT" },
1917 { __WCLONE, "__WCLONE" },
1920 { __WALL, "__WALL" },
1923 { __WNOTHREAD, "__WNOTHREAD" },
1928 #if !defined WCOREFLAG && defined WCOREFLG
1929 # define WCOREFLAG WCOREFLG
1932 #define WCOREFLAG 0x80
1936 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1939 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1949 * Here is a tricky presentation problem. This solution
1950 * is still not entirely satisfactory but since there
1951 * are no wait status constructors it will have to do.
1953 if (WIFSTOPPED(status)) {
1954 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1955 signame(WSTOPSIG(status)));
1956 status &= ~W_STOPCODE(WSTOPSIG(status));
1958 else if (WIFSIGNALED(status)) {
1959 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1960 signame(WTERMSIG(status)),
1961 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1962 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1964 else if (WIFEXITED(status)) {
1965 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1966 WEXITSTATUS(status));
1968 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1971 tprintf("[%#x]", status);
1978 tprintf(" | %#x]", status);
1984 printwaitn(tcp, n, bitness)
1992 if (entering(tcp)) {
1994 * Sign-extend a 32-bit value when that's what it is.
1996 long pid = tcp->u_arg[0];
1997 if (personality_wordsize[current_personality] < sizeof pid)
1998 pid = (long) (int) pid;
1999 tprintf("%ld, ", pid);
2004 else if (syserror(tcp) || tcp->u_rval == 0)
2005 tprintf("%#lx", tcp->u_arg[1]);
2006 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2009 exited = printstatus(status);
2012 printflags(wait4_options, tcp->u_arg[2], "W???");
2019 else if (tcp->u_rval > 0) {
2022 printrusage32(tcp, tcp->u_arg[3]);
2025 printrusage(tcp, tcp->u_arg[3]);
2029 else if (tcp->u_rval > 0 && exited)
2030 printrusage(tcp, tcp->u_arg[3]);
2033 tprintf("%#lx", tcp->u_arg[3]);
2040 internal_wait(tcp, flagarg)
2046 #ifdef TCB_CLONE_THREAD
2047 if (tcp->flags & TCB_CLONE_THREAD)
2048 /* The children we wait for are our parent's children. */
2049 got_kids = (tcp->parent->nchildren
2050 > tcp->parent->nclone_detached);
2052 got_kids = (tcp->nchildren > tcp->nclone_detached);
2054 got_kids = tcp->nchildren > 0;
2057 if (entering(tcp) && got_kids) {
2058 /* There are children that this parent should block for.
2059 But ptrace made us the parent of the traced children
2060 and the real parent will get ECHILD from the wait call.
2062 XXX If we attached with strace -f -p PID, then there
2063 may be untraced dead children the parent could be reaping
2064 now, but we make him block. */
2066 /* ??? WTA: fix bug with hanging children */
2068 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
2070 * There are traced children. We'll make the parent
2071 * block to avoid a false ECHILD error due to our
2072 * ptrace having stolen the children. However,
2073 * we shouldn't block if there are zombies to reap.
2074 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2076 struct tcb *child = NULL;
2077 if (tcp->nzombies > 0 &&
2078 (tcp->u_arg[0] == -1 ||
2079 (child = pid2tcb(tcp->u_arg[0])) == NULL))
2081 if (tcp->u_arg[0] > 0) {
2083 * If the parent waits for a specified child
2084 * PID, then it must get ECHILD right away
2085 * if that PID is not one of its children.
2086 * Make sure that the requested PID matches
2087 * one of the parent's children that we are
2088 * tracing, and don't suspend it otherwise.
2091 child = pid2tcb(tcp->u_arg[0]);
2092 if (child == NULL || child->parent != (
2093 #ifdef TCB_CLONE_THREAD
2094 (tcp->flags & TCB_CLONE_THREAD)
2098 (child->flags & TCB_EXITING))
2101 tcp->flags |= TCB_SUSPENDED;
2102 tcp->waitpid = tcp->u_arg[0];
2103 #ifdef TCB_CLONE_THREAD
2104 if (tcp->flags & TCB_CLONE_THREAD)
2105 tcp->parent->nclone_waiting++;
2109 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2110 if (tcp->u_arg[flagarg] & WNOHANG) {
2111 /* We must force a fake result of 0 instead of
2112 the ECHILD error. */
2113 extern int force_result();
2114 return force_result(tcp, 0, 0);
2117 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2118 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2120 * We just reaped a child we don't know about,
2121 * presumably a zombie we already droptcb'd.
2135 /* The library wrapper stuffs this into the user variable. */
2137 printstatus(getrval2(tcp));
2152 if (!syserror(tcp)) {
2153 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2154 tprintf("%#lx", tcp->u_arg[0]);
2156 printstatus(status);
2167 return printwaitn(tcp, 3, 0);
2174 return printwaitn(tcp, 4, 0);
2182 return printwaitn(tcp, 4, 1);
2186 #if defined SVR4 || defined LINUX
2188 static const struct xlat waitid_types[] = {
2191 { P_PPID, "P_PPID" },
2193 { P_PGID, "P_PGID" },
2208 { P_LWPID, "P_LWPID" },
2220 if (entering(tcp)) {
2221 printxval(waitid_types, tcp->u_arg[0], "P_???");
2222 tprintf(", %ld, ", tcp->u_arg[1]);
2229 else if (syserror(tcp))
2230 tprintf("%#lx", tcp->u_arg[2]);
2231 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2234 printsiginfo(&si, verbose (tcp));
2237 printflags(wait4_options, tcp->u_arg[3], "W???");
2238 if (tcp->u_nargs > 4) {
2243 else if (tcp->u_error)
2244 tprintf("%#lx", tcp->u_arg[4]);
2246 printrusage(tcp, tcp->u_arg[4]);
2252 #endif /* SVR4 or LINUX */
2259 tprintf("%lu", tcp->u_arg[0]);
2267 struct utsname uname;
2270 if (syserror(tcp) || !verbose(tcp))
2271 tprintf("%#lx", tcp->u_arg[0]);
2272 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2274 else if (!abbrev(tcp)) {
2276 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2277 uname.sysname, uname.nodename);
2278 tprintf("release=\"%s\", version=\"%s\", ",
2279 uname.release, uname.version);
2280 tprintf("machine=\"%s\"", uname.machine);
2283 tprintf(", domainname=\"%s\"", uname.domainname);
2284 #endif /* __GLIBC__ */
2289 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2290 uname.sysname, uname.nodename);
2297 static const struct xlat ptrace_cmds[] = {
2299 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2300 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2301 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2302 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2303 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2304 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2305 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2306 { PTRACE_CONT, "PTRACE_CONT" },
2307 { PTRACE_KILL, "PTRACE_KILL" },
2308 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2309 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2310 { PTRACE_DETACH, "PTRACE_DETACH" },
2311 #ifdef PTRACE_GETREGS
2312 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2314 #ifdef PTRACE_SETREGS
2315 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2317 #ifdef PTRACE_GETFPREGS
2318 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2320 #ifdef PTRACE_SETFPREGS
2321 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2323 #ifdef PTRACE_GETFPXREGS
2324 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2326 #ifdef PTRACE_SETFPXREGS
2327 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2329 #ifdef PTRACE_GETVRREGS
2330 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2332 #ifdef PTRACE_SETVRREGS
2333 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2336 { PTRACE_READDATA, "PTRACE_READDATA" },
2337 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2338 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2339 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2340 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2341 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2343 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2344 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2346 { PTRACE_22, "PTRACE_PTRACE_22" },
2347 { PTRACE_23, "PTRACE_PTRACE_23" },
2350 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2352 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2354 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2355 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2356 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2358 { PTRACE_26, "PTRACE_26" },
2359 { PTRACE_27, "PTRACE_27" },
2360 { PTRACE_28, "PTRACE_28" },
2362 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2365 { PT_TRACE_ME, "PT_TRACE_ME" },
2366 { PT_READ_I, "PT_READ_I" },
2367 { PT_READ_D, "PT_READ_D" },
2368 { PT_WRITE_I, "PT_WRITE_I" },
2369 { PT_WRITE_D, "PT_WRITE_D" },
2371 { PT_READ_U, "PT_READ_U" },
2373 { PT_CONTINUE, "PT_CONTINUE" },
2374 { PT_KILL, "PT_KILL" },
2375 { PT_STEP, "PT_STEP" },
2376 { PT_ATTACH, "PT_ATTACH" },
2377 { PT_DETACH, "PT_DETACH" },
2378 { PT_GETREGS, "PT_GETREGS" },
2379 { PT_SETREGS, "PT_SETREGS" },
2380 { PT_GETFPREGS, "PT_GETFPREGS" },
2381 { PT_SETFPREGS, "PT_SETFPREGS" },
2382 { PT_GETDBREGS, "PT_GETDBREGS" },
2383 { PT_SETDBREGS, "PT_SETDBREGS" },
2384 #endif /* FREEBSD */
2389 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2391 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2392 const struct xlat struct_user_offsets[] = {
2394 #if defined(S390) || defined(S390X)
2395 { PT_PSWMASK, "psw_mask" },
2396 { PT_PSWADDR, "psw_addr" },
2397 { PT_GPR0, "gpr0" },
2398 { PT_GPR1, "gpr1" },
2399 { PT_GPR2, "gpr2" },
2400 { PT_GPR3, "gpr3" },
2401 { PT_GPR4, "gpr4" },
2402 { PT_GPR5, "gpr5" },
2403 { PT_GPR6, "gpr6" },
2404 { PT_GPR7, "gpr7" },
2405 { PT_GPR8, "gpr8" },
2406 { PT_GPR9, "gpr9" },
2407 { PT_GPR10, "gpr10" },
2408 { PT_GPR11, "gpr11" },
2409 { PT_GPR12, "gpr12" },
2410 { PT_GPR13, "gpr13" },
2411 { PT_GPR14, "gpr14" },
2412 { PT_GPR15, "gpr15" },
2413 { PT_ACR0, "acr0" },
2414 { PT_ACR1, "acr1" },
2415 { PT_ACR2, "acr2" },
2416 { PT_ACR3, "acr3" },
2417 { PT_ACR4, "acr4" },
2418 { PT_ACR5, "acr5" },
2419 { PT_ACR6, "acr6" },
2420 { PT_ACR7, "acr7" },
2421 { PT_ACR8, "acr8" },
2422 { PT_ACR9, "acr9" },
2423 { PT_ACR10, "acr10" },
2424 { PT_ACR11, "acr11" },
2425 { PT_ACR12, "acr12" },
2426 { PT_ACR13, "acr13" },
2427 { PT_ACR14, "acr14" },
2428 { PT_ACR15, "acr15" },
2429 { PT_ORIGGPR2, "orig_gpr2" },
2432 { PT_FPR0_HI, "fpr0.hi" },
2433 { PT_FPR0_LO, "fpr0.lo" },
2434 { PT_FPR1_HI, "fpr1.hi" },
2435 { PT_FPR1_LO, "fpr1.lo" },
2436 { PT_FPR2_HI, "fpr2.hi" },
2437 { PT_FPR2_LO, "fpr2.lo" },
2438 { PT_FPR3_HI, "fpr3.hi" },
2439 { PT_FPR3_LO, "fpr3.lo" },
2440 { PT_FPR4_HI, "fpr4.hi" },
2441 { PT_FPR4_LO, "fpr4.lo" },
2442 { PT_FPR5_HI, "fpr5.hi" },
2443 { PT_FPR5_LO, "fpr5.lo" },
2444 { PT_FPR6_HI, "fpr6.hi" },
2445 { PT_FPR6_LO, "fpr6.lo" },
2446 { PT_FPR7_HI, "fpr7.hi" },
2447 { PT_FPR7_LO, "fpr7.lo" },
2448 { PT_FPR8_HI, "fpr8.hi" },
2449 { PT_FPR8_LO, "fpr8.lo" },
2450 { PT_FPR9_HI, "fpr9.hi" },
2451 { PT_FPR9_LO, "fpr9.lo" },
2452 { PT_FPR10_HI, "fpr10.hi" },
2453 { PT_FPR10_LO, "fpr10.lo" },
2454 { PT_FPR11_HI, "fpr11.hi" },
2455 { PT_FPR11_LO, "fpr11.lo" },
2456 { PT_FPR12_HI, "fpr12.hi" },
2457 { PT_FPR12_LO, "fpr12.lo" },
2458 { PT_FPR13_HI, "fpr13.hi" },
2459 { PT_FPR13_LO, "fpr13.lo" },
2460 { PT_FPR14_HI, "fpr14.hi" },
2461 { PT_FPR14_LO, "fpr14.lo" },
2462 { PT_FPR15_HI, "fpr15.hi" },
2463 { PT_FPR15_LO, "fpr15.lo" },
2466 { PT_FPR0, "fpr0" },
2467 { PT_FPR1, "fpr1" },
2468 { PT_FPR2, "fpr2" },
2469 { PT_FPR3, "fpr3" },
2470 { PT_FPR4, "fpr4" },
2471 { PT_FPR5, "fpr5" },
2472 { PT_FPR6, "fpr6" },
2473 { PT_FPR7, "fpr7" },
2474 { PT_FPR8, "fpr8" },
2475 { PT_FPR9, "fpr9" },
2476 { PT_FPR10, "fpr10" },
2477 { PT_FPR11, "fpr11" },
2478 { PT_FPR12, "fpr12" },
2479 { PT_FPR13, "fpr13" },
2480 { PT_FPR14, "fpr14" },
2481 { PT_FPR15, "fpr15" },
2484 { PT_CR_10, "cr10" },
2485 { PT_CR_11, "cr11" },
2486 { PT_IEEE_IP, "ieee_exception_ip" },
2489 /* XXX No support for these offsets yet. */
2491 /* XXX No support for these offsets yet. */
2492 #elif defined(POWERPC)
2494 #define PT_ORIG_R3 34
2496 #define REGSIZE (sizeof(unsigned long))
2497 { REGSIZE*PT_R0, "r0" },
2498 { REGSIZE*PT_R1, "r1" },
2499 { REGSIZE*PT_R2, "r2" },
2500 { REGSIZE*PT_R3, "r3" },
2501 { REGSIZE*PT_R4, "r4" },
2502 { REGSIZE*PT_R5, "r5" },
2503 { REGSIZE*PT_R6, "r6" },
2504 { REGSIZE*PT_R7, "r7" },
2505 { REGSIZE*PT_R8, "r8" },
2506 { REGSIZE*PT_R9, "r9" },
2507 { REGSIZE*PT_R10, "r10" },
2508 { REGSIZE*PT_R11, "r11" },
2509 { REGSIZE*PT_R12, "r12" },
2510 { REGSIZE*PT_R13, "r13" },
2511 { REGSIZE*PT_R14, "r14" },
2512 { REGSIZE*PT_R15, "r15" },
2513 { REGSIZE*PT_R16, "r16" },
2514 { REGSIZE*PT_R17, "r17" },
2515 { REGSIZE*PT_R18, "r18" },
2516 { REGSIZE*PT_R19, "r19" },
2517 { REGSIZE*PT_R20, "r20" },
2518 { REGSIZE*PT_R21, "r21" },
2519 { REGSIZE*PT_R22, "r22" },
2520 { REGSIZE*PT_R23, "r23" },
2521 { REGSIZE*PT_R24, "r24" },
2522 { REGSIZE*PT_R25, "r25" },
2523 { REGSIZE*PT_R26, "r26" },
2524 { REGSIZE*PT_R27, "r27" },
2525 { REGSIZE*PT_R28, "r28" },
2526 { REGSIZE*PT_R29, "r29" },
2527 { REGSIZE*PT_R30, "r30" },
2528 { REGSIZE*PT_R31, "r31" },
2529 { REGSIZE*PT_NIP, "NIP" },
2530 { REGSIZE*PT_MSR, "MSR" },
2531 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2532 { REGSIZE*PT_CTR, "CTR" },
2533 { REGSIZE*PT_LNK, "LNK" },
2534 { REGSIZE*PT_XER, "XER" },
2535 { REGSIZE*PT_CCR, "CCR" },
2536 { REGSIZE*PT_FPR0, "FPR0" },
2607 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2608 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2609 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2610 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2611 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2612 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2613 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2614 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2615 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2616 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2617 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2618 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2619 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2620 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2621 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2622 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2623 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2624 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2625 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2626 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2627 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2628 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2629 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2630 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2631 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2632 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2633 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2634 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2635 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2636 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2637 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2638 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2640 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2641 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2642 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2643 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2644 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2645 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2646 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2647 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2648 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2649 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2650 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2651 { PT_B4, "b4" }, { PT_B5, "b5" },
2652 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2654 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2655 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2656 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2657 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2658 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2659 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2660 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2661 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2662 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2663 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2664 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2665 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2666 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2667 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2668 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2669 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2670 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2672 { PT_AR_CSD, "ar.csd" },
2675 { PT_AR_SSD, "ar.ssd" },
2677 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2691 { 4*ORIG_EAX, "4*ORIG_EAX" },
2695 { 4*UESP, "4*UESP" },
2720 { 8*ORIG_RAX, "8*ORIG_RAX" },
2723 { 8*EFLAGS, "8*EFL" },
2728 { 4*PT_D1, "4*PT_D1" },
2729 { 4*PT_D2, "4*PT_D2" },
2730 { 4*PT_D3, "4*PT_D3" },
2731 { 4*PT_D4, "4*PT_D4" },
2732 { 4*PT_D5, "4*PT_D5" },
2733 { 4*PT_D6, "4*PT_D6" },
2734 { 4*PT_D7, "4*PT_D7" },
2735 { 4*PT_A0, "4*PT_A0" },
2736 { 4*PT_A1, "4*PT_A1" },
2737 { 4*PT_A2, "4*PT_A2" },
2738 { 4*PT_A3, "4*PT_A3" },
2739 { 4*PT_A4, "4*PT_A4" },
2740 { 4*PT_A5, "4*PT_A5" },
2741 { 4*PT_A6, "4*PT_A6" },
2742 { 4*PT_D0, "4*PT_D0" },
2743 { 4*PT_USP, "4*PT_USP" },
2744 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2745 { 4*PT_SR, "4*PT_SR" },
2746 { 4*PT_PC, "4*PT_PC" },
2750 { 4*REG_REG0, "4*REG_REG0" },
2751 { 4*(REG_REG0+1), "4*REG_REG1" },
2752 { 4*(REG_REG0+2), "4*REG_REG2" },
2753 { 4*(REG_REG0+3), "4*REG_REG3" },
2754 { 4*(REG_REG0+4), "4*REG_REG4" },
2755 { 4*(REG_REG0+5), "4*REG_REG5" },
2756 { 4*(REG_REG0+6), "4*REG_REG6" },
2757 { 4*(REG_REG0+7), "4*REG_REG7" },
2758 { 4*(REG_REG0+8), "4*REG_REG8" },
2759 { 4*(REG_REG0+9), "4*REG_REG9" },
2760 { 4*(REG_REG0+10), "4*REG_REG10" },
2761 { 4*(REG_REG0+11), "4*REG_REG11" },
2762 { 4*(REG_REG0+12), "4*REG_REG12" },
2763 { 4*(REG_REG0+13), "4*REG_REG13" },
2764 { 4*(REG_REG0+14), "4*REG_REG14" },
2765 { 4*REG_REG15, "4*REG_REG15" },
2766 { 4*REG_PC, "4*REG_PC" },
2767 { 4*REG_PR, "4*REG_PR" },
2768 { 4*REG_SR, "4*REG_SR" },
2769 { 4*REG_GBR, "4*REG_GBR" },
2770 { 4*REG_MACH, "4*REG_MACH" },
2771 { 4*REG_MACL, "4*REG_MACL" },
2772 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2773 { 4*REG_FPUL, "4*REG_FPUL" },
2774 { 4*REG_FPREG0, "4*REG_FPREG0" },
2775 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2776 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2777 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2778 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2779 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2780 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2781 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2782 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2783 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2784 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2785 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2786 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2787 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2788 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2789 { 4*REG_FPREG15, "4*REG_FPREG15" },
2791 { 4*REG_XDREG0, "4*REG_XDREG0" },
2792 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2793 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2794 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2795 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2796 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2797 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2798 { 4*REG_XDREG14, "4*REG_XDREG14" },
2800 { 4*REG_FPSCR, "4*REG_FPSCR" },
2807 { 16, "syscall no.(L)" },
2808 { 20, "syscall_no.(U)" },
2951 /* This entry is in case pt_regs contains dregs (depends on
2952 the kernel build options). */
2953 { uoff(regs), "offsetof(struct user, regs)" },
2954 { uoff(fpu), "offsetof(struct user, fpu)" },
2957 { uoff(regs.ARM_r0), "r0" },
2958 { uoff(regs.ARM_r1), "r1" },
2959 { uoff(regs.ARM_r2), "r2" },
2960 { uoff(regs.ARM_r3), "r3" },
2961 { uoff(regs.ARM_r4), "r4" },
2962 { uoff(regs.ARM_r5), "r5" },
2963 { uoff(regs.ARM_r6), "r6" },
2964 { uoff(regs.ARM_r7), "r7" },
2965 { uoff(regs.ARM_r8), "r8" },
2966 { uoff(regs.ARM_r9), "r9" },
2967 { uoff(regs.ARM_r10), "r10" },
2968 { uoff(regs.ARM_fp), "fp" },
2969 { uoff(regs.ARM_ip), "ip" },
2970 { uoff(regs.ARM_sp), "sp" },
2971 { uoff(regs.ARM_lr), "lr" },
2972 { uoff(regs.ARM_pc), "pc" },
2973 { uoff(regs.ARM_cpsr), "cpsr" },
3050 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
3051 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3053 #if defined(I386) || defined(X86_64)
3054 { uoff(i387), "offsetof(struct user, i387)" },
3057 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3060 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3061 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3062 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3063 #if !defined(SPARC64)
3064 { uoff(start_code), "offsetof(struct user, start_code)" },
3067 { uoff(start_data), "offsetof(struct user, start_data)" },
3069 #if !defined(SPARC64)
3070 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3072 { uoff(signal), "offsetof(struct user, signal)" },
3073 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
3074 { uoff(reserved), "offsetof(struct user, reserved)" },
3076 #if !defined(SPARC64)
3077 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3079 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
3080 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3082 { uoff(magic), "offsetof(struct user, magic)" },
3083 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3084 #if defined(I386) || defined(X86_64)
3085 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3089 #endif /* !POWERPC/!SPARC */
3092 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3093 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3094 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3095 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3096 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3097 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3098 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3099 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3100 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3101 { uoff(u_error), "offsetof(struct user, u_error)" },
3102 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3103 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3104 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3105 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3106 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3107 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3108 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3109 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3110 { uoff(u_code), "offsetof(struct user, u_code)" },
3111 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3112 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3113 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3114 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3115 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3116 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3117 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3118 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3119 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3120 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3121 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3122 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3123 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3124 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3125 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3126 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3127 { uoff(u_start), "offsetof(struct user, u_start)" },
3128 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3129 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3130 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3131 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3132 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3133 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3134 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3135 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3136 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3139 { sizeof(struct user), "sizeof(struct user)" },
3149 const struct xlat *x;
3152 if (entering(tcp)) {
3153 printxval(ptrace_cmds, tcp->u_arg[0],
3160 tprintf(", %lu, ", tcp->u_arg[1]);
3161 addr = tcp->u_arg[2];
3163 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3164 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3165 for (x = struct_user_offsets; x->str; x++) {
3170 tprintf("%#lx, ", addr);
3171 else if (x->val > addr && x != struct_user_offsets) {
3173 tprintf("%s + %ld, ", x->str, addr - x->val);
3176 tprintf("%s, ", x->str);
3180 tprintf("%#lx, ", tcp->u_arg[2]);
3182 switch (tcp->u_arg[0]) {
3184 case PTRACE_PEEKDATA:
3185 case PTRACE_PEEKTEXT:
3186 case PTRACE_PEEKUSER:
3190 case PTRACE_SINGLESTEP:
3191 case PTRACE_SYSCALL:
3193 printsignal(tcp->u_arg[3]);
3196 tprintf("%#lx", tcp->u_arg[3]);
3200 switch (tcp->u_arg[0]) {
3201 case PTRACE_PEEKDATA:
3202 case PTRACE_PEEKTEXT:
3203 case PTRACE_PEEKUSER:
3207 printnum(tcp, tcp->u_arg[3], "%#lx");
3214 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3215 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3216 tprintf("%lu, ", tcp->u_arg[3]);
3217 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3218 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3219 tcp->u_arg[0] != PTRACE_READTEXT) {
3220 tprintf("%#lx", tcp->u_arg[3]);
3223 if (tcp->u_arg[0] == PTRACE_READDATA ||
3224 tcp->u_arg[0] == PTRACE_READTEXT) {
3225 tprintf("%lu, ", tcp->u_arg[3]);
3226 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3231 tprintf("%lu", tcp->u_arg[3]);
3233 #endif /* FREEBSD */
3240 # ifndef FUTEX_CMP_REQUEUE
3241 # define FUTEX_CMP_REQUEUE 4
3243 # ifndef FUTEX_WAKE_OP
3244 # define FUTEX_WAKE_OP 5
3246 # ifndef FUTEX_LOCK_PI
3247 # define FUTEX_LOCK_PI 6
3248 # define FUTEX_UNLOCK_PI 7
3249 # define FUTEX_TRYLOCK_PI 8
3251 # ifndef FUTEX_WAIT_BITSET
3252 # define FUTEX_WAIT_BITSET 9
3254 # ifndef FUTEX_WAKE_BITSET
3255 # define FUTEX_WAKE_BITSET 10
3257 # ifndef FUTEX_PRIVATE_FLAG
3258 # define FUTEX_PRIVATE_FLAG 128
3260 static const struct xlat futexops[] = {
3261 { FUTEX_WAIT, "FUTEX_WAIT" },
3262 { FUTEX_WAKE, "FUTEX_WAKE" },
3263 { FUTEX_FD, "FUTEX_FD" },
3264 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3265 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3266 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3267 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3268 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3269 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3270 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3271 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3272 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3273 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3274 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3275 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3276 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3277 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3278 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3279 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3280 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3281 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3282 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3285 #ifndef FUTEX_OP_SET
3286 # define FUTEX_OP_SET 0
3287 # define FUTEX_OP_ADD 1
3288 # define FUTEX_OP_OR 2
3289 # define FUTEX_OP_ANDN 3
3290 # define FUTEX_OP_XOR 4
3291 # define FUTEX_OP_CMP_EQ 0
3292 # define FUTEX_OP_CMP_NE 1
3293 # define FUTEX_OP_CMP_LT 2
3294 # define FUTEX_OP_CMP_LE 3
3295 # define FUTEX_OP_CMP_GT 4
3296 # define FUTEX_OP_CMP_GE 5
3298 static const struct xlat futexwakeops[] = {
3299 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3300 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3301 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3302 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3303 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3306 static const struct xlat futexwakecmps[] = {
3307 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3308 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3309 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3310 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3311 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3312 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3320 if (entering(tcp)) {
3321 long int cmd = tcp->u_arg[1] & 127;
3322 tprintf("%p, ", (void *) tcp->u_arg[0]);
3323 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3324 tprintf(", %ld", tcp->u_arg[2]);
3325 if (cmd == FUTEX_WAKE_BITSET)
3326 tprintf(", %lx", tcp->u_arg[5]);
3327 else if (cmd == FUTEX_WAIT) {
3329 printtv(tcp, tcp->u_arg[3]);
3330 } else if (cmd == FUTEX_WAIT_BITSET) {
3332 printtv(tcp, tcp->u_arg[3]);
3333 tprintf(", %lx", tcp->u_arg[5]);
3334 } else if (cmd == FUTEX_REQUEUE)
3335 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3336 else if (cmd == FUTEX_CMP_REQUEUE)
3337 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3338 else if (cmd == FUTEX_WAKE_OP) {
3339 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3340 if ((tcp->u_arg[5] >> 28) & 8)
3341 tprintf("FUTEX_OP_OPARG_SHIFT|");
3342 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3343 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3344 if ((tcp->u_arg[5] >> 24) & 8)
3345 tprintf("FUTEX_OP_OPARG_SHIFT|");
3346 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3347 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3354 print_affinitylist(tcp, list, len)
3361 while (len >= sizeof (unsigned long)) {
3363 umove(tcp, list, &w);
3364 tprintf("%s %lx", first ? "" : ",", w);
3366 len -= sizeof (unsigned long);
3367 list += sizeof(unsigned long);
3373 sys_sched_setaffinity(tcp)
3376 if (entering(tcp)) {
3377 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3378 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3384 sys_sched_getaffinity(tcp)
3387 if (entering(tcp)) {
3388 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3390 if (tcp->u_rval == -1)
3391 tprintf("%#lx", tcp->u_arg[2]);
3393 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3398 static const struct xlat schedulers[] = {
3399 { SCHED_OTHER, "SCHED_OTHER" },
3400 { SCHED_RR, "SCHED_RR" },
3401 { SCHED_FIFO, "SCHED_FIFO" },
3406 sys_sched_getscheduler(tcp)
3409 if (entering(tcp)) {
3410 tprintf("%d", (int) tcp->u_arg[0]);
3411 } else if (! syserror(tcp)) {
3412 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3413 if (tcp->auxstr != NULL)
3420 sys_sched_setscheduler(tcp)
3423 if (entering(tcp)) {
3424 struct sched_param p;
3425 tprintf("%d, ", (int) tcp->u_arg[0]);
3426 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3427 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3428 tprintf(", %#lx", tcp->u_arg[2]);
3430 tprintf(", { %d }", p.__sched_priority);
3436 sys_sched_getparam(tcp)
3439 if (entering(tcp)) {
3440 tprintf("%d, ", (int) tcp->u_arg[0]);
3442 struct sched_param p;
3443 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3444 tprintf("%#lx", tcp->u_arg[1]);
3446 tprintf("{ %d }", p.__sched_priority);
3452 sys_sched_setparam(tcp)
3455 if (entering(tcp)) {
3456 struct sched_param p;
3457 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3458 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3460 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3466 sys_sched_get_priority_min(tcp)
3469 if (entering(tcp)) {
3470 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3476 #include <asm/prctl.h>
3478 static const struct xlat archvals[] = {
3479 { ARCH_SET_GS, "ARCH_SET_GS" },
3480 { ARCH_SET_FS, "ARCH_SET_FS" },
3481 { ARCH_GET_FS, "ARCH_GET_FS" },
3482 { ARCH_GET_GS, "ARCH_GET_GS" },
3490 if (entering(tcp)) {
3491 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3492 if (tcp->u_arg[0] == ARCH_SET_GS
3493 || tcp->u_arg[0] == ARCH_SET_FS)
3494 tprintf(", %#lx", tcp->u_arg[1]);
3496 if (tcp->u_arg[0] == ARCH_GET_GS
3497 || tcp->u_arg[0] == ARCH_GET_FS) {
3499 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3500 tprintf(", [%#lx]", v);
3502 tprintf(", %#lx", tcp->u_arg[1]);
3516 if (tcp->u_arg[0] == 0)
3518 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3519 tprintf("%#lx, ", tcp->u_arg[0]);
3521 tprintf("[%u], ", u);
3522 if (tcp->u_arg[1] == 0)
3524 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3525 tprintf("%#lx, ", tcp->u_arg[1]);
3527 tprintf("[%u], ", u);
3528 tprintf("%#lx", tcp->u_arg[2]);