2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * Copyright (c) 2000 PocketPenguins Inc. Linux for Hitachi SuperH
10 * port by Greg Banks <gbanks@pocketpenguins.com>
13 * All rights reserved.
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
18 * 1. Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 * 3. The name of the author may not be used to endorse or promote products
24 * derived from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 #include <sys/resource.h>
47 #include <sys/utsname.h>
49 #include <sys/syscall.h>
52 #include <machine/reg.h>
56 #include <sys/ptrace.h>
60 #if defined (SPARC) || defined (SPARC64)
61 # define fpq kernel_fpq
63 # define fpu kernel_fpu
64 #endif /* SPARC || SPARC64 */
66 #if defined (SPARC) || defined (SPARC64)
70 #endif /* SPARC || SPARC64 */
71 #endif /* HAVE_ASM_REG_H */
75 #ifndef PTRACE_PEEKUSR
76 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
78 #ifndef PTRACE_POKEUSR
79 # define PTRACE_POKEUSR PTRACE_POKEUSER
83 #ifdef HAVE_LINUX_PTRACE_H
85 # ifdef HAVE_STRUCT_IA64_FPREG
86 # define ia64_fpreg XXX_ia64_fpreg
88 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
89 # define pt_all_user_regs XXX_pt_all_user_regs
91 #include <linux/ptrace.h>
93 # undef pt_all_user_regs
96 #if defined (LINUX) && defined (SPARC64)
98 # undef PTRACE_GETREGS
99 # define PTRACE_GETREGS PTRACE_GETREGS64
100 # undef PTRACE_SETREGS
101 # define PTRACE_SETREGS PTRACE_SETREGS64
102 #endif /* LINUX && SPARC64 */
104 #ifdef HAVE_LINUX_FUTEX_H
105 #include <linux/futex.h>
109 # define FUTEX_WAIT 0
112 # define FUTEX_WAKE 1
117 # ifndef FUTEX_REQUEUE
118 # define FUTEX_REQUEUE 3
124 #include <asm/posix_types.h>
126 #define GETGROUPS_T __kernel_gid_t
128 #define GETGROUPS32_T __kernel_gid32_t
131 #if defined(LINUX) && defined(IA64)
132 # include <asm/ptrace_offsets.h>
133 # include <asm/rse.h>
137 #include <sys/prctl.h>
141 #define WCOREDUMP(status) ((status) & 0200)
144 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
145 #if defined(HAVE_PRCTL)
146 static const struct xlat prctl_options[] = {
148 { PR_MAXPROCS, "PR_MAXPROCS" },
151 { PR_ISBLOCKED, "PR_ISBLOCKED" },
153 #ifdef PR_SETSTACKSIZE
154 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
156 #ifdef PR_GETSTACKSIZE
157 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
160 { PR_MAXPPROCS, "PR_MAXPPROCS" },
162 #ifdef PR_UNBLKONEXEC
163 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
166 { PR_ATOMICSIM, "PR_ATOMICSIM" },
169 { PR_SETEXITSIG, "PR_SETEXITSIG" },
172 { PR_RESIDENT, "PR_RESIDENT" },
175 { PR_ATTACHADDR, "PR_ATTACHADDR" },
178 { PR_DETACHADDR, "PR_DETACHADDR" },
181 { PR_TERMCHILD, "PR_TERMCHILD" },
184 { PR_GETSHMASK, "PR_GETSHMASK" },
187 { PR_GETNSHARE, "PR_GETNSHARE" },
190 { PR_COREPID, "PR_COREPID" },
192 #ifdef PR_ATTACHADDRPERM
193 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
195 #ifdef PR_PTHREADEXIT
196 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
198 #ifdef PR_SET_PDEATHSIG
199 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
201 #ifdef PR_GET_PDEATHSIG
202 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
204 #ifdef PR_GET_DUMPABLE
205 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
207 #ifdef PR_SET_DUMPABLE
208 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
210 #ifdef PR_GET_UNALIGN
211 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
213 #ifdef PR_SET_UNALIGN
214 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
216 #ifdef PR_GET_KEEPCAPS
217 { PR_GET_KEEPCAPS, "PR_GET_KEEPCAPS" },
219 #ifdef PR_SET_KEEPCAPS
220 { PR_SET_KEEPCAPS, "PR_SET_KEEPCAPS" },
223 { PR_GET_FPEMU, "PR_GET_FPEMU" },
226 { PR_SET_FPEMU, "PR_SET_FPEMU" },
229 { PR_GET_FPEXC, "PR_GET_FPEXC" },
232 { PR_SET_FPEXC, "PR_SET_FPEXC" },
235 { PR_GET_TIMING, "PR_GET_TIMING" },
238 { PR_SET_TIMING, "PR_SET_TIMING" },
241 { PR_SET_NAME, "PR_SET_NAME" },
244 { PR_GET_NAME, "PR_GET_NAME" },
247 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
250 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
252 #ifdef PR_GET_SECCOMP
253 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
255 #ifdef PR_SET_SECCOMP
256 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
259 { PR_GET_TSC, "PR_GET_TSC" },
262 { PR_SET_TSC, "PR_SET_TSC" },
264 #ifdef PR_GET_SECUREBITS
265 { PR_GET_SECUREBITS, "PR_GET_SECUREBITS" },
267 #ifdef PR_SET_SECUREBITS
268 { PR_SET_SECUREBITS, "PR_SET_SECUREBITS" },
275 unalignctl_string (unsigned int ctl)
280 #ifdef PR_UNALIGN_NOPRINT
281 case PR_UNALIGN_NOPRINT:
284 #ifdef PR_UNALIGN_SIGBUS
285 case PR_UNALIGN_SIGBUS:
291 sprintf(buf, "%x", ctl);
303 printxval(prctl_options, tcp->u_arg[0], "PR_???");
304 switch (tcp->u_arg[0]) {
309 #ifdef PR_SET_PDEATHSIG
310 case PR_SET_PDEATHSIG:
311 tprintf(", %lu", tcp->u_arg[1]);
314 #ifdef PR_GET_PDEATHSIG
315 case PR_GET_PDEATHSIG:
318 #ifdef PR_SET_DUMPABLE
319 case PR_SET_DUMPABLE:
320 tprintf(", %lu", tcp->u_arg[1]);
323 #ifdef PR_GET_DUMPABLE
324 case PR_GET_DUMPABLE:
327 #ifdef PR_SET_UNALIGN
329 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
332 #ifdef PR_GET_UNALIGN
334 tprintf(", %#lx", tcp->u_arg[1]);
337 #ifdef PR_SET_KEEPCAPS
338 case PR_SET_KEEPCAPS:
339 tprintf(", %lu", tcp->u_arg[1]);
342 #ifdef PR_GET_KEEPCAPS
343 case PR_GET_KEEPCAPS:
347 for (i = 1; i < tcp->u_nargs; i++)
348 tprintf(", %#lx", tcp->u_arg[i]);
352 switch (tcp->u_arg[0]) {
353 #ifdef PR_GET_PDEATHSIG
354 case PR_GET_PDEATHSIG:
355 if (umove(tcp, tcp->u_arg[1], &i) < 0)
356 tprintf(", %#lx", tcp->u_arg[1]);
358 tprintf(", {%u}", i);
361 #ifdef PR_GET_DUMPABLE
362 case PR_GET_DUMPABLE:
363 return RVAL_UDECIMAL;
365 #ifdef PR_GET_UNALIGN
367 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
369 tcp->auxstr = unalignctl_string(i);
372 #ifdef PR_GET_KEEPCAPS
373 case PR_GET_KEEPCAPS:
374 return RVAL_UDECIMAL;
383 #endif /* HAVE_PRCTL */
385 #if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
394 #endif /* FREEBSD || SUNOS4 || SVR4 */
401 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
402 tprintf(", %lu", tcp->u_arg[1]);
407 #if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
414 tprintf("%#lx", tcp->u_arg[0]);
416 printpath(tcp, tcp->u_arg[0]);
417 tprintf(", %lu", tcp->u_arg[1]);
421 #endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
424 sys_setdomainname(tcp)
428 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
429 tprintf(", %lu", tcp->u_arg[1]);
437 sys_getdomainname(tcp)
442 tprintf("%#lx", tcp->u_arg[0]);
444 printpath(tcp, tcp->u_arg[0]);
445 tprintf(", %lu", tcp->u_arg[1]);
456 fprintf(stderr, "_exit returned!\n");
459 /* special case: we stop tracing this process, finish line now */
460 tprintf("%ld) ", tcp->u_arg[0]);
472 tcp->flags |= TCB_EXITING;
473 #ifdef __NR_exit_group
476 if (tcp->scno == 252)
477 tcp->flags |= TCB_GROUP_EXITING;
480 if (known_scno(tcp) == __NR_exit_group)
481 tcp->flags |= TCB_GROUP_EXITING;
487 /* TCP is creating a child we want to follow.
488 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
489 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
491 fork_tcb(struct tcb *tcp)
493 if (nprocs == tcbtabsize)
496 tcp->flags |= TCB_FOLLOWFORK;
502 sys_fork(struct tcb *tcp)
504 if (exiting(tcp) && !syserror(tcp)) {
506 tcp->auxstr = "child process";
507 return RVAL_UDECIMAL | RVAL_STR;
520 tprintf ("%ld", tcp->u_arg[0]);
522 else if (!syserror(tcp)) {
524 tcp->auxstr = "child process";
525 return RVAL_UDECIMAL | RVAL_STR;
537 struct tcb *tcpchild;
541 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
551 tcpchild = alloctcb(tcp->u_rval);
552 if (proc_open(tcpchild, 2) < 0)
558 #else /* !USE_PROCFS */
562 /* defines copied from linux/sched.h since we can't include that
563 * ourselves (it conflicts with *lots* of libc includes)
565 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
566 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
567 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
568 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
569 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
570 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
571 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
572 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
573 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
574 #define CLONE_THREAD 0x00010000 /* Same thread group? */
575 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
576 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
577 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
578 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
579 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
580 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
581 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
582 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
584 static const struct xlat clone_flags[] = {
585 { CLONE_VM, "CLONE_VM" },
586 { CLONE_FS, "CLONE_FS" },
587 { CLONE_FILES, "CLONE_FILES" },
588 { CLONE_SIGHAND, "CLONE_SIGHAND" },
589 { CLONE_IDLETASK, "CLONE_IDLETASK"},
590 { CLONE_PTRACE, "CLONE_PTRACE" },
591 { CLONE_VFORK, "CLONE_VFORK" },
592 { CLONE_PARENT, "CLONE_PARENT" },
593 { CLONE_THREAD, "CLONE_THREAD" },
594 { CLONE_NEWNS, "CLONE_NEWNS" },
595 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
596 { CLONE_SETTLS, "CLONE_SETTLS" },
597 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
598 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
599 { CLONE_DETACHED, "CLONE_DETACHED" },
600 { CLONE_UNTRACED, "CLONE_UNTRACED" },
601 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
606 # include <asm/ldt.h>
607 # ifdef HAVE_STRUCT_USER_DESC
608 # define modify_ldt_ldt_s user_desc
610 extern void print_ldt_entry();
616 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
617 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
618 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
619 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
620 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
626 # elif defined X86_64 || defined ALPHA
645 unsigned long flags = tcp->u_arg[ARG_FLAGS];
646 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
647 # ifdef ARG_STACKSIZE
648 if (ARG_STACKSIZE != -1)
649 tprintf("stack_size=%#lx, ",
650 tcp->u_arg[ARG_STACKSIZE]);
653 printflags(clone_flags, flags &~ CSIGNAL, NULL);
654 if ((flags & CSIGNAL) != 0)
655 tprintf("|%s", signame(flags & CSIGNAL));
656 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
657 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
659 if (flags & CLONE_PARENT_SETTID)
660 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
661 if (flags & CLONE_SETTLS) {
663 struct modify_ldt_ldt_s copy;
664 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
665 tprintf(", {entry_number:%d, ",
670 print_ldt_entry(©);
674 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
676 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
677 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
683 sys_unshare(struct tcb *tcp)
686 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
696 return RVAL_UDECIMAL;
701 change_syscall(struct tcb *tcp, int new)
705 /* Attempt to make vfork into fork, which we can follow. */
706 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
709 #elif defined(X86_64)
710 /* Attempt to make vfork into fork, which we can follow. */
711 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
714 #elif defined(POWERPC)
715 if (ptrace(PTRACE_POKEUSER, tcp->pid,
716 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
719 #elif defined(S390) || defined(S390X)
720 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
721 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
725 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
728 #elif defined(SPARC) || defined(SPARC64)
730 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
733 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
737 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
741 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
745 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
749 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
756 break; /* x86 SYS_fork */
761 fprintf(stderr, "%s: unexpected syscall %d\n",
765 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
767 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
771 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
775 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
779 /* Top half of reg encodes the no. of args n as 0x1n.
780 Assume 0 args as kernel never actually checks... */
781 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
785 #elif defined(CRISV10) || defined(CRISV32)
786 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
790 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
791 # ifndef PTRACE_SET_SYSCALL
792 # define PTRACE_SET_SYSCALL 23
795 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
800 #warning Do not know how to handle change_syscall for this architecture
801 #endif /* architecture */
816 ptrace(PTRACE_POKEUSER, tcp->pid,
817 (char *)(REG_R12_ORIG),
821 ptrace(PTRACE_POKEUSER, tcp->pid,
822 (char *)(REG_R12 - 4 * argnum),
826 ptrace(PTRACE_POKEUSER, tcp->pid,
831 ptrace(PTRACE_POKEUSER, tcp->pid,
841 unsigned long *bsp, *ap;
843 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
846 ap = ia64_rse_skip_regs(bsp, argnum);
848 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
855 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
859 #elif defined(X86_64)
861 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
865 #elif defined(POWERPC)
867 #define PT_ORIG_R3 34
870 ptrace(PTRACE_POKEUSER, tcp->pid,
871 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
880 ptrace(PTRACE_POKEUSER, tcp->pid,
881 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
885 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
888 ptrace(PTRACE_POKEDATA, tcp->pid,
889 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
894 #elif defined(S390) || defined(S390X)
897 ptrace(PTRACE_POKEUSER, tcp->pid,
898 (char *) (argnum==0 ? PT_ORIGGPR2 :
899 PT_GPR2 + argnum*sizeof(long)),
907 # warning Sorry, setargs not implemented for this architecture.
913 #if defined SYS_clone || defined SYS_clone2
918 struct tcb *tcpchild;
927 int bpt = tcp->flags & TCB_BPTSET;
929 if (!(tcp->flags & TCB_FOLLOWFORK))
940 #ifdef CLONE_PTRACE /* See new setbpt code. */
941 tcpchild = pid2tcb(pid);
942 if (tcpchild != NULL) {
943 /* The child already reported its startup trap
944 before the parent reported its syscall return. */
946 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
947 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
949 [preattached child %d of %d in weird state!]\n",
956 tcpchild = alloctcb(pid);
960 /* Attach to the new child */
961 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
964 perror("PTRACE_ATTACH");
965 fprintf(stderr, "Too late?\n");
974 tcpchild->flags |= TCB_ATTACHED;
975 /* Child has BPT too, must be removed on first occasion. */
977 tcpchild->flags |= TCB_BPTSET;
978 tcpchild->baddr = tcp->baddr;
979 memcpy(tcpchild->inst, tcp->inst,
980 sizeof tcpchild->inst);
982 tcpchild->parent = tcp;
984 if (tcpchild->flags & TCB_SUSPENDED) {
985 /* The child was born suspended, due to our having
986 forced CLONE_PTRACE. */
990 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
991 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
996 Process %u resumed (parent %d ready)\n",
1001 fprintf(stderr, "Process %d attached\n", pid);
1004 #ifdef TCB_CLONE_THREAD
1007 * Save the flags used in this call,
1008 * in case we point TCP to our parent below.
1010 int call_flags = tcp->u_arg[ARG_FLAGS];
1011 if ((tcp->flags & TCB_CLONE_THREAD) &&
1012 tcp->parent != NULL) {
1013 /* The parent in this clone is itself a
1014 thread belonging to another process.
1015 There is no meaning to the parentage
1016 relationship of the new child with the
1017 thread, only with the process. We
1018 associate the new thread with our
1019 parent. Since this is done for every
1020 new thread, there will never be a
1021 TCB_CLONE_THREAD process that has
1025 tcpchild->parent = tcp;
1028 if (call_flags & CLONE_THREAD) {
1029 tcpchild->flags |= TCB_CLONE_THREAD;
1030 ++tcp->nclone_threads;
1032 if (call_flags & CLONE_DETACHED) {
1033 tcpchild->flags |= TCB_CLONE_DETACHED;
1034 ++tcp->nclone_detached;
1048 /* We do special magic with clone for any clone or fork. */
1049 return internal_clone(tcp);
1052 struct tcb *tcpchild;
1054 int dont_follow = 0;
1057 if (known_scno(tcp) == SYS_vfork) {
1058 /* Attempt to make vfork into fork, which we can follow. */
1059 if (change_syscall(tcp, SYS_fork) < 0)
1063 if (entering(tcp)) {
1064 if (!followfork || dont_follow)
1067 if (setbpt(tcp) < 0)
1071 int bpt = tcp->flags & TCB_BPTSET;
1073 if (!(tcp->flags & TCB_FOLLOWFORK))
1083 tcpchild = alloctcb(pid);
1086 /* The child must have run before it can be attached. */
1087 /* This must be a bug in the parisc kernel, but I havn't
1088 * identified it yet. Seems to be an issue associated
1089 * with attaching to a process (which sends it a signal)
1090 * before that process has ever been scheduled. When
1091 * debugging, I started seeing crashes in
1092 * arch/parisc/kernel/signal.c:do_signal(), apparently
1093 * caused by r8 getting corrupt over the dequeue_signal()
1094 * call. Didn't make much sense though...
1100 select(0, NULL, NULL, NULL, &tv);
1103 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
1104 perror("PTRACE_ATTACH");
1105 fprintf(stderr, "Too late?\n");
1112 /* The child must have run before it can be attached. */
1117 select(0, NULL, NULL, NULL, &tv);
1119 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1120 perror("PTRACE_ATTACH");
1121 fprintf(stderr, "Too late?\n");
1126 /* Try to catch the new process as soon as possible. */
1129 for (i = 0; i < 1024; i++)
1130 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1133 perror("PTRACE_ATTACH");
1134 fprintf(stderr, "Too late?\n");
1139 #endif /* !oldway */
1141 tcpchild->flags |= TCB_ATTACHED;
1142 /* Child has BPT too, must be removed on first occasion */
1144 tcpchild->flags |= TCB_BPTSET;
1145 tcpchild->baddr = tcp->baddr;
1146 memcpy(tcpchild->inst, tcp->inst,
1147 sizeof tcpchild->inst);
1149 tcpchild->parent = tcp;
1152 fprintf(stderr, "Process %d attached\n", pid);
1158 #endif /* !USE_PROCFS */
1160 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1167 return RVAL_UDECIMAL;
1171 #endif /* SUNOS4 || LINUX || FREEBSD */
1175 static char idstr[16];
1182 sprintf(idstr, "ppid %lu", getrval2(tcp));
1183 tcp->auxstr = idstr;
1194 sprintf(idstr, "euid %lu", getrval2(tcp));
1195 tcp->auxstr = idstr;
1206 sprintf(idstr, "egid %lu", getrval2(tcp));
1207 tcp->auxstr = idstr;
1221 if (entering(tcp)) {
1222 tprintf("%u", (uid_t) tcp->u_arg[0]);
1231 if (entering(tcp)) {
1232 tprintf("%u", (gid_t) tcp->u_arg[0]);
1238 sys_getresuid(struct tcb *tcp)
1243 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1244 tcp->u_arg[1], tcp->u_arg[2]);
1246 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1247 tprintf("%#lx, ", tcp->u_arg[0]);
1249 tprintf("[%lu], ", (unsigned long) uid);
1250 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1251 tprintf("%#lx, ", tcp->u_arg[1]);
1253 tprintf("[%lu], ", (unsigned long) uid);
1254 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1255 tprintf("%#lx", tcp->u_arg[2]);
1257 tprintf("[%lu]", (unsigned long) uid);
1270 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1271 tcp->u_arg[1], tcp->u_arg[2]);
1273 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1274 tprintf("%#lx, ", tcp->u_arg[0]);
1276 tprintf("[%lu], ", (unsigned long) gid);
1277 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1278 tprintf("%#lx, ", tcp->u_arg[1]);
1280 tprintf("[%lu], ", (unsigned long) gid);
1281 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1282 tprintf("%#lx", tcp->u_arg[2]);
1284 tprintf("[%lu]", (unsigned long) gid);
1296 if (entering(tcp)) {
1297 printuid("", tcp->u_arg[0]);
1298 printuid(", ", tcp->u_arg[1]);
1307 if (entering(tcp)) {
1308 printuid("", tcp->u_arg[0]);
1309 printuid(", ", tcp->u_arg[1]);
1314 #if defined(LINUX) || defined(FREEBSD)
1319 if (entering(tcp)) {
1320 printuid("", tcp->u_arg[0]);
1321 printuid(", ", tcp->u_arg[1]);
1322 printuid(", ", tcp->u_arg[2]);
1330 if (entering(tcp)) {
1331 printuid("", tcp->u_arg[0]);
1332 printuid(", ", tcp->u_arg[1]);
1333 printuid(", ", tcp->u_arg[2]);
1338 #endif /* LINUX || FREEBSD */
1344 if (entering(tcp)) {
1345 unsigned long len, size, start, cur, end, abbrev_end;
1349 len = tcp->u_arg[0];
1350 tprintf("%lu, ", len);
1355 start = tcp->u_arg[1];
1360 size = len * sizeof(gid);
1362 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1363 tprintf("%#lx", start);
1367 abbrev_end = start + max_strlen * sizeof(gid);
1368 if (abbrev_end < start)
1374 for (cur = start; cur < end; cur += sizeof(gid)) {
1377 if (cur >= abbrev_end) {
1381 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1386 tprintf("%lu", (unsigned long) gid);
1390 tprintf(" %#lx", tcp->u_arg[1]);
1401 if (entering(tcp)) {
1402 len = tcp->u_arg[0];
1403 tprintf("%lu, ", len);
1405 unsigned long size, start, cur, end, abbrev_end;
1414 start = tcp->u_arg[1];
1419 if (tcp->u_arg[0] == 0) {
1420 tprintf("%#lx", start);
1423 size = len * sizeof(gid);
1425 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1426 size / sizeof(gid) != len || end < start) {
1427 tprintf("%#lx", start);
1431 abbrev_end = start + max_strlen * sizeof(gid);
1432 if (abbrev_end < start)
1438 for (cur = start; cur < end; cur += sizeof(gid)) {
1441 if (cur >= abbrev_end) {
1445 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1450 tprintf("%lu", (unsigned long) gid);
1454 tprintf(" %#lx", tcp->u_arg[1]);
1461 sys_setgroups32(tcp)
1464 if (entering(tcp)) {
1465 unsigned long len, size, start, cur, end, abbrev_end;
1469 len = tcp->u_arg[0];
1470 tprintf("%lu, ", len);
1475 start = tcp->u_arg[1];
1480 size = len * sizeof(gid);
1482 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1483 tprintf("%#lx", start);
1487 abbrev_end = start + max_strlen * sizeof(gid);
1488 if (abbrev_end < start)
1494 for (cur = start; cur < end; cur += sizeof(gid)) {
1497 if (cur >= abbrev_end) {
1501 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1506 tprintf("%lu", (unsigned long) gid);
1510 tprintf(" %#lx", tcp->u_arg[1]);
1516 sys_getgroups32(tcp)
1521 if (entering(tcp)) {
1522 len = tcp->u_arg[0];
1523 tprintf("%lu, ", len);
1525 unsigned long size, start, cur, end, abbrev_end;
1534 start = tcp->u_arg[1];
1539 size = len * sizeof(gid);
1541 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1542 size / sizeof(gid) != len || end < start) {
1543 tprintf("%#lx", start);
1547 abbrev_end = start + max_strlen * sizeof(gid);
1548 if (abbrev_end < start)
1554 for (cur = start; cur < end; cur += sizeof(gid)) {
1557 if (cur >= abbrev_end) {
1561 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1566 tprintf("%lu", (unsigned long) gid);
1570 tprintf(" %#lx", tcp->u_arg[1]);
1576 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1581 if (entering(tcp)) {
1583 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1588 #endif /* ALPHA || SUNOS4 || SVR4 */
1594 if (entering(tcp)) {
1596 tprintf("%lu", tcp->u_arg[0]);
1606 if (entering(tcp)) {
1607 tprintf("%lu", tcp->u_arg[0]);
1623 if (entering(tcp)) {
1624 tprintf("%lu", tcp->u_arg[0]);
1633 if (entering(tcp)) {
1634 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1641 #include <sys/privilege.h>
1644 static const struct xlat procpriv_cmds [] = {
1645 { SETPRV, "SETPRV" },
1646 { CLRPRV, "CLRPRV" },
1647 { PUTPRV, "PUTPRV" },
1648 { GETPRV, "GETPRV" },
1649 { CNTPRV, "CNTPRV" },
1654 static const struct xlat procpriv_priv [] = {
1655 { P_OWNER, "P_OWNER" },
1656 { P_AUDIT, "P_AUDIT" },
1657 { P_COMPAT, "P_COMPAT" },
1658 { P_DACREAD, "P_DACREAD" },
1659 { P_DACWRITE, "P_DACWRITE" },
1661 { P_FILESYS, "P_FILESYS" },
1662 { P_MACREAD, "P_MACREAD" },
1663 { P_MACWRITE, "P_MACWRITE" },
1664 { P_MOUNT, "P_MOUNT" },
1665 { P_MULTIDIR, "P_MULTIDIR" },
1666 { P_SETPLEVEL, "P_SETPLEVEL" },
1667 { P_SETSPRIV, "P_SETSPRIV" },
1668 { P_SETUID, "P_SETUID" },
1669 { P_SYSOPS, "P_SYSOPS" },
1670 { P_SETUPRIV, "P_SETUPRIV" },
1671 { P_DRIVER, "P_DRIVER" },
1672 { P_RTIME, "P_RTIME" },
1673 { P_MACUPGRADE, "P_MACUPGRADE" },
1674 { P_FSYSRANGE, "P_FSYSRANGE" },
1675 { P_SETFLEVEL, "P_SETFLEVEL" },
1676 { P_AUDITWR, "P_AUDITWR" },
1677 { P_TSHAR, "P_TSHAR" },
1678 { P_PLOCK, "P_PLOCK" },
1679 { P_CORE, "P_CORE" },
1680 { P_LOADMOD, "P_LOADMOD" },
1681 { P_BIND, "P_BIND" },
1682 { P_ALLPRIVS, "P_ALLPRIVS" },
1687 static const struct xlat procpriv_type [] = {
1688 { PS_FIX, "PS_FIX" },
1689 { PS_INH, "PS_INH" },
1690 { PS_MAX, "PS_MAX" },
1691 { PS_WKG, "PS_WKG" },
1697 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1700 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1701 int dots = len > max;
1704 if (len > max) len = max;
1707 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1709 tprintf ("%#lx", addr);
1715 for (i = 0; i < len; ++i) {
1718 if (i) tprintf (", ");
1720 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1721 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1723 tprintf ("%s|%s", t, p);
1726 tprintf ("%#lx", buf [i]);
1730 if (dots) tprintf (" ...");
1740 if (entering(tcp)) {
1741 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1742 switch (tcp->u_arg[0]) {
1744 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1752 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1753 tprintf (", %ld", tcp->u_arg[2]);
1756 else if (tcp->u_arg[0] == GETPRV) {
1757 if (syserror (tcp)) {
1758 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1762 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1763 tprintf (", %ld", tcp->u_arg[2]);
1774 printargv(tcp, addr)
1781 char data[sizeof(long)];
1787 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1788 if (umoven(tcp, addr, personality_wordsize[current_personality],
1790 tprintf("%#lx", addr);
1793 if (personality_wordsize[current_personality] == 4)
1798 printstr(tcp, cp.p64, -1);
1799 addr += personality_wordsize[current_personality];
1802 tprintf("%s...", sep);
1806 printargc(fmt, tcp, addr)
1814 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1815 addr += sizeof(char *);
1817 tprintf(fmt, count, count == 1 ? "" : "s");
1820 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1825 if (entering(tcp)) {
1826 printpath(tcp, tcp->u_arg[0]);
1828 tprintf(", %#lx", tcp->u_arg[1]);
1830 else if (abbrev(tcp))
1831 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1835 printargv(tcp, tcp->u_arg[1]);
1841 #endif /* SPARC || SPARC64 || SUNOS4 */
1847 if (entering(tcp)) {
1848 printpath(tcp, tcp->u_arg[0]);
1850 tprintf(", %#lx", tcp->u_arg[1]);
1852 else if (abbrev(tcp))
1853 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1857 printargv(tcp, tcp->u_arg[1]);
1861 tprintf(", %#lx", tcp->u_arg[2]);
1862 else if (abbrev(tcp))
1863 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1866 printargv(tcp, tcp->u_arg[2]);
1875 int sys_rexecve(tcp)
1878 if (entering (tcp)) {
1880 tprintf (", %ld", tcp->u_arg[3]);
1892 if (exiting(tcp) && !syserror(tcp) && followfork)
1895 #if defined LINUX && defined TCB_WAITEXECVE
1896 if (exiting(tcp) && syserror(tcp))
1897 tcp->flags &= ~TCB_WAITEXECVE;
1899 tcp->flags |= TCB_WAITEXECVE;
1900 #endif /* LINUX && TCB_WAITEXECVE */
1906 #define __WNOTHREAD 0x20000000
1909 #define __WALL 0x40000000
1912 #define __WCLONE 0x80000000
1916 static const struct xlat wait4_options[] = {
1917 { WNOHANG, "WNOHANG" },
1919 { WUNTRACED, "WUNTRACED" },
1922 { WEXITED, "WEXITED" },
1925 { WTRAPPED, "WTRAPPED" },
1928 { WSTOPPED, "WSTOPPED" },
1931 { WCONTINUED, "WCONTINUED" },
1934 { WNOWAIT, "WNOWAIT" },
1937 { __WCLONE, "__WCLONE" },
1940 { __WALL, "__WALL" },
1943 { __WNOTHREAD, "__WNOTHREAD" },
1948 #if !defined WCOREFLAG && defined WCOREFLG
1949 # define WCOREFLAG WCOREFLG
1952 #define WCOREFLAG 0x80
1956 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1959 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1969 * Here is a tricky presentation problem. This solution
1970 * is still not entirely satisfactory but since there
1971 * are no wait status constructors it will have to do.
1973 if (WIFSTOPPED(status)) {
1974 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1975 signame(WSTOPSIG(status)));
1976 status &= ~W_STOPCODE(WSTOPSIG(status));
1978 else if (WIFSIGNALED(status)) {
1979 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1980 signame(WTERMSIG(status)),
1981 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1982 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1984 else if (WIFEXITED(status)) {
1985 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1986 WEXITSTATUS(status));
1988 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1991 tprintf("[%#x]", status);
1998 tprintf(" | %#x]", status);
2004 printwaitn(struct tcb *tcp, int n, int bitness)
2009 if (entering(tcp)) {
2011 /* On Linux, kernel-side pid_t is typedef'ed to int
2012 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
2013 * pid argument to int on 64bit arches, producing,
2014 * for example, wait4(4294967295, ...) instead of -1
2015 * in strace. We have to use int here, not long.
2017 int pid = tcp->u_arg[0];
2018 tprintf("%d, ", pid);
2021 * Sign-extend a 32-bit value when that's what it is.
2023 long pid = tcp->u_arg[0];
2024 if (personality_wordsize[current_personality] < sizeof pid)
2025 pid = (long) (int) pid;
2026 tprintf("%ld, ", pid);
2032 else if (syserror(tcp) || tcp->u_rval == 0)
2033 tprintf("%#lx", tcp->u_arg[1]);
2034 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
2037 exited = printstatus(status);
2040 printflags(wait4_options, tcp->u_arg[2], "W???");
2047 else if (tcp->u_rval > 0) {
2050 printrusage32(tcp, tcp->u_arg[3]);
2053 printrusage(tcp, tcp->u_arg[3]);
2057 else if (tcp->u_rval > 0 && exited)
2058 printrusage(tcp, tcp->u_arg[3]);
2061 tprintf("%#lx", tcp->u_arg[3]);
2068 internal_wait(tcp, flagarg)
2074 #ifdef TCB_CLONE_THREAD
2075 if (tcp->flags & TCB_CLONE_THREAD)
2076 /* The children we wait for are our parent's children. */
2077 got_kids = (tcp->parent->nchildren
2078 > tcp->parent->nclone_detached);
2080 got_kids = (tcp->nchildren > tcp->nclone_detached);
2082 got_kids = tcp->nchildren > 0;
2085 if (entering(tcp) && got_kids) {
2086 /* There are children that this parent should block for.
2087 But ptrace made us the parent of the traced children
2088 and the real parent will get ECHILD from the wait call.
2090 XXX If we attached with strace -f -p PID, then there
2091 may be untraced dead children the parent could be reaping
2092 now, but we make him block. */
2094 /* ??? WTA: fix bug with hanging children */
2096 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
2098 * There are traced children. We'll make the parent
2099 * block to avoid a false ECHILD error due to our
2100 * ptrace having stolen the children. However,
2101 * we shouldn't block if there are zombies to reap.
2102 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2104 struct tcb *child = NULL;
2105 if (tcp->nzombies > 0 &&
2106 (tcp->u_arg[0] == -1 ||
2107 (child = pid2tcb(tcp->u_arg[0])) == NULL))
2109 if (tcp->u_arg[0] > 0) {
2111 * If the parent waits for a specified child
2112 * PID, then it must get ECHILD right away
2113 * if that PID is not one of its children.
2114 * Make sure that the requested PID matches
2115 * one of the parent's children that we are
2116 * tracing, and don't suspend it otherwise.
2119 child = pid2tcb(tcp->u_arg[0]);
2120 if (child == NULL || child->parent != (
2121 #ifdef TCB_CLONE_THREAD
2122 (tcp->flags & TCB_CLONE_THREAD)
2126 (child->flags & TCB_EXITING))
2129 tcp->flags |= TCB_SUSPENDED;
2130 tcp->waitpid = tcp->u_arg[0];
2131 #ifdef TCB_CLONE_THREAD
2132 if (tcp->flags & TCB_CLONE_THREAD)
2133 tcp->parent->nclone_waiting++;
2137 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2138 if (tcp->u_arg[flagarg] & WNOHANG) {
2139 /* We must force a fake result of 0 instead of
2140 the ECHILD error. */
2141 extern int force_result();
2142 return force_result(tcp, 0, 0);
2145 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2146 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2148 * We just reaped a child we don't know about,
2149 * presumably a zombie we already droptcb'd.
2163 /* The library wrapper stuffs this into the user variable. */
2165 printstatus(getrval2(tcp));
2180 if (!syserror(tcp)) {
2181 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2182 tprintf("%#lx", tcp->u_arg[0]);
2184 printstatus(status);
2195 return printwaitn(tcp, 3, 0);
2202 return printwaitn(tcp, 4, 0);
2210 return printwaitn(tcp, 4, 1);
2214 #if defined SVR4 || defined LINUX
2216 static const struct xlat waitid_types[] = {
2219 { P_PPID, "P_PPID" },
2221 { P_PGID, "P_PGID" },
2236 { P_LWPID, "P_LWPID" },
2248 if (entering(tcp)) {
2249 printxval(waitid_types, tcp->u_arg[0], "P_???");
2250 tprintf(", %ld, ", tcp->u_arg[1]);
2257 else if (syserror(tcp))
2258 tprintf("%#lx", tcp->u_arg[2]);
2259 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2262 printsiginfo(&si, verbose(tcp));
2265 printflags(wait4_options, tcp->u_arg[3], "W???");
2266 if (tcp->u_nargs > 4) {
2271 else if (tcp->u_error)
2272 tprintf("%#lx", tcp->u_arg[4]);
2274 printrusage(tcp, tcp->u_arg[4]);
2280 #endif /* SVR4 or LINUX */
2287 tprintf("%lu", tcp->u_arg[0]);
2295 struct utsname uname;
2298 if (syserror(tcp) || !verbose(tcp))
2299 tprintf("%#lx", tcp->u_arg[0]);
2300 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2302 else if (!abbrev(tcp)) {
2304 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2305 uname.sysname, uname.nodename);
2306 tprintf("release=\"%s\", version=\"%s\", ",
2307 uname.release, uname.version);
2308 tprintf("machine=\"%s\"", uname.machine);
2311 tprintf(", domainname=\"%s\"", uname.domainname);
2317 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2318 uname.sysname, uname.nodename);
2325 static const struct xlat ptrace_cmds[] = {
2327 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2328 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2329 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2330 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2331 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2332 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2333 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2334 { PTRACE_CONT, "PTRACE_CONT" },
2335 { PTRACE_KILL, "PTRACE_KILL" },
2336 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2337 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2338 { PTRACE_DETACH, "PTRACE_DETACH" },
2339 # ifdef PTRACE_GETREGS
2340 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2342 # ifdef PTRACE_SETREGS
2343 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2345 # ifdef PTRACE_GETFPREGS
2346 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2348 # ifdef PTRACE_SETFPREGS
2349 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2351 # ifdef PTRACE_GETFPXREGS
2352 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2354 # ifdef PTRACE_SETFPXREGS
2355 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2357 # ifdef PTRACE_GETVRREGS
2358 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2360 # ifdef PTRACE_SETVRREGS
2361 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2363 # ifdef PTRACE_SETOPTIONS
2364 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2366 # ifdef PTRACE_GETEVENTMSG
2367 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2369 # ifdef PTRACE_GETSIGINFO
2370 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2372 # ifdef PTRACE_SETSIGINFO
2373 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2375 # ifdef PTRACE_SET_SYSCALL
2376 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2379 { PTRACE_READDATA, "PTRACE_READDATA" },
2380 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2381 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2382 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2383 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2384 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2386 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2387 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2389 { PTRACE_22, "PTRACE_22" },
2390 { PTRACE_23, "PTRACE_3" },
2391 # endif /* !SPARC */
2392 # endif /* SUNOS4 */
2393 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2395 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2397 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2398 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2399 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2401 { PTRACE_26, "PTRACE_26" },
2402 { PTRACE_27, "PTRACE_27" },
2403 { PTRACE_28, "PTRACE_28" },
2405 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2406 # endif /* SUNOS4 */
2408 # else /* FREEBSD */
2410 { PT_TRACE_ME, "PT_TRACE_ME" },
2411 { PT_READ_I, "PT_READ_I" },
2412 { PT_READ_D, "PT_READ_D" },
2413 { PT_WRITE_I, "PT_WRITE_I" },
2414 { PT_WRITE_D, "PT_WRITE_D" },
2416 { PT_READ_U, "PT_READ_U" },
2418 { PT_CONTINUE, "PT_CONTINUE" },
2419 { PT_KILL, "PT_KILL" },
2420 { PT_STEP, "PT_STEP" },
2421 { PT_ATTACH, "PT_ATTACH" },
2422 { PT_DETACH, "PT_DETACH" },
2423 { PT_GETREGS, "PT_GETREGS" },
2424 { PT_SETREGS, "PT_SETREGS" },
2425 { PT_GETFPREGS, "PT_GETFPREGS" },
2426 { PT_SETFPREGS, "PT_SETFPREGS" },
2427 { PT_GETDBREGS, "PT_GETDBREGS" },
2428 { PT_SETDBREGS, "PT_SETDBREGS" },
2429 # endif /* FREEBSD */
2434 # ifdef PTRACE_SETOPTIONS
2435 static const struct xlat ptrace_setoptions_flags[] = {
2436 # ifdef PTRACE_O_TRACESYSGOOD
2437 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2439 # ifdef PTRACE_O_TRACEFORK
2440 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2442 # ifdef PTRACE_O_TRACEVFORK
2443 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2445 # ifdef PTRACE_O_TRACECLONE
2446 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2448 # ifdef PTRACE_O_TRACEEXEC
2449 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2451 # ifdef PTRACE_O_TRACEVFORKDONE
2452 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2454 # ifdef PTRACE_O_TRACEEXIT
2455 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2459 # endif /* PTRACE_SETOPTIONS */
2460 # endif /* !FREEBSD */
2463 const struct xlat struct_user_offsets[] = {
2465 # if defined(S390) || defined(S390X)
2466 { PT_PSWMASK, "psw_mask" },
2467 { PT_PSWADDR, "psw_addr" },
2468 { PT_GPR0, "gpr0" },
2469 { PT_GPR1, "gpr1" },
2470 { PT_GPR2, "gpr2" },
2471 { PT_GPR3, "gpr3" },
2472 { PT_GPR4, "gpr4" },
2473 { PT_GPR5, "gpr5" },
2474 { PT_GPR6, "gpr6" },
2475 { PT_GPR7, "gpr7" },
2476 { PT_GPR8, "gpr8" },
2477 { PT_GPR9, "gpr9" },
2478 { PT_GPR10, "gpr10" },
2479 { PT_GPR11, "gpr11" },
2480 { PT_GPR12, "gpr12" },
2481 { PT_GPR13, "gpr13" },
2482 { PT_GPR14, "gpr14" },
2483 { PT_GPR15, "gpr15" },
2484 { PT_ACR0, "acr0" },
2485 { PT_ACR1, "acr1" },
2486 { PT_ACR2, "acr2" },
2487 { PT_ACR3, "acr3" },
2488 { PT_ACR4, "acr4" },
2489 { PT_ACR5, "acr5" },
2490 { PT_ACR6, "acr6" },
2491 { PT_ACR7, "acr7" },
2492 { PT_ACR8, "acr8" },
2493 { PT_ACR9, "acr9" },
2494 { PT_ACR10, "acr10" },
2495 { PT_ACR11, "acr11" },
2496 { PT_ACR12, "acr12" },
2497 { PT_ACR13, "acr13" },
2498 { PT_ACR14, "acr14" },
2499 { PT_ACR15, "acr15" },
2500 { PT_ORIGGPR2, "orig_gpr2" },
2503 { PT_FPR0_HI, "fpr0.hi" },
2504 { PT_FPR0_LO, "fpr0.lo" },
2505 { PT_FPR1_HI, "fpr1.hi" },
2506 { PT_FPR1_LO, "fpr1.lo" },
2507 { PT_FPR2_HI, "fpr2.hi" },
2508 { PT_FPR2_LO, "fpr2.lo" },
2509 { PT_FPR3_HI, "fpr3.hi" },
2510 { PT_FPR3_LO, "fpr3.lo" },
2511 { PT_FPR4_HI, "fpr4.hi" },
2512 { PT_FPR4_LO, "fpr4.lo" },
2513 { PT_FPR5_HI, "fpr5.hi" },
2514 { PT_FPR5_LO, "fpr5.lo" },
2515 { PT_FPR6_HI, "fpr6.hi" },
2516 { PT_FPR6_LO, "fpr6.lo" },
2517 { PT_FPR7_HI, "fpr7.hi" },
2518 { PT_FPR7_LO, "fpr7.lo" },
2519 { PT_FPR8_HI, "fpr8.hi" },
2520 { PT_FPR8_LO, "fpr8.lo" },
2521 { PT_FPR9_HI, "fpr9.hi" },
2522 { PT_FPR9_LO, "fpr9.lo" },
2523 { PT_FPR10_HI, "fpr10.hi" },
2524 { PT_FPR10_LO, "fpr10.lo" },
2525 { PT_FPR11_HI, "fpr11.hi" },
2526 { PT_FPR11_LO, "fpr11.lo" },
2527 { PT_FPR12_HI, "fpr12.hi" },
2528 { PT_FPR12_LO, "fpr12.lo" },
2529 { PT_FPR13_HI, "fpr13.hi" },
2530 { PT_FPR13_LO, "fpr13.lo" },
2531 { PT_FPR14_HI, "fpr14.hi" },
2532 { PT_FPR14_LO, "fpr14.lo" },
2533 { PT_FPR15_HI, "fpr15.hi" },
2534 { PT_FPR15_LO, "fpr15.lo" },
2537 { PT_FPR0, "fpr0" },
2538 { PT_FPR1, "fpr1" },
2539 { PT_FPR2, "fpr2" },
2540 { PT_FPR3, "fpr3" },
2541 { PT_FPR4, "fpr4" },
2542 { PT_FPR5, "fpr5" },
2543 { PT_FPR6, "fpr6" },
2544 { PT_FPR7, "fpr7" },
2545 { PT_FPR8, "fpr8" },
2546 { PT_FPR9, "fpr9" },
2547 { PT_FPR10, "fpr10" },
2548 { PT_FPR11, "fpr11" },
2549 { PT_FPR12, "fpr12" },
2550 { PT_FPR13, "fpr13" },
2551 { PT_FPR14, "fpr14" },
2552 { PT_FPR15, "fpr15" },
2555 { PT_CR_10, "cr10" },
2556 { PT_CR_11, "cr11" },
2557 { PT_IEEE_IP, "ieee_exception_ip" },
2558 # elif defined(SPARC)
2559 /* XXX No support for these offsets yet. */
2560 # elif defined(HPPA)
2561 /* XXX No support for these offsets yet. */
2562 # elif defined(POWERPC)
2564 # define PT_ORIG_R3 34
2566 # define REGSIZE (sizeof(unsigned long))
2567 { REGSIZE*PT_R0, "r0" },
2568 { REGSIZE*PT_R1, "r1" },
2569 { REGSIZE*PT_R2, "r2" },
2570 { REGSIZE*PT_R3, "r3" },
2571 { REGSIZE*PT_R4, "r4" },
2572 { REGSIZE*PT_R5, "r5" },
2573 { REGSIZE*PT_R6, "r6" },
2574 { REGSIZE*PT_R7, "r7" },
2575 { REGSIZE*PT_R8, "r8" },
2576 { REGSIZE*PT_R9, "r9" },
2577 { REGSIZE*PT_R10, "r10" },
2578 { REGSIZE*PT_R11, "r11" },
2579 { REGSIZE*PT_R12, "r12" },
2580 { REGSIZE*PT_R13, "r13" },
2581 { REGSIZE*PT_R14, "r14" },
2582 { REGSIZE*PT_R15, "r15" },
2583 { REGSIZE*PT_R16, "r16" },
2584 { REGSIZE*PT_R17, "r17" },
2585 { REGSIZE*PT_R18, "r18" },
2586 { REGSIZE*PT_R19, "r19" },
2587 { REGSIZE*PT_R20, "r20" },
2588 { REGSIZE*PT_R21, "r21" },
2589 { REGSIZE*PT_R22, "r22" },
2590 { REGSIZE*PT_R23, "r23" },
2591 { REGSIZE*PT_R24, "r24" },
2592 { REGSIZE*PT_R25, "r25" },
2593 { REGSIZE*PT_R26, "r26" },
2594 { REGSIZE*PT_R27, "r27" },
2595 { REGSIZE*PT_R28, "r28" },
2596 { REGSIZE*PT_R29, "r29" },
2597 { REGSIZE*PT_R30, "r30" },
2598 { REGSIZE*PT_R31, "r31" },
2599 { REGSIZE*PT_NIP, "NIP" },
2600 { REGSIZE*PT_MSR, "MSR" },
2601 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2602 { REGSIZE*PT_CTR, "CTR" },
2603 { REGSIZE*PT_LNK, "LNK" },
2604 { REGSIZE*PT_XER, "XER" },
2605 { REGSIZE*PT_CCR, "CCR" },
2606 { REGSIZE*PT_FPR0, "FPR0" },
2608 # elif defined(ALPHA)
2674 # elif defined(IA64)
2675 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2676 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2677 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2678 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2679 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2680 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2681 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2682 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2683 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2684 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2685 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2686 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2687 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2688 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2689 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2690 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2691 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2692 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2693 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2694 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2695 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2696 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2697 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2698 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2699 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2700 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2701 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2702 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2703 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2704 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2705 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2706 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2708 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2709 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2710 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2711 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2712 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2713 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2714 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2715 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2716 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2717 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2718 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2719 { PT_B4, "b4" }, { PT_B5, "b5" },
2720 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2722 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2723 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2724 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2725 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2726 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2727 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2728 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2729 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2730 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2731 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2732 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2733 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2734 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2735 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2736 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2737 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2738 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2740 { PT_AR_CSD, "ar.csd" },
2743 { PT_AR_SSD, "ar.ssd" },
2745 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2746 # elif defined(I386)
2758 { 4*ORIG_EAX, "4*ORIG_EAX" },
2762 { 4*UESP, "4*UESP" },
2764 # elif defined(X86_64)
2786 { 8*ORIG_RAX, "8*ORIG_RAX" },
2789 { 8*EFLAGS, "8*EFL" },
2792 # elif defined(M68K)
2793 { 4*PT_D1, "4*PT_D1" },
2794 { 4*PT_D2, "4*PT_D2" },
2795 { 4*PT_D3, "4*PT_D3" },
2796 { 4*PT_D4, "4*PT_D4" },
2797 { 4*PT_D5, "4*PT_D5" },
2798 { 4*PT_D6, "4*PT_D6" },
2799 { 4*PT_D7, "4*PT_D7" },
2800 { 4*PT_A0, "4*PT_A0" },
2801 { 4*PT_A1, "4*PT_A1" },
2802 { 4*PT_A2, "4*PT_A2" },
2803 { 4*PT_A3, "4*PT_A3" },
2804 { 4*PT_A4, "4*PT_A4" },
2805 { 4*PT_A5, "4*PT_A5" },
2806 { 4*PT_A6, "4*PT_A6" },
2807 { 4*PT_D0, "4*PT_D0" },
2808 { 4*PT_USP, "4*PT_USP" },
2809 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2810 { 4*PT_SR, "4*PT_SR" },
2811 { 4*PT_PC, "4*PT_PC" },
2813 { 4*REG_REG0, "4*REG_REG0" },
2814 { 4*(REG_REG0+1), "4*REG_REG1" },
2815 { 4*(REG_REG0+2), "4*REG_REG2" },
2816 { 4*(REG_REG0+3), "4*REG_REG3" },
2817 { 4*(REG_REG0+4), "4*REG_REG4" },
2818 { 4*(REG_REG0+5), "4*REG_REG5" },
2819 { 4*(REG_REG0+6), "4*REG_REG6" },
2820 { 4*(REG_REG0+7), "4*REG_REG7" },
2821 { 4*(REG_REG0+8), "4*REG_REG8" },
2822 { 4*(REG_REG0+9), "4*REG_REG9" },
2823 { 4*(REG_REG0+10), "4*REG_REG10" },
2824 { 4*(REG_REG0+11), "4*REG_REG11" },
2825 { 4*(REG_REG0+12), "4*REG_REG12" },
2826 { 4*(REG_REG0+13), "4*REG_REG13" },
2827 { 4*(REG_REG0+14), "4*REG_REG14" },
2828 { 4*REG_REG15, "4*REG_REG15" },
2829 { 4*REG_PC, "4*REG_PC" },
2830 { 4*REG_PR, "4*REG_PR" },
2831 { 4*REG_SR, "4*REG_SR" },
2832 { 4*REG_GBR, "4*REG_GBR" },
2833 { 4*REG_MACH, "4*REG_MACH" },
2834 { 4*REG_MACL, "4*REG_MACL" },
2835 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2836 { 4*REG_FPUL, "4*REG_FPUL" },
2837 { 4*REG_FPREG0, "4*REG_FPREG0" },
2838 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2839 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2840 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2841 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2842 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2843 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2844 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2845 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2846 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2847 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2848 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2849 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2850 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2851 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2852 { 4*REG_FPREG15, "4*REG_FPREG15" },
2854 { 4*REG_XDREG0, "4*REG_XDREG0" },
2855 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2856 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2857 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2858 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2859 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2860 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2861 { 4*REG_XDREG14, "4*REG_XDREG14" },
2863 { 4*REG_FPSCR, "4*REG_FPSCR" },
2864 # elif defined(SH64)
2869 { 16, "syscall no.(L)" },
2870 { 20, "syscall_no.(U)" },
3013 /* This entry is in case pt_regs contains dregs (depends on
3014 the kernel build options). */
3015 { uoff(regs), "offsetof(struct user, regs)" },
3016 { uoff(fpu), "offsetof(struct user, fpu)" },
3018 { uoff(regs.ARM_r0), "r0" },
3019 { uoff(regs.ARM_r1), "r1" },
3020 { uoff(regs.ARM_r2), "r2" },
3021 { uoff(regs.ARM_r3), "r3" },
3022 { uoff(regs.ARM_r4), "r4" },
3023 { uoff(regs.ARM_r5), "r5" },
3024 { uoff(regs.ARM_r6), "r6" },
3025 { uoff(regs.ARM_r7), "r7" },
3026 { uoff(regs.ARM_r8), "r8" },
3027 { uoff(regs.ARM_r9), "r9" },
3028 { uoff(regs.ARM_r10), "r10" },
3029 { uoff(regs.ARM_fp), "fp" },
3030 { uoff(regs.ARM_ip), "ip" },
3031 { uoff(regs.ARM_sp), "sp" },
3032 { uoff(regs.ARM_lr), "lr" },
3033 { uoff(regs.ARM_pc), "pc" },
3034 { uoff(regs.ARM_cpsr), "cpsr" },
3035 # elif defined(AVR32)
3036 { uoff(regs.sr), "sr" },
3037 { uoff(regs.pc), "pc" },
3038 { uoff(regs.lr), "lr" },
3039 { uoff(regs.sp), "sp" },
3040 { uoff(regs.r12), "r12" },
3041 { uoff(regs.r11), "r11" },
3042 { uoff(regs.r10), "r10" },
3043 { uoff(regs.r9), "r9" },
3044 { uoff(regs.r8), "r8" },
3045 { uoff(regs.r7), "r7" },
3046 { uoff(regs.r6), "r6" },
3047 { uoff(regs.r5), "r5" },
3048 { uoff(regs.r4), "r4" },
3049 { uoff(regs.r3), "r3" },
3050 { uoff(regs.r2), "r2" },
3051 { uoff(regs.r1), "r1" },
3052 { uoff(regs.r0), "r0" },
3053 { uoff(regs.r12_orig), "orig_r12" },
3054 # elif defined(MIPS)
3128 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3129 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3130 { 4*PT_R13, "4*PT_R13" },
3131 { 4*PT_R12, "4*PT_R12" },
3132 { 4*PT_R11, "4*PT_R11" },
3133 { 4*PT_R10, "4*PT_R10" },
3134 { 4*PT_R9, "4*PT_R9" },
3135 { 4*PT_R8, "4*PT_R8" },
3136 { 4*PT_R7, "4*PT_R7" },
3137 { 4*PT_R6, "4*PT_R6" },
3138 { 4*PT_R5, "4*PT_R5" },
3139 { 4*PT_R4, "4*PT_R4" },
3140 { 4*PT_R3, "4*PT_R3" },
3141 { 4*PT_R2, "4*PT_R2" },
3142 { 4*PT_R1, "4*PT_R1" },
3143 { 4*PT_R0, "4*PT_R0" },
3144 { 4*PT_MOF, "4*PT_MOF" },
3145 { 4*PT_DCCR, "4*PT_DCCR" },
3146 { 4*PT_SRP, "4*PT_SRP" },
3147 { 4*PT_IRP, "4*PT_IRP" },
3148 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3149 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3150 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3151 { 4*PT_USP, "4*PT_USP" },
3154 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3155 { 4*PT_R0, "4*PT_R0" },
3156 { 4*PT_R1, "4*PT_R1" },
3157 { 4*PT_R2, "4*PT_R2" },
3158 { 4*PT_R3, "4*PT_R3" },
3159 { 4*PT_R4, "4*PT_R4" },
3160 { 4*PT_R5, "4*PT_R5" },
3161 { 4*PT_R6, "4*PT_R6" },
3162 { 4*PT_R7, "4*PT_R7" },
3163 { 4*PT_R8, "4*PT_R8" },
3164 { 4*PT_R9, "4*PT_R9" },
3165 { 4*PT_R10, "4*PT_R10" },
3166 { 4*PT_R11, "4*PT_R11" },
3167 { 4*PT_R12, "4*PT_R12" },
3168 { 4*PT_R13, "4*PT_R13" },
3169 { 4*PT_ACR, "4*PT_ACR" },
3170 { 4*PT_SRS, "4*PT_SRS" },
3171 { 4*PT_MOF, "4*PT_MOF" },
3172 { 4*PT_SPC, "4*PT_SPC" },
3173 { 4*PT_CCS, "4*PT_CCS" },
3174 { 4*PT_SRP, "4*PT_SRP" },
3175 { 4*PT_ERP, "4*PT_ERP" },
3176 { 4*PT_EXS, "4*PT_EXS" },
3177 { 4*PT_EDA, "4*PT_EDA" },
3178 { 4*PT_USP, "4*PT_USP" },
3179 { 4*PT_PPC, "4*PT_PPC" },
3180 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3181 { 4*PT_BP+4, "4*PT_BP+4" },
3182 { 4*PT_BP+8, "4*PT_BP+8" },
3183 { 4*PT_BP+12, "4*PT_BP+12" },
3184 { 4*PT_BP+16, "4*PT_BP+16" },
3185 { 4*PT_BP+20, "4*PT_BP+20" },
3186 { 4*PT_BP+24, "4*PT_BP+24" },
3187 { 4*PT_BP+28, "4*PT_BP+28" },
3188 { 4*PT_BP+32, "4*PT_BP+32" },
3189 { 4*PT_BP+36, "4*PT_BP+36" },
3190 { 4*PT_BP+40, "4*PT_BP+40" },
3191 { 4*PT_BP+44, "4*PT_BP+44" },
3192 { 4*PT_BP+48, "4*PT_BP+48" },
3193 { 4*PT_BP+52, "4*PT_BP+52" },
3194 { 4*PT_BP+56, "4*PT_BP+56" },
3197 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3198 && !defined(ALPHA) && !defined(IA64) \
3199 && !defined(CRISV10) && !defined(CRISV32)
3200 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN)
3201 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3203 # if defined(I386) || defined(X86_64)
3204 { uoff(i387), "offsetof(struct user, i387)" },
3207 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3209 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3210 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3211 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3212 # if !defined(SPARC64)
3213 { uoff(start_code), "offsetof(struct user, start_code)" },
3215 # if defined(AVR32) || defined(SH64)
3216 { uoff(start_data), "offsetof(struct user, start_data)" },
3218 # if !defined(SPARC64)
3219 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3221 { uoff(signal), "offsetof(struct user, signal)" },
3222 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
3223 { uoff(reserved), "offsetof(struct user, reserved)" },
3225 # if !defined(SPARC64)
3226 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3228 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
3229 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3231 { uoff(magic), "offsetof(struct user, magic)" },
3232 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3233 # if defined(I386) || defined(X86_64)
3234 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3236 # endif /* !defined(many arches) */
3241 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3242 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3243 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3244 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3245 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3246 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3247 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3248 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3249 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3250 { uoff(u_error), "offsetof(struct user, u_error)" },
3251 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3252 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3253 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3254 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3255 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3256 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3257 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3258 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3259 { uoff(u_code), "offsetof(struct user, u_code)" },
3260 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3261 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3262 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3263 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3264 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3265 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3266 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3267 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3268 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3269 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3270 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3271 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3272 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3273 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3274 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3275 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3276 { uoff(u_start), "offsetof(struct user, u_start)" },
3277 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3278 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3279 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3280 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3281 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3282 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3283 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3284 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3285 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3286 # endif /* SUNOS4 */
3288 { sizeof(struct user), "sizeof(struct user)" },
3292 # endif /* !FREEBSD */
3295 sys_ptrace(struct tcb *tcp)
3297 const struct xlat *x;
3300 if (entering(tcp)) {
3301 printxval(ptrace_cmds, tcp->u_arg[0],
3308 tprintf(", %lu, ", tcp->u_arg[1]);
3309 addr = tcp->u_arg[2];
3311 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3312 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3313 for (x = struct_user_offsets; x->str; x++) {
3318 tprintf("%#lx, ", addr);
3319 else if (x->val > addr && x != struct_user_offsets) {
3321 tprintf("%s + %ld, ", x->str, addr - x->val);
3324 tprintf("%s, ", x->str);
3328 tprintf("%#lx, ", tcp->u_arg[2]);
3330 switch (tcp->u_arg[0]) {
3332 case PTRACE_PEEKDATA:
3333 case PTRACE_PEEKTEXT:
3334 case PTRACE_PEEKUSER:
3338 case PTRACE_SINGLESTEP:
3339 case PTRACE_SYSCALL:
3341 printsignal(tcp->u_arg[3]);
3343 # ifdef PTRACE_SETOPTIONS
3344 case PTRACE_SETOPTIONS:
3345 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3348 # ifdef PTRACE_SETSIGINFO
3349 case PTRACE_SETSIGINFO: {
3353 else if (syserror(tcp))
3354 tprintf("%#lx", tcp->u_arg[3]);
3355 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3358 printsiginfo(&si, verbose(tcp));
3362 # ifdef PTRACE_GETSIGINFO
3363 case PTRACE_GETSIGINFO:
3364 /* Don't print anything, do it at syscall return. */
3368 tprintf("%#lx", tcp->u_arg[3]);
3372 switch (tcp->u_arg[0]) {
3373 case PTRACE_PEEKDATA:
3374 case PTRACE_PEEKTEXT:
3375 case PTRACE_PEEKUSER:
3379 printnum(tcp, tcp->u_arg[3], "%#lx");
3382 # ifdef PTRACE_GETSIGINFO
3383 case PTRACE_GETSIGINFO: {
3387 else if (syserror(tcp))
3388 tprintf("%#lx", tcp->u_arg[3]);
3389 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3392 printsiginfo(&si, verbose(tcp));
3400 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3401 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3402 tprintf("%lu, ", tcp->u_arg[3]);
3403 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3404 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3405 tcp->u_arg[0] != PTRACE_READTEXT) {
3406 tprintf("%#lx", tcp->u_arg[3]);
3409 if (tcp->u_arg[0] == PTRACE_READDATA ||
3410 tcp->u_arg[0] == PTRACE_READTEXT) {
3411 tprintf("%lu, ", tcp->u_arg[3]);
3412 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3415 # endif /* SUNOS4 */
3417 tprintf("%lu", tcp->u_arg[3]);
3419 # endif /* FREEBSD */
3426 # ifndef FUTEX_CMP_REQUEUE
3427 # define FUTEX_CMP_REQUEUE 4
3429 # ifndef FUTEX_WAKE_OP
3430 # define FUTEX_WAKE_OP 5
3432 # ifndef FUTEX_LOCK_PI
3433 # define FUTEX_LOCK_PI 6
3434 # define FUTEX_UNLOCK_PI 7
3435 # define FUTEX_TRYLOCK_PI 8
3437 # ifndef FUTEX_WAIT_BITSET
3438 # define FUTEX_WAIT_BITSET 9
3440 # ifndef FUTEX_WAKE_BITSET
3441 # define FUTEX_WAKE_BITSET 10
3443 # ifndef FUTEX_WAIT_REQUEUE_PI
3444 # define FUTEX_WAIT_REQUEUE_PI 11
3446 # ifndef FUTEX_CMP_REQUEUE_PI
3447 # define FUTEX_CMP_REQUEUE_PI 12
3449 # ifndef FUTEX_PRIVATE_FLAG
3450 # define FUTEX_PRIVATE_FLAG 128
3452 # ifndef FUTEX_CLOCK_REALTIME
3453 # define FUTEX_CLOCK_REALTIME 256
3455 static const struct xlat futexops[] = {
3456 { FUTEX_WAIT, "FUTEX_WAIT" },
3457 { FUTEX_WAKE, "FUTEX_WAKE" },
3458 { FUTEX_FD, "FUTEX_FD" },
3459 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3460 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3461 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3462 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3463 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3464 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3465 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3466 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3467 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3468 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3469 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3470 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3471 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3472 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3473 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3474 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3475 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3476 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3477 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3478 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3479 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3480 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3481 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3482 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3483 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3484 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3485 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3488 # ifndef FUTEX_OP_SET
3489 # define FUTEX_OP_SET 0
3490 # define FUTEX_OP_ADD 1
3491 # define FUTEX_OP_OR 2
3492 # define FUTEX_OP_ANDN 3
3493 # define FUTEX_OP_XOR 4
3494 # define FUTEX_OP_CMP_EQ 0
3495 # define FUTEX_OP_CMP_NE 1
3496 # define FUTEX_OP_CMP_LT 2
3497 # define FUTEX_OP_CMP_LE 3
3498 # define FUTEX_OP_CMP_GT 4
3499 # define FUTEX_OP_CMP_GE 5
3501 static const struct xlat futexwakeops[] = {
3502 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3503 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3504 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3505 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3506 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3509 static const struct xlat futexwakecmps[] = {
3510 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3511 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3512 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3513 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3514 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3515 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3520 sys_futex(struct tcb *tcp)
3522 if (entering(tcp)) {
3523 long int cmd = tcp->u_arg[1] & 127;
3524 tprintf("%p, ", (void *) tcp->u_arg[0]);
3525 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3526 tprintf(", %ld", tcp->u_arg[2]);
3527 if (cmd == FUTEX_WAKE_BITSET)
3528 tprintf(", %lx", tcp->u_arg[5]);
3529 else if (cmd == FUTEX_WAIT) {
3531 printtv(tcp, tcp->u_arg[3]);
3532 } else if (cmd == FUTEX_WAIT_BITSET) {
3534 printtv(tcp, tcp->u_arg[3]);
3535 tprintf(", %lx", tcp->u_arg[5]);
3536 } else if (cmd == FUTEX_REQUEUE)
3537 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3538 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3539 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3540 else if (cmd == FUTEX_WAKE_OP) {
3541 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3542 if ((tcp->u_arg[5] >> 28) & 8)
3543 tprintf("FUTEX_OP_OPARG_SHIFT|");
3544 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3545 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3546 if ((tcp->u_arg[5] >> 24) & 8)
3547 tprintf("FUTEX_OP_OPARG_SHIFT|");
3548 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3549 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3550 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3552 printtv(tcp, tcp->u_arg[3]);
3553 tprintf(", %p", (void *) tcp->u_arg[4]);
3560 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3564 while (len >= sizeof (unsigned long)) {
3566 umove(tcp, list, &w);
3567 tprintf("%s %lx", first ? "" : ",", w);
3569 len -= sizeof (unsigned long);
3570 list += sizeof(unsigned long);
3576 sys_sched_setaffinity(struct tcb *tcp)
3578 if (entering(tcp)) {
3579 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3580 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3586 sys_sched_getaffinity(struct tcb *tcp)
3588 if (entering(tcp)) {
3589 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3591 if (tcp->u_rval == -1)
3592 tprintf("%#lx", tcp->u_arg[2]);
3594 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3599 static const struct xlat schedulers[] = {
3600 { SCHED_OTHER, "SCHED_OTHER" },
3601 { SCHED_RR, "SCHED_RR" },
3602 { SCHED_FIFO, "SCHED_FIFO" },
3607 sys_sched_getscheduler(struct tcb *tcp)
3609 if (entering(tcp)) {
3610 tprintf("%d", (int) tcp->u_arg[0]);
3611 } else if (! syserror(tcp)) {
3612 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3613 if (tcp->auxstr != NULL)
3620 sys_sched_setscheduler(struct tcb *tcp)
3622 if (entering(tcp)) {
3623 struct sched_param p;
3624 tprintf("%d, ", (int) tcp->u_arg[0]);
3625 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3626 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3627 tprintf(", %#lx", tcp->u_arg[2]);
3629 tprintf(", { %d }", p.__sched_priority);
3635 sys_sched_getparam(struct tcb *tcp)
3637 if (entering(tcp)) {
3638 tprintf("%d, ", (int) tcp->u_arg[0]);
3640 struct sched_param p;
3641 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3642 tprintf("%#lx", tcp->u_arg[1]);
3644 tprintf("{ %d }", p.__sched_priority);
3650 sys_sched_setparam(struct tcb *tcp)
3652 if (entering(tcp)) {
3653 struct sched_param p;
3654 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3655 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3657 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3663 sys_sched_get_priority_min(struct tcb *tcp)
3665 if (entering(tcp)) {
3666 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3672 # include <asm/prctl.h>
3674 static const struct xlat archvals[] = {
3675 { ARCH_SET_GS, "ARCH_SET_GS" },
3676 { ARCH_SET_FS, "ARCH_SET_FS" },
3677 { ARCH_GET_FS, "ARCH_GET_FS" },
3678 { ARCH_GET_GS, "ARCH_GET_GS" },
3683 sys_arch_prctl(struct tcb *tcp)
3685 if (entering(tcp)) {
3686 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3687 if (tcp->u_arg[0] == ARCH_SET_GS
3688 || tcp->u_arg[0] == ARCH_SET_FS
3690 tprintf(", %#lx", tcp->u_arg[1]);
3693 if (tcp->u_arg[0] == ARCH_GET_GS
3694 || tcp->u_arg[0] == ARCH_GET_FS
3697 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3698 tprintf(", [%#lx]", v);
3700 tprintf(", %#lx", tcp->u_arg[1]);
3705 # endif /* X86_64 */
3709 sys_getcpu(struct tcb *tcp)
3713 if (tcp->u_arg[0] == 0)
3715 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3716 tprintf("%#lx, ", tcp->u_arg[0]);
3718 tprintf("[%u], ", u);
3719 if (tcp->u_arg[1] == 0)
3721 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3722 tprintf("%#lx, ", tcp->u_arg[1]);
3724 tprintf("[%u], ", u);
3725 tprintf("%#lx", tcp->u_arg[2]);