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();
531 # define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
532 # define ARG_CTID (tcp->scno == SYS_clone2 ? 3 : 2)
533 # define ARG_PTID (tcp->scno == SYS_clone2 ? 4 : -1)
534 # define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 3)
554 unsigned long flags = tcp->u_arg[ARG_FLAGS];
555 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
556 # ifdef ARG_STACKSIZE
557 if (ARG_STACKSIZE != -1)
558 tprintf("stack_size=%#lx, ",
559 tcp->u_arg[ARG_STACKSIZE]);
562 if (printflags(clone_flags, flags) == 0)
564 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
565 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
567 if (flags & CLONE_PARENT_SETTID) {
569 if (umove(tcp, tcp->u_arg[ARG_PTID], &pid) == 0)
570 tprintf(", parent_tidptr=[%d]", pid);
572 tprintf(", parent_tidptr=%#lx",
573 tcp->u_arg[ARG_PTID]);
575 if (flags & CLONE_SETTLS) {
577 struct modify_ldt_ldt_s copy;
578 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
579 tprintf(", {entry_number:%d, ",
584 print_ldt_entry(©);
588 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
590 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
591 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
602 return RVAL_UDECIMAL;
607 change_syscall(tcp, new)
613 /* Attempt to make vfork into fork, which we can follow. */
614 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
617 #elif defined(X86_64)
618 /* Attempt to make vfork into fork, which we can follow. */
619 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
622 #elif defined(POWERPC)
623 if (ptrace(PTRACE_POKEUSER, tcp->pid,
624 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
627 #elif defined(S390) || defined(S390X)
628 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
629 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
633 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
638 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
641 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
645 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
649 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
653 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
657 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
661 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL), new)<0)
665 #warning Do not know how to handle change_syscall for this architecture
666 #endif /* architecture */
678 unsigned long *bsp, *ap;
680 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
683 ap = ia64_rse_skip_regs(bsp, argnum);
685 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
692 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
696 #elif defined(X86_64)
698 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
702 #elif defined(POWERPC)
704 #define PT_ORIG_R3 34
707 ptrace(PTRACE_POKEUSER, tcp->pid,
708 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
717 ptrace(PTRACE_POKEUSER, tcp->pid,
718 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
722 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
725 ptrace(PTRACE_POKEDATA, tcp->pid,
726 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
731 #elif defined(S390) || defined(S390X)
734 ptrace(PTRACE_POKEUSER, tcp->pid,
735 (char *) (argnum==0 ? PT_ORIGGPR2 :
736 PT_GPR2 + argnum*sizeof(long)),
744 # warning Sorry, setargs not implemented for this architecture.
749 #if defined SYS_clone || defined SYS_clone2
754 struct tcb *tcpchild;
764 int bpt = tcp->flags & TCB_BPTSET;
766 if (!(tcp->flags & TCB_FOLLOWFORK))
777 #ifdef CLONE_PTRACE /* See new setbpt code. */
778 tcpchild = pid2tcb(pid);
779 if (tcpchild != NULL) {
780 /* The child already reported its startup trap
781 before the parent reported its syscall return. */
783 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
784 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
786 [preattached child %d of %d in weird state!]\n",
791 if ((tcpchild = alloctcb(pid)) == NULL) {
794 fprintf(stderr, " [tcb table full]\n");
795 kill(pid, SIGKILL); /* XXX */
800 /* Attach to the new child */
801 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
804 perror("PTRACE_ATTACH");
805 fprintf(stderr, "Too late?\n");
814 tcpchild->flags |= TCB_ATTACHED;
815 /* Child has BPT too, must be removed on first occasion. */
817 tcpchild->flags |= TCB_BPTSET;
818 tcpchild->baddr = tcp->baddr;
819 memcpy(tcpchild->inst, tcp->inst,
820 sizeof tcpchild->inst);
822 tcpchild->parent = tcp;
824 if (tcpchild->flags & TCB_SUSPENDED) {
825 /* The child was born suspended, due to our having
826 forced CLONE_PTRACE. */
830 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
831 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
832 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
838 Process %u resumed (parent %d ready)\n",
844 fprintf(stderr, "Process %d attached\n", pid);
847 #ifdef TCB_CLONE_THREAD
848 if ((tcp->flags & TCB_CLONE_THREAD) && tcp->parent != NULL) {
849 /* The parent in this clone is itself a thread
850 belonging to another process. There is no
851 meaning to the parentage relationship of the new
852 child with the thread, only with the process.
853 We associate the new thread with our parent.
854 Since this is done for every new thread, there
855 will never be a TCB_CLONE_THREAD process that
858 tcp->u_arg[0] = tcp->parent->u_arg[0];
860 tcpchild->parent = tcp;
864 if (tcp->u_arg[0] & CLONE_THREAD) {
865 tcpchild->flags |= TCB_CLONE_THREAD;
866 ++tcp->nclone_threads;
868 if (tcp->u_arg[0] & CLONE_DETACHED) {
869 tcpchild->flags |= TCB_CLONE_DETACHED;
870 ++tcp->nclone_detached;
884 /* We do special magic with clone for any clone or fork. */
885 return internal_clone(tcp);
888 struct tcb *tcpchild;
893 if (tcp->scno == SYS_vfork) {
894 /* Attempt to make vfork into fork, which we can follow. */
896 change_syscall(tcp, SYS_fork) < 0)
901 if (!followfork || dont_follow)
909 int bpt = tcp->flags & TCB_BPTSET;
911 if (!(tcp->flags & TCB_FOLLOWFORK))
920 if ((tcpchild = alloctcb(pid)) == NULL) {
921 fprintf(stderr, " [tcb table full]\n");
922 kill(pid, SIGKILL); /* XXX */
927 /* The child must have run before it can be attached. */
928 /* This must be a bug in the parisc kernel, but I havn't
929 * identified it yet. Seems to be an issue associated
930 * with attaching to a process (which sends it a signal)
931 * before that process has ever been scheduled. When
932 * debugging, I started seeing crashes in
933 * arch/parisc/kernel/signal.c:do_signal(), apparently
934 * caused by r8 getting corrupt over the dequeue_signal()
935 * call. Didn't make much sense though...
941 select(0, NULL, NULL, NULL, &tv);
944 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
945 perror("PTRACE_ATTACH");
946 fprintf(stderr, "Too late?\n");
953 /* The child must have run before it can be attached. */
958 select(0, NULL, NULL, NULL, &tv);
960 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
961 perror("PTRACE_ATTACH");
962 fprintf(stderr, "Too late?\n");
967 /* Try to catch the new process as soon as possible. */
970 for (i = 0; i < 1024; i++)
971 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
974 perror("PTRACE_ATTACH");
975 fprintf(stderr, "Too late?\n");
982 tcpchild->flags |= TCB_ATTACHED;
983 /* Child has BPT too, must be removed on first occasion */
985 tcpchild->flags |= TCB_BPTSET;
986 tcpchild->baddr = tcp->baddr;
987 memcpy(tcpchild->inst, tcp->inst,
988 sizeof tcpchild->inst);
991 tcpchild->parent = tcp;
994 fprintf(stderr, "Process %d attached\n", pid);
1000 #endif /* !USE_PROCFS */
1002 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1009 return RVAL_UDECIMAL;
1013 #endif /* SUNOS4 || LINUX || FREEBSD */
1017 static char idstr[16];
1024 sprintf(idstr, "ppid %lu", getrval2(tcp));
1025 tcp->auxstr = idstr;
1036 sprintf(idstr, "euid %lu", getrval2(tcp));
1037 tcp->auxstr = idstr;
1048 sprintf(idstr, "egid %lu", getrval2(tcp));
1049 tcp->auxstr = idstr;
1063 if (entering(tcp)) {
1064 tprintf("%u", (uid_t) tcp->u_arg[0]);
1073 if (entering(tcp)) {
1074 tprintf("%u", (gid_t) tcp->u_arg[0]);
1086 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1087 tcp->u_arg[1], tcp->u_arg[2]);
1089 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1090 tprintf("%#lx, ", tcp->u_arg[0]);
1092 tprintf("ruid %lu, ", (unsigned long) uid);
1093 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1094 tprintf("%#lx, ", tcp->u_arg[1]);
1096 tprintf("euid %lu, ", (unsigned long) uid);
1097 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1098 tprintf("%#lx", tcp->u_arg[2]);
1100 tprintf("suid %lu", (unsigned long) uid);
1113 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1114 tcp->u_arg[1], tcp->u_arg[2]);
1116 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1117 tprintf("%#lx, ", tcp->u_arg[0]);
1119 tprintf("rgid %lu, ", (unsigned long) gid);
1120 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1121 tprintf("%#lx, ", tcp->u_arg[1]);
1123 tprintf("egid %lu, ", (unsigned long) gid);
1124 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1125 tprintf("%#lx", tcp->u_arg[2]);
1127 tprintf("sgid %lu", (unsigned long) gid);
1139 if (entering(tcp)) {
1141 (unsigned long) (uid_t) tcp->u_arg[0],
1142 (unsigned long) (uid_t) tcp->u_arg[1]);
1151 if (entering(tcp)) {
1153 (unsigned long) (gid_t) tcp->u_arg[0],
1154 (unsigned long) (gid_t) tcp->u_arg[1]);
1159 #if defined(LINUX) || defined(FREEBSD)
1164 if (entering(tcp)) {
1165 tprintf("ruid %u, euid %u, suid %u",
1166 (uid_t) tcp->u_arg[0],
1167 (uid_t) tcp->u_arg[1],
1168 (uid_t) tcp->u_arg[2]);
1176 if (entering(tcp)) {
1177 tprintf("rgid %u, egid %u, sgid %u",
1178 (uid_t) tcp->u_arg[0],
1179 (uid_t) tcp->u_arg[1],
1180 (uid_t) tcp->u_arg[2]);
1185 #endif /* LINUX || FREEBSD */
1192 GETGROUPS_T *gidset;
1194 if (entering(tcp)) {
1195 len = tcp->u_arg[0];
1196 tprintf("%u, ", len);
1201 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1202 if (gidset == NULL) {
1203 fprintf(stderr, "sys_setgroups: out of memory\n");
1207 tprintf("%#lx", tcp->u_arg[1]);
1208 else if (umoven(tcp, tcp->u_arg[1],
1209 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1213 for (i = 0; i < len; i++)
1214 tprintf("%s%lu", i ? ", " : "",
1215 (unsigned long) gidset[i]);
1218 free((char *) gidset);
1228 GETGROUPS_T *gidset;
1230 if (entering(tcp)) {
1231 len = tcp->u_arg[0];
1232 tprintf("%u, ", len);
1239 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1240 if (gidset == NULL) {
1241 fprintf(stderr, "sys_getgroups: out of memory\n");
1246 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1247 tprintf("%#lx", tcp->u_arg[1]);
1248 else if (umoven(tcp, tcp->u_arg[1],
1249 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1253 for (i = 0; i < len; i++)
1254 tprintf("%s%lu", i ? ", " : "",
1255 (unsigned long) gidset[i]);
1258 free((char *)gidset);
1267 if (entering(tcp)) {
1269 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1279 if (entering(tcp)) {
1281 tprintf("%lu", tcp->u_arg[0]);
1291 if (entering(tcp)) {
1292 tprintf("%lu", tcp->u_arg[0]);
1308 if (entering(tcp)) {
1309 tprintf("%lu", tcp->u_arg[0]);
1318 if (entering(tcp)) {
1319 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1326 #include <sys/privilege.h>
1329 static struct xlat procpriv_cmds [] = {
1330 { SETPRV, "SETPRV" },
1331 { CLRPRV, "CLRPRV" },
1332 { PUTPRV, "PUTPRV" },
1333 { GETPRV, "GETPRV" },
1334 { CNTPRV, "CNTPRV" },
1339 static struct xlat procpriv_priv [] = {
1340 { P_OWNER, "P_OWNER" },
1341 { P_AUDIT, "P_AUDIT" },
1342 { P_COMPAT, "P_COMPAT" },
1343 { P_DACREAD, "P_DACREAD" },
1344 { P_DACWRITE, "P_DACWRITE" },
1346 { P_FILESYS, "P_FILESYS" },
1347 { P_MACREAD, "P_MACREAD" },
1348 { P_MACWRITE, "P_MACWRITE" },
1349 { P_MOUNT, "P_MOUNT" },
1350 { P_MULTIDIR, "P_MULTIDIR" },
1351 { P_SETPLEVEL, "P_SETPLEVEL" },
1352 { P_SETSPRIV, "P_SETSPRIV" },
1353 { P_SETUID, "P_SETUID" },
1354 { P_SYSOPS, "P_SYSOPS" },
1355 { P_SETUPRIV, "P_SETUPRIV" },
1356 { P_DRIVER, "P_DRIVER" },
1357 { P_RTIME, "P_RTIME" },
1358 { P_MACUPGRADE, "P_MACUPGRADE" },
1359 { P_FSYSRANGE, "P_FSYSRANGE" },
1360 { P_SETFLEVEL, "P_SETFLEVEL" },
1361 { P_AUDITWR, "P_AUDITWR" },
1362 { P_TSHAR, "P_TSHAR" },
1363 { P_PLOCK, "P_PLOCK" },
1364 { P_CORE, "P_CORE" },
1365 { P_LOADMOD, "P_LOADMOD" },
1366 { P_BIND, "P_BIND" },
1367 { P_ALLPRIVS, "P_ALLPRIVS" },
1372 static struct xlat procpriv_type [] = {
1373 { PS_FIX, "PS_FIX" },
1374 { PS_INH, "PS_INH" },
1375 { PS_MAX, "PS_MAX" },
1376 { PS_WKG, "PS_WKG" },
1382 printpriv(tcp, addr, len, opt)
1389 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1390 int dots = len > max;
1393 if (len > max) len = max;
1396 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1398 tprintf ("%#lx", addr);
1404 for (i = 0; i < len; ++i) {
1407 if (i) tprintf (", ");
1409 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1410 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1412 tprintf ("%s|%s", t, p);
1415 tprintf ("%#lx", buf [i]);
1419 if (dots) tprintf (" ...");
1429 if (entering(tcp)) {
1430 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1431 switch (tcp->u_arg[0]) {
1433 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1441 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1442 tprintf (", %ld", tcp->u_arg[2]);
1445 else if (tcp->u_arg[0] == GETPRV) {
1446 if (syserror (tcp)) {
1447 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1451 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1452 tprintf (", %ld", tcp->u_arg[2]);
1463 fake_execve(tcp, program, argv, envp)
1472 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1475 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1480 string_quote(program);
1482 for (i = 0; argv[i] != NULL; i++) {
1485 string_quote(argv[i]);
1487 for (i = 0; envp[i] != NULL; i++)
1489 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1496 printargv(tcp, addr)
1502 int max = max_strlen / 2;
1504 for (sep = ""; --max >= 0; sep = ", ") {
1507 if (umove(tcp, addr, &cp) < 0) {
1508 tprintf("%#lx", addr);
1514 printstr(tcp, (long) cp, -1);
1515 addr += sizeof(char *);
1522 printargc(fmt, tcp, addr)
1530 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1531 addr += sizeof(char *);
1533 tprintf(fmt, count, count == 1 ? "" : "s");
1540 if (entering(tcp)) {
1541 printpath(tcp, tcp->u_arg[0]);
1543 tprintf(", %#lx", tcp->u_arg[1]);
1545 else if (abbrev(tcp))
1546 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1550 printargv(tcp, tcp->u_arg[1]);
1561 if (entering(tcp)) {
1562 printpath(tcp, tcp->u_arg[0]);
1564 tprintf(", %#lx", tcp->u_arg[1]);
1566 else if (abbrev(tcp))
1567 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1571 printargv(tcp, tcp->u_arg[1]);
1575 tprintf(", %#lx", tcp->u_arg[2]);
1576 else if (abbrev(tcp))
1577 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1580 printargv(tcp, tcp->u_arg[2]);
1584 #if defined LINUX && defined TCB_WAITEXECVE
1585 tcp->flags |= TCB_WAITEXECVE;
1586 #endif /* LINUX && TCB_WAITEXECVE */
1592 int sys_rexecve(tcp)
1595 if (entering (tcp)) {
1597 tprintf (", %ld", tcp->u_arg[3]);
1609 if (exiting(tcp) && !syserror(tcp) && followfork)
1617 #define __WNOTHREAD 0x20000000
1620 #define __WALL 0x40000000
1623 #define __WCLONE 0x80000000
1627 static struct xlat wait4_options[] = {
1628 { WNOHANG, "WNOHANG" },
1630 { WUNTRACED, "WUNTRACED" },
1633 { WEXITED, "WEXITED" },
1636 { WTRAPPED, "WTRAPPED" },
1639 { WSTOPPED, "WSTOPPED" },
1642 { WCONTINUED, "WCONTINUED" },
1645 { WNOWAIT, "WNOWAIT" },
1648 { __WCLONE, "__WCLONE" },
1651 { __WALL, "__WALL" },
1654 { __WNOTHREAD, "__WNOTHREAD" },
1666 * Here is a tricky presentation problem. This solution
1667 * is still not entirely satisfactory but since there
1668 * are no wait status constructors it will have to do.
1670 if (WIFSTOPPED(status))
1671 tprintf("[WIFSTOPPED(s) && WSTOPSIG(s) == %s]",
1672 signame(WSTOPSIG(status)));
1673 else if WIFSIGNALED(status)
1674 tprintf("[WIFSIGNALED(s) && WTERMSIG(s) == %s%s]",
1675 signame(WTERMSIG(status)),
1676 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1677 else if WIFEXITED(status) {
1678 tprintf("[WIFEXITED(s) && WEXITSTATUS(s) == %d]",
1679 WEXITSTATUS(status));
1683 tprintf("[%#x]", status);
1688 printwaitn(tcp, n, bitness)
1696 if (entering(tcp)) {
1697 tprintf("%ld, ", tcp->u_arg[0]);
1702 else if (syserror(tcp) || tcp->u_rval == 0)
1703 tprintf("%#lx", tcp->u_arg[1]);
1704 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1707 exited = printstatus(status);
1710 if (!printflags(wait4_options, tcp->u_arg[2]))
1718 else if (tcp->u_rval > 0) {
1721 printrusage32(tcp, tcp->u_arg[3]);
1724 printrusage(tcp, tcp->u_arg[3]);
1728 else if (tcp->u_rval > 0 && exited)
1729 printrusage(tcp, tcp->u_arg[3]);
1732 tprintf("%#lx", tcp->u_arg[3]);
1744 #ifdef TCB_CLONE_THREAD
1745 if (tcp->flags & TCB_CLONE_THREAD)
1746 /* The children we wait for are our parent's children. */
1747 got_kids = (tcp->parent->nchildren
1748 > tcp->parent->nclone_detached);
1750 got_kids = (tcp->nchildren > tcp->nclone_detached);
1752 got_kids = tcp->nchildren > 0;
1755 if (entering(tcp) && got_kids) {
1756 /* There are children that this parent should block for.
1757 But ptrace made us the parent of the traced children
1758 and the real parent will get ECHILD from the wait call.
1760 XXX If we attached with strace -f -p PID, then there
1761 may be untraced dead children the parent could be reaping
1762 now, but we make him block. */
1764 /* ??? WTA: fix bug with hanging children */
1766 if (!(tcp->u_arg[2] & WNOHANG)) {
1767 /* There are traced children */
1768 tcp->flags |= TCB_SUSPENDED;
1769 tcp->waitpid = tcp->u_arg[0];
1770 #ifdef TCB_CLONE_THREAD
1771 if (tcp->flags & TCB_CLONE_THREAD)
1772 tcp->parent->nclone_waiting++;
1776 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1777 if (tcp->u_arg[2] & WNOHANG) {
1778 /* We must force a fake result of 0 instead of
1779 the ECHILD error. */
1780 extern int force_result();
1781 return force_result(tcp, 0, 0);
1785 "internal_wait: should not have resumed %d\n",
1798 /* The library wrapper stuffs this into the user variable. */
1800 printstatus(getrval2(tcp));
1815 if (!syserror(tcp)) {
1816 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1817 tprintf("%#lx", tcp->u_arg[0]);
1819 printstatus(status);
1830 return printwaitn(tcp, 3, 0);
1837 return printwaitn(tcp, 4, 0);
1845 return printwaitn(tcp, 4, 1);
1851 static struct xlat waitid_types[] = {
1853 { P_PPID, "P_PPID" },
1854 { P_PGID, "P_PGID" },
1861 { P_LWPID, "P_LWPID" },
1873 if (entering(tcp)) {
1874 printxval(waitid_types, tcp->u_arg[0], "P_???");
1875 tprintf(", %ld, ", tcp->u_arg[1]);
1876 if (tcp->nchildren > 0) {
1877 /* There are traced children */
1878 tcp->flags |= TCB_SUSPENDED;
1879 tcp->waitpid = tcp->u_arg[0];
1887 else if (syserror(tcp))
1888 tprintf("%#lx", tcp->u_arg[2]);
1889 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1892 printsiginfo(&si, verbose (tcp));
1895 if (!printflags(wait4_options, tcp->u_arg[3]))
1908 tprintf("%lu", tcp->u_arg[0]);
1916 struct utsname uname;
1919 if (syserror(tcp) || !verbose(tcp))
1920 tprintf("%#lx", tcp->u_arg[0]);
1921 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
1923 else if (!abbrev(tcp)) {
1925 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
1926 uname.sysname, uname.nodename);
1927 tprintf("release=\"%s\", version=\"%s\", ",
1928 uname.release, uname.version);
1929 tprintf("machine=\"%s\"", uname.machine);
1932 tprintf(", domainname=\"%s\"", uname.domainname);
1933 #endif /* __GLIBC__ */
1938 tprintf("{sys=\"%s\", node=\"%s\", ...}",
1939 uname.sysname, uname.nodename);
1946 static struct xlat ptrace_cmds[] = {
1948 { PTRACE_TRACEME, "PTRACE_TRACEME" },
1949 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
1950 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
1951 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
1952 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
1953 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
1954 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
1955 { PTRACE_CONT, "PTRACE_CONT" },
1956 { PTRACE_KILL, "PTRACE_KILL" },
1957 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
1958 { PTRACE_ATTACH, "PTRACE_ATTACH" },
1959 { PTRACE_DETACH, "PTRACE_DETACH" },
1960 #ifdef PTRACE_GETREGS
1961 { PTRACE_GETREGS, "PTRACE_GETREGS" },
1963 #ifdef PTRACE_SETREGS
1964 { PTRACE_SETREGS, "PTRACE_SETREGS" },
1966 #ifdef PTRACE_GETFPREGS
1967 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
1969 #ifdef PTRACE_SETFPREGS
1970 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
1972 #ifdef PTRACE_GETFPXREGS
1973 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
1975 #ifdef PTRACE_SETFPXREGS
1976 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
1979 { PTRACE_READDATA, "PTRACE_READDATA" },
1980 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
1981 { PTRACE_READTEXT, "PTRACE_READTEXT" },
1982 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
1983 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
1984 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
1986 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
1987 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
1989 { PTRACE_22, "PTRACE_PTRACE_22" },
1990 { PTRACE_23, "PTRACE_PTRACE_23" },
1993 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
1995 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
1997 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
1998 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
1999 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2001 { PTRACE_26, "PTRACE_26" },
2002 { PTRACE_27, "PTRACE_27" },
2003 { PTRACE_28, "PTRACE_28" },
2005 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2008 { PT_TRACE_ME, "PT_TRACE_ME" },
2009 { PT_READ_I, "PT_READ_I" },
2010 { PT_READ_D, "PT_READ_D" },
2011 { PT_WRITE_I, "PT_WRITE_I" },
2012 { PT_WRITE_D, "PT_WRITE_D" },
2014 { PT_READ_U, "PT_READ_U" },
2016 { PT_CONTINUE, "PT_CONTINUE" },
2017 { PT_KILL, "PT_KILL" },
2018 { PT_STEP, "PT_STEP" },
2019 { PT_ATTACH, "PT_ATTACH" },
2020 { PT_DETACH, "PT_DETACH" },
2021 { PT_GETREGS, "PT_GETREGS" },
2022 { PT_SETREGS, "PT_SETREGS" },
2023 { PT_GETFPREGS, "PT_GETFPREGS" },
2024 { PT_SETFPREGS, "PT_SETFPREGS" },
2025 { PT_GETDBREGS, "PT_GETDBREGS" },
2026 { PT_SETDBREGS, "PT_SETDBREGS" },
2027 #endif /* FREEBSD */
2032 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2034 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2035 struct xlat struct_user_offsets[] = {
2037 #if defined(S390) || defined(S390X)
2038 { PT_PSWMASK, "psw_mask" },
2039 { PT_PSWADDR, "psw_addr" },
2040 { PT_GPR0, "gpr0" },
2041 { PT_GPR1, "gpr1" },
2042 { PT_GPR2, "gpr2" },
2043 { PT_GPR3, "gpr3" },
2044 { PT_GPR4, "gpr4" },
2045 { PT_GPR5, "gpr5" },
2046 { PT_GPR6, "gpr6" },
2047 { PT_GPR7, "gpr7" },
2048 { PT_GPR8, "gpr8" },
2049 { PT_GPR9, "gpr9" },
2050 { PT_GPR10, "gpr10" },
2051 { PT_GPR11, "gpr11" },
2052 { PT_GPR12, "gpr12" },
2053 { PT_GPR13, "gpr13" },
2054 { PT_GPR14, "gpr14" },
2055 { PT_GPR15, "gpr15" },
2056 { PT_ACR0, "acr0" },
2057 { PT_ACR1, "acr1" },
2058 { PT_ACR2, "acr2" },
2059 { PT_ACR3, "acr3" },
2060 { PT_ACR4, "acr4" },
2061 { PT_ACR5, "acr5" },
2062 { PT_ACR6, "acr6" },
2063 { PT_ACR7, "acr7" },
2064 { PT_ACR8, "acr8" },
2065 { PT_ACR9, "acr9" },
2066 { PT_ACR10, "acr10" },
2067 { PT_ACR11, "acr11" },
2068 { PT_ACR12, "acr12" },
2069 { PT_ACR13, "acr13" },
2070 { PT_ACR14, "acr14" },
2071 { PT_ACR15, "acr15" },
2072 { PT_ORIGGPR2, "orig_gpr2" },
2075 { PT_FPR0_HI, "fpr0.hi" },
2076 { PT_FPR0_LO, "fpr0.lo" },
2077 { PT_FPR1_HI, "fpr1.hi" },
2078 { PT_FPR1_LO, "fpr1.lo" },
2079 { PT_FPR2_HI, "fpr2.hi" },
2080 { PT_FPR2_LO, "fpr2.lo" },
2081 { PT_FPR3_HI, "fpr3.hi" },
2082 { PT_FPR3_LO, "fpr3.lo" },
2083 { PT_FPR4_HI, "fpr4.hi" },
2084 { PT_FPR4_LO, "fpr4.lo" },
2085 { PT_FPR5_HI, "fpr5.hi" },
2086 { PT_FPR5_LO, "fpr5.lo" },
2087 { PT_FPR6_HI, "fpr6.hi" },
2088 { PT_FPR6_LO, "fpr6.lo" },
2089 { PT_FPR7_HI, "fpr7.hi" },
2090 { PT_FPR7_LO, "fpr7.lo" },
2091 { PT_FPR8_HI, "fpr8.hi" },
2092 { PT_FPR8_LO, "fpr8.lo" },
2093 { PT_FPR9_HI, "fpr9.hi" },
2094 { PT_FPR9_LO, "fpr9.lo" },
2095 { PT_FPR10_HI, "fpr10.hi" },
2096 { PT_FPR10_LO, "fpr10.lo" },
2097 { PT_FPR11_HI, "fpr11.hi" },
2098 { PT_FPR11_LO, "fpr11.lo" },
2099 { PT_FPR12_HI, "fpr12.hi" },
2100 { PT_FPR12_LO, "fpr12.lo" },
2101 { PT_FPR13_HI, "fpr13.hi" },
2102 { PT_FPR13_LO, "fpr13.lo" },
2103 { PT_FPR14_HI, "fpr14.hi" },
2104 { PT_FPR14_LO, "fpr14.lo" },
2105 { PT_FPR15_HI, "fpr15.hi" },
2106 { PT_FPR15_LO, "fpr15.lo" },
2109 { PT_FPR0, "fpr0" },
2110 { PT_FPR1, "fpr1" },
2111 { PT_FPR2, "fpr2" },
2112 { PT_FPR3, "fpr3" },
2113 { PT_FPR4, "fpr4" },
2114 { PT_FPR5, "fpr5" },
2115 { PT_FPR6, "fpr6" },
2116 { PT_FPR7, "fpr7" },
2117 { PT_FPR8, "fpr8" },
2118 { PT_FPR9, "fpr9" },
2119 { PT_FPR10, "fpr10" },
2120 { PT_FPR11, "fpr11" },
2121 { PT_FPR12, "fpr12" },
2122 { PT_FPR13, "fpr13" },
2123 { PT_FPR14, "fpr14" },
2124 { PT_FPR15, "fpr15" },
2127 { PT_CR_10, "cr10" },
2128 { PT_CR_11, "cr11" },
2129 { PT_IEEE_IP, "ieee_exception_ip" },
2132 /* XXX No support for these offsets yet. */
2134 /* XXX No support for these offsets yet. */
2135 #elif defined(POWERPC)
2137 #define PT_ORIG_R3 34
2139 #define REGSIZE (sizeof(unsigned long))
2140 { REGSIZE*PT_R0, "r0" },
2141 { REGSIZE*PT_R1, "r1" },
2142 { REGSIZE*PT_R2, "r2" },
2143 { REGSIZE*PT_R3, "r3" },
2144 { REGSIZE*PT_R4, "r4" },
2145 { REGSIZE*PT_R5, "r5" },
2146 { REGSIZE*PT_R6, "r6" },
2147 { REGSIZE*PT_R7, "r7" },
2148 { REGSIZE*PT_R8, "r8" },
2149 { REGSIZE*PT_R9, "r9" },
2150 { REGSIZE*PT_R10, "r10" },
2151 { REGSIZE*PT_R11, "r11" },
2152 { REGSIZE*PT_R12, "r12" },
2153 { REGSIZE*PT_R13, "r13" },
2154 { REGSIZE*PT_R14, "r14" },
2155 { REGSIZE*PT_R15, "r15" },
2156 { REGSIZE*PT_R16, "r16" },
2157 { REGSIZE*PT_R17, "r17" },
2158 { REGSIZE*PT_R18, "r18" },
2159 { REGSIZE*PT_R19, "r19" },
2160 { REGSIZE*PT_R20, "r20" },
2161 { REGSIZE*PT_R21, "r21" },
2162 { REGSIZE*PT_R22, "r22" },
2163 { REGSIZE*PT_R23, "r23" },
2164 { REGSIZE*PT_R24, "r24" },
2165 { REGSIZE*PT_R25, "r25" },
2166 { REGSIZE*PT_R26, "r26" },
2167 { REGSIZE*PT_R27, "r27" },
2168 { REGSIZE*PT_R28, "r28" },
2169 { REGSIZE*PT_R29, "r29" },
2170 { REGSIZE*PT_R30, "r30" },
2171 { REGSIZE*PT_R31, "r31" },
2172 { REGSIZE*PT_NIP, "NIP" },
2173 { REGSIZE*PT_MSR, "MSR" },
2174 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2175 { REGSIZE*PT_CTR, "CTR" },
2176 { REGSIZE*PT_LNK, "LNK" },
2177 { REGSIZE*PT_XER, "XER" },
2178 { REGSIZE*PT_CCR, "CCR" },
2179 { REGSIZE*PT_FPR0, "FPR0" },
2250 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2251 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2252 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2253 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2254 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2255 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2256 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2257 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2258 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2259 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2260 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2261 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2262 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2263 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2264 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2265 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2266 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2267 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2268 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2269 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2270 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2271 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2272 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2273 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2274 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2275 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2276 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2277 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2278 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2279 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2280 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2281 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2283 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2284 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2285 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2286 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2287 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2288 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2289 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2290 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2291 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2292 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2294 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2295 { PT_B4, "b4" }, { PT_B5, "b5" },
2296 { PT_AR_PFS, "kar.pfs" },
2297 { PT_AR_LC, "ar.lc" }, { PT_AR_UNAT, "kar.unat" },
2298 { PT_AR_RNAT, "kar.rnat" }, { PT_AR_BSPSTORE, "kar.bspstore" },
2301 { PT_CR_IPSR, "cr.ipsr" }, { PT_CR_IIP, "cr.iip" },
2302 /*{ PT_CR_IFS, "cr.ifs" },*/ { PT_AR_UNAT, "ar.unat" },
2303 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2304 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2305 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2306 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2307 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2308 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2309 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2310 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2311 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2312 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2313 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2314 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2315 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2316 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2317 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2331 { 4*ORIG_EAX, "4*ORIG_EAX" },
2335 { 4*UESP, "4*UESP" },
2355 { 8*ORIG_RAX, "8*ORIG_EAX" },
2358 { 8*EFLAGS, "8*EFL" },
2368 { 4*PT_D1, "4*PT_D1" },
2369 { 4*PT_D2, "4*PT_D2" },
2370 { 4*PT_D3, "4*PT_D3" },
2371 { 4*PT_D4, "4*PT_D4" },
2372 { 4*PT_D5, "4*PT_D5" },
2373 { 4*PT_D6, "4*PT_D6" },
2374 { 4*PT_D7, "4*PT_D7" },
2375 { 4*PT_A0, "4*PT_A0" },
2376 { 4*PT_A1, "4*PT_A1" },
2377 { 4*PT_A2, "4*PT_A2" },
2378 { 4*PT_A3, "4*PT_A3" },
2379 { 4*PT_A4, "4*PT_A4" },
2380 { 4*PT_A5, "4*PT_A5" },
2381 { 4*PT_A6, "4*PT_A6" },
2382 { 4*PT_D0, "4*PT_D0" },
2383 { 4*PT_USP, "4*PT_USP" },
2384 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2385 { 4*PT_SR, "4*PT_SR" },
2386 { 4*PT_PC, "4*PT_PC" },
2390 { 4*REG_REG0, "4*REG_REG0" },
2391 { 4*(REG_REG0+1), "4*REG_REG1" },
2392 { 4*(REG_REG0+2), "4*REG_REG2" },
2393 { 4*(REG_REG0+3), "4*REG_REG3" },
2394 { 4*(REG_REG0+4), "4*REG_REG4" },
2395 { 4*(REG_REG0+5), "4*REG_REG5" },
2396 { 4*(REG_REG0+6), "4*REG_REG6" },
2397 { 4*(REG_REG0+7), "4*REG_REG7" },
2398 { 4*(REG_REG0+8), "4*REG_REG8" },
2399 { 4*(REG_REG0+9), "4*REG_REG9" },
2400 { 4*(REG_REG0+10), "4*REG_REG10" },
2401 { 4*(REG_REG0+11), "4*REG_REG11" },
2402 { 4*(REG_REG0+12), "4*REG_REG12" },
2403 { 4*(REG_REG0+13), "4*REG_REG13" },
2404 { 4*(REG_REG0+14), "4*REG_REG14" },
2405 { 4*REG_REG15, "4*REG_REG15" },
2406 { 4*REG_PC, "4*REG_PC" },
2407 { 4*REG_PR, "4*REG_PR" },
2408 { 4*REG_SR, "4*REG_SR" },
2409 { 4*REG_GBR, "4*REG_GBR" },
2410 { 4*REG_MACH, "4*REG_MACH" },
2411 { 4*REG_MACL, "4*REG_MACL" },
2412 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2413 { 4*REG_FPUL, "4*REG_FPUL" },
2414 { 4*REG_FPREG0, "4*REG_FPREG0" },
2415 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2416 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2417 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2418 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2419 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2420 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2421 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2422 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2423 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2424 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2425 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2426 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2427 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2428 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2429 { 4*REG_FPREG15, "4*REG_FPREG15" },
2430 { 4*REG_XDREG0, "4*REG_XDREG0" },
2431 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2432 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2433 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2434 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2435 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2436 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2437 { 4*REG_XDREG14, "4*REG_XDREG14" },
2438 { 4*REG_FPSCR, "4*REG_FPSCR" },
2441 #if !defined(S390) && !defined(S390X) && !defined(MIPS)
2442 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
2444 #if defined(I386) || defined(X86_64)
2445 { uoff(i387), "offsetof(struct user, i387)" },
2448 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2451 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2452 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2453 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2454 { uoff(start_code), "offsetof(struct user, start_code)" },
2455 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2456 { uoff(signal), "offsetof(struct user, signal)" },
2457 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH)
2458 { uoff(reserved), "offsetof(struct user, reserved)" },
2460 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2461 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
2462 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2464 { uoff(magic), "offsetof(struct user, magic)" },
2465 { uoff(u_comm), "offsetof(struct user, u_comm)" },
2466 #if defined(I386) || defined(X86_64)
2467 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2471 #endif /* !POWERPC/!SPARC */
2474 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2475 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2476 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2477 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2478 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2479 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2480 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2481 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2482 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2483 { uoff(u_error), "offsetof(struct user, u_error)" },
2484 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2485 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2486 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2487 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2488 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2489 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2490 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2491 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2492 { uoff(u_code), "offsetof(struct user, u_code)" },
2493 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2494 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2495 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2496 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2497 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2498 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2499 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2500 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2501 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2502 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2503 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2504 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2505 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2506 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2507 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2508 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2509 { uoff(u_start), "offsetof(struct user, u_start)" },
2510 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2511 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2512 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2513 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2514 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2515 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2516 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2517 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2518 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2521 { sizeof(struct user), "sizeof(struct user)" },
2534 if (entering(tcp)) {
2535 printxval(ptrace_cmds, tcp->u_arg[0],
2542 tprintf(", %lu, ", tcp->u_arg[1]);
2543 addr = tcp->u_arg[2];
2545 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2546 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2547 for (x = struct_user_offsets; x->str; x++) {
2552 tprintf("%#lx, ", addr);
2553 else if (x->val > addr && x != struct_user_offsets) {
2555 tprintf("%s + %ld, ", x->str, addr - x->val);
2558 tprintf("%s, ", x->str);
2562 tprintf("%#lx, ", tcp->u_arg[2]);
2564 switch (tcp->u_arg[0]) {
2565 case PTRACE_PEEKDATA:
2566 case PTRACE_PEEKTEXT:
2567 case PTRACE_PEEKUSER:
2570 case PTRACE_SINGLESTEP:
2571 case PTRACE_SYSCALL:
2573 printsignal(tcp->u_arg[3]);
2576 tprintf("%#lx", tcp->u_arg[3]);
2580 switch (tcp->u_arg[0]) {
2581 case PTRACE_PEEKDATA:
2582 case PTRACE_PEEKTEXT:
2583 case PTRACE_PEEKUSER:
2584 printnum(tcp, tcp->u_arg[3], "%#lx");
2590 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2591 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2592 tprintf("%lu, ", tcp->u_arg[3]);
2593 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2594 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2595 tcp->u_arg[0] != PTRACE_READTEXT) {
2596 tprintf("%#lx", tcp->u_arg[3]);
2599 if (tcp->u_arg[0] == PTRACE_READDATA ||
2600 tcp->u_arg[0] == PTRACE_READTEXT) {
2601 tprintf("%lu, ", tcp->u_arg[3]);
2602 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2607 tprintf("%lu", tcp->u_arg[3]);
2609 #endif /* FREEBSD */
2616 static struct xlat futexops[] = {
2617 { FUTEX_WAIT, "FUTEX_WAIT" },
2618 { FUTEX_WAKE, "FUTEX_WAKE" },
2619 { FUTEX_FD, "FUTEX_FD" },
2627 if (entering(tcp)) {
2628 tprintf("%p, ", (void *) tcp->u_arg[0]);
2629 printflags(futexops, tcp->u_arg[1]);
2630 tprintf(", %ld", tcp->u_arg[2]);
2631 if (tcp->u_arg[1] == FUTEX_WAIT) {
2633 printtv(tcp, tcp->u_arg[3]);
2640 print_affinitylist(list, len)
2641 unsigned long *list;
2646 while (len > sizeof (unsigned long)) {
2647 tprintf("%s %lx", first ? "" : ",", *list++);
2649 len -= sizeof (unsigned long);
2655 sys_sched_setaffinity(tcp)
2658 if (entering(tcp)) {
2659 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2660 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_arg[1]);
2666 sys_sched_getaffinity(tcp)
2669 if (entering(tcp)) {
2670 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
2672 print_affinitylist((unsigned long *) tcp->u_arg[2], tcp->u_rval);