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;
462 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
463 fprintf(stderr, "sys_fork: tcb table full\n");
466 if (proc_open(tcpchild, 2) < 0)
472 #else /* !USE_PROCFS */
476 /* defines copied from linux/sched.h since we can't include that
477 * ourselves (it conflicts with *lots* of libc includes)
479 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
480 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
481 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
482 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
483 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
484 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
485 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
486 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
487 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
488 #define CLONE_THREAD 0x00010000 /* Same thread group? */
489 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
490 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
491 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
492 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
493 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
494 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
495 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
496 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
498 static struct xlat clone_flags[] = {
499 { CLONE_VM, "CLONE_VM" },
500 { CLONE_FS, "CLONE_FS" },
501 { CLONE_FILES, "CLONE_FILES" },
502 { CLONE_SIGHAND, "CLONE_SIGHAND" },
503 { CLONE_IDLETASK, "CLONE_IDLETASK"},
504 { CLONE_PTRACE, "CLONE_PTRACE" },
505 { CLONE_VFORK, "CLONE_VFORK" },
506 { CLONE_PARENT, "CLONE_PARENT" },
507 { CLONE_THREAD, "CLONE_THREAD" },
508 { CLONE_NEWNS, "CLONE_NEWNS" },
509 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
510 { CLONE_SETTLS, "CLONE_SETTLS" },
511 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
512 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
513 { CLONE_DETACHED, "CLONE_DETACHED" },
514 { CLONE_UNTRACED, "CLONE_UNTRACED" },
515 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
520 # include <asm/ldt.h>
521 extern void print_ldt_entry();
530 # if defined S390 || defined S390X
531 /* For some reason, S390 has the stack argument first. */
532 stack = tcp->u_arg[0];
533 flags = tcp->u_arg[1];
535 flags = tcp->u_arg[0];
536 stack = tcp->u_arg[1];
538 tprintf("child_stack=%#lx, flags=", stack);
539 if (printflags(clone_flags, flags) == 0)
541 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
542 |CLONE_SETTLS)) == 0)
544 if (flags & CLONE_PARENT_SETTID) {
546 if (umove(tcp, tcp->u_arg[2], &pid) == 0)
547 tprintf(", [%d]", pid);
549 tprintf(", %#lx", tcp->u_arg[2]);
552 tprintf(", <ignored>");
554 if (flags & CLONE_SETTLS) {
555 struct modify_ldt_ldt_s copy;
556 if (umove(tcp, tcp->u_arg[3], ©) != -1) {
557 tprintf(", {entry_number:%d, ",
562 print_ldt_entry(©);
565 tprintf(", %#lx", tcp->u_arg[3]);
568 tprintf(", <ignored>");
573 if (flags & CLONE_CHILD_SETTID)
574 tprintf(", %#lx", tcp->u_arg[TIDARG]);
585 tprintf("child_stack=%#lx, stack_size=%#lx, flags=",
586 tcp->u_arg[1], tcp->u_arg[2]);
587 if (printflags(clone_flags, tcp->u_arg[0]) == 0)
600 return RVAL_UDECIMAL;
605 change_syscall(tcp, new)
611 /* Attempt to make vfork into fork, which we can follow. */
612 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
615 #elif defined(X86_64)
616 /* Attempt to make vfork into fork, which we can follow. */
617 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
620 #elif defined(POWERPC)
621 if (ptrace(PTRACE_POKEUSER, tcp->pid,
622 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
625 #elif defined(S390) || defined(S390X)
626 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
627 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
631 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
636 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
639 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
643 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
647 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
651 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
655 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
659 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
663 #warning Do not know how to handle change_syscall for this architecture
664 #endif /* architecture */
676 unsigned long *bsp, *ap;
678 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
681 ap = ia64_rse_skip_regs(bsp, argnum);
683 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
690 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
694 #elif defined(X86_64)
696 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
700 #elif defined(POWERPC)
702 #define PT_ORIG_R3 34
705 ptrace(PTRACE_POKEUSER, tcp->pid,
706 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
715 ptrace(PTRACE_POKEUSER, tcp->pid,
716 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
720 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
723 ptrace(PTRACE_POKEDATA, tcp->pid,
724 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
729 #elif defined(S390) || defined(S390X)
732 ptrace(PTRACE_POKEUSER, tcp->pid,
733 (char *) (argnum==0 ? PT_ORIGGPR2 :
734 PT_GPR2 + argnum*sizeof(long)),
742 # warning Sorry, setargs not implemented for this architecture.
747 #if defined SYS_clone || defined SYS_clone2
752 struct tcb *tcpchild;
762 int bpt = tcp->flags & TCB_BPTSET;
764 if (!(tcp->flags & TCB_FOLLOWFORK))
775 #ifdef CLONE_PTRACE /* See new setbpt code. */
776 tcpchild = pid2tcb(pid);
777 if (tcpchild != NULL) {
778 /* The child already reported its startup trap
779 before the parent reported its syscall return. */
781 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
782 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
784 [preattached child %d of %d in weird state!]\n",
789 if ((tcpchild = alloctcb(pid)) == NULL) {
792 fprintf(stderr, " [tcb table full]\n");
793 kill(pid, SIGKILL); /* XXX */
798 /* Attach to the new child */
799 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
802 perror("PTRACE_ATTACH");
803 fprintf(stderr, "Too late?\n");
812 tcpchild->flags |= TCB_ATTACHED;
813 /* Child has BPT too, must be removed on first occasion. */
815 tcpchild->flags |= TCB_BPTSET;
816 tcpchild->baddr = tcp->baddr;
817 memcpy(tcpchild->inst, tcp->inst,
818 sizeof tcpchild->inst);
820 tcpchild->parent = tcp;
822 if (tcpchild->flags & TCB_SUSPENDED) {
823 /* The child was born suspended, due to our having
824 forced CLONE_PTRACE. */
828 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
829 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
830 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
836 Process %u resumed (parent %d ready)\n",
842 fprintf(stderr, "Process %d attached\n", pid);
845 #ifdef TCB_CLONE_THREAD
846 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
847 /* The parent in this clone is itself a thread
848 belonging to another process. There is no
849 meaning to the parentage relationship of the new
850 child with the thread, only with the process.
851 We associate the new thread with our parent.
852 Since this is done for every new thread, there
853 will never be a TCB_CLONE_THREAD process that
856 tcp->u_arg[0] = tcp->parent->u_arg[0];
858 tcpchild->parent = tcp;
862 if (tcp->u_arg[0] & CLONE_THREAD) {
863 tcpchild->flags |= TCB_CLONE_THREAD;
864 ++tcp->nclone_threads;
866 if (tcp->u_arg[0] & CLONE_DETACHED) {
867 tcpchild->flags |= TCB_CLONE_DETACHED;
868 ++tcp->nclone_detached;
882 /* We do special magic with clone for any clone or fork. */
883 return internal_clone(tcp);
886 struct tcb *tcpchild;
891 if (tcp->scno == SYS_vfork) {
892 /* Attempt to make vfork into fork, which we can follow. */
894 change_syscall(tcp, SYS_fork) < 0)
899 if (!followfork || dont_follow)
907 int bpt = tcp->flags & TCB_BPTSET;
909 if (!(tcp->flags & TCB_FOLLOWFORK))
918 if ((tcpchild = alloctcb(pid)) == NULL) {
919 fprintf(stderr, " [tcb table full]\n");
920 kill(pid, SIGKILL); /* XXX */
925 /* The child must have run before it can be attached. */
926 /* This must be a bug in the parisc kernel, but I havn't
927 * identified it yet. Seems to be an issue associated
928 * with attaching to a process (which sends it a signal)
929 * before that process has ever been scheduled. When
930 * debugging, I started seeing crashes in
931 * arch/parisc/kernel/signal.c:do_signal(), apparently
932 * caused by r8 getting corrupt over the dequeue_signal()
933 * call. Didn't make much sense though...
939 select(0, NULL, NULL, NULL, &tv);
942 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
943 perror("PTRACE_ATTACH");
944 fprintf(stderr, "Too late?\n");
951 /* The child must have run before it can be attached. */
956 select(0, NULL, NULL, NULL, &tv);
958 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
959 perror("PTRACE_ATTACH");
960 fprintf(stderr, "Too late?\n");
965 /* Try to catch the new process as soon as possible. */
968 for (i = 0; i < 1024; i++)
969 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
972 perror("PTRACE_ATTACH");
973 fprintf(stderr, "Too late?\n");
980 tcpchild->flags |= TCB_ATTACHED;
981 /* Child has BPT too, must be removed on first occasion */
983 tcpchild->flags |= TCB_BPTSET;
984 tcpchild->baddr = tcp->baddr;
985 memcpy(tcpchild->inst, tcp->inst,
986 sizeof tcpchild->inst);
989 tcpchild->parent = tcp;
992 fprintf(stderr, "Process %d attached\n", pid);
998 #endif /* !USE_PROCFS */
1000 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1007 return RVAL_UDECIMAL;
1011 #endif /* SUNOS4 || LINUX || FREEBSD */
1015 static char idstr[16];
1022 sprintf(idstr, "ppid %lu", getrval2(tcp));
1023 tcp->auxstr = idstr;
1034 sprintf(idstr, "euid %lu", getrval2(tcp));
1035 tcp->auxstr = idstr;
1046 sprintf(idstr, "egid %lu", getrval2(tcp));
1047 tcp->auxstr = idstr;
1061 if (entering(tcp)) {
1062 tprintf("%u", (uid_t) tcp->u_arg[0]);
1071 if (entering(tcp)) {
1072 tprintf("%u", (gid_t) tcp->u_arg[0]);
1084 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1085 tcp->u_arg[1], tcp->u_arg[2]);
1087 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1088 tprintf("%#lx, ", tcp->u_arg[0]);
1090 tprintf("ruid %lu, ", (unsigned long) uid);
1091 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1092 tprintf("%#lx, ", tcp->u_arg[0]);
1094 tprintf("euid %lu, ", (unsigned long) uid);
1095 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1096 tprintf("%#lx", tcp->u_arg[0]);
1098 tprintf("suid %lu", (unsigned long) uid);
1111 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1112 tcp->u_arg[1], tcp->u_arg[2]);
1114 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1115 tprintf("%#lx, ", tcp->u_arg[0]);
1117 tprintf("rgid %lu, ", (unsigned long) gid);
1118 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1119 tprintf("%#lx, ", tcp->u_arg[0]);
1121 tprintf("egid %lu, ", (unsigned long) gid);
1122 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1123 tprintf("%#lx", tcp->u_arg[0]);
1125 tprintf("sgid %lu", (unsigned long) gid);
1137 if (entering(tcp)) {
1139 (unsigned long) (uid_t) tcp->u_arg[0],
1140 (unsigned long) (uid_t) tcp->u_arg[1]);
1149 if (entering(tcp)) {
1151 (unsigned long) (gid_t) tcp->u_arg[0],
1152 (unsigned long) (gid_t) tcp->u_arg[1]);
1157 #if defined(LINUX) || defined(FREEBSD)
1162 if (entering(tcp)) {
1163 tprintf("ruid %u, euid %u, suid %u",
1164 (uid_t) tcp->u_arg[0],
1165 (uid_t) tcp->u_arg[1],
1166 (uid_t) tcp->u_arg[2]);
1174 if (entering(tcp)) {
1175 tprintf("rgid %u, egid %u, sgid %u",
1176 (uid_t) tcp->u_arg[0],
1177 (uid_t) tcp->u_arg[1],
1178 (uid_t) tcp->u_arg[2]);
1183 #endif /* LINUX || FREEBSD */
1190 GETGROUPS_T *gidset;
1192 if (entering(tcp)) {
1193 len = tcp->u_arg[0];
1194 tprintf("%u, ", len);
1199 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1200 if (gidset == NULL) {
1201 fprintf(stderr, "sys_setgroups: out of memory\n");
1205 tprintf("%#lx", tcp->u_arg[1]);
1206 else if (umoven(tcp, tcp->u_arg[1],
1207 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1211 for (i = 0; i < len; i++)
1212 tprintf("%s%lu", i ? ", " : "",
1213 (unsigned long) gidset[i]);
1216 free((char *) gidset);
1226 GETGROUPS_T *gidset;
1228 if (entering(tcp)) {
1229 len = tcp->u_arg[0];
1230 tprintf("%u, ", len);
1237 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1238 if (gidset == NULL) {
1239 fprintf(stderr, "sys_getgroups: out of memory\n");
1244 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1245 tprintf("%#lx", tcp->u_arg[1]);
1246 else if (umoven(tcp, tcp->u_arg[1],
1247 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1251 for (i = 0; i < len; i++)
1252 tprintf("%s%lu", i ? ", " : "",
1253 (unsigned long) gidset[i]);
1256 free((char *)gidset);
1265 if (entering(tcp)) {
1267 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1277 if (entering(tcp)) {
1279 tprintf("%lu", tcp->u_arg[0]);
1289 if (entering(tcp)) {
1290 tprintf("%lu", tcp->u_arg[0]);
1306 if (entering(tcp)) {
1307 tprintf("%lu", tcp->u_arg[0]);
1316 if (entering(tcp)) {
1317 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1324 #include <sys/privilege.h>
1327 static struct xlat procpriv_cmds [] = {
1328 { SETPRV, "SETPRV" },
1329 { CLRPRV, "CLRPRV" },
1330 { PUTPRV, "PUTPRV" },
1331 { GETPRV, "GETPRV" },
1332 { CNTPRV, "CNTPRV" },
1337 static struct xlat procpriv_priv [] = {
1338 { P_OWNER, "P_OWNER" },
1339 { P_AUDIT, "P_AUDIT" },
1340 { P_COMPAT, "P_COMPAT" },
1341 { P_DACREAD, "P_DACREAD" },
1342 { P_DACWRITE, "P_DACWRITE" },
1344 { P_FILESYS, "P_FILESYS" },
1345 { P_MACREAD, "P_MACREAD" },
1346 { P_MACWRITE, "P_MACWRITE" },
1347 { P_MOUNT, "P_MOUNT" },
1348 { P_MULTIDIR, "P_MULTIDIR" },
1349 { P_SETPLEVEL, "P_SETPLEVEL" },
1350 { P_SETSPRIV, "P_SETSPRIV" },
1351 { P_SETUID, "P_SETUID" },
1352 { P_SYSOPS, "P_SYSOPS" },
1353 { P_SETUPRIV, "P_SETUPRIV" },
1354 { P_DRIVER, "P_DRIVER" },
1355 { P_RTIME, "P_RTIME" },
1356 { P_MACUPGRADE, "P_MACUPGRADE" },
1357 { P_FSYSRANGE, "P_FSYSRANGE" },
1358 { P_SETFLEVEL, "P_SETFLEVEL" },
1359 { P_AUDITWR, "P_AUDITWR" },
1360 { P_TSHAR, "P_TSHAR" },
1361 { P_PLOCK, "P_PLOCK" },
1362 { P_CORE, "P_CORE" },
1363 { P_LOADMOD, "P_LOADMOD" },
1364 { P_BIND, "P_BIND" },
1365 { P_ALLPRIVS, "P_ALLPRIVS" },
1370 static struct xlat procpriv_type [] = {
1371 { PS_FIX, "PS_FIX" },
1372 { PS_INH, "PS_INH" },
1373 { PS_MAX, "PS_MAX" },
1374 { PS_WKG, "PS_WKG" },
1380 printpriv(tcp, addr, len, opt)
1387 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1388 int dots = len > max;
1391 if (len > max) len = max;
1394 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1396 tprintf ("%#lx", addr);
1402 for (i = 0; i < len; ++i) {
1405 if (i) tprintf (", ");
1407 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1408 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1410 tprintf ("%s|%s", t, p);
1413 tprintf ("%#lx", buf [i]);
1417 if (dots) tprintf (" ...");
1427 if (entering(tcp)) {
1428 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1429 switch (tcp->u_arg[0]) {
1431 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1439 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1440 tprintf (", %ld", tcp->u_arg[2]);
1443 else if (tcp->u_arg[0] == GETPRV) {
1444 if (syserror (tcp)) {
1445 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1449 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1450 tprintf (", %ld", tcp->u_arg[2]);
1461 fake_execve(tcp, program, argv, envp)
1470 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1473 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1478 string_quote(program);
1480 for (i = 0; argv[i] != NULL; i++) {
1483 string_quote(argv[i]);
1485 for (i = 0; envp[i] != NULL; i++)
1487 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1494 printargv(tcp, addr)
1500 int max = max_strlen / 2;
1502 for (sep = ""; --max >= 0; sep = ", ") {
1505 if (umove(tcp, addr, &cp) < 0) {
1506 tprintf("%#lx", addr);
1512 printstr(tcp, (long) cp, -1);
1513 addr += sizeof(char *);
1520 printargc(fmt, tcp, addr)
1528 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1529 addr += sizeof(char *);
1531 tprintf(fmt, count, count == 1 ? "" : "s");
1538 if (entering(tcp)) {
1539 printpath(tcp, tcp->u_arg[0]);
1541 tprintf(", %#lx", tcp->u_arg[1]);
1543 else if (abbrev(tcp))
1544 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1548 printargv(tcp, tcp->u_arg[1]);
1559 if (entering(tcp)) {
1560 printpath(tcp, tcp->u_arg[0]);
1562 tprintf(", %#lx", tcp->u_arg[1]);
1564 else if (abbrev(tcp))
1565 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1569 printargv(tcp, tcp->u_arg[1]);
1573 tprintf(", %#lx", tcp->u_arg[2]);
1574 else if (abbrev(tcp))
1575 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1578 printargv(tcp, tcp->u_arg[2]);
1582 #if defined LINUX && defined TCB_WAITEXECVE
1583 tcp->flags |= TCB_WAITEXECVE;
1584 #endif /* LINUX && TCB_WAITEXECVE */
1590 int sys_rexecve(tcp)
1593 if (entering (tcp)) {
1595 tprintf (", %ld", tcp->u_arg[3]);
1607 if (exiting(tcp) && !syserror(tcp) && followfork)
1615 #define __WNOTHREAD 0x20000000
1618 #define __WALL 0x40000000
1621 #define __WCLONE 0x80000000
1625 static struct xlat wait4_options[] = {
1626 { WNOHANG, "WNOHANG" },
1628 { WUNTRACED, "WUNTRACED" },
1631 { WEXITED, "WEXITED" },
1634 { WTRAPPED, "WTRAPPED" },
1637 { WSTOPPED, "WSTOPPED" },
1640 { WCONTINUED, "WCONTINUED" },
1643 { WNOWAIT, "WNOWAIT" },
1646 { __WCLONE, "__WCLONE" },
1649 { __WALL, "__WALL" },
1652 { __WNOTHREAD, "__WNOTHREAD" },
1664 * Here is a tricky presentation problem. This solution
1665 * is still not entirely satisfactory but since there
1666 * are no wait status constructors it will have to do.
1668 if (WIFSTOPPED(status))
1669 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
1670 signame(WSTOPSIG(status)));
1671 else if WIFSIGNALED(status)
1672 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
1673 signame(WTERMSIG(status)),
1674 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1675 else if WIFEXITED(status) {
1676 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1677 WEXITSTATUS(status));
1681 tprintf("[%#x]", status);
1686 printwaitn(tcp, n, bitness)
1694 if (entering(tcp)) {
1695 tprintf("%ld, ", tcp->u_arg[0]);
1700 else if (syserror(tcp) || tcp->u_rval == 0)
1701 tprintf("%#lx", tcp->u_arg[1]);
1702 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1705 exited = printstatus(status);
1708 if (!printflags(wait4_options, tcp->u_arg[2]))
1716 else if (tcp->u_rval > 0) {
1719 printrusage32(tcp, tcp->u_arg[3]);
1722 printrusage(tcp, tcp->u_arg[3]);
1726 else if (tcp->u_rval > 0 && exited)
1727 printrusage(tcp, tcp->u_arg[3]);
1730 tprintf("%#lx", tcp->u_arg[3]);
1742 #ifdef TCB_CLONE_THREAD
1743 if (tcp->flags & TCB_CLONE_THREAD)
1744 /* The children we wait for are our parent's children. */
1745 got_kids = (tcp->parent->nchildren
1746 > tcp->parent->nclone_detached);
1748 got_kids = (tcp->nchildren > tcp->nclone_detached);
1750 got_kids = tcp->nchildren > 0;
1753 if (entering(tcp) && got_kids) {
1754 /* There are children that this parent should block for.
1755 But ptrace made us the parent of the traced children
1756 and the real parent will get ECHILD from the wait call.
1758 XXX If we attached with strace -f -p PID, then there
1759 may be untraced dead children the parent could be reaping
1760 now, but we make him block. */
1762 /* ??? WTA: fix bug with hanging children */
1764 if (!(tcp->u_arg[2] & WNOHANG)) {
1765 /* There are traced children */
1766 tcp->flags |= TCB_SUSPENDED;
1767 tcp->waitpid = tcp->u_arg[0];
1768 #ifdef TCB_CLONE_THREAD
1769 if (tcp->flags & TCB_CLONE_THREAD)
1770 tcp->parent->nclone_waiting++;
1774 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1775 if (tcp->u_arg[2] & WNOHANG) {
1776 /* We must force a fake result of 0 instead of
1777 the ECHILD error. */
1778 extern int force_result();
1779 return force_result(tcp, 0, 0);
1783 "internal_wait: should not have resumed %d\n",
1796 /* The library wrapper stuffs this into the user variable. */
1798 printstatus(getrval2(tcp));
1813 if (!syserror(tcp)) {
1814 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1815 tprintf("%#lx", tcp->u_arg[0]);
1817 printstatus(status);
1828 return printwaitn(tcp, 3, 0);
1835 return printwaitn(tcp, 4, 0);
1843 return printwaitn(tcp, 4, 1);
1849 static struct xlat waitid_types[] = {
1851 { P_PPID, "P_PPID" },
1852 { P_PGID, "P_PGID" },
1859 { P_LWPID, "P_LWPID" },
1871 if (entering(tcp)) {
1872 printxval(waitid_types, tcp->u_arg[0], "P_???");
1873 tprintf(", %ld, ", tcp->u_arg[1]);
1874 if (tcp->nchildren > 0) {
1875 /* There are traced children */
1876 tcp->flags |= TCB_SUSPENDED;
1877 tcp->waitpid = tcp->u_arg[0];
1885 else if (syserror(tcp))
1886 tprintf("%#lx", tcp->u_arg[2]);
1887 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1890 printsiginfo(&si, verbose (tcp));
1893 if (!printflags(wait4_options, tcp->u_arg[3]))
1906 tprintf("%lu", tcp->u_arg[0]);
1914 struct utsname uname;
1917 if (syserror(tcp) || !verbose(tcp))
1918 tprintf("%#lx", tcp->u_arg[0]);
1919 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1921 else if (!abbrev(tcp)) {
1923 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1924 uname.sysname, uname.nodename);
1925 tprintf("release=\"%s\", version=\"%s\", ",
1926 uname.release, uname.version);
1927 tprintf("machine=\"%s\"", uname.machine);
1930 tprintf(", domainname=\"%s\"", uname.domainname);
1931 #endif /* __GLIBC__ */
1936 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1937 uname.sysname, uname.nodename);
1944 static struct xlat ptrace_cmds[] = {
1946 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1947 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1948 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1949 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1950 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1951 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1952 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1953 { PTRACE_CONT, "PTRACE_CONT" },
1954 { PTRACE_KILL, "PTRACE_KILL" },
1955 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1956 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1957 { PTRACE_DETACH, "PTRACE_DETACH" },
1958 #ifdef PTRACE_GETREGS
1959 { PTRACE_GETREGS, "PTRACE_GETREGS" },
1961 #ifdef PTRACE_SETREGS
1962 { PTRACE_SETREGS, "PTRACE_SETREGS" },
1964 #ifdef PTRACE_GETFPREGS
1965 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
1967 #ifdef PTRACE_SETFPREGS
1968 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
1970 #ifdef PTRACE_GETFPXREGS
1971 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1973 #ifdef PTRACE_SETFPXREGS
1974 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1977 { PTRACE_READDATA, "PTRACE_READDATA" },
1978 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1979 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1980 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1981 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1982 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1984 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1985 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1987 { PTRACE_22, "PTRACE_PTRACE_22" },
1988 { PTRACE_23, "PTRACE_PTRACE_23" },
1991 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1993 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1995 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1996 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1997 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
1999 { PTRACE_26, "PTRACE_26" },
2000 { PTRACE_27, "PTRACE_27" },
2001 { PTRACE_28, "PTRACE_28" },
2003 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2006 { PT_TRACE_ME, "PT_TRACE_ME" },
2007 { PT_READ_I, "PT_READ_I" },
2008 { PT_READ_D, "PT_READ_D" },
2009 { PT_WRITE_I, "PT_WRITE_I" },
2010 { PT_WRITE_D, "PT_WRITE_D" },
2012 { PT_READ_U, "PT_READ_U" },
2014 { PT_CONTINUE, "PT_CONTINUE" },
2015 { PT_KILL, "PT_KILL" },
2016 { PT_STEP, "PT_STEP" },
2017 { PT_ATTACH, "PT_ATTACH" },
2018 { PT_DETACH, "PT_DETACH" },
2019 { PT_GETREGS, "PT_GETREGS" },
2020 { PT_SETREGS, "PT_SETREGS" },
2021 { PT_GETFPREGS, "PT_GETFPREGS" },
2022 { PT_SETFPREGS, "PT_SETFPREGS" },
2023 { PT_GETDBREGS, "PT_GETDBREGS" },
2024 { PT_SETDBREGS, "PT_SETDBREGS" },
2025 #endif /* FREEBSD */
2030 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2032 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2033 struct xlat struct_user_offsets[] = {
2035 #if defined(S390) || defined(S390X)
2036 { PT_PSWMASK, "psw_mask" },
2037 { PT_PSWADDR, "psw_addr" },
2038 { PT_GPR0, "gpr0" },
2039 { PT_GPR1, "gpr1" },
2040 { PT_GPR2, "gpr2" },
2041 { PT_GPR3, "gpr3" },
2042 { PT_GPR4, "gpr4" },
2043 { PT_GPR5, "gpr5" },
2044 { PT_GPR6, "gpr6" },
2045 { PT_GPR7, "gpr7" },
2046 { PT_GPR8, "gpr8" },
2047 { PT_GPR9, "gpr9" },
2048 { PT_GPR10, "gpr10" },
2049 { PT_GPR11, "gpr11" },
2050 { PT_GPR12, "gpr12" },
2051 { PT_GPR13, "gpr13" },
2052 { PT_GPR14, "gpr14" },
2053 { PT_GPR15, "gpr15" },
2054 { PT_ACR0, "acr0" },
2055 { PT_ACR1, "acr1" },
2056 { PT_ACR2, "acr2" },
2057 { PT_ACR3, "acr3" },
2058 { PT_ACR4, "acr4" },
2059 { PT_ACR5, "acr5" },
2060 { PT_ACR6, "acr6" },
2061 { PT_ACR7, "acr7" },
2062 { PT_ACR8, "acr8" },
2063 { PT_ACR9, "acr9" },
2064 { PT_ACR10, "acr10" },
2065 { PT_ACR11, "acr11" },
2066 { PT_ACR12, "acr12" },
2067 { PT_ACR13, "acr13" },
2068 { PT_ACR14, "acr14" },
2069 { PT_ACR15, "acr15" },
2070 { PT_ORIGGPR2, "orig_gpr2" },
2073 { PT_FPR0_HI, "fpr0.hi" },
2074 { PT_FPR0_LO, "fpr0.lo" },
2075 { PT_FPR1_HI, "fpr1.hi" },
2076 { PT_FPR1_LO, "fpr1.lo" },
2077 { PT_FPR2_HI, "fpr2.hi" },
2078 { PT_FPR2_LO, "fpr2.lo" },
2079 { PT_FPR3_HI, "fpr3.hi" },
2080 { PT_FPR3_LO, "fpr3.lo" },
2081 { PT_FPR4_HI, "fpr4.hi" },
2082 { PT_FPR4_LO, "fpr4.lo" },
2083 { PT_FPR5_HI, "fpr5.hi" },
2084 { PT_FPR5_LO, "fpr5.lo" },
2085 { PT_FPR6_HI, "fpr6.hi" },
2086 { PT_FPR6_LO, "fpr6.lo" },
2087 { PT_FPR7_HI, "fpr7.hi" },
2088 { PT_FPR7_LO, "fpr7.lo" },
2089 { PT_FPR8_HI, "fpr8.hi" },
2090 { PT_FPR8_LO, "fpr8.lo" },
2091 { PT_FPR9_HI, "fpr9.hi" },
2092 { PT_FPR9_LO, "fpr9.lo" },
2093 { PT_FPR10_HI, "fpr10.hi" },
2094 { PT_FPR10_LO, "fpr10.lo" },
2095 { PT_FPR11_HI, "fpr11.hi" },
2096 { PT_FPR11_LO, "fpr11.lo" },
2097 { PT_FPR12_HI, "fpr12.hi" },
2098 { PT_FPR12_LO, "fpr12.lo" },
2099 { PT_FPR13_HI, "fpr13.hi" },
2100 { PT_FPR13_LO, "fpr13.lo" },
2101 { PT_FPR14_HI, "fpr14.hi" },
2102 { PT_FPR14_LO, "fpr14.lo" },
2103 { PT_FPR15_HI, "fpr15.hi" },
2104 { PT_FPR15_LO, "fpr15.lo" },
2107 { PT_FPR0, "fpr0" },
2108 { PT_FPR1, "fpr1" },
2109 { PT_FPR2, "fpr2" },
2110 { PT_FPR3, "fpr3" },
2111 { PT_FPR4, "fpr4" },
2112 { PT_FPR5, "fpr5" },
2113 { PT_FPR6, "fpr6" },
2114 { PT_FPR7, "fpr7" },
2115 { PT_FPR8, "fpr8" },
2116 { PT_FPR9, "fpr9" },
2117 { PT_FPR10, "fpr10" },
2118 { PT_FPR11, "fpr11" },
2119 { PT_FPR12, "fpr12" },
2120 { PT_FPR13, "fpr13" },
2121 { PT_FPR14, "fpr14" },
2122 { PT_FPR15, "fpr15" },
2125 { PT_CR_10, "cr10" },
2126 { PT_CR_11, "cr11" },
2127 { PT_IEEE_IP, "ieee_exception_ip" },
2130 /* XXX No support for these offsets yet. */
2132 /* XXX No support for these offsets yet. */
2133 #elif defined(POWERPC)
2135 #define PT_ORIG_R3 34
2137 #define REGSIZE (sizeof(unsigned long))
2138 { REGSIZE*PT_R0, "r0" },
2139 { REGSIZE*PT_R1, "r1" },
2140 { REGSIZE*PT_R2, "r2" },
2141 { REGSIZE*PT_R3, "r3" },
2142 { REGSIZE*PT_R4, "r4" },
2143 { REGSIZE*PT_R5, "r5" },
2144 { REGSIZE*PT_R6, "r6" },
2145 { REGSIZE*PT_R7, "r7" },
2146 { REGSIZE*PT_R8, "r8" },
2147 { REGSIZE*PT_R9, "r9" },
2148 { REGSIZE*PT_R10, "r10" },
2149 { REGSIZE*PT_R11, "r11" },
2150 { REGSIZE*PT_R12, "r12" },
2151 { REGSIZE*PT_R13, "r13" },
2152 { REGSIZE*PT_R14, "r14" },
2153 { REGSIZE*PT_R15, "r15" },
2154 { REGSIZE*PT_R16, "r16" },
2155 { REGSIZE*PT_R17, "r17" },
2156 { REGSIZE*PT_R18, "r18" },
2157 { REGSIZE*PT_R19, "r19" },
2158 { REGSIZE*PT_R20, "r20" },
2159 { REGSIZE*PT_R21, "r21" },
2160 { REGSIZE*PT_R22, "r22" },
2161 { REGSIZE*PT_R23, "r23" },
2162 { REGSIZE*PT_R24, "r24" },
2163 { REGSIZE*PT_R25, "r25" },
2164 { REGSIZE*PT_R26, "r26" },
2165 { REGSIZE*PT_R27, "r27" },
2166 { REGSIZE*PT_R28, "r28" },
2167 { REGSIZE*PT_R29, "r29" },
2168 { REGSIZE*PT_R30, "r30" },
2169 { REGSIZE*PT_R31, "r31" },
2170 { REGSIZE*PT_NIP, "NIP" },
2171 { REGSIZE*PT_MSR, "MSR" },
2172 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2173 { REGSIZE*PT_CTR, "CTR" },
2174 { REGSIZE*PT_LNK, "LNK" },
2175 { REGSIZE*PT_XER, "XER" },
2176 { REGSIZE*PT_CCR, "CCR" },
2177 { REGSIZE*PT_FPR0, "FPR0" },
2248 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2249 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2250 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2251 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2252 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2253 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2254 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2255 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2256 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2257 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2258 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2259 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2260 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2261 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2262 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2263 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2264 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2265 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2266 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2267 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2268 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2269 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2270 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2271 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2272 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2273 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2274 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2275 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2276 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2277 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2278 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2279 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2281 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2282 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2283 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2284 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2285 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2286 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2287 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2288 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2289 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2290 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2292 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2293 { PT_B4, "b4" }, { PT_B5, "b5" },
2294 { PT_AR_PFS, "kar.pfs" },
2295 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2296 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2299 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
2300 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
2301 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2302 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2303 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2304 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2305 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2306 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2307 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2308 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2309 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2310 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2311 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2312 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2313 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2314 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2315 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2329 { 4*ORIG_EAX, "4*ORIG_EAX" },
2333 { 4*UESP, "4*UESP" },
2353 { 8*ORIG_RAX, "8*ORIG_EAX" },
2356 { 8*EFLAGS, "8*EFL" },
2366 { 4*PT_D1, "4*PT_D1" },
2367 { 4*PT_D2, "4*PT_D2" },
2368 { 4*PT_D3, "4*PT_D3" },
2369 { 4*PT_D4, "4*PT_D4" },
2370 { 4*PT_D5, "4*PT_D5" },
2371 { 4*PT_D6, "4*PT_D6" },
2372 { 4*PT_D7, "4*PT_D7" },
2373 { 4*PT_A0, "4*PT_A0" },
2374 { 4*PT_A1, "4*PT_A1" },
2375 { 4*PT_A2, "4*PT_A2" },
2376 { 4*PT_A3, "4*PT_A3" },
2377 { 4*PT_A4, "4*PT_A4" },
2378 { 4*PT_A5, "4*PT_A5" },
2379 { 4*PT_A6, "4*PT_A6" },
2380 { 4*PT_D0, "4*PT_D0" },
2381 { 4*PT_USP, "4*PT_USP" },
2382 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2383 { 4*PT_SR, "4*PT_SR" },
2384 { 4*PT_PC, "4*PT_PC" },
2388 { 4*REG_REG0, "4*REG_REG0" },
2389 { 4*(REG_REG0+1), "4*REG_REG1" },
2390 { 4*(REG_REG0+2), "4*REG_REG2" },
2391 { 4*(REG_REG0+3), "4*REG_REG3" },
2392 { 4*(REG_REG0+4), "4*REG_REG4" },
2393 { 4*(REG_REG0+5), "4*REG_REG5" },
2394 { 4*(REG_REG0+6), "4*REG_REG6" },
2395 { 4*(REG_REG0+7), "4*REG_REG7" },
2396 { 4*(REG_REG0+8), "4*REG_REG8" },
2397 { 4*(REG_REG0+9), "4*REG_REG9" },
2398 { 4*(REG_REG0+10), "4*REG_REG10" },
2399 { 4*(REG_REG0+11), "4*REG_REG11" },
2400 { 4*(REG_REG0+12), "4*REG_REG12" },
2401 { 4*(REG_REG0+13), "4*REG_REG13" },
2402 { 4*(REG_REG0+14), "4*REG_REG14" },
2403 { 4*REG_REG15, "4*REG_REG15" },
2404 { 4*REG_PC, "4*REG_PC" },
2405 { 4*REG_PR, "4*REG_PR" },
2406 { 4*REG_SR, "4*REG_SR" },
2407 { 4*REG_GBR, "4*REG_GBR" },
2408 { 4*REG_MACH, "4*REG_MACH" },
2409 { 4*REG_MACL, "4*REG_MACL" },
2410 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2411 { 4*REG_FPUL, "4*REG_FPUL" },
2412 { 4*REG_FPREG0, "4*REG_FPREG0" },
2413 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2414 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2415 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2416 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2417 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2418 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2419 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2420 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2421 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2422 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2423 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2424 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2425 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2426 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2427 { 4*REG_FPREG15, "4*REG_FPREG15" },
2428 { 4*REG_XDREG0, "4*REG_XDREG0" },
2429 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2430 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2431 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2432 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2433 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2434 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2435 { 4*REG_XDREG14, "4*REG_XDREG14" },
2436 { 4*REG_FPSCR, "4*REG_FPSCR" },
2439 #if !defined(S390) && !defined(S390X) && !defined(MIPS)
2440 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
2442 #if defined(I386) || defined(X86_64)
2443 { uoff(i387), "offsetof(struct user, i387)" },
2446 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2449 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2450 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2451 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2452 { uoff(start_code), "offsetof(struct user, start_code)" },
2453 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2454 { uoff(signal), "offsetof(struct user, signal)" },
2455 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
2456 { uoff(reserved), "offsetof(struct user, reserved)" },
2458 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2459 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
2460 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2462 { uoff(magic), "offsetof(struct user, magic)" },
2463 { uoff(u_comm), "offsetof(struct user, u_comm)" },
2464 #if defined(I386) || defined(X86_64)
2465 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2469 #endif /* !POWERPC/!SPARC */
2472 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2473 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2474 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2475 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2476 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2477 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2478 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2479 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2480 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2481 { uoff(u_error), "offsetof(struct user, u_error)" },
2482 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2483 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2484 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2485 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2486 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2487 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2488 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2489 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2490 { uoff(u_code), "offsetof(struct user, u_code)" },
2491 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2492 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2493 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2494 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2495 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2496 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2497 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2498 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2499 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2500 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2501 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2502 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2503 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2504 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2505 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2506 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2507 { uoff(u_start), "offsetof(struct user, u_start)" },
2508 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2509 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2510 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2511 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2512 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2513 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2514 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2515 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2516 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2519 { sizeof(struct user), "sizeof(struct user)" },
2532 if (entering(tcp)) {
2533 printxval(ptrace_cmds, tcp->u_arg[0],
2540 tprintf(", %lu, ", tcp->u_arg[1]);
2541 addr = tcp->u_arg[2];
2543 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2544 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2545 for (x = struct_user_offsets; x->str; x++) {
2550 tprintf("%#lx, ", addr);
2551 else if (x->val > addr && x != struct_user_offsets) {
2553 tprintf("%s + %ld, ", x->str, addr - x->val);
2556 tprintf("%s, ", x->str);
2560 tprintf("%#lx, ", tcp->u_arg[2]);
2562 switch (tcp->u_arg[0]) {
2563 case PTRACE_PEEKDATA:
2564 case PTRACE_PEEKTEXT:
2565 case PTRACE_PEEKUSER:
2568 case PTRACE_SINGLESTEP:
2569 case PTRACE_SYSCALL:
2571 printsignal(tcp->u_arg[3]);
2574 tprintf("%#lx", tcp->u_arg[3]);
2578 switch (tcp->u_arg[0]) {
2579 case PTRACE_PEEKDATA:
2580 case PTRACE_PEEKTEXT:
2581 case PTRACE_PEEKUSER:
2582 printnum(tcp, tcp->u_arg[3], "%#lx");
2588 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2589 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2590 tprintf("%lu, ", tcp->u_arg[3]);
2591 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2592 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2593 tcp->u_arg[0] != PTRACE_READTEXT) {
2594 tprintf("%#lx", tcp->u_arg[3]);
2597 if (tcp->u_arg[0] == PTRACE_READDATA ||
2598 tcp->u_arg[0] == PTRACE_READTEXT) {
2599 tprintf("%lu, ", tcp->u_arg[3]);
2600 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2605 tprintf("%lu", tcp->u_arg[3]);
2607 #endif /* FREEBSD */
2614 static struct xlat futexops[] = {
2615 { FUTEX_WAIT, "FUTEX_WAIT" },
2616 { FUTEX_WAKE, "FUTEX_WAKE" },
2617 { FUTEX_FD, "FUTEX_FD" },
2625 if (entering(tcp)) {
2626 tprintf("%p, ", (void *) tcp->u_arg[0]);
2627 printflags(futexops, tcp->u_arg[1]);
2628 tprintf(", %ld, ", tcp->u_arg[2]);
2629 printtv(tcp, tcp->u_arg[3]);
2635 print_affinitylist(list, len)
2636 unsigned long *list;
2641 while (len > sizeof (unsigned long)) {
2642 tprintf("%s %lx", first ? "" : ",", *list++);
2644 len -= sizeof (unsigned long);
2650 sys_sched_setaffinity(tcp)
2653 if (entering(tcp)) {
2654 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2655 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2661 sys_sched_getaffinity(tcp)
2664 if (entering(tcp)) {
2665 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2667 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);