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 # ifdef HAVE_STRUCT_IA64_FPREG
86 # define ia64_fpreg XXX_ia64_fpreg
88 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89 # define pt_all_user_regs XXX_pt_all_user_regs
91 #include <linux/ptrace.h>
93 # undef pt_all_user_regs
96 #ifdef HAVE_LINUX_FUTEX_H
97 #include <linux/futex.h>
101 # define FUTEX_WAIT 0
104 # define FUTEX_WAKE 1
109 # ifndef FUTEX_REQUEUE
110 # define FUTEX_REQUEUE 3
116 #include <asm/posix_types.h>
118 #define GETGROUPS_T __kernel_gid_t
120 #define GETGROUPS32_T __kernel_gid32_t
123 #if defined(LINUX) && defined(IA64)
124 # include <asm/ptrace_offsets.h>
125 # include <asm/rse.h>
129 #include <sys/prctl.h>
133 #define WCOREDUMP(status) ((status) & 0200)
136 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
137 #if defined(HAVE_PRCTL)
138 static struct xlat prctl_options[] = {
140 { PR_MAXPROCS, "PR_MAXPROCS" },
143 { PR_ISBLOCKED, "PR_ISBLOCKED" },
145 #ifdef PR_SETSTACKSIZE
146 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
148 #ifdef PR_GETSTACKSIZE
149 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
152 { PR_MAXPPROCS, "PR_MAXPPROCS" },
154 #ifdef PR_UNBLKONEXEC
155 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
158 { PR_ATOMICSIM, "PR_ATOMICSIM" },
161 { PR_SETEXITSIG, "PR_SETEXITSIG" },
164 { PR_RESIDENT, "PR_RESIDENT" },
167 { PR_ATTACHADDR, "PR_ATTACHADDR" },
170 { PR_DETACHADDR, "PR_DETACHADDR" },
173 { PR_TERMCHILD, "PR_TERMCHILD" },
176 { PR_GETSHMASK, "PR_GETSHMASK" },
179 { PR_GETNSHARE, "PR_GETNSHARE" },
181 #if defined(PR_SET_PDEATHSIG)
182 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
185 { PR_COREPID, "PR_COREPID" },
187 #ifdef PR_ATTACHADDRPERM
188 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
190 #ifdef PR_PTHREADEXIT
191 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
193 #ifdef PR_SET_PDEATHSIG
194 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
196 #ifdef PR_GET_PDEATHSIG
197 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
199 #ifdef PR_GET_UNALIGN
200 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
202 #ifdef PR_SET_UNALIGN
203 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
205 #ifdef PR_GET_KEEPCAPS
206 { PR_GET_KEEPCAPS, "PR_GET_KEEP_CAPS" },
208 #ifdef PR_SET_KEEPCAPS
209 { PR_SET_KEEPCAPS, "PR_SET_KEEP_CAPS" },
216 unalignctl_string (unsigned int ctl)
221 #ifdef PR_UNALIGN_NOPRINT
222 case PR_UNALIGN_NOPRINT:
225 #ifdef PR_UNALIGN_SIGBUS
226 case PR_UNALIGN_SIGBUS:
232 sprintf(buf, "%x", ctl);
244 printxval(prctl_options, tcp->u_arg[0], "PR_???");
245 switch (tcp->u_arg[0]) {
250 #ifdef PR_SET_DEATHSIG
251 case PR_GET_PDEATHSIG:
254 #ifdef PR_SET_UNALIGN
256 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
259 #ifdef PR_GET_UNALIGN
261 tprintf(", %#lx", tcp->u_arg[1]);
265 for (i = 1; i < tcp->u_nargs; i++)
266 tprintf(", %#lx", tcp->u_arg[i]);
270 switch (tcp->u_arg[0]) {
271 #ifdef PR_GET_PDEATHSIG
272 case PR_GET_PDEATHSIG:
273 for (i=1; i<tcp->u_nargs; i++)
274 tprintf(", %#lx", tcp->u_arg[i]);
277 #ifdef PR_SET_UNALIGN
281 #ifdef PR_GET_UNALIGN
286 umove(tcp, tcp->u_arg[1], &ctl);
287 tcp->auxstr = unalignctl_string(ctl);
298 #endif /* HAVE_PRCTL */
314 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
315 tprintf(", %lu", tcp->u_arg[1]);
326 tprintf("%#lx", tcp->u_arg[0]);
328 printpath(tcp, tcp->u_arg[0]);
329 tprintf(", %lu", tcp->u_arg[1]);
335 sys_setdomainname(tcp)
339 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
340 tprintf(", %lu", tcp->u_arg[1]);
348 sys_getdomainname(tcp)
353 tprintf("%#lx", tcp->u_arg[0]);
355 printpath(tcp, tcp->u_arg[0]);
356 tprintf(", %lu", tcp->u_arg[1]);
367 fprintf(stderr, "_exit returned!\n");
370 /* special case: we stop tracing this process, finish line now */
371 tprintf("%ld) ", tcp->u_arg[0]);
383 tcp->flags |= TCB_EXITING;
384 #ifdef __NR_exit_group
387 if (tcp->scno == 252)
388 tcp->flags |= TCB_GROUP_EXITING;
391 if (tcp->scno == __NR_exit_group)
392 tcp->flags |= TCB_GROUP_EXITING;
398 /* TCP is creating a child we want to follow.
399 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
400 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
402 fork_tcb(struct tcb *tcp)
404 if (nprocs == tcbtabsize) {
405 if (expand_tcbtab()) {
406 tcp->flags &= ~TCB_FOLLOWFORK;
407 fprintf(stderr, "sys_fork: tcb table full\n");
411 tcp->flags |= TCB_FOLLOWFORK;
423 tcp->auxstr = "child process";
424 return RVAL_UDECIMAL | RVAL_STR;
437 tprintf ("%ld", tcp->u_arg[0]);
441 tcp->auxstr = "child process";
442 return RVAL_UDECIMAL | RVAL_STR;
454 struct tcb *tcpchild;
458 if (tcp->scno == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
469 if ((tcpchild = alloctcb(tcp->u_rval)) == NULL) {
470 fprintf(stderr, "sys_fork: tcb table full\n");
473 if (proc_open(tcpchild, 2) < 0)
479 #else /* !USE_PROCFS */
483 /* defines copied from linux/sched.h since we can't include that
484 * ourselves (it conflicts with *lots* of libc includes)
486 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
487 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
488 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
489 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
490 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
491 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
492 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
493 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
494 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
495 #define CLONE_THREAD 0x00010000 /* Same thread group? */
496 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
497 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
498 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
499 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
500 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
501 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
502 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
503 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
505 static struct xlat clone_flags[] = {
506 { CLONE_VM, "CLONE_VM" },
507 { CLONE_FS, "CLONE_FS" },
508 { CLONE_FILES, "CLONE_FILES" },
509 { CLONE_SIGHAND, "CLONE_SIGHAND" },
510 { CLONE_IDLETASK, "CLONE_IDLETASK"},
511 { CLONE_PTRACE, "CLONE_PTRACE" },
512 { CLONE_VFORK, "CLONE_VFORK" },
513 { CLONE_PARENT, "CLONE_PARENT" },
514 { CLONE_THREAD, "CLONE_THREAD" },
515 { CLONE_NEWNS, "CLONE_NEWNS" },
516 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
517 { CLONE_SETTLS, "CLONE_SETTLS" },
518 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
519 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
520 { CLONE_DETACHED, "CLONE_DETACHED" },
521 { CLONE_UNTRACED, "CLONE_UNTRACED" },
522 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
527 # include <asm/ldt.h>
528 # ifdef HAVE_STRUCT_USER_DESC
529 # define modify_ldt_ldt_s user_desc
531 extern void print_ldt_entry();
537 # define ARG_STACKSIZE (tcp->scno == SYS_clone2 ? 2 : -1)
538 # define ARG_PTID (tcp->scno == SYS_clone2 ? 3 : 2)
539 # define ARG_CTID (tcp->scno == SYS_clone2 ? 4 : 3)
540 # define ARG_TLS (tcp->scno == SYS_clone2 ? 5 : 4)
541 # elif defined S390 || defined S390X
547 # elif defined X86_64 || defined ALPHA
566 unsigned long flags = tcp->u_arg[ARG_FLAGS];
567 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
568 # ifdef ARG_STACKSIZE
569 if (ARG_STACKSIZE != -1)
570 tprintf("stack_size=%#lx, ",
571 tcp->u_arg[ARG_STACKSIZE]);
574 if (printflags(clone_flags, flags &~ CSIGNAL) == 0)
576 if ((flags & CSIGNAL) != 0)
577 tprintf("|%s", signame(flags & CSIGNAL));
578 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
579 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
581 if (flags & CLONE_PARENT_SETTID)
582 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
583 if (flags & CLONE_SETTLS) {
585 struct modify_ldt_ldt_s copy;
586 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
587 tprintf(", {entry_number:%d, ",
592 print_ldt_entry(©);
596 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
598 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
599 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
610 return RVAL_UDECIMAL;
615 change_syscall(tcp, new)
621 /* Attempt to make vfork into fork, which we can follow. */
622 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
625 #elif defined(X86_64)
626 /* Attempt to make vfork into fork, which we can follow. */
627 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
630 #elif defined(POWERPC)
631 if (ptrace(PTRACE_POKEUSER, tcp->pid,
632 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
635 #elif defined(S390) || defined(S390X)
636 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
637 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
641 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
646 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
649 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
653 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
657 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
663 case 2: break; /* x86 SYS_fork */
664 case SYS_clone: new = 120; break;
666 fprintf(stderr, "%s: unexpected syscall %d\n",
670 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
672 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
676 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
680 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
684 /* Top half of reg encodes the no. of args n as 0x1n.
685 Assume 0 args as kernel never actually checks... */
686 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
691 #warning Do not know how to handle change_syscall for this architecture
692 #endif /* architecture */
704 unsigned long *bsp, *ap;
706 if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) , 0)
709 ap = ia64_rse_skip_regs(bsp, argnum);
711 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
718 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
722 #elif defined(X86_64)
724 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
728 #elif defined(POWERPC)
730 #define PT_ORIG_R3 34
733 ptrace(PTRACE_POKEUSER, tcp->pid,
734 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
743 ptrace(PTRACE_POKEUSER, tcp->pid,
744 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
748 if (upeek(tcp->pid, REG_SP, (long *) &sp) , 0)
751 ptrace(PTRACE_POKEDATA, tcp->pid,
752 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
757 #elif defined(S390) || defined(S390X)
760 ptrace(PTRACE_POKEUSER, tcp->pid,
761 (char *) (argnum==0 ? PT_ORIGGPR2 :
762 PT_GPR2 + argnum*sizeof(long)),
770 # warning Sorry, setargs not implemented for this architecture.
775 #if defined SYS_clone || defined SYS_clone2
780 struct tcb *tcpchild;
790 int bpt = tcp->flags & TCB_BPTSET;
792 if (!(tcp->flags & TCB_FOLLOWFORK))
803 #ifdef CLONE_PTRACE /* See new setbpt code. */
804 tcpchild = pid2tcb(pid);
805 if (tcpchild != NULL) {
806 /* The child already reported its startup trap
807 before the parent reported its syscall return. */
809 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
810 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
812 [preattached child %d of %d in weird state!]\n",
817 if ((tcpchild = alloctcb(pid)) == NULL) {
820 fprintf(stderr, " [tcb table full]\n");
821 kill(pid, SIGKILL); /* XXX */
826 /* Attach to the new child */
827 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
830 perror("PTRACE_ATTACH");
831 fprintf(stderr, "Too late?\n");
840 tcpchild->flags |= TCB_ATTACHED;
841 /* Child has BPT too, must be removed on first occasion. */
843 tcpchild->flags |= TCB_BPTSET;
844 tcpchild->baddr = tcp->baddr;
845 memcpy(tcpchild->inst, tcp->inst,
846 sizeof tcpchild->inst);
848 tcpchild->parent = tcp;
850 if (tcpchild->flags & TCB_SUSPENDED) {
851 /* The child was born suspended, due to our having
852 forced CLONE_PTRACE. */
856 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
857 if (ptrace(PTRACE_SYSCALL, pid, (char *) 1, 0) < 0) {
858 perror("resume: ptrace(PTRACE_SYSCALL, ...)");
864 Process %u resumed (parent %d ready)\n",
870 fprintf(stderr, "Process %d attached\n", pid);
873 #ifdef TCB_CLONE_THREAD
876 * Save the flags used in this call,
877 * in case we point TCP to our parent below.
879 int call_flags = tcp->u_arg[ARG_FLAGS];
880 if ((tcp->flags & TCB_CLONE_THREAD) &&
881 tcp->parent != NULL) {
882 /* The parent in this clone is itself a
883 thread belonging to another process.
884 There is no meaning to the parentage
885 relationship of the new child with the
886 thread, only with the process. We
887 associate the new thread with our
888 parent. Since this is done for every
889 new thread, there will never be a
890 TCB_CLONE_THREAD process that has
894 tcpchild->parent = tcp;
897 if (call_flags & CLONE_THREAD) {
898 tcpchild->flags |= TCB_CLONE_THREAD;
899 ++tcp->nclone_threads;
901 if (call_flags & CLONE_DETACHED) {
902 tcpchild->flags |= TCB_CLONE_DETACHED;
903 ++tcp->nclone_detached;
918 /* We do special magic with clone for any clone or fork. */
919 return internal_clone(tcp);
922 struct tcb *tcpchild;
927 if (tcp->scno == SYS_vfork) {
928 /* Attempt to make vfork into fork, which we can follow. */
930 change_syscall(tcp, SYS_fork) < 0)
935 if (!followfork || dont_follow)
943 int bpt = tcp->flags & TCB_BPTSET;
945 if (!(tcp->flags & TCB_FOLLOWFORK))
954 if ((tcpchild = alloctcb(pid)) == NULL) {
955 fprintf(stderr, " [tcb table full]\n");
956 kill(pid, SIGKILL); /* XXX */
961 /* The child must have run before it can be attached. */
962 /* This must be a bug in the parisc kernel, but I havn't
963 * identified it yet. Seems to be an issue associated
964 * with attaching to a process (which sends it a signal)
965 * before that process has ever been scheduled. When
966 * debugging, I started seeing crashes in
967 * arch/parisc/kernel/signal.c:do_signal(), apparently
968 * caused by r8 getting corrupt over the dequeue_signal()
969 * call. Didn't make much sense though...
975 select(0, NULL, NULL, NULL, &tv);
978 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
979 perror("PTRACE_ATTACH");
980 fprintf(stderr, "Too late?\n");
987 /* The child must have run before it can be attached. */
992 select(0, NULL, NULL, NULL, &tv);
994 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
995 perror("PTRACE_ATTACH");
996 fprintf(stderr, "Too late?\n");
1001 /* Try to catch the new process as soon as possible. */
1004 for (i = 0; i < 1024; i++)
1005 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1008 perror("PTRACE_ATTACH");
1009 fprintf(stderr, "Too late?\n");
1014 #endif /* !oldway */
1016 tcpchild->flags |= TCB_ATTACHED;
1017 /* Child has BPT too, must be removed on first occasion */
1019 tcpchild->flags |= TCB_BPTSET;
1020 tcpchild->baddr = tcp->baddr;
1021 memcpy(tcpchild->inst, tcp->inst,
1022 sizeof tcpchild->inst);
1025 tcpchild->parent = tcp;
1028 fprintf(stderr, "Process %d attached\n", pid);
1034 #endif /* !USE_PROCFS */
1036 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1043 return RVAL_UDECIMAL;
1047 #endif /* SUNOS4 || LINUX || FREEBSD */
1051 static char idstr[16];
1058 sprintf(idstr, "ppid %lu", getrval2(tcp));
1059 tcp->auxstr = idstr;
1070 sprintf(idstr, "euid %lu", getrval2(tcp));
1071 tcp->auxstr = idstr;
1082 sprintf(idstr, "egid %lu", getrval2(tcp));
1083 tcp->auxstr = idstr;
1097 if (entering(tcp)) {
1098 tprintf("%u", (uid_t) tcp->u_arg[0]);
1107 if (entering(tcp)) {
1108 tprintf("%u", (gid_t) tcp->u_arg[0]);
1120 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1121 tcp->u_arg[1], tcp->u_arg[2]);
1123 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1124 tprintf("%#lx, ", tcp->u_arg[0]);
1126 tprintf("[%lu], ", (unsigned long) uid);
1127 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1128 tprintf("%#lx, ", tcp->u_arg[1]);
1130 tprintf("[%lu], ", (unsigned long) uid);
1131 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1132 tprintf("%#lx", tcp->u_arg[2]);
1134 tprintf("[%lu]", (unsigned long) uid);
1147 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1148 tcp->u_arg[1], tcp->u_arg[2]);
1150 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1151 tprintf("%#lx, ", tcp->u_arg[0]);
1153 tprintf("[%lu], ", (unsigned long) gid);
1154 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1155 tprintf("%#lx, ", tcp->u_arg[1]);
1157 tprintf("[%lu], ", (unsigned long) gid);
1158 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1159 tprintf("%#lx", tcp->u_arg[2]);
1161 tprintf("[%lu]", (unsigned long) gid);
1173 if (entering(tcp)) {
1174 printuid("", tcp->u_arg[0]);
1175 printuid(", ", tcp->u_arg[1]);
1184 if (entering(tcp)) {
1185 printuid("", tcp->u_arg[0]);
1186 printuid(", ", tcp->u_arg[1]);
1191 #if defined(LINUX) || defined(FREEBSD)
1196 if (entering(tcp)) {
1197 printuid("", tcp->u_arg[0]);
1198 printuid(", ", tcp->u_arg[1]);
1199 printuid(", ", tcp->u_arg[2]);
1207 if (entering(tcp)) {
1208 printuid("", tcp->u_arg[0]);
1209 printuid(", ", tcp->u_arg[1]);
1210 printuid(", ", tcp->u_arg[2]);
1215 #endif /* LINUX || FREEBSD */
1222 GETGROUPS_T *gidset;
1224 if (entering(tcp)) {
1225 len = tcp->u_arg[0];
1226 tprintf("%u, ", len);
1231 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1232 if (gidset == NULL) {
1233 fprintf(stderr, "sys_setgroups: out of memory\n");
1237 tprintf("%#lx", tcp->u_arg[1]);
1238 else if (umoven(tcp, tcp->u_arg[1],
1239 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1243 for (i = 0; i < len; i++)
1244 tprintf("%s%lu", i ? ", " : "",
1245 (unsigned long) gidset[i]);
1248 free((char *) gidset);
1258 GETGROUPS_T *gidset;
1260 if (entering(tcp)) {
1261 len = tcp->u_arg[0];
1262 tprintf("%u, ", len);
1269 gidset = (GETGROUPS_T *) malloc(len * sizeof(GETGROUPS_T));
1270 if (gidset == NULL) {
1271 fprintf(stderr, "sys_getgroups: out of memory\n");
1276 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1277 tprintf("%#lx", tcp->u_arg[1]);
1278 else if (umoven(tcp, tcp->u_arg[1],
1279 len * sizeof(GETGROUPS_T), (char *) gidset) < 0)
1283 for (i = 0; i < len; i++)
1284 tprintf("%s%lu", i ? ", " : "",
1285 (unsigned long) gidset[i]);
1288 free((char *)gidset);
1295 sys_setgroups32(tcp)
1299 GETGROUPS32_T *gidset;
1301 if (entering(tcp)) {
1302 len = tcp->u_arg[0];
1303 tprintf("%u, ", len);
1308 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1309 if (gidset == NULL) {
1310 fprintf(stderr, "sys_setgroups32: out of memory\n");
1314 tprintf("%#lx", tcp->u_arg[1]);
1315 else if (umoven(tcp, tcp->u_arg[1],
1316 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1320 for (i = 0; i < len; i++)
1321 tprintf("%s%lu", i ? ", " : "",
1322 (unsigned long) gidset[i]);
1325 free((char *) gidset);
1331 sys_getgroups32(tcp)
1335 GETGROUPS32_T *gidset;
1337 if (entering(tcp)) {
1338 len = tcp->u_arg[0];
1339 tprintf("%u, ", len);
1346 gidset = (GETGROUPS32_T *) malloc(len * sizeof(GETGROUPS32_T));
1347 if (gidset == NULL) {
1348 fprintf(stderr, "sys_getgroups32: out of memory\n");
1353 else if (!verbose(tcp) || tcp->u_arg[0] == 0)
1354 tprintf("%#lx", tcp->u_arg[1]);
1355 else if (umoven(tcp, tcp->u_arg[1],
1356 len * sizeof(GETGROUPS32_T), (char *) gidset) < 0)
1360 for (i = 0; i < len; i++)
1361 tprintf("%s%lu", i ? ", " : "",
1362 (unsigned long) gidset[i]);
1365 free((char *)gidset);
1375 if (entering(tcp)) {
1377 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1387 if (entering(tcp)) {
1389 tprintf("%lu", tcp->u_arg[0]);
1399 if (entering(tcp)) {
1400 tprintf("%lu", tcp->u_arg[0]);
1416 if (entering(tcp)) {
1417 tprintf("%lu", tcp->u_arg[0]);
1426 if (entering(tcp)) {
1427 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1434 #include <sys/privilege.h>
1437 static struct xlat procpriv_cmds [] = {
1438 { SETPRV, "SETPRV" },
1439 { CLRPRV, "CLRPRV" },
1440 { PUTPRV, "PUTPRV" },
1441 { GETPRV, "GETPRV" },
1442 { CNTPRV, "CNTPRV" },
1447 static struct xlat procpriv_priv [] = {
1448 { P_OWNER, "P_OWNER" },
1449 { P_AUDIT, "P_AUDIT" },
1450 { P_COMPAT, "P_COMPAT" },
1451 { P_DACREAD, "P_DACREAD" },
1452 { P_DACWRITE, "P_DACWRITE" },
1454 { P_FILESYS, "P_FILESYS" },
1455 { P_MACREAD, "P_MACREAD" },
1456 { P_MACWRITE, "P_MACWRITE" },
1457 { P_MOUNT, "P_MOUNT" },
1458 { P_MULTIDIR, "P_MULTIDIR" },
1459 { P_SETPLEVEL, "P_SETPLEVEL" },
1460 { P_SETSPRIV, "P_SETSPRIV" },
1461 { P_SETUID, "P_SETUID" },
1462 { P_SYSOPS, "P_SYSOPS" },
1463 { P_SETUPRIV, "P_SETUPRIV" },
1464 { P_DRIVER, "P_DRIVER" },
1465 { P_RTIME, "P_RTIME" },
1466 { P_MACUPGRADE, "P_MACUPGRADE" },
1467 { P_FSYSRANGE, "P_FSYSRANGE" },
1468 { P_SETFLEVEL, "P_SETFLEVEL" },
1469 { P_AUDITWR, "P_AUDITWR" },
1470 { P_TSHAR, "P_TSHAR" },
1471 { P_PLOCK, "P_PLOCK" },
1472 { P_CORE, "P_CORE" },
1473 { P_LOADMOD, "P_LOADMOD" },
1474 { P_BIND, "P_BIND" },
1475 { P_ALLPRIVS, "P_ALLPRIVS" },
1480 static struct xlat procpriv_type [] = {
1481 { PS_FIX, "PS_FIX" },
1482 { PS_INH, "PS_INH" },
1483 { PS_MAX, "PS_MAX" },
1484 { PS_WKG, "PS_WKG" },
1490 printpriv(tcp, addr, len, opt)
1497 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1498 int dots = len > max;
1501 if (len > max) len = max;
1504 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1506 tprintf ("%#lx", addr);
1512 for (i = 0; i < len; ++i) {
1515 if (i) tprintf (", ");
1517 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1518 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1520 tprintf ("%s|%s", t, p);
1523 tprintf ("%#lx", buf [i]);
1527 if (dots) tprintf (" ...");
1537 if (entering(tcp)) {
1538 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1539 switch (tcp->u_arg[0]) {
1541 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1549 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1550 tprintf (", %ld", tcp->u_arg[2]);
1553 else if (tcp->u_arg[0] == GETPRV) {
1554 if (syserror (tcp)) {
1555 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1559 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1560 tprintf (", %ld", tcp->u_arg[2]);
1571 fake_execve(tcp, program, argv, envp)
1580 if (!(qual_flags[SYS_execve - __NR_SYSCALL_BASE] & QUAL_TRACE))
1583 if (!(qual_flags[SYS_execve] & QUAL_TRACE))
1588 string_quote(program);
1590 for (i = 0; argv[i] != NULL; i++) {
1593 string_quote(argv[i]);
1595 for (i = 0; envp[i] != NULL; i++)
1597 tprintf("], [/* %d var%s */]) ", i, (i != 1) ? "s" : "");
1604 printargv(tcp, addr)
1610 int max = max_strlen / 2;
1612 for (sep = ""; --max >= 0; sep = ", ") {
1615 if (umove(tcp, addr, &cp) < 0) {
1616 tprintf("%#lx", addr);
1622 printstr(tcp, (long) cp, -1);
1623 addr += sizeof(char *);
1630 printargc(fmt, tcp, addr)
1638 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1639 addr += sizeof(char *);
1641 tprintf(fmt, count, count == 1 ? "" : "s");
1648 if (entering(tcp)) {
1649 printpath(tcp, tcp->u_arg[0]);
1651 tprintf(", %#lx", tcp->u_arg[1]);
1653 else if (abbrev(tcp))
1654 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1658 printargv(tcp, tcp->u_arg[1]);
1669 if (entering(tcp)) {
1670 printpath(tcp, tcp->u_arg[0]);
1672 tprintf(", %#lx", tcp->u_arg[1]);
1674 else if (abbrev(tcp))
1675 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1679 printargv(tcp, tcp->u_arg[1]);
1683 tprintf(", %#lx", tcp->u_arg[2]);
1684 else if (abbrev(tcp))
1685 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1688 printargv(tcp, tcp->u_arg[2]);
1692 #if defined LINUX && defined TCB_WAITEXECVE
1693 if (exiting(tcp) && syserror(tcp))
1694 tcp->flags &= ~TCB_WAITEXECVE;
1696 tcp->flags |= TCB_WAITEXECVE;
1697 #endif /* LINUX && TCB_WAITEXECVE */
1703 int sys_rexecve(tcp)
1706 if (entering (tcp)) {
1708 tprintf (", %ld", tcp->u_arg[3]);
1720 if (exiting(tcp) && !syserror(tcp) && followfork)
1728 #define __WNOTHREAD 0x20000000
1731 #define __WALL 0x40000000
1734 #define __WCLONE 0x80000000
1738 static struct xlat wait4_options[] = {
1739 { WNOHANG, "WNOHANG" },
1741 { WUNTRACED, "WUNTRACED" },
1744 { WEXITED, "WEXITED" },
1747 { WTRAPPED, "WTRAPPED" },
1750 { WSTOPPED, "WSTOPPED" },
1753 { WCONTINUED, "WCONTINUED" },
1756 { WNOWAIT, "WNOWAIT" },
1759 { __WCLONE, "__WCLONE" },
1762 { __WALL, "__WALL" },
1765 { __WNOTHREAD, "__WNOTHREAD" },
1777 * Here is a tricky presentation problem. This solution
1778 * is still not entirely satisfactory but since there
1779 * are no wait status constructors it will have to do.
1781 if (WIFSTOPPED(status)) {
1782 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1783 signame(WSTOPSIG(status)));
1784 status &= ~W_STOPCODE(WSTOPSIG(status));
1786 else if (WIFSIGNALED(status)) {
1787 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1788 signame(WTERMSIG(status)),
1789 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1790 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1792 else if (WIFEXITED(status)) {
1793 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1794 WEXITSTATUS(status));
1796 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1799 tprintf("[%#x]", status);
1806 tprintf(" | %#x]", status);
1812 printwaitn(tcp, n, bitness)
1820 if (entering(tcp)) {
1821 tprintf("%ld, ", tcp->u_arg[0]);
1826 else if (syserror(tcp) || tcp->u_rval == 0)
1827 tprintf("%#lx", tcp->u_arg[1]);
1828 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1831 exited = printstatus(status);
1834 if (!printflags(wait4_options, tcp->u_arg[2]))
1842 else if (tcp->u_rval > 0) {
1845 printrusage32(tcp, tcp->u_arg[3]);
1848 printrusage(tcp, tcp->u_arg[3]);
1852 else if (tcp->u_rval > 0 && exited)
1853 printrusage(tcp, tcp->u_arg[3]);
1856 tprintf("%#lx", tcp->u_arg[3]);
1868 #ifdef TCB_CLONE_THREAD
1869 if (tcp->flags & TCB_CLONE_THREAD)
1870 /* The children we wait for are our parent's children. */
1871 got_kids = (tcp->parent->nchildren
1872 > tcp->parent->nclone_detached);
1874 got_kids = (tcp->nchildren > tcp->nclone_detached);
1876 got_kids = tcp->nchildren > 0;
1879 if (entering(tcp) && got_kids) {
1880 /* There are children that this parent should block for.
1881 But ptrace made us the parent of the traced children
1882 and the real parent will get ECHILD from the wait call.
1884 XXX If we attached with strace -f -p PID, then there
1885 may be untraced dead children the parent could be reaping
1886 now, but we make him block. */
1888 /* ??? WTA: fix bug with hanging children */
1890 if (!(tcp->u_arg[2] & WNOHANG)) {
1892 * There are traced children. We'll make the parent
1893 * block to avoid a false ECHILD error due to our
1894 * ptrace having stolen the children. However,
1895 * we shouldn't block if there are zombies to reap.
1896 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1898 struct tcb *child = NULL;
1899 if (tcp->nzombies > 0 &&
1900 (tcp->u_arg[0] == -1 ||
1901 (child = pid2tcb(tcp->u_arg[0])) == NULL))
1903 if (tcp->u_arg[0] > 0) {
1905 * If the parent waits for a specified child
1906 * PID, then it must get ECHILD right away
1907 * if that PID is not one of its children.
1908 * Make sure that the requested PID matches
1909 * one of the parent's children that we are
1910 * tracing, and don't suspend it otherwise.
1913 child = pid2tcb(tcp->u_arg[0]);
1914 if (child == NULL || child->parent != (
1915 #ifdef TCB_CLONE_THREAD
1916 (tcp->flags & TCB_CLONE_THREAD)
1922 tcp->flags |= TCB_SUSPENDED;
1923 tcp->waitpid = tcp->u_arg[0];
1924 #ifdef TCB_CLONE_THREAD
1925 if (tcp->flags & TCB_CLONE_THREAD)
1926 tcp->parent->nclone_waiting++;
1930 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
1931 if (tcp->u_arg[2] & WNOHANG) {
1932 /* We must force a fake result of 0 instead of
1933 the ECHILD error. */
1934 extern int force_result();
1935 return force_result(tcp, 0, 0);
1938 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
1939 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
1941 * We just reaped a child we don't know about,
1942 * presumably a zombie we already droptcb'd.
1956 /* The library wrapper stuffs this into the user variable. */
1958 printstatus(getrval2(tcp));
1973 if (!syserror(tcp)) {
1974 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1975 tprintf("%#lx", tcp->u_arg[0]);
1977 printstatus(status);
1988 return printwaitn(tcp, 3, 0);
1995 return printwaitn(tcp, 4, 0);
2003 return printwaitn(tcp, 4, 1);
2009 static struct xlat waitid_types[] = {
2011 { P_PPID, "P_PPID" },
2012 { P_PGID, "P_PGID" },
2019 { P_LWPID, "P_LWPID" },
2031 if (entering(tcp)) {
2032 printxval(waitid_types, tcp->u_arg[0], "P_???");
2033 tprintf(", %ld, ", tcp->u_arg[1]);
2034 if (tcp->nchildren > 0) {
2035 /* There are traced children */
2036 tcp->flags |= TCB_SUSPENDED;
2037 tcp->waitpid = tcp->u_arg[0];
2045 else if (syserror(tcp))
2046 tprintf("%#lx", tcp->u_arg[2]);
2047 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2050 printsiginfo(&si, verbose (tcp));
2053 if (!printflags(wait4_options, tcp->u_arg[3]))
2066 tprintf("%lu", tcp->u_arg[0]);
2074 struct utsname uname;
2077 if (syserror(tcp) || !verbose(tcp))
2078 tprintf("%#lx", tcp->u_arg[0]);
2079 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2081 else if (!abbrev(tcp)) {
2083 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2084 uname.sysname, uname.nodename);
2085 tprintf("release=\"%s\", version=\"%s\", ",
2086 uname.release, uname.version);
2087 tprintf("machine=\"%s\"", uname.machine);
2090 tprintf(", domainname=\"%s\"", uname.domainname);
2091 #endif /* __GLIBC__ */
2096 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2097 uname.sysname, uname.nodename);
2104 static struct xlat ptrace_cmds[] = {
2106 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2107 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2108 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2109 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2110 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2111 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2112 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2113 { PTRACE_CONT, "PTRACE_CONT" },
2114 { PTRACE_KILL, "PTRACE_KILL" },
2115 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2116 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2117 { PTRACE_DETACH, "PTRACE_DETACH" },
2118 #ifdef PTRACE_GETREGS
2119 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2121 #ifdef PTRACE_SETREGS
2122 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2124 #ifdef PTRACE_GETFPREGS
2125 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2127 #ifdef PTRACE_SETFPREGS
2128 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2130 #ifdef PTRACE_GETFPXREGS
2131 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2133 #ifdef PTRACE_SETFPXREGS
2134 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2137 { PTRACE_READDATA, "PTRACE_READDATA" },
2138 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2139 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2140 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2141 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2142 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2144 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2145 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2147 { PTRACE_22, "PTRACE_PTRACE_22" },
2148 { PTRACE_23, "PTRACE_PTRACE_23" },
2151 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2153 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2155 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2156 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2157 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2159 { PTRACE_26, "PTRACE_26" },
2160 { PTRACE_27, "PTRACE_27" },
2161 { PTRACE_28, "PTRACE_28" },
2163 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2166 { PT_TRACE_ME, "PT_TRACE_ME" },
2167 { PT_READ_I, "PT_READ_I" },
2168 { PT_READ_D, "PT_READ_D" },
2169 { PT_WRITE_I, "PT_WRITE_I" },
2170 { PT_WRITE_D, "PT_WRITE_D" },
2172 { PT_READ_U, "PT_READ_U" },
2174 { PT_CONTINUE, "PT_CONTINUE" },
2175 { PT_KILL, "PT_KILL" },
2176 { PT_STEP, "PT_STEP" },
2177 { PT_ATTACH, "PT_ATTACH" },
2178 { PT_DETACH, "PT_DETACH" },
2179 { PT_GETREGS, "PT_GETREGS" },
2180 { PT_SETREGS, "PT_SETREGS" },
2181 { PT_GETFPREGS, "PT_GETFPREGS" },
2182 { PT_SETFPREGS, "PT_SETFPREGS" },
2183 { PT_GETDBREGS, "PT_GETDBREGS" },
2184 { PT_SETDBREGS, "PT_SETDBREGS" },
2185 #endif /* FREEBSD */
2190 #ifndef SUNOS4_KERNEL_ARCH_KLUDGE
2192 #endif /* !SUNOS4_KERNEL_ARCH_KLUDGE */
2193 struct xlat struct_user_offsets[] = {
2195 #if defined(S390) || defined(S390X)
2196 { PT_PSWMASK, "psw_mask" },
2197 { PT_PSWADDR, "psw_addr" },
2198 { PT_GPR0, "gpr0" },
2199 { PT_GPR1, "gpr1" },
2200 { PT_GPR2, "gpr2" },
2201 { PT_GPR3, "gpr3" },
2202 { PT_GPR4, "gpr4" },
2203 { PT_GPR5, "gpr5" },
2204 { PT_GPR6, "gpr6" },
2205 { PT_GPR7, "gpr7" },
2206 { PT_GPR8, "gpr8" },
2207 { PT_GPR9, "gpr9" },
2208 { PT_GPR10, "gpr10" },
2209 { PT_GPR11, "gpr11" },
2210 { PT_GPR12, "gpr12" },
2211 { PT_GPR13, "gpr13" },
2212 { PT_GPR14, "gpr14" },
2213 { PT_GPR15, "gpr15" },
2214 { PT_ACR0, "acr0" },
2215 { PT_ACR1, "acr1" },
2216 { PT_ACR2, "acr2" },
2217 { PT_ACR3, "acr3" },
2218 { PT_ACR4, "acr4" },
2219 { PT_ACR5, "acr5" },
2220 { PT_ACR6, "acr6" },
2221 { PT_ACR7, "acr7" },
2222 { PT_ACR8, "acr8" },
2223 { PT_ACR9, "acr9" },
2224 { PT_ACR10, "acr10" },
2225 { PT_ACR11, "acr11" },
2226 { PT_ACR12, "acr12" },
2227 { PT_ACR13, "acr13" },
2228 { PT_ACR14, "acr14" },
2229 { PT_ACR15, "acr15" },
2230 { PT_ORIGGPR2, "orig_gpr2" },
2233 { PT_FPR0_HI, "fpr0.hi" },
2234 { PT_FPR0_LO, "fpr0.lo" },
2235 { PT_FPR1_HI, "fpr1.hi" },
2236 { PT_FPR1_LO, "fpr1.lo" },
2237 { PT_FPR2_HI, "fpr2.hi" },
2238 { PT_FPR2_LO, "fpr2.lo" },
2239 { PT_FPR3_HI, "fpr3.hi" },
2240 { PT_FPR3_LO, "fpr3.lo" },
2241 { PT_FPR4_HI, "fpr4.hi" },
2242 { PT_FPR4_LO, "fpr4.lo" },
2243 { PT_FPR5_HI, "fpr5.hi" },
2244 { PT_FPR5_LO, "fpr5.lo" },
2245 { PT_FPR6_HI, "fpr6.hi" },
2246 { PT_FPR6_LO, "fpr6.lo" },
2247 { PT_FPR7_HI, "fpr7.hi" },
2248 { PT_FPR7_LO, "fpr7.lo" },
2249 { PT_FPR8_HI, "fpr8.hi" },
2250 { PT_FPR8_LO, "fpr8.lo" },
2251 { PT_FPR9_HI, "fpr9.hi" },
2252 { PT_FPR9_LO, "fpr9.lo" },
2253 { PT_FPR10_HI, "fpr10.hi" },
2254 { PT_FPR10_LO, "fpr10.lo" },
2255 { PT_FPR11_HI, "fpr11.hi" },
2256 { PT_FPR11_LO, "fpr11.lo" },
2257 { PT_FPR12_HI, "fpr12.hi" },
2258 { PT_FPR12_LO, "fpr12.lo" },
2259 { PT_FPR13_HI, "fpr13.hi" },
2260 { PT_FPR13_LO, "fpr13.lo" },
2261 { PT_FPR14_HI, "fpr14.hi" },
2262 { PT_FPR14_LO, "fpr14.lo" },
2263 { PT_FPR15_HI, "fpr15.hi" },
2264 { PT_FPR15_LO, "fpr15.lo" },
2267 { PT_FPR0, "fpr0" },
2268 { PT_FPR1, "fpr1" },
2269 { PT_FPR2, "fpr2" },
2270 { PT_FPR3, "fpr3" },
2271 { PT_FPR4, "fpr4" },
2272 { PT_FPR5, "fpr5" },
2273 { PT_FPR6, "fpr6" },
2274 { PT_FPR7, "fpr7" },
2275 { PT_FPR8, "fpr8" },
2276 { PT_FPR9, "fpr9" },
2277 { PT_FPR10, "fpr10" },
2278 { PT_FPR11, "fpr11" },
2279 { PT_FPR12, "fpr12" },
2280 { PT_FPR13, "fpr13" },
2281 { PT_FPR14, "fpr14" },
2282 { PT_FPR15, "fpr15" },
2285 { PT_CR_10, "cr10" },
2286 { PT_CR_11, "cr11" },
2287 { PT_IEEE_IP, "ieee_exception_ip" },
2290 /* XXX No support for these offsets yet. */
2292 /* XXX No support for these offsets yet. */
2293 #elif defined(POWERPC)
2295 #define PT_ORIG_R3 34
2297 #define REGSIZE (sizeof(unsigned long))
2298 { REGSIZE*PT_R0, "r0" },
2299 { REGSIZE*PT_R1, "r1" },
2300 { REGSIZE*PT_R2, "r2" },
2301 { REGSIZE*PT_R3, "r3" },
2302 { REGSIZE*PT_R4, "r4" },
2303 { REGSIZE*PT_R5, "r5" },
2304 { REGSIZE*PT_R6, "r6" },
2305 { REGSIZE*PT_R7, "r7" },
2306 { REGSIZE*PT_R8, "r8" },
2307 { REGSIZE*PT_R9, "r9" },
2308 { REGSIZE*PT_R10, "r10" },
2309 { REGSIZE*PT_R11, "r11" },
2310 { REGSIZE*PT_R12, "r12" },
2311 { REGSIZE*PT_R13, "r13" },
2312 { REGSIZE*PT_R14, "r14" },
2313 { REGSIZE*PT_R15, "r15" },
2314 { REGSIZE*PT_R16, "r16" },
2315 { REGSIZE*PT_R17, "r17" },
2316 { REGSIZE*PT_R18, "r18" },
2317 { REGSIZE*PT_R19, "r19" },
2318 { REGSIZE*PT_R20, "r20" },
2319 { REGSIZE*PT_R21, "r21" },
2320 { REGSIZE*PT_R22, "r22" },
2321 { REGSIZE*PT_R23, "r23" },
2322 { REGSIZE*PT_R24, "r24" },
2323 { REGSIZE*PT_R25, "r25" },
2324 { REGSIZE*PT_R26, "r26" },
2325 { REGSIZE*PT_R27, "r27" },
2326 { REGSIZE*PT_R28, "r28" },
2327 { REGSIZE*PT_R29, "r29" },
2328 { REGSIZE*PT_R30, "r30" },
2329 { REGSIZE*PT_R31, "r31" },
2330 { REGSIZE*PT_NIP, "NIP" },
2331 { REGSIZE*PT_MSR, "MSR" },
2332 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2333 { REGSIZE*PT_CTR, "CTR" },
2334 { REGSIZE*PT_LNK, "LNK" },
2335 { REGSIZE*PT_XER, "XER" },
2336 { REGSIZE*PT_CCR, "CCR" },
2337 { REGSIZE*PT_FPR0, "FPR0" },
2408 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2409 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2410 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2411 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2412 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2413 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2414 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2415 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2416 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2417 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2418 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2419 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2420 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2421 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2422 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2423 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2424 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2425 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2426 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2427 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2428 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2429 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2430 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2431 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2432 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2433 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2434 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2435 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2436 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2437 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2438 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2439 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2441 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2442 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2443 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2444 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2445 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2446 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2447 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2448 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2449 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2450 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2451 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2452 { PT_B4, "b4" }, { PT_B5, "b5" },
2453 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2455 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2456 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2457 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2458 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2459 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2460 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2461 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2462 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2463 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2464 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2465 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2466 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2467 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2468 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2469 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2470 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2471 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2473 { PT_AR_CSD, "ar.csd" },
2476 { PT_AR_SSD, "ar.ssd" },
2478 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2492 { 4*ORIG_EAX, "4*ORIG_EAX" },
2496 { 4*UESP, "4*UESP" },
2516 { 8*ORIG_RAX, "8*ORIG_EAX" },
2519 { 8*EFLAGS, "8*EFL" },
2529 { 4*PT_D1, "4*PT_D1" },
2530 { 4*PT_D2, "4*PT_D2" },
2531 { 4*PT_D3, "4*PT_D3" },
2532 { 4*PT_D4, "4*PT_D4" },
2533 { 4*PT_D5, "4*PT_D5" },
2534 { 4*PT_D6, "4*PT_D6" },
2535 { 4*PT_D7, "4*PT_D7" },
2536 { 4*PT_A0, "4*PT_A0" },
2537 { 4*PT_A1, "4*PT_A1" },
2538 { 4*PT_A2, "4*PT_A2" },
2539 { 4*PT_A3, "4*PT_A3" },
2540 { 4*PT_A4, "4*PT_A4" },
2541 { 4*PT_A5, "4*PT_A5" },
2542 { 4*PT_A6, "4*PT_A6" },
2543 { 4*PT_D0, "4*PT_D0" },
2544 { 4*PT_USP, "4*PT_USP" },
2545 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2546 { 4*PT_SR, "4*PT_SR" },
2547 { 4*PT_PC, "4*PT_PC" },
2551 { 4*REG_REG0, "4*REG_REG0" },
2552 { 4*(REG_REG0+1), "4*REG_REG1" },
2553 { 4*(REG_REG0+2), "4*REG_REG2" },
2554 { 4*(REG_REG0+3), "4*REG_REG3" },
2555 { 4*(REG_REG0+4), "4*REG_REG4" },
2556 { 4*(REG_REG0+5), "4*REG_REG5" },
2557 { 4*(REG_REG0+6), "4*REG_REG6" },
2558 { 4*(REG_REG0+7), "4*REG_REG7" },
2559 { 4*(REG_REG0+8), "4*REG_REG8" },
2560 { 4*(REG_REG0+9), "4*REG_REG9" },
2561 { 4*(REG_REG0+10), "4*REG_REG10" },
2562 { 4*(REG_REG0+11), "4*REG_REG11" },
2563 { 4*(REG_REG0+12), "4*REG_REG12" },
2564 { 4*(REG_REG0+13), "4*REG_REG13" },
2565 { 4*(REG_REG0+14), "4*REG_REG14" },
2566 { 4*REG_REG15, "4*REG_REG15" },
2567 { 4*REG_PC, "4*REG_PC" },
2568 { 4*REG_PR, "4*REG_PR" },
2569 { 4*REG_SR, "4*REG_SR" },
2570 { 4*REG_GBR, "4*REG_GBR" },
2571 { 4*REG_MACH, "4*REG_MACH" },
2572 { 4*REG_MACL, "4*REG_MACL" },
2573 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2574 { 4*REG_FPUL, "4*REG_FPUL" },
2575 { 4*REG_FPREG0, "4*REG_FPREG0" },
2576 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2577 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2578 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2579 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2580 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2581 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2582 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2583 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2584 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2585 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2586 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2587 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2588 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2589 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2590 { 4*REG_FPREG15, "4*REG_FPREG15" },
2592 { 4*REG_XDREG0, "4*REG_XDREG0" },
2593 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2594 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2595 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2596 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2597 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2598 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2599 { 4*REG_XDREG14, "4*REG_XDREG14" },
2601 { 4*REG_FPSCR, "4*REG_FPSCR" },
2608 { 16, "syscall no.(L)" },
2609 { 20, "syscall_no.(U)" },
2752 /* This entry is in case pt_regs contains dregs (depends on
2753 the kernel build options). */
2754 { uoff(regs), "offsetof(struct user, regs)" },
2755 { uoff(fpu), "offsetof(struct user, fpu)" },
2758 { uoff(regs.ARM_r0), "r0" },
2759 { uoff(regs.ARM_r1), "r1" },
2760 { uoff(regs.ARM_r2), "r2" },
2761 { uoff(regs.ARM_r3), "r3" },
2762 { uoff(regs.ARM_r4), "r4" },
2763 { uoff(regs.ARM_r5), "r5" },
2764 { uoff(regs.ARM_r6), "r6" },
2765 { uoff(regs.ARM_r7), "r7" },
2766 { uoff(regs.ARM_r8), "r8" },
2767 { uoff(regs.ARM_r9), "r9" },
2768 { uoff(regs.ARM_r10), "r10" },
2769 { uoff(regs.ARM_fp), "fp" },
2770 { uoff(regs.ARM_ip), "ip" },
2771 { uoff(regs.ARM_sp), "sp" },
2772 { uoff(regs.ARM_lr), "lr" },
2773 { uoff(regs.ARM_pc), "pc" },
2774 { uoff(regs.ARM_cpsr), "cpsr" },
2777 #if !defined(S390) && !defined(S390X) && !defined(MIPS)
2778 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
2780 #if defined(I386) || defined(X86_64)
2781 { uoff(i387), "offsetof(struct user, i387)" },
2784 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
2787 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
2788 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
2789 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
2790 { uoff(start_code), "offsetof(struct user, start_code)" },
2792 { uoff(start_data), "offsetof(struct user, start_data)" },
2794 { uoff(start_stack), "offsetof(struct user, start_stack)" },
2795 { uoff(signal), "offsetof(struct user, signal)" },
2796 #if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64)
2797 { uoff(reserved), "offsetof(struct user, reserved)" },
2799 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2800 #if !defined(ARM) && !defined(MIPS) && !defined(S390) && !defined(S390X)
2801 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
2803 { uoff(magic), "offsetof(struct user, magic)" },
2804 { uoff(u_comm), "offsetof(struct user, u_comm)" },
2805 #if defined(I386) || defined(X86_64)
2806 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
2810 #endif /* !POWERPC/!SPARC */
2813 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
2814 { uoff(u_procp), "offsetof(struct user, u_procp)" },
2815 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
2816 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
2817 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
2818 { uoff(u_ap), "offsetof(struct user, u_ap)" },
2819 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
2820 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
2821 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
2822 { uoff(u_error), "offsetof(struct user, u_error)" },
2823 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
2824 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
2825 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
2826 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
2827 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
2828 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
2829 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
2830 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
2831 { uoff(u_code), "offsetof(struct user, u_code)" },
2832 { uoff(u_addr), "offsetof(struct user, u_addr)" },
2833 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
2834 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
2835 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
2836 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
2837 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
2838 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
2839 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
2840 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
2841 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
2842 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
2843 { uoff(u_ru), "offsetof(struct user, u_ru)" },
2844 { uoff(u_cru), "offsetof(struct user, u_cru)" },
2845 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
2846 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
2847 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
2848 { uoff(u_start), "offsetof(struct user, u_start)" },
2849 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
2850 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
2851 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
2852 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
2853 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
2854 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
2855 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
2856 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
2857 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
2860 { sizeof(struct user), "sizeof(struct user)" },
2873 if (entering(tcp)) {
2874 printxval(ptrace_cmds, tcp->u_arg[0],
2881 tprintf(", %lu, ", tcp->u_arg[1]);
2882 addr = tcp->u_arg[2];
2884 if (tcp->u_arg[0] == PTRACE_PEEKUSER
2885 || tcp->u_arg[0] == PTRACE_POKEUSER) {
2886 for (x = struct_user_offsets; x->str; x++) {
2891 tprintf("%#lx, ", addr);
2892 else if (x->val > addr && x != struct_user_offsets) {
2894 tprintf("%s + %ld, ", x->str, addr - x->val);
2897 tprintf("%s, ", x->str);
2901 tprintf("%#lx, ", tcp->u_arg[2]);
2903 switch (tcp->u_arg[0]) {
2904 case PTRACE_PEEKDATA:
2905 case PTRACE_PEEKTEXT:
2906 case PTRACE_PEEKUSER:
2909 case PTRACE_SINGLESTEP:
2910 case PTRACE_SYSCALL:
2912 printsignal(tcp->u_arg[3]);
2915 tprintf("%#lx", tcp->u_arg[3]);
2919 switch (tcp->u_arg[0]) {
2920 case PTRACE_PEEKDATA:
2921 case PTRACE_PEEKTEXT:
2922 case PTRACE_PEEKUSER:
2923 printnum(tcp, tcp->u_arg[3], "%#lx");
2929 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
2930 tcp->u_arg[0] == PTRACE_WRITETEXT) {
2931 tprintf("%lu, ", tcp->u_arg[3]);
2932 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2933 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
2934 tcp->u_arg[0] != PTRACE_READTEXT) {
2935 tprintf("%#lx", tcp->u_arg[3]);
2938 if (tcp->u_arg[0] == PTRACE_READDATA ||
2939 tcp->u_arg[0] == PTRACE_READTEXT) {
2940 tprintf("%lu, ", tcp->u_arg[3]);
2941 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
2946 tprintf("%lu", tcp->u_arg[3]);
2948 #endif /* FREEBSD */
2955 static struct xlat futexops[] = {
2956 { FUTEX_WAIT, "FUTEX_WAIT" },
2957 { FUTEX_WAKE, "FUTEX_WAKE" },
2958 { FUTEX_FD, "FUTEX_FD" },
2959 { FUTEX_REQUEUE,"FUTEX_REQUEUE" },
2967 if (entering(tcp)) {
2968 tprintf("%p, ", (void *) tcp->u_arg[0]);
2969 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
2970 tprintf(", %ld", tcp->u_arg[2]);
2971 if (tcp->u_arg[1] == FUTEX_WAIT) {
2973 printtv(tcp, tcp->u_arg[3]);
2974 } else if (tcp->u_arg[1] == FUTEX_REQUEUE)
2975 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
2981 print_affinitylist(tcp, list, len)
2988 while (len >= sizeof (unsigned long)) {
2990 umove(tcp, list, &w);
2991 tprintf("%s %lx", first ? "" : ",", w);
2993 len -= sizeof (unsigned long);
2994 list += sizeof(unsigned long);
3000 sys_sched_setaffinity(tcp)
3003 if (entering(tcp)) {
3004 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3005 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3011 sys_sched_getaffinity(tcp)
3014 if (entering(tcp)) {
3015 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3017 if (tcp->u_rval == -1)
3018 tprintf("%#lx", tcp->u_arg[2]);
3020 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3025 static struct xlat schedulers[] = {
3026 { SCHED_OTHER, "SCHED_OTHER" },
3027 { SCHED_RR, "SCHED_RR" },
3028 { SCHED_FIFO, "SCHED_FIFO" },
3033 sys_sched_getscheduler(tcp)
3036 if (entering(tcp)) {
3037 tprintf("%d", (int) tcp->u_arg[0]);
3038 } else if (! syserror(tcp)) {
3039 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3040 if (tcp->auxstr != NULL)
3047 sys_sched_setscheduler(tcp)
3050 if (entering(tcp)) {
3051 struct sched_param p;
3052 tprintf("%d, ", (int) tcp->u_arg[0]);
3053 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3054 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3055 tprintf(", %lx", tcp->u_arg[2]);
3057 tprintf(", { %d }", p.__sched_priority);
3063 sys_sched_getparam(tcp)
3066 if (entering(tcp)) {
3067 tprintf("%d, ", (int) tcp->u_arg[0]);
3069 struct sched_param p;
3070 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3071 tprintf("%lx", tcp->u_arg[1]);
3073 tprintf("{ %d }", p.__sched_priority);
3079 sys_sched_setparam(tcp)
3082 if (entering(tcp)) {
3083 struct sched_param p;
3084 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3085 tprintf("%d, %lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3087 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3093 sys_sched_get_priority_min(tcp)
3096 if (entering(tcp)) {
3097 printxval(schedulers, tcp->u_arg[0], "SCHED_???");