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;
490 sys_fork(struct tcb *tcp)
492 if (exiting(tcp) && !syserror(tcp)) {
494 tcp->auxstr = "child process";
495 return RVAL_UDECIMAL | RVAL_STR;
508 tprintf ("%ld", tcp->u_arg[0]);
510 else if (!syserror(tcp)) {
512 tcp->auxstr = "child process";
513 return RVAL_UDECIMAL | RVAL_STR;
525 struct tcb *tcpchild;
529 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
538 tcpchild = alloctcb(tcp->u_rval);
539 if (proc_open(tcpchild, 2) < 0)
545 #else /* !USE_PROCFS */
549 /* defines copied from linux/sched.h since we can't include that
550 * ourselves (it conflicts with *lots* of libc includes)
552 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
553 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
554 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
555 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
556 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
557 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
558 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
559 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
560 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
561 #define CLONE_THREAD 0x00010000 /* Same thread group? */
562 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
563 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
564 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
565 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
566 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
567 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
568 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
569 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
571 static const struct xlat clone_flags[] = {
572 { CLONE_VM, "CLONE_VM" },
573 { CLONE_FS, "CLONE_FS" },
574 { CLONE_FILES, "CLONE_FILES" },
575 { CLONE_SIGHAND, "CLONE_SIGHAND" },
576 { CLONE_IDLETASK, "CLONE_IDLETASK"},
577 { CLONE_PTRACE, "CLONE_PTRACE" },
578 { CLONE_VFORK, "CLONE_VFORK" },
579 { CLONE_PARENT, "CLONE_PARENT" },
580 { CLONE_THREAD, "CLONE_THREAD" },
581 { CLONE_NEWNS, "CLONE_NEWNS" },
582 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
583 { CLONE_SETTLS, "CLONE_SETTLS" },
584 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
585 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
586 { CLONE_DETACHED, "CLONE_DETACHED" },
587 { CLONE_UNTRACED, "CLONE_UNTRACED" },
588 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
593 # include <asm/ldt.h>
594 # ifdef HAVE_STRUCT_USER_DESC
595 # define modify_ldt_ldt_s user_desc
597 extern void print_ldt_entry();
603 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
604 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
605 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
606 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
607 # elif defined S390 || defined S390X
613 # elif defined X86_64 || defined ALPHA
632 unsigned long flags = tcp->u_arg[ARG_FLAGS];
633 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
634 # ifdef ARG_STACKSIZE
635 if (ARG_STACKSIZE != -1)
636 tprintf("stack_size=%#lx, ",
637 tcp->u_arg[ARG_STACKSIZE]);
640 printflags(clone_flags, flags &~ CSIGNAL, NULL);
641 if ((flags & CSIGNAL) != 0)
642 tprintf("|%s", signame(flags & CSIGNAL));
643 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
644 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
646 if (flags & CLONE_PARENT_SETTID)
647 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
648 if (flags & CLONE_SETTLS) {
650 struct modify_ldt_ldt_s copy;
651 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
652 tprintf(", {entry_number:%d, ",
657 print_ldt_entry(©);
661 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
663 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
664 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
670 sys_unshare(struct tcb *tcp)
673 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
683 return RVAL_UDECIMAL;
688 change_syscall(struct tcb *tcp, int new)
692 /* Attempt to make vfork into fork, which we can follow. */
693 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
696 #elif defined(X86_64)
697 /* Attempt to make vfork into fork, which we can follow. */
698 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
701 #elif defined(POWERPC)
702 if (ptrace(PTRACE_POKEUSER, tcp->pid,
703 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
706 #elif defined(S390) || defined(S390X)
707 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
708 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
712 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
715 #elif defined(SPARC) || defined(SPARC64)
717 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
720 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
724 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
728 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
732 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
739 break; /* x86 SYS_fork */
744 fprintf(stderr, "%s: unexpected syscall %d\n",
748 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
750 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
754 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
758 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
762 /* Top half of reg encodes the no. of args n as 0x1n.
763 Assume 0 args as kernel never actually checks... */
764 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
769 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
770 # ifndef PTRACE_SET_SYSCALL
771 # define PTRACE_SET_SYSCALL 23
774 if (do_ptrace(PTRACE_SET_SYSCALL, tcp, NULL, new) != 0)
779 #warning Do not know how to handle change_syscall for this architecture
780 #endif /* architecture */
793 unsigned long *bsp, *ap;
795 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
798 ap = ia64_rse_skip_regs(bsp, argnum);
800 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
807 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
811 #elif defined(X86_64)
813 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
817 #elif defined(POWERPC)
819 #define PT_ORIG_R3 34
822 ptrace(PTRACE_POKEUSER, tcp->pid,
823 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
832 ptrace(PTRACE_POKEUSER, tcp->pid,
833 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
837 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
840 ptrace(PTRACE_POKEDATA, tcp->pid,
841 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
846 #elif defined(S390) || defined(S390X)
849 ptrace(PTRACE_POKEUSER, tcp->pid,
850 (char *) (argnum==0 ? PT_ORIGGPR2 :
851 PT_GPR2 + argnum*sizeof(long)),
859 # warning Sorry, setargs not implemented for this architecture.
865 #if defined SYS_clone || defined SYS_clone2
867 internal_clone(struct tcb *tcp)
869 struct tcb *tcpchild;
878 bpt = tcp->flags & TCB_BPTSET;
887 /* Should not happen, but bugs often cause bogus value here. */
889 || (sizeof(pid) != sizeof(tcp->u_rval) && pid != tcp->u_rval)
893 fprintf(stderr, "bogus clone() return value %lx!\n", tcp->u_rval);
897 #ifdef CLONE_PTRACE /* See new setbpt code. */
898 tcpchild = pid2tcb(pid);
899 if (tcpchild != NULL) {
900 /* The child already reported its startup trap
901 before the parent reported its syscall return. */
903 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
904 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
906 [preattached child %d of %d in weird state!]\n",
912 tcpchild = alloctcb(pid);
916 /* Attach to the new child */
917 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
920 perror("PTRACE_ATTACH");
921 fprintf(stderr, "Too late?\n");
930 tcpchild->flags |= TCB_ATTACHED;
931 /* Child has BPT too, must be removed on first occasion. */
933 tcpchild->flags |= TCB_BPTSET;
934 tcpchild->baddr = tcp->baddr;
935 memcpy(tcpchild->inst, tcp->inst,
936 sizeof tcpchild->inst);
938 tcpchild->parent = tcp;
940 if (tcpchild->flags & TCB_SUSPENDED) {
941 /* The child was born suspended, due to our having
942 forced CLONE_PTRACE. */
946 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
947 /* TCB_SUSPENDED tasks are not collected by waitpid
948 * loop, and left stopped. Restart it:
950 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
955 Process %u resumed (parent %d ready)\n",
960 fprintf(stderr, "Process %d attached\n", pid);
963 #ifdef TCB_CLONE_THREAD
966 * Save the flags used in this call,
967 * in case we point TCP to our parent below.
969 int call_flags = tcp->u_arg[ARG_FLAGS];
970 if ((tcp->flags & TCB_CLONE_THREAD) &&
971 tcp->parent != NULL) {
972 /* The parent in this clone is itself a
973 thread belonging to another process.
974 There is no meaning to the parentage
975 relationship of the new child with the
976 thread, only with the process. We
977 associate the new thread with our
978 parent. Since this is done for every
979 new thread, there will never be a
980 TCB_CLONE_THREAD process that has
984 tcpchild->parent = tcp;
987 if (call_flags & CLONE_THREAD) {
988 tcpchild->flags |= TCB_CLONE_THREAD;
989 ++tcp->nclone_threads;
991 if (call_flags & CLONE_DETACHED) {
992 tcpchild->flags |= TCB_CLONE_DETACHED;
993 ++tcp->nclone_detached;
1007 /* We do special magic with clone for any clone or fork. */
1008 return internal_clone(tcp);
1011 struct tcb *tcpchild;
1016 if (known_scno(tcp) == SYS_vfork) {
1017 /* Attempt to make vfork into fork, which we can follow. */
1018 if (change_syscall(tcp, SYS_fork) < 0)
1022 if (!followfork || !follow)
1025 if (entering(tcp)) {
1026 if (setbpt(tcp) < 0)
1030 int bpt = tcp->flags & TCB_BPTSET;
1039 tcpchild = alloctcb(pid);
1042 /* The child must have run before it can be attached. */
1043 /* This must be a bug in the parisc kernel, but I havn't
1044 * identified it yet. Seems to be an issue associated
1045 * with attaching to a process (which sends it a signal)
1046 * before that process has ever been scheduled. When
1047 * debugging, I started seeing crashes in
1048 * arch/parisc/kernel/signal.c:do_signal(), apparently
1049 * caused by r8 getting corrupt over the dequeue_signal()
1050 * call. Didn't make much sense though...
1056 select(0, NULL, NULL, NULL, &tv);
1059 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1060 perror("PTRACE_ATTACH");
1061 fprintf(stderr, "Too late?\n");
1068 /* The child must have run before it can be attached. */
1073 select(0, NULL, NULL, NULL, &tv);
1075 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1076 perror("PTRACE_ATTACH");
1077 fprintf(stderr, "Too late?\n");
1082 /* Try to catch the new process as soon as possible. */
1085 for (i = 0; i < 1024; i++)
1086 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1089 perror("PTRACE_ATTACH");
1090 fprintf(stderr, "Too late?\n");
1095 #endif /* !oldway */
1097 tcpchild->flags |= TCB_ATTACHED;
1098 /* Child has BPT too, must be removed on first occasion */
1100 tcpchild->flags |= TCB_BPTSET;
1101 tcpchild->baddr = tcp->baddr;
1102 memcpy(tcpchild->inst, tcp->inst,
1103 sizeof tcpchild->inst);
1105 tcpchild->parent = tcp;
1108 fprintf(stderr, "Process %d attached\n", pid);
1114 #endif /* !USE_PROCFS */
1116 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1123 return RVAL_UDECIMAL;
1127 #endif /* SUNOS4 || LINUX || FREEBSD */
1131 static char idstr[16];
1138 sprintf(idstr, "ppid %lu", getrval2(tcp));
1139 tcp->auxstr = idstr;
1150 sprintf(idstr, "euid %lu", getrval2(tcp));
1151 tcp->auxstr = idstr;
1162 sprintf(idstr, "egid %lu", getrval2(tcp));
1163 tcp->auxstr = idstr;
1177 if (entering(tcp)) {
1178 tprintf("%u", (uid_t) tcp->u_arg[0]);
1187 if (entering(tcp)) {
1188 tprintf("%u", (gid_t) tcp->u_arg[0]);
1200 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1201 tcp->u_arg[1], tcp->u_arg[2]);
1203 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1204 tprintf("%#lx, ", tcp->u_arg[0]);
1206 tprintf("[%lu], ", (unsigned long) uid);
1207 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1208 tprintf("%#lx, ", tcp->u_arg[1]);
1210 tprintf("[%lu], ", (unsigned long) uid);
1211 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1212 tprintf("%#lx", tcp->u_arg[2]);
1214 tprintf("[%lu]", (unsigned long) uid);
1227 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1228 tcp->u_arg[1], tcp->u_arg[2]);
1230 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1231 tprintf("%#lx, ", tcp->u_arg[0]);
1233 tprintf("[%lu], ", (unsigned long) gid);
1234 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1235 tprintf("%#lx, ", tcp->u_arg[1]);
1237 tprintf("[%lu], ", (unsigned long) gid);
1238 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1239 tprintf("%#lx", tcp->u_arg[2]);
1241 tprintf("[%lu]", (unsigned long) gid);
1253 if (entering(tcp)) {
1254 printuid("", tcp->u_arg[0]);
1255 printuid(", ", tcp->u_arg[1]);
1264 if (entering(tcp)) {
1265 printuid("", tcp->u_arg[0]);
1266 printuid(", ", tcp->u_arg[1]);
1271 #if defined(LINUX) || defined(FREEBSD)
1276 if (entering(tcp)) {
1277 printuid("", tcp->u_arg[0]);
1278 printuid(", ", tcp->u_arg[1]);
1279 printuid(", ", tcp->u_arg[2]);
1287 if (entering(tcp)) {
1288 printuid("", tcp->u_arg[0]);
1289 printuid(", ", tcp->u_arg[1]);
1290 printuid(", ", tcp->u_arg[2]);
1295 #endif /* LINUX || FREEBSD */
1301 if (entering(tcp)) {
1302 unsigned long len, size, start, cur, end, abbrev_end;
1306 len = tcp->u_arg[0];
1307 tprintf("%lu, ", len);
1312 start = tcp->u_arg[1];
1317 size = len * sizeof(gid);
1319 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1320 tprintf("%#lx", start);
1324 abbrev_end = start + max_strlen * sizeof(gid);
1325 if (abbrev_end < start)
1331 for (cur = start; cur < end; cur += sizeof(gid)) {
1334 if (cur >= abbrev_end) {
1338 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1343 tprintf("%lu", (unsigned long) gid);
1347 tprintf(" %#lx", tcp->u_arg[1]);
1358 if (entering(tcp)) {
1359 len = tcp->u_arg[0];
1360 tprintf("%lu, ", len);
1362 unsigned long size, start, cur, end, abbrev_end;
1371 start = tcp->u_arg[1];
1376 if (tcp->u_arg[0] == 0) {
1377 tprintf("%#lx", start);
1380 size = len * sizeof(gid);
1382 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1383 size / sizeof(gid) != len || end < start) {
1384 tprintf("%#lx", start);
1388 abbrev_end = start + max_strlen * sizeof(gid);
1389 if (abbrev_end < start)
1395 for (cur = start; cur < end; cur += sizeof(gid)) {
1398 if (cur >= abbrev_end) {
1402 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1407 tprintf("%lu", (unsigned long) gid);
1411 tprintf(" %#lx", tcp->u_arg[1]);
1418 sys_setgroups32(tcp)
1421 if (entering(tcp)) {
1422 unsigned long len, size, start, cur, end, abbrev_end;
1426 len = tcp->u_arg[0];
1427 tprintf("%lu, ", len);
1432 start = tcp->u_arg[1];
1437 size = len * sizeof(gid);
1439 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1440 tprintf("%#lx", start);
1444 abbrev_end = start + max_strlen * sizeof(gid);
1445 if (abbrev_end < start)
1451 for (cur = start; cur < end; cur += sizeof(gid)) {
1454 if (cur >= abbrev_end) {
1458 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1463 tprintf("%lu", (unsigned long) gid);
1467 tprintf(" %#lx", tcp->u_arg[1]);
1473 sys_getgroups32(tcp)
1478 if (entering(tcp)) {
1479 len = tcp->u_arg[0];
1480 tprintf("%lu, ", len);
1482 unsigned long size, start, cur, end, abbrev_end;
1491 start = tcp->u_arg[1];
1496 size = len * sizeof(gid);
1498 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1499 size / sizeof(gid) != len || end < start) {
1500 tprintf("%#lx", start);
1504 abbrev_end = start + max_strlen * sizeof(gid);
1505 if (abbrev_end < start)
1511 for (cur = start; cur < end; cur += sizeof(gid)) {
1514 if (cur >= abbrev_end) {
1518 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1523 tprintf("%lu", (unsigned long) gid);
1527 tprintf(" %#lx", tcp->u_arg[1]);
1533 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1538 if (entering(tcp)) {
1540 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1545 #endif /* ALPHA || SUNOS4 || SVR4 */
1551 if (entering(tcp)) {
1553 tprintf("%lu", tcp->u_arg[0]);
1563 if (entering(tcp)) {
1564 tprintf("%lu", tcp->u_arg[0]);
1580 if (entering(tcp)) {
1581 tprintf("%lu", tcp->u_arg[0]);
1590 if (entering(tcp)) {
1591 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1598 #include <sys/privilege.h>
1601 static const struct xlat procpriv_cmds [] = {
1602 { SETPRV, "SETPRV" },
1603 { CLRPRV, "CLRPRV" },
1604 { PUTPRV, "PUTPRV" },
1605 { GETPRV, "GETPRV" },
1606 { CNTPRV, "CNTPRV" },
1611 static const struct xlat procpriv_priv [] = {
1612 { P_OWNER, "P_OWNER" },
1613 { P_AUDIT, "P_AUDIT" },
1614 { P_COMPAT, "P_COMPAT" },
1615 { P_DACREAD, "P_DACREAD" },
1616 { P_DACWRITE, "P_DACWRITE" },
1618 { P_FILESYS, "P_FILESYS" },
1619 { P_MACREAD, "P_MACREAD" },
1620 { P_MACWRITE, "P_MACWRITE" },
1621 { P_MOUNT, "P_MOUNT" },
1622 { P_MULTIDIR, "P_MULTIDIR" },
1623 { P_SETPLEVEL, "P_SETPLEVEL" },
1624 { P_SETSPRIV, "P_SETSPRIV" },
1625 { P_SETUID, "P_SETUID" },
1626 { P_SYSOPS, "P_SYSOPS" },
1627 { P_SETUPRIV, "P_SETUPRIV" },
1628 { P_DRIVER, "P_DRIVER" },
1629 { P_RTIME, "P_RTIME" },
1630 { P_MACUPGRADE, "P_MACUPGRADE" },
1631 { P_FSYSRANGE, "P_FSYSRANGE" },
1632 { P_SETFLEVEL, "P_SETFLEVEL" },
1633 { P_AUDITWR, "P_AUDITWR" },
1634 { P_TSHAR, "P_TSHAR" },
1635 { P_PLOCK, "P_PLOCK" },
1636 { P_CORE, "P_CORE" },
1637 { P_LOADMOD, "P_LOADMOD" },
1638 { P_BIND, "P_BIND" },
1639 { P_ALLPRIVS, "P_ALLPRIVS" },
1644 static const struct xlat procpriv_type [] = {
1645 { PS_FIX, "PS_FIX" },
1646 { PS_INH, "PS_INH" },
1647 { PS_MAX, "PS_MAX" },
1648 { PS_WKG, "PS_WKG" },
1654 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1657 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1658 int dots = len > max;
1661 if (len > max) len = max;
1664 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1666 tprintf ("%#lx", addr);
1672 for (i = 0; i < len; ++i) {
1675 if (i) tprintf (", ");
1677 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1678 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1680 tprintf ("%s|%s", t, p);
1683 tprintf ("%#lx", buf [i]);
1687 if (dots) tprintf (" ...");
1697 if (entering(tcp)) {
1698 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1699 switch (tcp->u_arg[0]) {
1701 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1709 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1710 tprintf (", %ld", tcp->u_arg[2]);
1713 else if (tcp->u_arg[0] == GETPRV) {
1714 if (syserror (tcp)) {
1715 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1719 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1720 tprintf (", %ld", tcp->u_arg[2]);
1731 printargv(tcp, addr)
1738 char data[sizeof(long)];
1744 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1745 if (umoven(tcp, addr, personality_wordsize[current_personality],
1747 tprintf("%#lx", addr);
1750 if (personality_wordsize[current_personality] == 4)
1755 printstr(tcp, cp.p64, -1);
1756 addr += personality_wordsize[current_personality];
1759 tprintf("%s...", sep);
1763 printargc(fmt, tcp, addr)
1771 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1772 addr += sizeof(char *);
1774 tprintf(fmt, count, count == 1 ? "" : "s");
1777 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1782 if (entering(tcp)) {
1783 printpath(tcp, tcp->u_arg[0]);
1785 tprintf(", %#lx", tcp->u_arg[1]);
1787 else if (abbrev(tcp))
1788 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1792 printargv(tcp, tcp->u_arg[1]);
1798 #endif /* SPARC || SPARC64 || SUNOS4 */
1804 if (entering(tcp)) {
1805 printpath(tcp, tcp->u_arg[0]);
1807 tprintf(", %#lx", tcp->u_arg[1]);
1809 else if (abbrev(tcp))
1810 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1814 printargv(tcp, tcp->u_arg[1]);
1818 tprintf(", %#lx", tcp->u_arg[2]);
1819 else if (abbrev(tcp))
1820 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1823 printargv(tcp, tcp->u_arg[2]);
1832 int sys_rexecve(tcp)
1835 if (entering (tcp)) {
1837 tprintf (", %ld", tcp->u_arg[3]);
1849 if (exiting(tcp) && !syserror(tcp) && followfork)
1852 #if defined LINUX && defined TCB_WAITEXECVE
1853 if (exiting(tcp) && syserror(tcp))
1854 tcp->flags &= ~TCB_WAITEXECVE;
1856 tcp->flags |= TCB_WAITEXECVE;
1857 #endif /* LINUX && TCB_WAITEXECVE */
1863 #define __WNOTHREAD 0x20000000
1866 #define __WALL 0x40000000
1869 #define __WCLONE 0x80000000
1873 static const struct xlat wait4_options[] = {
1874 { WNOHANG, "WNOHANG" },
1876 { WUNTRACED, "WUNTRACED" },
1879 { WEXITED, "WEXITED" },
1882 { WTRAPPED, "WTRAPPED" },
1885 { WSTOPPED, "WSTOPPED" },
1888 { WCONTINUED, "WCONTINUED" },
1891 { WNOWAIT, "WNOWAIT" },
1894 { __WCLONE, "__WCLONE" },
1897 { __WALL, "__WALL" },
1900 { __WNOTHREAD, "__WNOTHREAD" },
1905 #if !defined WCOREFLAG && defined WCOREFLG
1906 # define WCOREFLAG WCOREFLG
1909 #define WCOREFLAG 0x80
1913 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1916 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1926 * Here is a tricky presentation problem. This solution
1927 * is still not entirely satisfactory but since there
1928 * are no wait status constructors it will have to do.
1930 if (WIFSTOPPED(status)) {
1931 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1932 signame(WSTOPSIG(status)));
1933 status &= ~W_STOPCODE(WSTOPSIG(status));
1935 else if (WIFSIGNALED(status)) {
1936 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1937 signame(WTERMSIG(status)),
1938 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1939 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1941 else if (WIFEXITED(status)) {
1942 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1943 WEXITSTATUS(status));
1945 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1948 tprintf("[%#x]", status);
1955 tprintf(" | %#x]", status);
1961 printwaitn(struct tcb *tcp, int n, int bitness)
1966 if (entering(tcp)) {
1968 * Sign-extend a 32-bit value when that's what it is.
1970 * NB: On Linux, kernel-side pid_t is typedef'ed to int
1971 * on all arches; also, glibc-2.8 truncates wait3 and wait4
1972 * pid argument to int on 64bit arches, producing,
1973 * for example, wait4(4294967295, ...) instead of -1
1975 * Therefore, maybe it makes sense to *unconditionally*
1976 * widen int to long here...
1978 long pid = tcp->u_arg[0];
1979 if (personality_wordsize[current_personality] < sizeof pid)
1980 pid = (long) (int) pid;
1981 tprintf("%ld, ", pid);
1986 else if (syserror(tcp) || tcp->u_rval == 0)
1987 tprintf("%#lx", tcp->u_arg[1]);
1988 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1991 exited = printstatus(status);
1994 printflags(wait4_options, tcp->u_arg[2], "W???");
2001 else if (tcp->u_rval > 0) {
2004 printrusage32(tcp, tcp->u_arg[3]);
2007 printrusage(tcp, tcp->u_arg[3]);
2011 else if (tcp->u_rval > 0 && exited)
2012 printrusage(tcp, tcp->u_arg[3]);
2015 tprintf("%#lx", tcp->u_arg[3]);
2022 internal_wait(tcp, flagarg)
2028 #ifdef TCB_CLONE_THREAD
2029 if (tcp->flags & TCB_CLONE_THREAD)
2030 /* The children we wait for are our parent's children. */
2031 got_kids = (tcp->parent->nchildren
2032 > tcp->parent->nclone_detached);
2034 got_kids = (tcp->nchildren > tcp->nclone_detached);
2036 got_kids = tcp->nchildren > 0;
2039 if (entering(tcp) && got_kids) {
2040 /* There are children that this parent should block for.
2041 But ptrace made us the parent of the traced children
2042 and the real parent will get ECHILD from the wait call.
2044 XXX If we attached with strace -f -p PID, then there
2045 may be untraced dead children the parent could be reaping
2046 now, but we make him block. */
2048 /* ??? WTA: fix bug with hanging children */
2050 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
2052 * There are traced children. We'll make the parent
2053 * block to avoid a false ECHILD error due to our
2054 * ptrace having stolen the children. However,
2055 * we shouldn't block if there are zombies to reap.
2056 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2058 struct tcb *child = NULL;
2059 if (tcp->nzombies > 0 &&
2060 (tcp->u_arg[0] == -1 ||
2061 (child = pid2tcb(tcp->u_arg[0])) == NULL))
2063 if (tcp->u_arg[0] > 0) {
2065 * If the parent waits for a specified child
2066 * PID, then it must get ECHILD right away
2067 * if that PID is not one of its children.
2068 * Make sure that the requested PID matches
2069 * one of the parent's children that we are
2070 * tracing, and don't suspend it otherwise.
2073 child = pid2tcb(tcp->u_arg[0]);
2074 if (child == NULL || child->parent != (
2075 #ifdef TCB_CLONE_THREAD
2076 (tcp->flags & TCB_CLONE_THREAD)
2080 (child->flags & TCB_EXITING))
2083 tcp->flags |= TCB_SUSPENDED;
2084 tcp->waitpid = tcp->u_arg[0];
2085 #ifdef TCB_CLONE_THREAD
2086 if (tcp->flags & TCB_CLONE_THREAD)
2087 tcp->parent->nclone_waiting++;
2091 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2092 if (tcp->u_arg[flagarg] & WNOHANG) {
2093 /* We must force a fake result of 0 instead of
2094 the ECHILD error. */
2095 extern int force_result();
2096 return force_result(tcp, 0, 0);
2099 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2100 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2102 * We just reaped a child we don't know about,
2103 * presumably a zombie we already droptcb'd.
2117 /* The library wrapper stuffs this into the user variable. */
2119 printstatus(getrval2(tcp));
2134 if (!syserror(tcp)) {
2135 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2136 tprintf("%#lx", tcp->u_arg[0]);
2138 printstatus(status);
2149 return printwaitn(tcp, 3, 0);
2156 return printwaitn(tcp, 4, 0);
2164 return printwaitn(tcp, 4, 1);
2168 #if defined SVR4 || defined LINUX
2170 static const struct xlat waitid_types[] = {
2173 { P_PPID, "P_PPID" },
2175 { P_PGID, "P_PGID" },
2190 { P_LWPID, "P_LWPID" },
2202 if (entering(tcp)) {
2203 printxval(waitid_types, tcp->u_arg[0], "P_???");
2204 tprintf(", %ld, ", tcp->u_arg[1]);
2211 else if (syserror(tcp))
2212 tprintf("%#lx", tcp->u_arg[2]);
2213 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2216 printsiginfo(&si, verbose(tcp));
2219 printflags(wait4_options, tcp->u_arg[3], "W???");
2220 if (tcp->u_nargs > 4) {
2225 else if (tcp->u_error)
2226 tprintf("%#lx", tcp->u_arg[4]);
2228 printrusage(tcp, tcp->u_arg[4]);
2234 #endif /* SVR4 or LINUX */
2241 tprintf("%lu", tcp->u_arg[0]);
2249 struct utsname uname;
2252 if (syserror(tcp) || !verbose(tcp))
2253 tprintf("%#lx", tcp->u_arg[0]);
2254 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2256 else if (!abbrev(tcp)) {
2258 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2259 uname.sysname, uname.nodename);
2260 tprintf("release=\"%s\", version=\"%s\", ",
2261 uname.release, uname.version);
2262 tprintf("machine=\"%s\"", uname.machine);
2265 tprintf(", domainname=\"%s\"", uname.domainname);
2271 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2272 uname.sysname, uname.nodename);
2279 const struct xlat ptrace_cmds[] = {
2281 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2282 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2283 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2284 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2285 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2286 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2287 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2288 { PTRACE_CONT, "PTRACE_CONT" },
2289 { PTRACE_KILL, "PTRACE_KILL" },
2290 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2291 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2292 { PTRACE_DETACH, "PTRACE_DETACH" },
2293 # ifdef PTRACE_GETREGS
2294 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2296 # ifdef PTRACE_SETREGS
2297 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2299 # ifdef PTRACE_GETFPREGS
2300 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2302 # ifdef PTRACE_SETFPREGS
2303 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2305 # ifdef PTRACE_GETFPXREGS
2306 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2308 # ifdef PTRACE_SETFPXREGS
2309 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2311 # ifdef PTRACE_GETVRREGS
2312 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2314 # ifdef PTRACE_SETVRREGS
2315 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2317 # ifdef PTRACE_SETOPTIONS
2318 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2320 # ifdef PTRACE_GETEVENTMSG
2321 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2323 # ifdef PTRACE_GETSIGINFO
2324 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2326 # ifdef PTRACE_SETSIGINFO
2327 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2329 # ifdef PTRACE_SET_SYSCALL
2330 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2333 { PTRACE_READDATA, "PTRACE_READDATA" },
2334 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2335 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2336 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2337 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2338 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2340 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2341 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2343 { PTRACE_22, "PTRACE_22" },
2344 { PTRACE_23, "PTRACE_3" },
2345 # endif /* !SPARC */
2346 # endif /* SUNOS4 */
2347 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2349 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2351 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2352 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2353 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2355 { PTRACE_26, "PTRACE_26" },
2356 { PTRACE_27, "PTRACE_27" },
2357 { PTRACE_28, "PTRACE_28" },
2359 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2360 # endif /* SUNOS4 */
2362 # else /* FREEBSD */
2364 { PT_TRACE_ME, "PT_TRACE_ME" },
2365 { PT_READ_I, "PT_READ_I" },
2366 { PT_READ_D, "PT_READ_D" },
2367 { PT_WRITE_I, "PT_WRITE_I" },
2368 { PT_WRITE_D, "PT_WRITE_D" },
2370 { PT_READ_U, "PT_READ_U" },
2372 { PT_CONTINUE, "PT_CONTINUE" },
2373 { PT_KILL, "PT_KILL" },
2374 { PT_STEP, "PT_STEP" },
2375 { PT_ATTACH, "PT_ATTACH" },
2376 { PT_DETACH, "PT_DETACH" },
2377 { PT_GETREGS, "PT_GETREGS" },
2378 { PT_SETREGS, "PT_SETREGS" },
2379 { PT_GETFPREGS, "PT_GETFPREGS" },
2380 { PT_SETFPREGS, "PT_SETFPREGS" },
2381 { PT_GETDBREGS, "PT_GETDBREGS" },
2382 { PT_SETDBREGS, "PT_SETDBREGS" },
2383 # endif /* FREEBSD */
2388 # ifdef PTRACE_SETOPTIONS
2389 static const struct xlat ptrace_setoptions_flags[] = {
2390 # ifdef PTRACE_O_TRACESYSGOOD
2391 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2393 # ifdef PTRACE_O_TRACEFORK
2394 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2396 # ifdef PTRACE_O_TRACEVFORK
2397 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2399 # ifdef PTRACE_O_TRACECLONE
2400 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2402 # ifdef PTRACE_O_TRACEEXEC
2403 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2405 # ifdef PTRACE_O_TRACEVFORKDONE
2406 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2408 # ifdef PTRACE_O_TRACEEXIT
2409 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2413 # endif /* PTRACE_SETOPTIONS */
2414 # endif /* !FREEBSD */
2417 const struct xlat struct_user_offsets[] = {
2419 # if defined(S390) || defined(S390X)
2420 { PT_PSWMASK, "psw_mask" },
2421 { PT_PSWADDR, "psw_addr" },
2422 { PT_GPR0, "gpr0" },
2423 { PT_GPR1, "gpr1" },
2424 { PT_GPR2, "gpr2" },
2425 { PT_GPR3, "gpr3" },
2426 { PT_GPR4, "gpr4" },
2427 { PT_GPR5, "gpr5" },
2428 { PT_GPR6, "gpr6" },
2429 { PT_GPR7, "gpr7" },
2430 { PT_GPR8, "gpr8" },
2431 { PT_GPR9, "gpr9" },
2432 { PT_GPR10, "gpr10" },
2433 { PT_GPR11, "gpr11" },
2434 { PT_GPR12, "gpr12" },
2435 { PT_GPR13, "gpr13" },
2436 { PT_GPR14, "gpr14" },
2437 { PT_GPR15, "gpr15" },
2438 { PT_ACR0, "acr0" },
2439 { PT_ACR1, "acr1" },
2440 { PT_ACR2, "acr2" },
2441 { PT_ACR3, "acr3" },
2442 { PT_ACR4, "acr4" },
2443 { PT_ACR5, "acr5" },
2444 { PT_ACR6, "acr6" },
2445 { PT_ACR7, "acr7" },
2446 { PT_ACR8, "acr8" },
2447 { PT_ACR9, "acr9" },
2448 { PT_ACR10, "acr10" },
2449 { PT_ACR11, "acr11" },
2450 { PT_ACR12, "acr12" },
2451 { PT_ACR13, "acr13" },
2452 { PT_ACR14, "acr14" },
2453 { PT_ACR15, "acr15" },
2454 { PT_ORIGGPR2, "orig_gpr2" },
2457 { PT_FPR0_HI, "fpr0.hi" },
2458 { PT_FPR0_LO, "fpr0.lo" },
2459 { PT_FPR1_HI, "fpr1.hi" },
2460 { PT_FPR1_LO, "fpr1.lo" },
2461 { PT_FPR2_HI, "fpr2.hi" },
2462 { PT_FPR2_LO, "fpr2.lo" },
2463 { PT_FPR3_HI, "fpr3.hi" },
2464 { PT_FPR3_LO, "fpr3.lo" },
2465 { PT_FPR4_HI, "fpr4.hi" },
2466 { PT_FPR4_LO, "fpr4.lo" },
2467 { PT_FPR5_HI, "fpr5.hi" },
2468 { PT_FPR5_LO, "fpr5.lo" },
2469 { PT_FPR6_HI, "fpr6.hi" },
2470 { PT_FPR6_LO, "fpr6.lo" },
2471 { PT_FPR7_HI, "fpr7.hi" },
2472 { PT_FPR7_LO, "fpr7.lo" },
2473 { PT_FPR8_HI, "fpr8.hi" },
2474 { PT_FPR8_LO, "fpr8.lo" },
2475 { PT_FPR9_HI, "fpr9.hi" },
2476 { PT_FPR9_LO, "fpr9.lo" },
2477 { PT_FPR10_HI, "fpr10.hi" },
2478 { PT_FPR10_LO, "fpr10.lo" },
2479 { PT_FPR11_HI, "fpr11.hi" },
2480 { PT_FPR11_LO, "fpr11.lo" },
2481 { PT_FPR12_HI, "fpr12.hi" },
2482 { PT_FPR12_LO, "fpr12.lo" },
2483 { PT_FPR13_HI, "fpr13.hi" },
2484 { PT_FPR13_LO, "fpr13.lo" },
2485 { PT_FPR14_HI, "fpr14.hi" },
2486 { PT_FPR14_LO, "fpr14.lo" },
2487 { PT_FPR15_HI, "fpr15.hi" },
2488 { PT_FPR15_LO, "fpr15.lo" },
2491 { PT_FPR0, "fpr0" },
2492 { PT_FPR1, "fpr1" },
2493 { PT_FPR2, "fpr2" },
2494 { PT_FPR3, "fpr3" },
2495 { PT_FPR4, "fpr4" },
2496 { PT_FPR5, "fpr5" },
2497 { PT_FPR6, "fpr6" },
2498 { PT_FPR7, "fpr7" },
2499 { PT_FPR8, "fpr8" },
2500 { PT_FPR9, "fpr9" },
2501 { PT_FPR10, "fpr10" },
2502 { PT_FPR11, "fpr11" },
2503 { PT_FPR12, "fpr12" },
2504 { PT_FPR13, "fpr13" },
2505 { PT_FPR14, "fpr14" },
2506 { PT_FPR15, "fpr15" },
2509 { PT_CR_10, "cr10" },
2510 { PT_CR_11, "cr11" },
2511 { PT_IEEE_IP, "ieee_exception_ip" },
2512 # elif defined(SPARC)
2513 /* XXX No support for these offsets yet. */
2514 # elif defined(HPPA)
2515 /* XXX No support for these offsets yet. */
2516 # elif defined(POWERPC)
2518 # define PT_ORIG_R3 34
2520 # define REGSIZE (sizeof(unsigned long))
2521 { REGSIZE*PT_R0, "r0" },
2522 { REGSIZE*PT_R1, "r1" },
2523 { REGSIZE*PT_R2, "r2" },
2524 { REGSIZE*PT_R3, "r3" },
2525 { REGSIZE*PT_R4, "r4" },
2526 { REGSIZE*PT_R5, "r5" },
2527 { REGSIZE*PT_R6, "r6" },
2528 { REGSIZE*PT_R7, "r7" },
2529 { REGSIZE*PT_R8, "r8" },
2530 { REGSIZE*PT_R9, "r9" },
2531 { REGSIZE*PT_R10, "r10" },
2532 { REGSIZE*PT_R11, "r11" },
2533 { REGSIZE*PT_R12, "r12" },
2534 { REGSIZE*PT_R13, "r13" },
2535 { REGSIZE*PT_R14, "r14" },
2536 { REGSIZE*PT_R15, "r15" },
2537 { REGSIZE*PT_R16, "r16" },
2538 { REGSIZE*PT_R17, "r17" },
2539 { REGSIZE*PT_R18, "r18" },
2540 { REGSIZE*PT_R19, "r19" },
2541 { REGSIZE*PT_R20, "r20" },
2542 { REGSIZE*PT_R21, "r21" },
2543 { REGSIZE*PT_R22, "r22" },
2544 { REGSIZE*PT_R23, "r23" },
2545 { REGSIZE*PT_R24, "r24" },
2546 { REGSIZE*PT_R25, "r25" },
2547 { REGSIZE*PT_R26, "r26" },
2548 { REGSIZE*PT_R27, "r27" },
2549 { REGSIZE*PT_R28, "r28" },
2550 { REGSIZE*PT_R29, "r29" },
2551 { REGSIZE*PT_R30, "r30" },
2552 { REGSIZE*PT_R31, "r31" },
2553 { REGSIZE*PT_NIP, "NIP" },
2554 { REGSIZE*PT_MSR, "MSR" },
2555 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2556 { REGSIZE*PT_CTR, "CTR" },
2557 { REGSIZE*PT_LNK, "LNK" },
2558 { REGSIZE*PT_XER, "XER" },
2559 { REGSIZE*PT_CCR, "CCR" },
2560 { REGSIZE*PT_FPR0, "FPR0" },
2562 # elif defined(ALPHA)
2628 # elif defined(IA64)
2629 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2630 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2631 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2632 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2633 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2634 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2635 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2636 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2637 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2638 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2639 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2640 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2641 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2642 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2643 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2644 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2645 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2646 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2647 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2648 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2649 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2650 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2651 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2652 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2653 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2654 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2655 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2656 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2657 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2658 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2659 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2660 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2662 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2663 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2664 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2665 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2666 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2667 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2668 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2669 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2670 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2671 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2672 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2673 { PT_B4, "b4" }, { PT_B5, "b5" },
2674 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2676 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2677 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2678 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2679 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2680 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2681 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2682 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2683 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2684 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2685 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2686 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2687 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2688 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2689 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2690 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2691 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2692 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2694 { PT_AR_CSD, "ar.csd" },
2697 { PT_AR_SSD, "ar.ssd" },
2699 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2700 # elif defined(I386)
2712 { 4*ORIG_EAX, "4*ORIG_EAX" },
2716 { 4*UESP, "4*UESP" },
2718 # elif defined(X86_64)
2740 { 8*ORIG_RAX, "8*ORIG_RAX" },
2743 { 8*EFLAGS, "8*EFL" },
2746 # elif defined(M68K)
2747 { 4*PT_D1, "4*PT_D1" },
2748 { 4*PT_D2, "4*PT_D2" },
2749 { 4*PT_D3, "4*PT_D3" },
2750 { 4*PT_D4, "4*PT_D4" },
2751 { 4*PT_D5, "4*PT_D5" },
2752 { 4*PT_D6, "4*PT_D6" },
2753 { 4*PT_D7, "4*PT_D7" },
2754 { 4*PT_A0, "4*PT_A0" },
2755 { 4*PT_A1, "4*PT_A1" },
2756 { 4*PT_A2, "4*PT_A2" },
2757 { 4*PT_A3, "4*PT_A3" },
2758 { 4*PT_A4, "4*PT_A4" },
2759 { 4*PT_A5, "4*PT_A5" },
2760 { 4*PT_A6, "4*PT_A6" },
2761 { 4*PT_D0, "4*PT_D0" },
2762 { 4*PT_USP, "4*PT_USP" },
2763 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2764 { 4*PT_SR, "4*PT_SR" },
2765 { 4*PT_PC, "4*PT_PC" },
2767 { 4*REG_REG0, "4*REG_REG0" },
2768 { 4*(REG_REG0+1), "4*REG_REG1" },
2769 { 4*(REG_REG0+2), "4*REG_REG2" },
2770 { 4*(REG_REG0+3), "4*REG_REG3" },
2771 { 4*(REG_REG0+4), "4*REG_REG4" },
2772 { 4*(REG_REG0+5), "4*REG_REG5" },
2773 { 4*(REG_REG0+6), "4*REG_REG6" },
2774 { 4*(REG_REG0+7), "4*REG_REG7" },
2775 { 4*(REG_REG0+8), "4*REG_REG8" },
2776 { 4*(REG_REG0+9), "4*REG_REG9" },
2777 { 4*(REG_REG0+10), "4*REG_REG10" },
2778 { 4*(REG_REG0+11), "4*REG_REG11" },
2779 { 4*(REG_REG0+12), "4*REG_REG12" },
2780 { 4*(REG_REG0+13), "4*REG_REG13" },
2781 { 4*(REG_REG0+14), "4*REG_REG14" },
2782 { 4*REG_REG15, "4*REG_REG15" },
2783 { 4*REG_PC, "4*REG_PC" },
2784 { 4*REG_PR, "4*REG_PR" },
2785 { 4*REG_SR, "4*REG_SR" },
2786 { 4*REG_GBR, "4*REG_GBR" },
2787 { 4*REG_MACH, "4*REG_MACH" },
2788 { 4*REG_MACL, "4*REG_MACL" },
2789 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2790 { 4*REG_FPUL, "4*REG_FPUL" },
2791 { 4*REG_FPREG0, "4*REG_FPREG0" },
2792 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2793 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2794 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2795 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2796 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2797 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2798 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2799 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2800 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2801 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2802 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2803 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2804 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2805 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2806 { 4*REG_FPREG15, "4*REG_FPREG15" },
2808 { 4*REG_XDREG0, "4*REG_XDREG0" },
2809 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2810 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2811 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2812 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2813 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2814 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2815 { 4*REG_XDREG14, "4*REG_XDREG14" },
2817 { 4*REG_FPSCR, "4*REG_FPSCR" },
2818 # elif defined(SH64)
2823 { 16, "syscall no.(L)" },
2824 { 20, "syscall_no.(U)" },
2967 /* This entry is in case pt_regs contains dregs (depends on
2968 the kernel build options). */
2969 { uoff(regs), "offsetof(struct user, regs)" },
2970 { uoff(fpu), "offsetof(struct user, fpu)" },
2972 { uoff(regs.ARM_r0), "r0" },
2973 { uoff(regs.ARM_r1), "r1" },
2974 { uoff(regs.ARM_r2), "r2" },
2975 { uoff(regs.ARM_r3), "r3" },
2976 { uoff(regs.ARM_r4), "r4" },
2977 { uoff(regs.ARM_r5), "r5" },
2978 { uoff(regs.ARM_r6), "r6" },
2979 { uoff(regs.ARM_r7), "r7" },
2980 { uoff(regs.ARM_r8), "r8" },
2981 { uoff(regs.ARM_r9), "r9" },
2982 { uoff(regs.ARM_r10), "r10" },
2983 { uoff(regs.ARM_fp), "fp" },
2984 { uoff(regs.ARM_ip), "ip" },
2985 { uoff(regs.ARM_sp), "sp" },
2986 { uoff(regs.ARM_lr), "lr" },
2987 { uoff(regs.ARM_pc), "pc" },
2988 { uoff(regs.ARM_cpsr), "cpsr" },
2989 # elif defined(MIPS)
3063 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) && !defined(ALPHA) && !defined(IA64)
3064 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(BFIN)
3065 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3067 # if defined(I386) || defined(X86_64)
3068 { uoff(i387), "offsetof(struct user, i387)" },
3071 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3073 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3074 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3075 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3076 # if !defined(SPARC64)
3077 { uoff(start_code), "offsetof(struct user, start_code)" },
3080 { uoff(start_data), "offsetof(struct user, start_data)" },
3082 # if !defined(SPARC64)
3083 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3085 { uoff(signal), "offsetof(struct user, signal)" },
3086 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
3087 { uoff(reserved), "offsetof(struct user, reserved)" },
3089 # if !defined(SPARC64)
3090 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3092 # if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
3093 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3095 { uoff(magic), "offsetof(struct user, magic)" },
3096 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3097 # if defined(I386) || defined(X86_64)
3098 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3100 # endif /* !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) && !defined(ALPHA) && !defined(IA64) */
3105 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3106 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3107 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3108 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3109 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3110 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3111 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3112 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3113 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3114 { uoff(u_error), "offsetof(struct user, u_error)" },
3115 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3116 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3117 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3118 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3119 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3120 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3121 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3122 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3123 { uoff(u_code), "offsetof(struct user, u_code)" },
3124 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3125 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3126 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3127 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3128 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3129 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3130 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3131 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3132 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3133 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3134 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3135 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3136 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3137 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3138 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3139 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3140 { uoff(u_start), "offsetof(struct user, u_start)" },
3141 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3142 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3143 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3144 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3145 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3146 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3147 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3148 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3149 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3150 # endif /* SUNOS4 */
3152 { sizeof(struct user), "sizeof(struct user)" },
3156 # endif /* !FREEBSD */
3159 sys_ptrace(struct tcb *tcp)
3161 const struct xlat *x;
3164 if (entering(tcp)) {
3165 printxval(ptrace_cmds, tcp->u_arg[0],
3172 tprintf(", %lu, ", tcp->u_arg[1]);
3173 addr = tcp->u_arg[2];
3175 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3176 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3177 for (x = struct_user_offsets; x->str; x++) {
3182 tprintf("%#lx, ", addr);
3183 else if (x->val > addr && x != struct_user_offsets) {
3185 tprintf("%s + %ld, ", x->str, addr - x->val);
3188 tprintf("%s, ", x->str);
3192 tprintf("%#lx, ", tcp->u_arg[2]);
3194 switch (tcp->u_arg[0]) {
3196 case PTRACE_PEEKDATA:
3197 case PTRACE_PEEKTEXT:
3198 case PTRACE_PEEKUSER:
3202 case PTRACE_SINGLESTEP:
3203 case PTRACE_SYSCALL:
3205 printsignal(tcp->u_arg[3]);
3207 # ifdef PTRACE_SETOPTIONS
3208 case PTRACE_SETOPTIONS:
3209 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3212 # ifdef PTRACE_SETSIGINFO
3213 case PTRACE_SETSIGINFO: {
3217 else if (syserror(tcp))
3218 tprintf("%#lx", tcp->u_arg[3]);
3219 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3222 printsiginfo(&si, verbose(tcp));
3226 # ifdef PTRACE_GETSIGINFO
3227 case PTRACE_GETSIGINFO:
3228 /* Don't print anything, do it at syscall return. */
3232 tprintf("%#lx", tcp->u_arg[3]);
3236 switch (tcp->u_arg[0]) {
3237 case PTRACE_PEEKDATA:
3238 case PTRACE_PEEKTEXT:
3239 case PTRACE_PEEKUSER:
3243 printnum(tcp, tcp->u_arg[3], "%#lx");
3246 # ifdef PTRACE_GETSIGINFO
3247 case PTRACE_GETSIGINFO: {
3251 else if (syserror(tcp))
3252 tprintf("%#lx", tcp->u_arg[3]);
3253 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3256 printsiginfo(&si, verbose(tcp));
3264 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3265 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3266 tprintf("%lu, ", tcp->u_arg[3]);
3267 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3268 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3269 tcp->u_arg[0] != PTRACE_READTEXT) {
3270 tprintf("%#lx", tcp->u_arg[3]);
3273 if (tcp->u_arg[0] == PTRACE_READDATA ||
3274 tcp->u_arg[0] == PTRACE_READTEXT) {
3275 tprintf("%lu, ", tcp->u_arg[3]);
3276 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3279 # endif /* SUNOS4 */
3281 tprintf("%lu", tcp->u_arg[3]);
3283 # endif /* FREEBSD */
3290 # ifndef FUTEX_CMP_REQUEUE
3291 # define FUTEX_CMP_REQUEUE 4
3293 # ifndef FUTEX_WAKE_OP
3294 # define FUTEX_WAKE_OP 5
3296 # ifndef FUTEX_LOCK_PI
3297 # define FUTEX_LOCK_PI 6
3298 # define FUTEX_UNLOCK_PI 7
3299 # define FUTEX_TRYLOCK_PI 8
3301 # ifndef FUTEX_WAIT_BITSET
3302 # define FUTEX_WAIT_BITSET 9
3304 # ifndef FUTEX_WAKE_BITSET
3305 # define FUTEX_WAKE_BITSET 10
3307 # ifndef FUTEX_PRIVATE_FLAG
3308 # define FUTEX_PRIVATE_FLAG 128
3310 static const struct xlat futexops[] = {
3311 { FUTEX_WAIT, "FUTEX_WAIT" },
3312 { FUTEX_WAKE, "FUTEX_WAKE" },
3313 { FUTEX_FD, "FUTEX_FD" },
3314 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3315 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3316 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3317 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3318 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3319 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3320 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3321 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3322 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3323 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3324 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3325 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3326 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3327 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3328 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3329 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3330 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3331 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3332 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3335 # ifndef FUTEX_OP_SET
3336 # define FUTEX_OP_SET 0
3337 # define FUTEX_OP_ADD 1
3338 # define FUTEX_OP_OR 2
3339 # define FUTEX_OP_ANDN 3
3340 # define FUTEX_OP_XOR 4
3341 # define FUTEX_OP_CMP_EQ 0
3342 # define FUTEX_OP_CMP_NE 1
3343 # define FUTEX_OP_CMP_LT 2
3344 # define FUTEX_OP_CMP_LE 3
3345 # define FUTEX_OP_CMP_GT 4
3346 # define FUTEX_OP_CMP_GE 5
3348 static const struct xlat futexwakeops[] = {
3349 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3350 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3351 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3352 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3353 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3356 static const struct xlat futexwakecmps[] = {
3357 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3358 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3359 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3360 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3361 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3362 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3370 if (entering(tcp)) {
3371 long int cmd = tcp->u_arg[1] & 127;
3372 tprintf("%p, ", (void *) tcp->u_arg[0]);
3373 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3374 tprintf(", %ld", tcp->u_arg[2]);
3375 if (cmd == FUTEX_WAKE_BITSET)
3376 tprintf(", %lx", tcp->u_arg[5]);
3377 else if (cmd == FUTEX_WAIT) {
3379 printtv(tcp, tcp->u_arg[3]);
3380 } else if (cmd == FUTEX_WAIT_BITSET) {
3382 printtv(tcp, tcp->u_arg[3]);
3383 tprintf(", %lx", tcp->u_arg[5]);
3384 } else if (cmd == FUTEX_REQUEUE)
3385 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3386 else if (cmd == FUTEX_CMP_REQUEUE)
3387 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3388 else if (cmd == FUTEX_WAKE_OP) {
3389 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3390 if ((tcp->u_arg[5] >> 28) & 8)
3391 tprintf("FUTEX_OP_OPARG_SHIFT|");
3392 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3393 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3394 if ((tcp->u_arg[5] >> 24) & 8)
3395 tprintf("FUTEX_OP_OPARG_SHIFT|");
3396 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3397 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3404 print_affinitylist(tcp, list, len)
3411 while (len >= sizeof (unsigned long)) {
3413 umove(tcp, list, &w);
3414 tprintf("%s %lx", first ? "" : ",", w);
3416 len -= sizeof (unsigned long);
3417 list += sizeof(unsigned long);
3423 sys_sched_setaffinity(tcp)
3426 if (entering(tcp)) {
3427 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3428 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3434 sys_sched_getaffinity(tcp)
3437 if (entering(tcp)) {
3438 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3440 if (tcp->u_rval == -1)
3441 tprintf("%#lx", tcp->u_arg[2]);
3443 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3448 static const struct xlat schedulers[] = {
3449 { SCHED_OTHER, "SCHED_OTHER" },
3450 { SCHED_RR, "SCHED_RR" },
3451 { SCHED_FIFO, "SCHED_FIFO" },
3456 sys_sched_getscheduler(tcp)
3459 if (entering(tcp)) {
3460 tprintf("%d", (int) tcp->u_arg[0]);
3461 } else if (! syserror(tcp)) {
3462 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3463 if (tcp->auxstr != NULL)
3470 sys_sched_setscheduler(tcp)
3473 if (entering(tcp)) {
3474 struct sched_param p;
3475 tprintf("%d, ", (int) tcp->u_arg[0]);
3476 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3477 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3478 tprintf(", %#lx", tcp->u_arg[2]);
3480 tprintf(", { %d }", p.__sched_priority);
3486 sys_sched_getparam(tcp)
3489 if (entering(tcp)) {
3490 tprintf("%d, ", (int) tcp->u_arg[0]);
3492 struct sched_param p;
3493 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3494 tprintf("%#lx", tcp->u_arg[1]);
3496 tprintf("{ %d }", p.__sched_priority);
3502 sys_sched_setparam(tcp)
3505 if (entering(tcp)) {
3506 struct sched_param p;
3507 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3508 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3510 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3516 sys_sched_get_priority_min(tcp)
3519 if (entering(tcp)) {
3520 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3526 # include <asm/prctl.h>
3528 static const struct xlat archvals[] = {
3529 { ARCH_SET_GS, "ARCH_SET_GS" },
3530 { ARCH_SET_FS, "ARCH_SET_FS" },
3531 { ARCH_GET_FS, "ARCH_GET_FS" },
3532 { ARCH_GET_GS, "ARCH_GET_GS" },
3540 if (entering(tcp)) {
3541 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3542 if (tcp->u_arg[0] == ARCH_SET_GS
3543 || tcp->u_arg[0] == ARCH_SET_FS)
3544 tprintf(", %#lx", tcp->u_arg[1]);
3546 if (tcp->u_arg[0] == ARCH_GET_GS
3547 || tcp->u_arg[0] == ARCH_GET_FS) {
3549 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3550 tprintf(", [%#lx]", v);
3552 tprintf(", %#lx", tcp->u_arg[1]);
3557 # endif /* X86_64 */
3566 if (tcp->u_arg[0] == 0)
3568 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3569 tprintf("%#lx, ", tcp->u_arg[0]);
3571 tprintf("[%u], ", u);
3572 if (tcp->u_arg[1] == 0)
3574 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3575 tprintf("%#lx, ", tcp->u_arg[1]);
3577 tprintf("[%u], ", u);
3578 tprintf("%#lx", tcp->u_arg[2]);