2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 #include <sys/resource.h>
47 #include <sys/utsname.h>
49 #include <sys/syscall.h>
52 #include <machine/reg.h>
56 #include <sys/ptrace.h>
61 # define fpq kernel_fpq
63 # define fpu kernel_fpu
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 #include <linux/ptrace.h>
88 #ifdef HAVE_LINUX_FUTEX_H
89 #include <linux/futex.h>
104 #include <asm/posix_types.h>
106 #define GETGROUPS_T __kernel_gid_t
109 #if defined(LINUX) && defined(IA64)
110 # include <asm/ptrace_offsets.h>
111 # include <asm/rse.h>
115 #include <sys/prctl.h>
119 #define WCOREDUMP(status) ((status) & 0200)
122 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
123 #if defined(HAVE_PRCTL)
124 static struct xlat prctl_options[] = {
126 { PR_MAXPROCS, "PR_MAXPROCS" },
129 { PR_ISBLOCKED, "PR_ISBLOCKED" },
131 #ifdef PR_SETSTACKSIZE
132 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
134 #ifdef PR_GETSTACKSIZE
135 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
138 { PR_MAXPPROCS, "PR_MAXPPROCS" },
140 #ifdef PR_UNBLKONEXEC
141 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
144 { PR_ATOMICSIM, "PR_ATOMICSIM" },
147 { PR_SETEXITSIG, "PR_SETEXITSIG" },
150 { PR_RESIDENT, "PR_RESIDENT" },
153 { PR_ATTACHADDR, "PR_ATTACHADDR" },
156 { PR_DETACHADDR, "PR_DETACHADDR" },
159 { PR_TERMCHILD, "PR_TERMCHILD" },
162 { PR_GETSHMASK, "PR_GETSHMASK" },
165 { PR_GETNSHARE, "PR_GETNSHARE" },
167 #if defined(PR_SET_PDEATHSIG)
168 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
171 { PR_COREPID, "PR_COREPID" },
173 #ifdef PR_ATTACHADDRPERM
174 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
176 #ifdef PR_PTHREADEXIT
177 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
179 #ifdef PR_SET_PDEATHSIG
180 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
182 #ifdef PR_GET_PDEATHSIG
183 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
185 #ifdef PR_GET_UNALIGN
186 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
188 #ifdef PR_SET_UNALIGN
189 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
191 #ifdef PR_GET_KEEPCAPS
192 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
194 #ifdef PR_SET_KEEPCAPS
195 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
202 unalignctl_string (unsigned int ctl)
207 #ifdef PR_UNALIGN_NOPRINT
208 case PR_UNALIGN_NOPRINT:
211 #ifdef PR_UNALIGN_SIGBUS
212 case PR_UNALIGN_SIGBUS:
218 sprintf(buf, "%x", ctl);
230 printxval(prctl_options, tcp->u_arg[0], "PR_???");
231 switch (tcp->u_arg[0]) {
236 #ifdef PR_SET_DEATHSIG
237 case PR_GET_PDEATHSIG:
240 #ifdef PR_SET_UNALIGN
242 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
245 #ifdef PR_GET_UNALIGN
247 tprintf(", %#lx", tcp->u_arg[1]);
251 for (i = 1; i < tcp->u_nargs; i++)
252 tprintf(", %#lx", tcp->u_arg[i]);
256 switch (tcp->u_arg[0]) {
257 #ifdef PR_GET_PDEATHSIG
258 case PR_GET_PDEATHSIG:
259 for (i=1; i<tcp->u_nargs; i++)
260 tprintf(", %#lx", tcp->u_arg[i]);
263 #ifdef PR_SET_UNALIGN
267 #ifdef PR_GET_UNALIGN
272 umove(tcp, tcp->u_arg[1], &ctl);
273 tcp->auxstr = unalignctl_string(ctl);
284 #endif /* HAVE_PRCTL */
300 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
301 tprintf(", %lu", tcp->u_arg[1]);
312 tprintf("%#lx", tcp->u_arg[0]);
314 printpath(tcp, tcp->u_arg[0]);
315 tprintf(", %lu", tcp->u_arg[1]);
321 sys_setdomainname(tcp)
325 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
326 tprintf(", %lu", tcp->u_arg[1]);
334 sys_getdomainname(tcp)
339 tprintf("%#lx", tcp->u_arg[0]);
341 printpath(tcp, tcp->u_arg[0]);
342 tprintf(", %lu", tcp->u_arg[1]);
353 fprintf(stderr, "_exit returned!\n");
356 /* special case: we stop tracing this process, finish line now */
357 tprintf("%ld) ", tcp->u_arg[0]);
369 tcp->flags |= TCB_EXITING;
370 #ifdef __NR_exit_group
371 if (tcp->scno == __NR_exit_group)
372 tcp->flags |= TCB_GROUP_EXITING;
378 /* TCP is creating a child we want to follow.
379 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
380 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
382 fork_tcb(struct tcb *tcp)
384 if (nprocs == tcbtabsize) {
385 /* Allocate some more TCBs and expand the table.
386 We don't want to relocate the TCBs because our
387 callers have pointers and it would be a pain.
388 So tcbtab is a table of pointers. Since we never
389 free the TCBs, we allocate a single chunk of many. */
390 struct tcb **newtab = (struct tcb **)
391 realloc(tcbtab, 2 * tcbtabsize * sizeof tcbtab[0]);
392 struct tcb *newtcbs = (struct tcb *) calloc(tcbtabsize,
395 if (newtab == NULL || newtcbs == NULL) {
398 tcp->flags &= ~TCB_FOLLOWFORK;
399 fprintf(stderr, "sys_fork: tcb table full\n");
402 for (i = tcbtabsize; i < 2 * tcbtabsize; ++i)
403 newtab[i] = &newtcbs[i - tcbtabsize];
408 tcp->flags |= TCB_FOLLOWFORK;
420 tcp->auxstr = "child process";
421 return RVAL_UDECIMAL | RVAL_STR;
434 tprintf ("%ld", tcp->u_arg[0]);
438 tcp->auxstr = "child process";
439 return RVAL_UDECIMAL | RVAL_STR;
451 struct tcb *tcpchild;
455 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
466 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
467 fprintf(stderr, "sys_fork: tcb table full\n");
470 if (proc_open(tcpchild, 2) < 0)
476 #else /* !USE_PROCFS */
480 /* defines copied from linux/sched.h since we can't include that
481 * ourselves (it conflicts with *lots* of libc includes)
483 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
484 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
485 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
486 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
487 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
488 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
489 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
490 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
491 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
492 #define CLONE_THREAD 0x00010000 /* Same thread group? */
493 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
494 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
495 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
496 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
497 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
498 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
499 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
500 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
502 static struct xlat clone_flags[] = {
503 { CLONE_VM, "CLONE_VM" },
504 { CLONE_FS, "CLONE_FS" },
505 { CLONE_FILES, "CLONE_FILES" },
506 { CLONE_SIGHAND, "CLONE_SIGHAND" },
507 { CLONE_IDLETASK, "CLONE_IDLETASK"},
508 { CLONE_PTRACE, "CLONE_PTRACE" },
509 { CLONE_VFORK, "CLONE_VFORK" },
510 { CLONE_PARENT, "CLONE_PARENT" },
511 { CLONE_THREAD, "CLONE_THREAD" },
512 { CLONE_NEWNS, "CLONE_NEWNS" },
513 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
514 { CLONE_SETTLS, "CLONE_SETTLS" },
515 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
516 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
517 { CLONE_DETACHED, "CLONE_DETACHED" },
518 { CLONE_UNTRACED, "CLONE_UNTRACED" },
519 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
524 # include <asm/ldt.h>
525 extern void print_ldt_entry();
534 # if defined S390 || defined S390X
535 /* For some reason, S390 has the stack argument first. */
536 stack = tcp->u_arg[0];
537 flags = tcp->u_arg[1];
539 flags = tcp->u_arg[0];
540 stack = tcp->u_arg[1];
542 tprintf("child_stack=%#lx, flags=", stack);
543 if (printflags(clone_flags, flags) == 0)
545 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
546 |CLONE_SETTLS)) == 0)
548 if (flags & CLONE_PARENT_SETTID) {
550 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
551 tprintf(", [%d]", pid);
553 tprintf(", %#lx", tcp->u_arg[2]);
556 tprintf(", <ignored>");
558 if (flags & CLONE_SETTLS) {
559 struct modify_ldt_ldt_s copy;
560 if (umove(tcp, tcp->u_arg[3], ©) != -1) {
561 tprintf(", {entry_number:%d, ",
566 print_ldt_entry(©);
569 tprintf(", %#lx", tcp->u_arg[3]);
572 tprintf(", <ignored>");
577 if (flags & CLONE_CHILD_SETTID)
578 tprintf(", %#lx", tcp->u_arg[TIDARG]);
589 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
590 tcp->u_arg[1], tcp->u_arg[2]);
591 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
604 return RVAL_UDECIMAL;
609 change_syscall(tcp, new)
615 /* Attempt to make vfork into fork, which we can follow. */
616 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
619 #elif defined(X86_64)
620 /* Attempt to make vfork into fork, which we can follow. */
621 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
624 #elif defined(POWERPC)
625 if (ptrace(PTRACE_POKEUSER, tcp->pid,
626 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
629 #elif defined(S390) || defined(S390X)
630 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
631 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
635 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
640 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
643 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
647 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
651 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
655 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
659 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
663 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
667 #warning Do not know how to handle change_syscall for this architecture
668 #endif /* architecture */
680 unsigned long *bsp, *ap;
682 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
685 ap = ia64_rse_skip_regs(bsp, argnum);
687 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
694 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
698 #elif defined(X86_64)
700 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
704 #elif defined(POWERPC)
706 #define PT_ORIG_R3 34
709 ptrace(PTRACE_POKEUSER, tcp->pid,
710 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
719 ptrace(PTRACE_POKEUSER, tcp->pid,
720 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
724 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
727 ptrace(PTRACE_POKEDATA, tcp->pid,
728 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
733 #elif defined(S390) || defined(S390X)
736 ptrace(PTRACE_POKEUSER, tcp->pid,
737 (char *) (argnum==0 ? PT_ORIGGPR2 :
738 PT_GPR2 + argnum*sizeof(long)),
746 # warning Sorry, setargs not implemented for this architecture.
751 #if defined SYS_clone || defined SYS_clone2
756 struct tcb *tcpchild;
766 int bpt = tcp->flags & TCB_BPTSET;
768 if (!(tcp->flags & TCB_FOLLOWFORK))
779 #ifdef CLONE_PTRACE /* See new setbpt code. */
780 tcpchild = pid2tcb(pid);
781 if (tcpchild != NULL) {
782 /* The child already reported its startup trap
783 before the parent reported its syscall return. */
785 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
786 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
788 [preattached child %d of %d in weird state!]\n",
793 if ((tcpchild = alloctcb(pid)) == NULL) {
796 fprintf(stderr, " [tcb table full]\n");
797 kill(pid, SIGKILL); /* XXX */
802 /* Attach to the new child */
803 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
806 perror("PTRACE_ATTACH");
807 fprintf(stderr, "Too late?\n");
816 tcpchild->flags |= TCB_ATTACHED;
817 /* Child has BPT too, must be removed on first occasion. */
819 tcpchild->flags |= TCB_BPTSET;
820 tcpchild->baddr = tcp->baddr;
821 memcpy(tcpchild->inst, tcp->inst,
822 sizeof tcpchild->inst);
824 tcpchild->parent = tcp;
826 if (tcpchild->flags & TCB_SUSPENDED) {
827 /* The child was born suspended, due to our having
828 forced CLONE_PTRACE. */
832 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
833 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
834 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
840 Process %u resumed (parent %d ready)\n",
846 fprintf(stderr, "Process %d attached\n", pid);
849 #ifdef TCB_CLONE_THREAD
850 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
851 /* The parent in this clone is itself a thread
852 belonging to another process. There is no
853 meaning to the parentage relationship of the new
854 child with the thread, only with the process.
855 We associate the new thread with our parent.
856 Since this is done for every new thread, there
857 will never be a TCB_CLONE_THREAD process that
860 tcp->u_arg[0] = tcp->parent->u_arg[0];
862 tcpchild->parent = tcp;
866 if (tcp->u_arg[0] & CLONE_THREAD) {
867 tcpchild->flags |= TCB_CLONE_THREAD;
868 ++tcp->nclone_threads;
870 if (tcp->u_arg[0] & CLONE_DETACHED) {
871 tcpchild->flags |= TCB_CLONE_DETACHED;
872 ++tcp->nclone_detached;
886 /* We do special magic with clone for any clone or fork. */
887 return internal_clone(tcp);
890 struct tcb *tcpchild;
895 if (tcp->scno == SYS_vfork) {
896 /* Attempt to make vfork into fork, which we can follow. */
898 change_syscall(tcp, SYS_fork) < 0)
903 if (!followfork || dont_follow)
911 int bpt = tcp->flags & TCB_BPTSET;
913 if (!(tcp->flags & TCB_FOLLOWFORK))
922 if ((tcpchild = alloctcb(pid)) == NULL) {
923 fprintf(stderr, " [tcb table full]\n");
924 kill(pid, SIGKILL); /* XXX */
929 /* The child must have run before it can be attached. */
930 /* This must be a bug in the parisc kernel, but I havn't
931 * identified it yet. Seems to be an issue associated
932 * with attaching to a process (which sends it a signal)
933 * before that process has ever been scheduled. When
934 * debugging, I started seeing crashes in
935 * arch/parisc/kernel/signal.c:do_signal(), apparently
936 * caused by r8 getting corrupt over the dequeue_signal()
937 * call. Didn't make much sense though...
943 select(0, NULL, NULL, NULL, &tv);
946 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
947 perror("PTRACE_ATTACH");
948 fprintf(stderr, "Too late?\n");
955 /* The child must have run before it can be attached. */
960 select(0, NULL, NULL, NULL, &tv);
962 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
963 perror("PTRACE_ATTACH");
964 fprintf(stderr, "Too late?\n");
969 /* Try to catch the new process as soon as possible. */
972 for (i = 0; i < 1024; i++)
973 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
976 perror("PTRACE_ATTACH");
977 fprintf(stderr, "Too late?\n");
984 tcpchild->flags |= TCB_ATTACHED;
985 /* Child has BPT too, must be removed on first occasion */
987 tcpchild->flags |= TCB_BPTSET;
988 tcpchild->baddr = tcp->baddr;
989 memcpy(tcpchild->inst, tcp->inst,
990 sizeof tcpchild->inst);
993 tcpchild->parent = tcp;
996 fprintf(stderr, "Process %d attached\n", pid);
1002 #endif /* !USE_PROCFS */
1004 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1011 return RVAL_UDECIMAL;
1015 #endif /* SUNOS4 || LINUX || FREEBSD */
1019 static char idstr[16];
1026 sprintf(idstr, "ppid %lu", getrval2(tcp));
1027 tcp->auxstr = idstr;
1038 sprintf(idstr, "euid %lu", getrval2(tcp));
1039 tcp->auxstr = idstr;
1050 sprintf(idstr, "egid %lu", getrval2(tcp));
1051 tcp->auxstr = idstr;
1065 if (entering(tcp)) {
1066 tprintf("%u", (uid_t) tcp->u_arg[0]);
1075 if (entering(tcp)) {
1076 tprintf("%u", (gid_t) tcp->u_arg[0]);
1088 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1089 tcp->u_arg[1], tcp->u_arg[2]);
1091 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1092 tprintf("%#lx, ", tcp->u_arg[0]);
1094 tprintf("ruid %lu, ", (unsigned long) uid);
1095 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1096 tprintf("%#lx, ", tcp->u_arg[0]);
1098 tprintf("euid %lu, ", (unsigned long) uid);
1099 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1100 tprintf("%#lx", tcp->u_arg[0]);
1102 tprintf("suid %lu", (unsigned long) uid);
1115 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1116 tcp->u_arg[1], tcp->u_arg[2]);
1118 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1119 tprintf("%#lx, ", tcp->u_arg[0]);
1121 tprintf("rgid %lu, ", (unsigned long) gid);
1122 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1123 tprintf("%#lx, ", tcp->u_arg[0]);
1125 tprintf("egid %lu, ", (unsigned long) gid);
1126 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1127 tprintf("%#lx", tcp->u_arg[0]);
1129 tprintf("sgid %lu", (unsigned long) gid);
1141 if (entering(tcp)) {
1143 (unsigned long) (uid_t) tcp->u_arg[0],
1144 (unsigned long) (uid_t) tcp->u_arg[1]);
1153 if (entering(tcp)) {
1155 (unsigned long) (gid_t) tcp->u_arg[0],
1156 (unsigned long) (gid_t) tcp->u_arg[1]);
1161 #if defined(LINUX) || defined(FREEBSD)
1166 if (entering(tcp)) {
1167 tprintf("ruid %u, euid %u, suid %u",
1168 (uid_t) tcp->u_arg[0],
1169 (uid_t) tcp->u_arg[1],
1170 (uid_t) tcp->u_arg[2]);
1178 if (entering(tcp)) {
1179 tprintf("rgid %u, egid %u, sgid %u",
1180 (uid_t) tcp->u_arg[0],
1181 (uid_t) tcp->u_arg[1],
1182 (uid_t) tcp->u_arg[2]);
1187 #endif /* LINUX || FREEBSD */
1194 GETGROUPS_T *gidset;
1196 if (entering(tcp)) {
1197 len = tcp->u_arg[0];
1198 tprintf("%u, ", len);
1203 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1204 if (gidset == NULL) {
1205 fprintf(stderr, "sys_setgroups: out of memory\n");
1209 tprintf("%#lx", tcp->u_arg[1]);
1210 else if (umoven(tcp, tcp->u_arg[1],
1211 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1215 for (i = 0; i < len; i++)
1216 tprintf("%s%lu", i ? ", " : "",
1217 (unsigned long) gidset[i]);
1220 free((char *) gidset);
1230 GETGROUPS_T *gidset;
1232 if (entering(tcp)) {
1233 len = tcp->u_arg[0];
1234 tprintf("%u, ", len);
1241 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1242 if (gidset == NULL) {
1243 fprintf(stderr, "sys_getgroups: out of memory\n");
1248 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1249 tprintf("%#lx", tcp->u_arg[1]);
1250 else if (umoven(tcp, tcp->u_arg[1],
1251 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1255 for (i = 0; i < len; i++)
1256 tprintf("%s%lu", i ? ", " : "",
1257 (unsigned long) gidset[i]);
1260 free((char *)gidset);
1269 if (entering(tcp)) {
1271 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1281 if (entering(tcp)) {
1283 tprintf("%lu", tcp->u_arg[0]);
1293 if (entering(tcp)) {
1294 tprintf("%lu", tcp->u_arg[0]);
1310 if (entering(tcp)) {
1311 tprintf("%lu", tcp->u_arg[0]);
1320 if (entering(tcp)) {
1321 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1328 #include <sys/privilege.h>
1331 static struct xlat procpriv_cmds [] = {
1332 { SETPRV, "SETPRV" },
1333 { CLRPRV, "CLRPRV" },
1334 { PUTPRV, "PUTPRV" },
1335 { GETPRV, "GETPRV" },
1336 { CNTPRV, "CNTPRV" },
1341 static struct xlat procpriv_priv [] = {
1342 { P_OWNER, "P_OWNER" },
1343 { P_AUDIT, "P_AUDIT" },
1344 { P_COMPAT, "P_COMPAT" },
1345 { P_DACREAD, "P_DACREAD" },
1346 { P_DACWRITE, "P_DACWRITE" },
1348 { P_FILESYS, "P_FILESYS" },
1349 { P_MACREAD, "P_MACREAD" },
1350 { P_MACWRITE, "P_MACWRITE" },
1351 { P_MOUNT, "P_MOUNT" },
1352 { P_MULTIDIR, "P_MULTIDIR" },
1353 { P_SETPLEVEL, "P_SETPLEVEL" },
1354 { P_SETSPRIV, "P_SETSPRIV" },
1355 { P_SETUID, "P_SETUID" },
1356 { P_SYSOPS, "P_SYSOPS" },
1357 { P_SETUPRIV, "P_SETUPRIV" },
1358 { P_DRIVER, "P_DRIVER" },
1359 { P_RTIME, "P_RTIME" },
1360 { P_MACUPGRADE, "P_MACUPGRADE" },
1361 { P_FSYSRANGE, "P_FSYSRANGE" },
1362 { P_SETFLEVEL, "P_SETFLEVEL" },
1363 { P_AUDITWR, "P_AUDITWR" },
1364 { P_TSHAR, "P_TSHAR" },
1365 { P_PLOCK, "P_PLOCK" },
1366 { P_CORE, "P_CORE" },
1367 { P_LOADMOD, "P_LOADMOD" },
1368 { P_BIND, "P_BIND" },
1369 { P_ALLPRIVS, "P_ALLPRIVS" },
1374 static struct xlat procpriv_type [] = {
1375 { PS_FIX, "PS_FIX" },
1376 { PS_INH, "PS_INH" },
1377 { PS_MAX, "PS_MAX" },
1378 { PS_WKG, "PS_WKG" },
1384 printpriv(tcp, addr, len, opt)
1391 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1392 int dots = len > max;
1395 if (len > max) len = max;
1398 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1400 tprintf ("%#lx", addr);
1406 for (i = 0; i < len; ++i) {
1409 if (i) tprintf (", ");
1411 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1412 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1414 tprintf ("%s|%s", t, p);
1417 tprintf ("%#lx", buf [i]);
1421 if (dots) tprintf (" ...");
1431 if (entering(tcp)) {
1432 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1433 switch (tcp->u_arg[0]) {
1435 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1443 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1444 tprintf (", %ld", tcp->u_arg[2]);
1447 else if (tcp->u_arg[0] == GETPRV) {
1448 if (syserror (tcp)) {
1449 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1453 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1454 tprintf (", %ld", tcp->u_arg[2]);
1465 fake_execve(tcp, program, argv, envp)
1474 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1477 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1482 string_quote(program);
1484 for (i = 0; argv[i] != NULL; i++) {
1487 string_quote(argv[i]);
1489 for (i = 0; envp[i] != NULL; i++)
1491 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1498 printargv(tcp, addr)
1504 int max = max_strlen / 2;
1506 for (sep = ""; --max >= 0; sep = ", ") {
1509 if (umove(tcp, addr, &cp) < 0) {
1510 tprintf("%#lx", addr);
1516 printstr(tcp, (long) cp, -1);
1517 addr += sizeof(char *);
1524 printargc(fmt, tcp, addr)
1532 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1533 addr += sizeof(char *);
1535 tprintf(fmt, count, count == 1 ? "" : "s");
1542 if (entering(tcp)) {
1543 printpath(tcp, tcp->u_arg[0]);
1545 tprintf(", %#lx", tcp->u_arg[1]);
1547 else if (abbrev(tcp))
1548 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1552 printargv(tcp, tcp->u_arg[1]);
1563 if (entering(tcp)) {
1564 printpath(tcp, tcp->u_arg[0]);
1566 tprintf(", %#lx", tcp->u_arg[1]);
1568 else if (abbrev(tcp))
1569 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1573 printargv(tcp, tcp->u_arg[1]);
1577 tprintf(", %#lx", tcp->u_arg[2]);
1578 else if (abbrev(tcp))
1579 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1582 printargv(tcp, tcp->u_arg[2]);
1586 #if defined LINUX && defined TCB_WAITEXECVE
1587 tcp->flags |= TCB_WAITEXECVE;
1588 #endif /* LINUX && TCB_WAITEXECVE */
1594 int sys_rexecve(tcp)
1597 if (entering (tcp)) {
1599 tprintf (", %ld", tcp->u_arg[3]);
1611 if (exiting(tcp) && !syserror(tcp) && followfork)
1619 #define __WNOTHREAD 0x20000000
1622 #define __WALL 0x40000000
1625 #define __WCLONE 0x80000000
1629 static struct xlat wait4_options[] = {
1630 { WNOHANG, "WNOHANG" },
1632 { WUNTRACED, "WUNTRACED" },
1635 { WEXITED, "WEXITED" },
1638 { WTRAPPED, "WTRAPPED" },
1641 { WSTOPPED, "WSTOPPED" },
1644 { WCONTINUED, "WCONTINUED" },
1647 { WNOWAIT, "WNOWAIT" },
1650 { __WCLONE, "__WCLONE" },
1653 { __WALL, "__WALL" },
1656 { __WNOTHREAD, "__WNOTHREAD" },
1668 * Here is a tricky presentation problem. This solution
1669 * is still not entirely satisfactory but since there
1670 * are no wait status constructors it will have to do.
1672 if (WIFSTOPPED(status))
1673 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
1674 signame(WSTOPSIG(status)));
1675 else if WIFSIGNALED(status)
1676 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
1677 signame(WTERMSIG(status)),
1678 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1679 else if WIFEXITED(status) {
1680 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1681 WEXITSTATUS(status));
1685 tprintf("[%#x]", status);
1690 printwaitn(tcp, n, bitness)
1698 if (entering(tcp)) {
1699 tprintf("%ld, ", tcp->u_arg[0]);
1704 else if (syserror(tcp) || tcp->u_rval == 0)
1705 tprintf("%#lx", tcp->u_arg[1]);
1706 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1709 exited = printstatus(status);
1712 if (!printflags(wait4_options, tcp->u_arg[2]))
1720 else if (tcp->u_rval > 0) {
1723 printrusage32(tcp, tcp->u_arg[3]);
1726 printrusage(tcp, tcp->u_arg[3]);
1730 else if (tcp->u_rval > 0 && exited)
1731 printrusage(tcp, tcp->u_arg[3]);
1734 tprintf("%#lx", tcp->u_arg[3]);
1746 #ifdef TCB_CLONE_THREAD
1747 if (tcp->flags & TCB_CLONE_THREAD)
1748 /* The children we wait for are our parent's children. */
1749 got_kids = (tcp->parent->nchildren
1750 > tcp->parent->nclone_detached);
1752 got_kids = (tcp->nchildren > tcp->nclone_detached);
1754 got_kids = tcp->nchildren > 0;
1757 if (entering(tcp) && got_kids) {
1758 /* There are children that this parent should block for.
1759 But ptrace made us the parent of the traced children
1760 and the real parent will get ECHILD from the wait call.
1762 XXX If we attached with strace -f -p PID, then there
1763 may be untraced dead children the parent could be reaping
1764 now, but we make him block. */
1766 /* ??? WTA: fix bug with hanging children */
1768 if (!(tcp->u_arg[2] & WNOHANG)) {
1769 /* There are traced children */
1770 tcp->flags |= TCB_SUSPENDED;
1771 tcp->waitpid = tcp->u_arg[0];
1772 #ifdef TCB_CLONE_THREAD
1773 if (tcp->flags & TCB_CLONE_THREAD)
1774 tcp->parent->nclone_waiting++;
1778 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1779 if (tcp->u_arg[2] & WNOHANG) {
1780 /* We must force a fake result of 0 instead of
1781 the ECHILD error. */
1782 extern int force_result();
1783 return force_result(tcp, 0, 0);
1787 "internal_wait: should not have resumed %d\n",
1800 /* The library wrapper stuffs this into the user variable. */
1802 printstatus(getrval2(tcp));
1817 if (!syserror(tcp)) {
1818 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1819 tprintf("%#lx", tcp->u_arg[0]);
1821 printstatus(status);
1832 return printwaitn(tcp, 3, 0);
1839 return printwaitn(tcp, 4, 0);
1847 return printwaitn(tcp, 4, 1);
1853 static struct xlat waitid_types[] = {
1855 { P_PPID, "P_PPID" },
1856 { P_PGID, "P_PGID" },
1863 { P_LWPID, "P_LWPID" },
1875 if (entering(tcp)) {
1876 printxval(waitid_types, tcp->u_arg[0], "P_???");
1877 tprintf(", %ld, ", tcp->u_arg[1]);
1878 if (tcp->nchildren > 0) {
1879 /* There are traced children */
1880 tcp->flags |= TCB_SUSPENDED;
1881 tcp->waitpid = tcp->u_arg[0];
1889 else if (syserror(tcp))
1890 tprintf("%#lx", tcp->u_arg[2]);
1891 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1894 printsiginfo(&si, verbose (tcp));
1897 if (!printflags(wait4_options, tcp->u_arg[3]))
1910 tprintf("%lu", tcp->u_arg[0]);
1918 struct utsname uname;
1921 if (syserror(tcp) || !verbose(tcp))
1922 tprintf("%#lx", tcp->u_arg[0]);
1923 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1925 else if (!abbrev(tcp)) {
1927 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1928 uname.sysname, uname.nodename);
1929 tprintf("release=\"%s\", version=\"%s\", ",
1930 uname.release, uname.version);
1931 tprintf("machine=\"%s\"", uname.machine);
1934 tprintf(", domainname=\"%s\"", uname.domainname);
1935 #endif /* __GLIBC__ */
1940 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1941 uname.sysname, uname.nodename);
1948 static struct xlat ptrace_cmds[] = {
1950 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1951 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1952 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1953 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1954 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1955 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1956 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1957 { PTRACE_CONT, "PTRACE_CONT" },
1958 { PTRACE_KILL, "PTRACE_KILL" },
1959 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1960 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1961 { PTRACE_DETACH, "PTRACE_DETACH" },
1962 #ifdef PTRACE_GETREGS
1963 { PTRACE_GETREGS, "PTRACE_GETREGS" },
1965 #ifdef PTRACE_SETREGS
1966 { PTRACE_SETREGS, "PTRACE_SETREGS" },
1968 #ifdef PTRACE_GETFPREGS
1969 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
1971 #ifdef PTRACE_SETFPREGS
1972 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
1974 #ifdef PTRACE_GETFPXREGS
1975 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1977 #ifdef PTRACE_SETFPXREGS
1978 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1981 { PTRACE_READDATA, "PTRACE_READDATA" },
1982 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1983 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1984 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1985 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1986 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1988 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1989 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1991 { PTRACE_22, "PTRACE_PTRACE_22" },
1992 { PTRACE_23, "PTRACE_PTRACE_23" },
1995 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1997 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1999 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2000 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2001 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2003 { PTRACE_26, "PTRACE_26" },
2004 { PTRACE_27, "PTRACE_27" },
2005 { PTRACE_28, "PTRACE_28" },
2007 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2010 { PT_TRACE_ME, "PT_TRACE_ME" },
2011 { PT_READ_I, "PT_READ_I" },
2012 { PT_READ_D, "PT_READ_D" },
2013 { PT_WRITE_I, "PT_WRITE_I" },
2014 { PT_WRITE_D, "PT_WRITE_D" },
2016 { PT_READ_U, "PT_READ_U" },
2018 { PT_CONTINUE, "PT_CONTINUE" },
2019 { PT_KILL, "PT_KILL" },
2020 { PT_STEP, "PT_STEP" },
2021 { PT_ATTACH, "PT_ATTACH" },
2022 { PT_DETACH, "PT_DETACH" },
2023 { PT_GETREGS, "PT_GETREGS" },
2024 { PT_SETREGS, "PT_SETREGS" },
2025 { PT_GETFPREGS, "PT_GETFPREGS" },
2026 { PT_SETFPREGS, "PT_SETFPREGS" },
2027 { PT_GETDBREGS, "PT_GETDBREGS" },
2028 { PT_SETDBREGS, "PT_SETDBREGS" },
2029 #endif /* FREEBSD */
2034 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2036 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2037 struct xlat struct_user_offsets[] = {
2039 #if defined(S390) || defined(S390X)
2040 { PT_PSWMASK, "psw_mask" },
2041 { PT_PSWADDR, "psw_addr" },
2042 { PT_GPR0, "gpr0" },
2043 { PT_GPR1, "gpr1" },
2044 { PT_GPR2, "gpr2" },
2045 { PT_GPR3, "gpr3" },
2046 { PT_GPR4, "gpr4" },
2047 { PT_GPR5, "gpr5" },
2048 { PT_GPR6, "gpr6" },
2049 { PT_GPR7, "gpr7" },
2050 { PT_GPR8, "gpr8" },
2051 { PT_GPR9, "gpr9" },
2052 { PT_GPR10, "gpr10" },
2053 { PT_GPR11, "gpr11" },
2054 { PT_GPR12, "gpr12" },
2055 { PT_GPR13, "gpr13" },
2056 { PT_GPR14, "gpr14" },
2057 { PT_GPR15, "gpr15" },
2058 { PT_ACR0, "acr0" },
2059 { PT_ACR1, "acr1" },
2060 { PT_ACR2, "acr2" },
2061 { PT_ACR3, "acr3" },
2062 { PT_ACR4, "acr4" },
2063 { PT_ACR5, "acr5" },
2064 { PT_ACR6, "acr6" },
2065 { PT_ACR7, "acr7" },
2066 { PT_ACR8, "acr8" },
2067 { PT_ACR9, "acr9" },
2068 { PT_ACR10, "acr10" },
2069 { PT_ACR11, "acr11" },
2070 { PT_ACR12, "acr12" },
2071 { PT_ACR13, "acr13" },
2072 { PT_ACR14, "acr14" },
2073 { PT_ACR15, "acr15" },
2074 { PT_ORIGGPR2, "orig_gpr2" },
2077 { PT_FPR0_HI, "fpr0.hi" },
2078 { PT_FPR0_LO, "fpr0.lo" },
2079 { PT_FPR1_HI, "fpr1.hi" },
2080 { PT_FPR1_LO, "fpr1.lo" },
2081 { PT_FPR2_HI, "fpr2.hi" },
2082 { PT_FPR2_LO, "fpr2.lo" },
2083 { PT_FPR3_HI, "fpr3.hi" },
2084 { PT_FPR3_LO, "fpr3.lo" },
2085 { PT_FPR4_HI, "fpr4.hi" },
2086 { PT_FPR4_LO, "fpr4.lo" },
2087 { PT_FPR5_HI, "fpr5.hi" },
2088 { PT_FPR5_LO, "fpr5.lo" },
2089 { PT_FPR6_HI, "fpr6.hi" },
2090 { PT_FPR6_LO, "fpr6.lo" },
2091 { PT_FPR7_HI, "fpr7.hi" },
2092 { PT_FPR7_LO, "fpr7.lo" },
2093 { PT_FPR8_HI, "fpr8.hi" },
2094 { PT_FPR8_LO, "fpr8.lo" },
2095 { PT_FPR9_HI, "fpr9.hi" },
2096 { PT_FPR9_LO, "fpr9.lo" },
2097 { PT_FPR10_HI, "fpr10.hi" },
2098 { PT_FPR10_LO, "fpr10.lo" },
2099 { PT_FPR11_HI, "fpr11.hi" },
2100 { PT_FPR11_LO, "fpr11.lo" },
2101 { PT_FPR12_HI, "fpr12.hi" },
2102 { PT_FPR12_LO, "fpr12.lo" },
2103 { PT_FPR13_HI, "fpr13.hi" },
2104 { PT_FPR13_LO, "fpr13.lo" },
2105 { PT_FPR14_HI, "fpr14.hi" },
2106 { PT_FPR14_LO, "fpr14.lo" },
2107 { PT_FPR15_HI, "fpr15.hi" },
2108 { PT_FPR15_LO, "fpr15.lo" },
2111 { PT_FPR0, "fpr0" },
2112 { PT_FPR1, "fpr1" },
2113 { PT_FPR2, "fpr2" },
2114 { PT_FPR3, "fpr3" },
2115 { PT_FPR4, "fpr4" },
2116 { PT_FPR5, "fpr5" },
2117 { PT_FPR6, "fpr6" },
2118 { PT_FPR7, "fpr7" },
2119 { PT_FPR8, "fpr8" },
2120 { PT_FPR9, "fpr9" },
2121 { PT_FPR10, "fpr10" },
2122 { PT_FPR11, "fpr11" },
2123 { PT_FPR12, "fpr12" },
2124 { PT_FPR13, "fpr13" },
2125 { PT_FPR14, "fpr14" },
2126 { PT_FPR15, "fpr15" },
2129 { PT_CR_10, "cr10" },
2130 { PT_CR_11, "cr11" },
2131 { PT_IEEE_IP, "ieee_exception_ip" },
2134 /* XXX No support for these offsets yet. */
2136 /* XXX No support for these offsets yet. */
2137 #elif defined(POWERPC)
2139 #define PT_ORIG_R3 34
2141 #define REGSIZE (sizeof(unsigned long))
2142 { REGSIZE*PT_R0, "r0" },
2143 { REGSIZE*PT_R1, "r1" },
2144 { REGSIZE*PT_R2, "r2" },
2145 { REGSIZE*PT_R3, "r3" },
2146 { REGSIZE*PT_R4, "r4" },
2147 { REGSIZE*PT_R5, "r5" },
2148 { REGSIZE*PT_R6, "r6" },
2149 { REGSIZE*PT_R7, "r7" },
2150 { REGSIZE*PT_R8, "r8" },
2151 { REGSIZE*PT_R9, "r9" },
2152 { REGSIZE*PT_R10, "r10" },
2153 { REGSIZE*PT_R11, "r11" },
2154 { REGSIZE*PT_R12, "r12" },
2155 { REGSIZE*PT_R13, "r13" },
2156 { REGSIZE*PT_R14, "r14" },
2157 { REGSIZE*PT_R15, "r15" },
2158 { REGSIZE*PT_R16, "r16" },
2159 { REGSIZE*PT_R17, "r17" },
2160 { REGSIZE*PT_R18, "r18" },
2161 { REGSIZE*PT_R19, "r19" },
2162 { REGSIZE*PT_R20, "r20" },
2163 { REGSIZE*PT_R21, "r21" },
2164 { REGSIZE*PT_R22, "r22" },
2165 { REGSIZE*PT_R23, "r23" },
2166 { REGSIZE*PT_R24, "r24" },
2167 { REGSIZE*PT_R25, "r25" },
2168 { REGSIZE*PT_R26, "r26" },
2169 { REGSIZE*PT_R27, "r27" },
2170 { REGSIZE*PT_R28, "r28" },
2171 { REGSIZE*PT_R29, "r29" },
2172 { REGSIZE*PT_R30, "r30" },
2173 { REGSIZE*PT_R31, "r31" },
2174 { REGSIZE*PT_NIP, "NIP" },
2175 { REGSIZE*PT_MSR, "MSR" },
2176 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2177 { REGSIZE*PT_CTR, "CTR" },
2178 { REGSIZE*PT_LNK, "LNK" },
2179 { REGSIZE*PT_XER, "XER" },
2180 { REGSIZE*PT_CCR, "CCR" },
2181 { REGSIZE*PT_FPR0, "FPR0" },
2252 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2253 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2254 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2255 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2256 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2257 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2258 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2259 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2260 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2261 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2262 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2263 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2264 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2265 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2266 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2267 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2268 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2269 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2270 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2271 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2272 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2273 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2274 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2275 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2276 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2277 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2278 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2279 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2280 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2281 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2282 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2283 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2285 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2286 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2287 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2288 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2289 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2290 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2291 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2292 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2293 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2294 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2296 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2297 { PT_B4, "b4" }, { PT_B5, "b5" },
2298 { PT_AR_PFS, "kar.pfs" },
2299 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2300 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2303 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
2304 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
2305 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2306 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2307 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2308 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2309 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2310 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2311 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2312 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2313 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2314 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2315 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2316 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2317 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2318 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2319 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2333 { 4*ORIG_EAX, "4*ORIG_EAX" },
2337 { 4*UESP, "4*UESP" },
2357 { 8*ORIG_RAX, "8*ORIG_EAX" },
2360 { 8*EFLAGS, "8*EFL" },
2370 { 4*PT_D1, "4*PT_D1" },
2371 { 4*PT_D2, "4*PT_D2" },
2372 { 4*PT_D3, "4*PT_D3" },
2373 { 4*PT_D4, "4*PT_D4" },
2374 { 4*PT_D5, "4*PT_D5" },
2375 { 4*PT_D6, "4*PT_D6" },
2376 { 4*PT_D7, "4*PT_D7" },
2377 { 4*PT_A0, "4*PT_A0" },
2378 { 4*PT_A1, "4*PT_A1" },
2379 { 4*PT_A2, "4*PT_A2" },
2380 { 4*PT_A3, "4*PT_A3" },
2381 { 4*PT_A4, "4*PT_A4" },
2382 { 4*PT_A5, "4*PT_A5" },
2383 { 4*PT_A6, "4*PT_A6" },
2384 { 4*PT_D0, "4*PT_D0" },
2385 { 4*PT_USP, "4*PT_USP" },
2386 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2387 { 4*PT_SR, "4*PT_SR" },
2388 { 4*PT_PC, "4*PT_PC" },
2392 { 4*REG_REG0, "4*REG_REG0" },
2393 { 4*(REG_REG0+1), "4*REG_REG1" },
2394 { 4*(REG_REG0+2), "4*REG_REG2" },
2395 { 4*(REG_REG0+3), "4*REG_REG3" },
2396 { 4*(REG_REG0+4), "4*REG_REG4" },
2397 { 4*(REG_REG0+5), "4*REG_REG5" },
2398 { 4*(REG_REG0+6), "4*REG_REG6" },
2399 { 4*(REG_REG0+7), "4*REG_REG7" },
2400 { 4*(REG_REG0+8), "4*REG_REG8" },
2401 { 4*(REG_REG0+9), "4*REG_REG9" },
2402 { 4*(REG_REG0+10), "4*REG_REG10" },
2403 { 4*(REG_REG0+11), "4*REG_REG11" },
2404 { 4*(REG_REG0+12), "4*REG_REG12" },
2405 { 4*(REG_REG0+13), "4*REG_REG13" },
2406 { 4*(REG_REG0+14), "4*REG_REG14" },
2407 { 4*REG_REG15, "4*REG_REG15" },
2408 { 4*REG_PC, "4*REG_PC" },
2409 { 4*REG_PR, "4*REG_PR" },
2410 { 4*REG_SR, "4*REG_SR" },
2411 { 4*REG_GBR, "4*REG_GBR" },
2412 { 4*REG_MACH, "4*REG_MACH" },
2413 { 4*REG_MACL, "4*REG_MACL" },
2414 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2415 { 4*REG_FPUL, "4*REG_FPUL" },
2416 { 4*REG_FPREG0, "4*REG_FPREG0" },
2417 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2418 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2419 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2420 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2421 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2422 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2423 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2424 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2425 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2426 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2427 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2428 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2429 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2430 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2431 { 4*REG_FPREG15, "4*REG_FPREG15" },
2432 { 4*REG_XDREG0, "4*REG_XDREG0" },
2433 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2434 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2435 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2436 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2437 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2438 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2439 { 4*REG_XDREG14, "4*REG_XDREG14" },
2440 { 4*REG_FPSCR, "4*REG_FPSCR" },
2443 #if !defined(S390) && !defined(S390X) && !defined(MIPS)
2444 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
2446 #if defined(I386) || defined(X86_64)
2447 { uoff(i387), "offsetof(struct user, i387)" },
2450 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2453 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2454 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2455 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2456 { uoff(start_code), "offsetof(struct user, start_code)" },
2457 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2458 { uoff(signal), "offsetof(struct user, signal)" },
2459 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
2460 { uoff(reserved), "offsetof(struct user, reserved)" },
2462 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2463 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
2464 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2466 { uoff(magic), "offsetof(struct user, magic)" },
2467 { uoff(u_comm), "offsetof(struct user, u_comm)" },
2468 #if defined(I386) || defined(X86_64)
2469 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2473 #endif /* !POWERPC/!SPARC */
2476 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2477 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2478 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2479 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2480 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2481 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2482 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2483 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2484 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2485 { uoff(u_error), "offsetof(struct user, u_error)" },
2486 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2487 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2488 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2489 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2490 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2491 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2492 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2493 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2494 { uoff(u_code), "offsetof(struct user, u_code)" },
2495 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2496 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2497 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2498 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2499 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2500 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2501 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2502 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2503 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2504 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2505 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2506 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2507 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2508 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2509 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2510 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2511 { uoff(u_start), "offsetof(struct user, u_start)" },
2512 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2513 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2514 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2515 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2516 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2517 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2518 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2519 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2520 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2523 { sizeof(struct user), "sizeof(struct user)" },
2536 if (entering(tcp)) {
2537 printxval(ptrace_cmds, tcp->u_arg[0],
2544 tprintf(", %lu, ", tcp->u_arg[1]);
2545 addr = tcp->u_arg[2];
2547 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2548 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2549 for (x = struct_user_offsets; x->str; x++) {
2554 tprintf("%#lx, ", addr);
2555 else if (x->val > addr && x != struct_user_offsets) {
2557 tprintf("%s + %ld, ", x->str, addr - x->val);
2560 tprintf("%s, ", x->str);
2564 tprintf("%#lx, ", tcp->u_arg[2]);
2566 switch (tcp->u_arg[0]) {
2567 case PTRACE_PEEKDATA:
2568 case PTRACE_PEEKTEXT:
2569 case PTRACE_PEEKUSER:
2572 case PTRACE_SINGLESTEP:
2573 case PTRACE_SYSCALL:
2575 printsignal(tcp->u_arg[3]);
2578 tprintf("%#lx", tcp->u_arg[3]);
2582 switch (tcp->u_arg[0]) {
2583 case PTRACE_PEEKDATA:
2584 case PTRACE_PEEKTEXT:
2585 case PTRACE_PEEKUSER:
2586 printnum(tcp, tcp->u_arg[3], "%#lx");
2592 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2593 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2594 tprintf("%lu, ", tcp->u_arg[3]);
2595 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2596 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2597 tcp->u_arg[0] != PTRACE_READTEXT) {
2598 tprintf("%#lx", tcp->u_arg[3]);
2601 if (tcp->u_arg[0] == PTRACE_READDATA ||
2602 tcp->u_arg[0] == PTRACE_READTEXT) {
2603 tprintf("%lu, ", tcp->u_arg[3]);
2604 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2609 tprintf("%lu", tcp->u_arg[3]);
2611 #endif /* FREEBSD */
2618 static struct xlat futexops[] = {
2619 { FUTEX_WAIT, "FUTEX_WAIT" },
2620 { FUTEX_WAKE, "FUTEX_WAKE" },
2621 { FUTEX_FD, "FUTEX_FD" },
2629 if (entering(tcp)) {
2630 tprintf("%p, ", (void *) tcp->u_arg[0]);
2631 printflags(futexops, tcp->u_arg[1]);
2632 tprintf(", %ld, ", tcp->u_arg[2]);
2633 printtv(tcp, tcp->u_arg[3]);
2639 print_affinitylist(list, len)
2640 unsigned long *list;
2645 while (len > sizeof (unsigned long)) {
2646 tprintf("%s %lx", first ? "" : ",", *list++);
2648 len -= sizeof (unsigned long);
2654 sys_sched_setaffinity(tcp)
2657 if (entering(tcp)) {
2658 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2659 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2665 sys_sched_getaffinity(tcp)
2668 if (entering(tcp)) {
2669 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2671 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);