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 #ifndef PTRACE_PEEKUSR
62 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
64 #ifndef PTRACE_POKEUSR
65 # define PTRACE_POKEUSR PTRACE_POKEUSER
69 #ifdef HAVE_LINUX_PTRACE_H
71 # ifdef HAVE_STRUCT_IA64_FPREG
72 # define ia64_fpreg XXX_ia64_fpreg
74 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
75 # define pt_all_user_regs XXX_pt_all_user_regs
77 #include <linux/ptrace.h>
79 # undef pt_all_user_regs
82 #if defined (LINUX) && defined (SPARC64)
84 # undef PTRACE_GETREGS
85 # define PTRACE_GETREGS PTRACE_GETREGS64
86 # undef PTRACE_SETREGS
87 # define PTRACE_SETREGS PTRACE_SETREGS64
88 #endif /* LINUX && SPARC64 */
90 #ifdef HAVE_LINUX_FUTEX_H
91 #include <linux/futex.h>
103 # ifndef FUTEX_REQUEUE
104 # define FUTEX_REQUEUE 3
110 #include <asm/posix_types.h>
112 #define GETGROUPS_T __kernel_gid_t
114 #define GETGROUPS32_T __kernel_gid32_t
117 #if defined(LINUX) && defined(IA64)
118 # include <asm/ptrace_offsets.h>
119 # include <asm/rse.h>
123 #include <sys/prctl.h>
127 #define WCOREDUMP(status) ((status) & 0200)
130 /* WTA: this was `&& !defined(LINUXSPARC)', this seems unneeded though? */
131 #if defined(HAVE_PRCTL)
132 static const struct xlat prctl_options[] = {
134 { PR_MAXPROCS, "PR_MAXPROCS" },
137 { PR_ISBLOCKED, "PR_ISBLOCKED" },
139 #ifdef PR_SETSTACKSIZE
140 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
142 #ifdef PR_GETSTACKSIZE
143 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
146 { PR_MAXPPROCS, "PR_MAXPPROCS" },
148 #ifdef PR_UNBLKONEXEC
149 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
152 { PR_ATOMICSIM, "PR_ATOMICSIM" },
155 { PR_SETEXITSIG, "PR_SETEXITSIG" },
158 { PR_RESIDENT, "PR_RESIDENT" },
161 { PR_ATTACHADDR, "PR_ATTACHADDR" },
164 { PR_DETACHADDR, "PR_DETACHADDR" },
167 { PR_TERMCHILD, "PR_TERMCHILD" },
170 { PR_GETSHMASK, "PR_GETSHMASK" },
173 { PR_GETNSHARE, "PR_GETNSHARE" },
176 { PR_COREPID, "PR_COREPID" },
178 #ifdef PR_ATTACHADDRPERM
179 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
181 #ifdef PR_PTHREADEXIT
182 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
184 #ifdef PR_SET_PDEATHSIG
185 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
187 #ifdef PR_GET_PDEATHSIG
188 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
190 #ifdef PR_GET_DUMPABLE
191 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
193 #ifdef PR_SET_DUMPABLE
194 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
196 #ifdef PR_GET_UNALIGN
197 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
199 #ifdef PR_SET_UNALIGN
200 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
202 #ifdef PR_GET_KEEPCAPS
203 { PR_GET_KEEPCAPS, "PR_GET_KEEPCAPS" },
205 #ifdef PR_SET_KEEPCAPS
206 { PR_SET_KEEPCAPS, "PR_SET_KEEPCAPS" },
209 { PR_GET_FPEMU, "PR_GET_FPEMU" },
212 { PR_SET_FPEMU, "PR_SET_FPEMU" },
215 { PR_GET_FPEXC, "PR_GET_FPEXC" },
218 { PR_SET_FPEXC, "PR_SET_FPEXC" },
221 { PR_GET_TIMING, "PR_GET_TIMING" },
224 { PR_SET_TIMING, "PR_SET_TIMING" },
227 { PR_SET_NAME, "PR_SET_NAME" },
230 { PR_GET_NAME, "PR_GET_NAME" },
233 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
236 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
238 #ifdef PR_GET_SECCOMP
239 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
241 #ifdef PR_SET_SECCOMP
242 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
245 { PR_GET_TSC, "PR_GET_TSC" },
248 { PR_SET_TSC, "PR_SET_TSC" },
250 #ifdef PR_GET_SECUREBITS
251 { PR_GET_SECUREBITS, "PR_GET_SECUREBITS" },
253 #ifdef PR_SET_SECUREBITS
254 { PR_SET_SECUREBITS, "PR_SET_SECUREBITS" },
261 unalignctl_string (unsigned int ctl)
266 #ifdef PR_UNALIGN_NOPRINT
267 case PR_UNALIGN_NOPRINT:
270 #ifdef PR_UNALIGN_SIGBUS
271 case PR_UNALIGN_SIGBUS:
277 sprintf(buf, "%x", ctl);
289 printxval(prctl_options, tcp->u_arg[0], "PR_???");
290 switch (tcp->u_arg[0]) {
295 #ifdef PR_SET_PDEATHSIG
296 case PR_SET_PDEATHSIG:
297 tprintf(", %lu", tcp->u_arg[1]);
300 #ifdef PR_GET_PDEATHSIG
301 case PR_GET_PDEATHSIG:
304 #ifdef PR_SET_DUMPABLE
305 case PR_SET_DUMPABLE:
306 tprintf(", %lu", tcp->u_arg[1]);
309 #ifdef PR_GET_DUMPABLE
310 case PR_GET_DUMPABLE:
313 #ifdef PR_SET_UNALIGN
315 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
318 #ifdef PR_GET_UNALIGN
320 tprintf(", %#lx", tcp->u_arg[1]);
323 #ifdef PR_SET_KEEPCAPS
324 case PR_SET_KEEPCAPS:
325 tprintf(", %lu", tcp->u_arg[1]);
328 #ifdef PR_GET_KEEPCAPS
329 case PR_GET_KEEPCAPS:
333 for (i = 1; i < tcp->u_nargs; i++)
334 tprintf(", %#lx", tcp->u_arg[i]);
338 switch (tcp->u_arg[0]) {
339 #ifdef PR_GET_PDEATHSIG
340 case PR_GET_PDEATHSIG:
341 if (umove(tcp, tcp->u_arg[1], &i) < 0)
342 tprintf(", %#lx", tcp->u_arg[1]);
344 tprintf(", {%u}", i);
347 #ifdef PR_GET_DUMPABLE
348 case PR_GET_DUMPABLE:
349 return RVAL_UDECIMAL;
351 #ifdef PR_GET_UNALIGN
353 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
355 tcp->auxstr = unalignctl_string(i);
358 #ifdef PR_GET_KEEPCAPS
359 case PR_GET_KEEPCAPS:
360 return RVAL_UDECIMAL;
369 #endif /* HAVE_PRCTL */
371 #if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
380 #endif /* FREEBSD || SUNOS4 || SVR4 */
387 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
388 tprintf(", %lu", tcp->u_arg[1]);
393 #if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
400 tprintf("%#lx", tcp->u_arg[0]);
402 printpath(tcp, tcp->u_arg[0]);
403 tprintf(", %lu", tcp->u_arg[1]);
407 #endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
410 sys_setdomainname(tcp)
414 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
415 tprintf(", %lu", tcp->u_arg[1]);
423 sys_getdomainname(tcp)
428 tprintf("%#lx", tcp->u_arg[0]);
430 printpath(tcp, tcp->u_arg[0]);
431 tprintf(", %lu", tcp->u_arg[1]);
442 fprintf(stderr, "_exit returned!\n");
445 /* special case: we stop tracing this process, finish line now */
446 tprintf("%ld) ", tcp->u_arg[0]);
458 tcp->flags |= TCB_EXITING;
459 #ifdef __NR_exit_group
462 if (tcp->scno == 252)
463 tcp->flags |= TCB_GROUP_EXITING;
466 if (known_scno(tcp) == __NR_exit_group)
467 tcp->flags |= TCB_GROUP_EXITING;
473 /* TCP is creating a child we want to follow.
474 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
475 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
477 fork_tcb(struct tcb *tcp)
479 if (nprocs == tcbtabsize)
482 tcp->flags |= TCB_FOLLOWFORK;
488 sys_fork(struct tcb *tcp)
490 if (exiting(tcp) && !syserror(tcp)) {
492 tcp->auxstr = "child process";
493 return RVAL_UDECIMAL | RVAL_STR;
506 tprintf ("%ld", tcp->u_arg[0]);
508 else if (!syserror(tcp)) {
510 tcp->auxstr = "child process";
511 return RVAL_UDECIMAL | RVAL_STR;
523 struct tcb *tcpchild;
527 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
537 tcpchild = alloctcb(tcp->u_rval);
538 if (proc_open(tcpchild, 2) < 0)
544 #else /* !USE_PROCFS */
548 /* defines copied from linux/sched.h since we can't include that
549 * ourselves (it conflicts with *lots* of libc includes)
551 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
552 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
553 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
554 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
555 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
556 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
557 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
558 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
559 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
560 #define CLONE_THREAD 0x00010000 /* Same thread group? */
561 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
562 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
563 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
564 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
565 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
566 #define CLONE_DETACHED 0x00400000 /* parent wants no child-exit signal */
567 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
568 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
570 static const struct xlat clone_flags[] = {
571 { CLONE_VM, "CLONE_VM" },
572 { CLONE_FS, "CLONE_FS" },
573 { CLONE_FILES, "CLONE_FILES" },
574 { CLONE_SIGHAND, "CLONE_SIGHAND" },
575 { CLONE_IDLETASK, "CLONE_IDLETASK"},
576 { CLONE_PTRACE, "CLONE_PTRACE" },
577 { CLONE_VFORK, "CLONE_VFORK" },
578 { CLONE_PARENT, "CLONE_PARENT" },
579 { CLONE_THREAD, "CLONE_THREAD" },
580 { CLONE_NEWNS, "CLONE_NEWNS" },
581 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
582 { CLONE_SETTLS, "CLONE_SETTLS" },
583 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
584 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
585 { CLONE_DETACHED, "CLONE_DETACHED" },
586 { CLONE_UNTRACED, "CLONE_UNTRACED" },
587 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
592 # include <asm/ldt.h>
593 # ifdef HAVE_STRUCT_USER_DESC
594 # define modify_ldt_ldt_s user_desc
596 extern void print_ldt_entry();
602 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
603 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
604 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
605 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
606 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
612 # elif defined X86_64 || defined ALPHA
631 unsigned long flags = tcp->u_arg[ARG_FLAGS];
632 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
633 # ifdef ARG_STACKSIZE
634 if (ARG_STACKSIZE != -1)
635 tprintf("stack_size=%#lx, ",
636 tcp->u_arg[ARG_STACKSIZE]);
639 printflags(clone_flags, flags &~ CSIGNAL, NULL);
640 if ((flags & CSIGNAL) != 0)
641 tprintf("|%s", signame(flags & CSIGNAL));
642 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
643 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
645 if (flags & CLONE_PARENT_SETTID)
646 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
647 if (flags & CLONE_SETTLS) {
649 struct modify_ldt_ldt_s copy;
650 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
651 tprintf(", {entry_number:%d, ",
656 print_ldt_entry(©);
660 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
662 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
663 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
669 sys_unshare(struct tcb *tcp)
672 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
682 return RVAL_UDECIMAL;
687 change_syscall(struct tcb *tcp, int new)
691 /* Attempt to make vfork into fork, which we can follow. */
692 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
695 #elif defined(X86_64)
696 /* Attempt to make vfork into fork, which we can follow. */
697 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
700 #elif defined(POWERPC)
701 if (ptrace(PTRACE_POKEUSER, tcp->pid,
702 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
705 #elif defined(S390) || defined(S390X)
706 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
707 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new)<0)
711 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new)<0)
714 #elif defined(SPARC) || defined(SPARC64)
716 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0)<0)
718 regs.u_regs[U_REG_G1] = new;
719 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0)<0)
723 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new)<0)
727 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new)<0)
731 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
735 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new)<0)
742 break; /* x86 SYS_fork */
747 fprintf(stderr, "%s: unexpected syscall %d\n",
751 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new)<0)
753 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new)<0)
757 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new)<0)
761 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new)<0)
765 /* Top half of reg encodes the no. of args n as 0x1n.
766 Assume 0 args as kernel never actually checks... */
767 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
771 #elif defined(CRISV10) || defined(CRISV32)
772 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
776 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
777 # ifndef PTRACE_SET_SYSCALL
778 # define PTRACE_SET_SYSCALL 23
781 if (ptrace (PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
786 #warning Do not know how to handle change_syscall for this architecture
787 #endif /* architecture */
802 ptrace(PTRACE_POKEUSER, tcp->pid,
803 (char *)(REG_R12_ORIG),
807 ptrace(PTRACE_POKEUSER, tcp->pid,
808 (char *)(REG_R12 - 4 * argnum),
812 ptrace(PTRACE_POKEUSER, tcp->pid,
817 ptrace(PTRACE_POKEUSER, tcp->pid,
827 unsigned long *bsp, *ap;
829 if (upeek(tcp, PT_AR_BSP, (long *) &bsp) , 0)
832 ap = ia64_rse_skip_regs(bsp, argnum);
834 ptrace(PTRACE_POKEDATA, tcp->pid, (char *) ap, tcp->u_arg[argnum]);
841 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*argnum), tcp->u_arg[argnum]);
845 #elif defined(X86_64)
847 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(8*(long)argnum), tcp->u_arg[argnum]);
851 #elif defined(POWERPC)
853 #define PT_ORIG_R3 34
856 ptrace(PTRACE_POKEUSER, tcp->pid,
857 (char*)((argnum==0 ? PT_ORIG_R3 : argnum+PT_R3)*sizeof(unsigned long)),
866 ptrace(PTRACE_POKEUSER, tcp->pid,
867 (char*)(REG_A0 + argnum), tcp->u_arg[argnum]);
871 if (upeek(tcp, REG_SP, (long *) &sp) , 0)
874 ptrace(PTRACE_POKEDATA, tcp->pid,
875 (char*)(sp + argnum - 4), tcp->u_arg[argnum]);
880 #elif defined(S390) || defined(S390X)
883 ptrace(PTRACE_POKEUSER, tcp->pid,
884 (char *) (argnum==0 ? PT_ORIGGPR2 :
885 PT_GPR2 + argnum*sizeof(long)),
893 # warning Sorry, setargs not implemented for this architecture.
901 internal_fork(struct tcb *tcp)
910 struct tcb *tcpchild;
914 if (!(tcp->flags & TCB_FOLLOWFORK))
917 bpt = tcp->flags & TCB_BPTSET;
927 #ifdef CLONE_PTRACE /* See new setbpt code. */
928 tcpchild = pid2tcb(pid);
929 if (tcpchild != NULL) {
930 /* The child already reported its startup trap
931 before the parent reported its syscall return. */
933 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
934 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
936 [preattached child %d of %d in weird state!]\n",
940 #endif /* CLONE_PTRACE */
943 tcpchild = alloctcb(pid);
947 /* Attach to the new child */
948 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
951 perror("PTRACE_ATTACH");
952 fprintf(stderr, "Too late?\n");
956 #endif /* !CLONE_PTRACE */
961 tcpchild->flags |= TCB_ATTACHED;
962 /* Child has BPT too, must be removed on first occasion. */
964 tcpchild->flags |= TCB_BPTSET;
965 tcpchild->baddr = tcp->baddr;
966 memcpy(tcpchild->inst, tcp->inst,
967 sizeof tcpchild->inst);
969 tcpchild->parent = tcp;
971 if (tcpchild->flags & TCB_SUSPENDED) {
972 /* The child was born suspended, due to our having
973 forced CLONE_PTRACE. */
977 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
978 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
983 Process %u resumed (parent %d ready)\n",
988 fprintf(stderr, "Process %d attached\n", pid);
991 #ifdef TCB_CLONE_THREAD
994 * Save the flags used in this call,
995 * in case we point TCP to our parent below.
997 int call_flags = tcp->u_arg[ARG_FLAGS];
998 if ((tcp->flags & TCB_CLONE_THREAD) &&
999 tcp->parent != NULL) {
1000 /* The parent in this clone is itself a
1001 thread belonging to another process.
1002 There is no meaning to the parentage
1003 relationship of the new child with the
1004 thread, only with the process. We
1005 associate the new thread with our
1006 parent. Since this is done for every
1007 new thread, there will never be a
1008 TCB_CLONE_THREAD process that has
1012 tcpchild->parent = tcp;
1015 if (call_flags & CLONE_THREAD) {
1016 tcpchild->flags |= TCB_CLONE_THREAD;
1017 ++tcp->nclone_threads;
1019 if (call_flags & CLONE_DETACHED) {
1020 tcpchild->flags |= TCB_CLONE_DETACHED;
1021 ++tcp->nclone_detached;
1024 #endif /* TCB_CLONE_THREAD */
1035 struct tcb *tcpchild;
1037 int dont_follow = 0;
1040 if (known_scno(tcp) == SYS_vfork) {
1041 /* Attempt to make vfork into fork, which we can follow. */
1042 if (change_syscall(tcp, SYS_fork) < 0)
1046 if (entering(tcp)) {
1047 if (!followfork || dont_follow)
1050 if (setbpt(tcp) < 0)
1054 int bpt = tcp->flags & TCB_BPTSET;
1056 if (!(tcp->flags & TCB_FOLLOWFORK))
1066 tcpchild = alloctcb(pid);
1069 /* The child must have run before it can be attached. */
1074 select(0, NULL, NULL, NULL, &tv);
1076 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
1077 perror("PTRACE_ATTACH");
1078 fprintf(stderr, "Too late?\n");
1083 /* Try to catch the new process as soon as possible. */
1086 for (i = 0; i < 1024; i++)
1087 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1090 perror("PTRACE_ATTACH");
1091 fprintf(stderr, "Too late?\n");
1096 #endif /* !oldway */
1098 tcpchild->flags |= TCB_ATTACHED;
1099 /* Child has BPT too, must be removed on first occasion */
1101 tcpchild->flags |= TCB_BPTSET;
1102 tcpchild->baddr = tcp->baddr;
1103 memcpy(tcpchild->inst, tcp->inst,
1104 sizeof tcpchild->inst);
1106 tcpchild->parent = tcp;
1109 fprintf(stderr, "Process %d attached\n", pid);
1116 #endif /* !USE_PROCFS */
1118 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1125 return RVAL_UDECIMAL;
1129 #endif /* SUNOS4 || LINUX || FREEBSD */
1133 static char idstr[16];
1140 sprintf(idstr, "ppid %lu", getrval2(tcp));
1141 tcp->auxstr = idstr;
1152 sprintf(idstr, "euid %lu", getrval2(tcp));
1153 tcp->auxstr = idstr;
1164 sprintf(idstr, "egid %lu", getrval2(tcp));
1165 tcp->auxstr = idstr;
1179 if (entering(tcp)) {
1180 tprintf("%u", (uid_t) tcp->u_arg[0]);
1189 if (entering(tcp)) {
1190 tprintf("%u", (gid_t) tcp->u_arg[0]);
1196 sys_getresuid(struct tcb *tcp)
1201 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1202 tcp->u_arg[1], tcp->u_arg[2]);
1204 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1205 tprintf("%#lx, ", tcp->u_arg[0]);
1207 tprintf("[%lu], ", (unsigned long) uid);
1208 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1209 tprintf("%#lx, ", tcp->u_arg[1]);
1211 tprintf("[%lu], ", (unsigned long) uid);
1212 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1213 tprintf("%#lx", tcp->u_arg[2]);
1215 tprintf("[%lu]", (unsigned long) uid);
1228 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1229 tcp->u_arg[1], tcp->u_arg[2]);
1231 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1232 tprintf("%#lx, ", tcp->u_arg[0]);
1234 tprintf("[%lu], ", (unsigned long) gid);
1235 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1236 tprintf("%#lx, ", tcp->u_arg[1]);
1238 tprintf("[%lu], ", (unsigned long) gid);
1239 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1240 tprintf("%#lx", tcp->u_arg[2]);
1242 tprintf("[%lu]", (unsigned long) gid);
1254 if (entering(tcp)) {
1255 printuid("", tcp->u_arg[0]);
1256 printuid(", ", tcp->u_arg[1]);
1265 if (entering(tcp)) {
1266 printuid("", tcp->u_arg[0]);
1267 printuid(", ", tcp->u_arg[1]);
1272 #if defined(LINUX) || defined(FREEBSD)
1277 if (entering(tcp)) {
1278 printuid("", tcp->u_arg[0]);
1279 printuid(", ", tcp->u_arg[1]);
1280 printuid(", ", tcp->u_arg[2]);
1288 if (entering(tcp)) {
1289 printuid("", tcp->u_arg[0]);
1290 printuid(", ", tcp->u_arg[1]);
1291 printuid(", ", tcp->u_arg[2]);
1296 #endif /* LINUX || FREEBSD */
1302 if (entering(tcp)) {
1303 unsigned long len, size, start, cur, end, abbrev_end;
1307 len = tcp->u_arg[0];
1308 tprintf("%lu, ", len);
1313 start = tcp->u_arg[1];
1318 size = len * sizeof(gid);
1320 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1321 tprintf("%#lx", start);
1325 abbrev_end = start + max_strlen * sizeof(gid);
1326 if (abbrev_end < start)
1332 for (cur = start; cur < end; cur += sizeof(gid)) {
1335 if (cur >= abbrev_end) {
1339 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1344 tprintf("%lu", (unsigned long) gid);
1348 tprintf(" %#lx", tcp->u_arg[1]);
1359 if (entering(tcp)) {
1360 len = tcp->u_arg[0];
1361 tprintf("%lu, ", len);
1363 unsigned long size, start, cur, end, abbrev_end;
1372 start = tcp->u_arg[1];
1377 if (tcp->u_arg[0] == 0) {
1378 tprintf("%#lx", start);
1381 size = len * sizeof(gid);
1383 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1384 size / sizeof(gid) != len || end < start) {
1385 tprintf("%#lx", start);
1389 abbrev_end = start + max_strlen * sizeof(gid);
1390 if (abbrev_end < start)
1396 for (cur = start; cur < end; cur += sizeof(gid)) {
1399 if (cur >= abbrev_end) {
1403 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1408 tprintf("%lu", (unsigned long) gid);
1412 tprintf(" %#lx", tcp->u_arg[1]);
1419 sys_setgroups32(tcp)
1422 if (entering(tcp)) {
1423 unsigned long len, size, start, cur, end, abbrev_end;
1427 len = tcp->u_arg[0];
1428 tprintf("%lu, ", len);
1433 start = tcp->u_arg[1];
1438 size = len * sizeof(gid);
1440 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1441 tprintf("%#lx", start);
1445 abbrev_end = start + max_strlen * sizeof(gid);
1446 if (abbrev_end < start)
1452 for (cur = start; cur < end; cur += sizeof(gid)) {
1455 if (cur >= abbrev_end) {
1459 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1464 tprintf("%lu", (unsigned long) gid);
1468 tprintf(" %#lx", tcp->u_arg[1]);
1474 sys_getgroups32(tcp)
1479 if (entering(tcp)) {
1480 len = tcp->u_arg[0];
1481 tprintf("%lu, ", len);
1483 unsigned long size, start, cur, end, abbrev_end;
1492 start = tcp->u_arg[1];
1497 size = len * sizeof(gid);
1499 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1500 size / sizeof(gid) != len || end < start) {
1501 tprintf("%#lx", start);
1505 abbrev_end = start + max_strlen * sizeof(gid);
1506 if (abbrev_end < start)
1512 for (cur = start; cur < end; cur += sizeof(gid)) {
1515 if (cur >= abbrev_end) {
1519 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1524 tprintf("%lu", (unsigned long) gid);
1528 tprintf(" %#lx", tcp->u_arg[1]);
1534 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1539 if (entering(tcp)) {
1541 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1546 #endif /* ALPHA || SUNOS4 || SVR4 */
1552 if (entering(tcp)) {
1554 tprintf("%lu", tcp->u_arg[0]);
1564 if (entering(tcp)) {
1565 tprintf("%lu", tcp->u_arg[0]);
1581 if (entering(tcp)) {
1582 tprintf("%lu", tcp->u_arg[0]);
1591 if (entering(tcp)) {
1592 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1599 #include <sys/privilege.h>
1602 static const struct xlat procpriv_cmds [] = {
1603 { SETPRV, "SETPRV" },
1604 { CLRPRV, "CLRPRV" },
1605 { PUTPRV, "PUTPRV" },
1606 { GETPRV, "GETPRV" },
1607 { CNTPRV, "CNTPRV" },
1612 static const struct xlat procpriv_priv [] = {
1613 { P_OWNER, "P_OWNER" },
1614 { P_AUDIT, "P_AUDIT" },
1615 { P_COMPAT, "P_COMPAT" },
1616 { P_DACREAD, "P_DACREAD" },
1617 { P_DACWRITE, "P_DACWRITE" },
1619 { P_FILESYS, "P_FILESYS" },
1620 { P_MACREAD, "P_MACREAD" },
1621 { P_MACWRITE, "P_MACWRITE" },
1622 { P_MOUNT, "P_MOUNT" },
1623 { P_MULTIDIR, "P_MULTIDIR" },
1624 { P_SETPLEVEL, "P_SETPLEVEL" },
1625 { P_SETSPRIV, "P_SETSPRIV" },
1626 { P_SETUID, "P_SETUID" },
1627 { P_SYSOPS, "P_SYSOPS" },
1628 { P_SETUPRIV, "P_SETUPRIV" },
1629 { P_DRIVER, "P_DRIVER" },
1630 { P_RTIME, "P_RTIME" },
1631 { P_MACUPGRADE, "P_MACUPGRADE" },
1632 { P_FSYSRANGE, "P_FSYSRANGE" },
1633 { P_SETFLEVEL, "P_SETFLEVEL" },
1634 { P_AUDITWR, "P_AUDITWR" },
1635 { P_TSHAR, "P_TSHAR" },
1636 { P_PLOCK, "P_PLOCK" },
1637 { P_CORE, "P_CORE" },
1638 { P_LOADMOD, "P_LOADMOD" },
1639 { P_BIND, "P_BIND" },
1640 { P_ALLPRIVS, "P_ALLPRIVS" },
1645 static const struct xlat procpriv_type [] = {
1646 { PS_FIX, "PS_FIX" },
1647 { PS_INH, "PS_INH" },
1648 { PS_MAX, "PS_MAX" },
1649 { PS_WKG, "PS_WKG" },
1655 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1658 int max = verbose (tcp) ? sizeof buf / sizeof buf [0] : 10;
1659 int dots = len > max;
1662 if (len > max) len = max;
1665 umoven (tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1667 tprintf ("%#lx", addr);
1673 for (i = 0; i < len; ++i) {
1676 if (i) tprintf (", ");
1678 if ((t = xlookup (procpriv_type, buf [i] & PS_TYPE)) &&
1679 (p = xlookup (procpriv_priv, buf [i] & ~PS_TYPE)))
1681 tprintf ("%s|%s", t, p);
1684 tprintf ("%#lx", buf [i]);
1688 if (dots) tprintf (" ...");
1698 if (entering(tcp)) {
1699 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1700 switch (tcp->u_arg[0]) {
1702 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1710 printpriv (tcp, tcp->u_arg[1], tcp->u_arg[2]);
1711 tprintf (", %ld", tcp->u_arg[2]);
1714 else if (tcp->u_arg[0] == GETPRV) {
1715 if (syserror (tcp)) {
1716 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1720 printpriv (tcp, tcp->u_arg[1], tcp->u_rval);
1721 tprintf (", %ld", tcp->u_arg[2]);
1732 printargv(tcp, addr)
1739 char data[sizeof(long)];
1745 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1746 if (umoven(tcp, addr, personality_wordsize[current_personality],
1748 tprintf("%#lx", addr);
1751 if (personality_wordsize[current_personality] == 4)
1756 printstr(tcp, cp.p64, -1);
1757 addr += personality_wordsize[current_personality];
1760 tprintf("%s...", sep);
1764 printargc(fmt, tcp, addr)
1772 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1773 addr += sizeof(char *);
1775 tprintf(fmt, count, count == 1 ? "" : "s");
1778 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1783 if (entering(tcp)) {
1784 printpath(tcp, tcp->u_arg[0]);
1786 tprintf(", %#lx", tcp->u_arg[1]);
1788 else if (abbrev(tcp))
1789 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1793 printargv(tcp, tcp->u_arg[1]);
1799 #endif /* SPARC || SPARC64 || SUNOS4 */
1805 if (entering(tcp)) {
1806 printpath(tcp, tcp->u_arg[0]);
1808 tprintf(", %#lx", tcp->u_arg[1]);
1810 else if (abbrev(tcp))
1811 printargc(", [/* %d arg%s */]", tcp, tcp->u_arg[1]);
1815 printargv(tcp, tcp->u_arg[1]);
1819 tprintf(", %#lx", tcp->u_arg[2]);
1820 else if (abbrev(tcp))
1821 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1824 printargv(tcp, tcp->u_arg[2]);
1833 int sys_rexecve(tcp)
1836 if (entering (tcp)) {
1838 tprintf (", %ld", tcp->u_arg[3]);
1850 if (exiting(tcp) && !syserror(tcp) && followfork)
1853 #if defined LINUX && defined TCB_WAITEXECVE
1854 if (exiting(tcp) && syserror(tcp))
1855 tcp->flags &= ~TCB_WAITEXECVE;
1857 tcp->flags |= TCB_WAITEXECVE;
1858 #endif /* LINUX && TCB_WAITEXECVE */
1864 #define __WNOTHREAD 0x20000000
1867 #define __WALL 0x40000000
1870 #define __WCLONE 0x80000000
1874 static const struct xlat wait4_options[] = {
1875 { WNOHANG, "WNOHANG" },
1877 { WUNTRACED, "WUNTRACED" },
1880 { WEXITED, "WEXITED" },
1883 { WTRAPPED, "WTRAPPED" },
1886 { WSTOPPED, "WSTOPPED" },
1889 { WCONTINUED, "WCONTINUED" },
1892 { WNOWAIT, "WNOWAIT" },
1895 { __WCLONE, "__WCLONE" },
1898 { __WALL, "__WALL" },
1901 { __WNOTHREAD, "__WNOTHREAD" },
1906 #if !defined WCOREFLAG && defined WCOREFLG
1907 # define WCOREFLAG WCOREFLG
1910 #define WCOREFLAG 0x80
1914 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1917 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1927 * Here is a tricky presentation problem. This solution
1928 * is still not entirely satisfactory but since there
1929 * are no wait status constructors it will have to do.
1931 if (WIFSTOPPED(status)) {
1932 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1933 signame(WSTOPSIG(status)));
1934 status &= ~W_STOPCODE(WSTOPSIG(status));
1936 else if (WIFSIGNALED(status)) {
1937 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1938 signame(WTERMSIG(status)),
1939 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1940 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1942 else if (WIFEXITED(status)) {
1943 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1944 WEXITSTATUS(status));
1946 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1949 tprintf("[%#x]", status);
1956 tprintf(" | %#x]", status);
1962 printwaitn(struct tcb *tcp, int n, int bitness)
1967 if (entering(tcp)) {
1969 /* On Linux, kernel-side pid_t is typedef'ed to int
1970 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1971 * pid argument to int on 64bit arches, producing,
1972 * for example, wait4(4294967295, ...) instead of -1
1973 * in strace. We have to use int here, not long.
1975 int pid = tcp->u_arg[0];
1976 tprintf("%d, ", pid);
1979 * Sign-extend a 32-bit value when that's what it is.
1981 long pid = tcp->u_arg[0];
1982 if (personality_wordsize[current_personality] < sizeof pid)
1983 pid = (long) (int) pid;
1984 tprintf("%ld, ", pid);
1990 else if (syserror(tcp) || tcp->u_rval == 0)
1991 tprintf("%#lx", tcp->u_arg[1]);
1992 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1995 exited = printstatus(status);
1998 printflags(wait4_options, tcp->u_arg[2], "W???");
2005 else if (tcp->u_rval > 0) {
2008 printrusage32(tcp, tcp->u_arg[3]);
2011 printrusage(tcp, tcp->u_arg[3]);
2015 else if (tcp->u_rval > 0 && exited)
2016 printrusage(tcp, tcp->u_arg[3]);
2019 tprintf("%#lx", tcp->u_arg[3]);
2026 internal_wait(tcp, flagarg)
2032 #ifdef TCB_CLONE_THREAD
2033 if (tcp->flags & TCB_CLONE_THREAD)
2034 /* The children we wait for are our parent's children. */
2035 got_kids = (tcp->parent->nchildren
2036 > tcp->parent->nclone_detached);
2038 got_kids = (tcp->nchildren > tcp->nclone_detached);
2040 got_kids = tcp->nchildren > 0;
2043 if (entering(tcp) && got_kids) {
2044 /* There are children that this parent should block for.
2045 But ptrace made us the parent of the traced children
2046 and the real parent will get ECHILD from the wait call.
2048 XXX If we attached with strace -f -p PID, then there
2049 may be untraced dead children the parent could be reaping
2050 now, but we make him block. */
2052 /* ??? WTA: fix bug with hanging children */
2054 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
2056 * There are traced children. We'll make the parent
2057 * block to avoid a false ECHILD error due to our
2058 * ptrace having stolen the children. However,
2059 * we shouldn't block if there are zombies to reap.
2060 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
2062 struct tcb *child = NULL;
2063 if (tcp->nzombies > 0 &&
2064 (tcp->u_arg[0] == -1 ||
2065 (child = pid2tcb(tcp->u_arg[0])) == NULL))
2067 if (tcp->u_arg[0] > 0) {
2069 * If the parent waits for a specified child
2070 * PID, then it must get ECHILD right away
2071 * if that PID is not one of its children.
2072 * Make sure that the requested PID matches
2073 * one of the parent's children that we are
2074 * tracing, and don't suspend it otherwise.
2077 child = pid2tcb(tcp->u_arg[0]);
2078 if (child == NULL || child->parent != (
2079 #ifdef TCB_CLONE_THREAD
2080 (tcp->flags & TCB_CLONE_THREAD)
2084 (child->flags & TCB_EXITING))
2087 tcp->flags |= TCB_SUSPENDED;
2088 tcp->waitpid = tcp->u_arg[0];
2089 #ifdef TCB_CLONE_THREAD
2090 if (tcp->flags & TCB_CLONE_THREAD)
2091 tcp->parent->nclone_waiting++;
2095 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2096 if (tcp->u_arg[flagarg] & WNOHANG) {
2097 /* We must force a fake result of 0 instead of
2098 the ECHILD error. */
2099 extern int force_result();
2100 return force_result(tcp, 0, 0);
2103 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2104 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2106 * We just reaped a child we don't know about,
2107 * presumably a zombie we already droptcb'd.
2121 /* The library wrapper stuffs this into the user variable. */
2123 printstatus(getrval2(tcp));
2138 if (!syserror(tcp)) {
2139 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2140 tprintf("%#lx", tcp->u_arg[0]);
2142 printstatus(status);
2153 return printwaitn(tcp, 3, 0);
2160 return printwaitn(tcp, 4, 0);
2168 return printwaitn(tcp, 4, 1);
2172 #if defined SVR4 || defined LINUX
2174 static const struct xlat waitid_types[] = {
2177 { P_PPID, "P_PPID" },
2179 { P_PGID, "P_PGID" },
2194 { P_LWPID, "P_LWPID" },
2206 if (entering(tcp)) {
2207 printxval(waitid_types, tcp->u_arg[0], "P_???");
2208 tprintf(", %ld, ", tcp->u_arg[1]);
2215 else if (syserror(tcp))
2216 tprintf("%#lx", tcp->u_arg[2]);
2217 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2220 printsiginfo(&si, verbose(tcp));
2223 printflags(wait4_options, tcp->u_arg[3], "W???");
2224 if (tcp->u_nargs > 4) {
2229 else if (tcp->u_error)
2230 tprintf("%#lx", tcp->u_arg[4]);
2232 printrusage(tcp, tcp->u_arg[4]);
2238 #endif /* SVR4 or LINUX */
2245 tprintf("%lu", tcp->u_arg[0]);
2253 struct utsname uname;
2256 if (syserror(tcp) || !verbose(tcp))
2257 tprintf("%#lx", tcp->u_arg[0]);
2258 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2260 else if (!abbrev(tcp)) {
2262 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2263 uname.sysname, uname.nodename);
2264 tprintf("release=\"%s\", version=\"%s\", ",
2265 uname.release, uname.version);
2266 tprintf("machine=\"%s\"", uname.machine);
2269 tprintf(", domainname=\"%s\"", uname.domainname);
2275 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2276 uname.sysname, uname.nodename);
2283 static const struct xlat ptrace_cmds[] = {
2285 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2286 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2287 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2288 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2289 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2290 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2291 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2292 { PTRACE_CONT, "PTRACE_CONT" },
2293 { PTRACE_KILL, "PTRACE_KILL" },
2294 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2295 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2296 { PTRACE_DETACH, "PTRACE_DETACH" },
2297 # ifdef PTRACE_GETREGS
2298 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2300 # ifdef PTRACE_SETREGS
2301 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2303 # ifdef PTRACE_GETFPREGS
2304 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2306 # ifdef PTRACE_SETFPREGS
2307 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2309 # ifdef PTRACE_GETFPXREGS
2310 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2312 # ifdef PTRACE_SETFPXREGS
2313 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2315 # ifdef PTRACE_GETVRREGS
2316 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2318 # ifdef PTRACE_SETVRREGS
2319 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2321 # ifdef PTRACE_SETOPTIONS
2322 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2324 # ifdef PTRACE_GETEVENTMSG
2325 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2327 # ifdef PTRACE_GETSIGINFO
2328 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2330 # ifdef PTRACE_SETSIGINFO
2331 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2333 # ifdef PTRACE_SET_SYSCALL
2334 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2337 { PTRACE_READDATA, "PTRACE_READDATA" },
2338 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2339 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2340 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2341 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2342 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2344 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2345 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2347 { PTRACE_22, "PTRACE_22" },
2348 { PTRACE_23, "PTRACE_3" },
2349 # endif /* !SPARC */
2350 # endif /* SUNOS4 */
2351 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2353 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2355 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2356 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2357 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2359 { PTRACE_26, "PTRACE_26" },
2360 { PTRACE_27, "PTRACE_27" },
2361 { PTRACE_28, "PTRACE_28" },
2363 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2364 # endif /* SUNOS4 */
2366 # else /* FREEBSD */
2368 { PT_TRACE_ME, "PT_TRACE_ME" },
2369 { PT_READ_I, "PT_READ_I" },
2370 { PT_READ_D, "PT_READ_D" },
2371 { PT_WRITE_I, "PT_WRITE_I" },
2372 { PT_WRITE_D, "PT_WRITE_D" },
2374 { PT_READ_U, "PT_READ_U" },
2376 { PT_CONTINUE, "PT_CONTINUE" },
2377 { PT_KILL, "PT_KILL" },
2378 { PT_STEP, "PT_STEP" },
2379 { PT_ATTACH, "PT_ATTACH" },
2380 { PT_DETACH, "PT_DETACH" },
2381 { PT_GETREGS, "PT_GETREGS" },
2382 { PT_SETREGS, "PT_SETREGS" },
2383 { PT_GETFPREGS, "PT_GETFPREGS" },
2384 { PT_SETFPREGS, "PT_SETFPREGS" },
2385 { PT_GETDBREGS, "PT_GETDBREGS" },
2386 { PT_SETDBREGS, "PT_SETDBREGS" },
2387 # endif /* FREEBSD */
2392 # ifdef PTRACE_SETOPTIONS
2393 static const struct xlat ptrace_setoptions_flags[] = {
2394 # ifdef PTRACE_O_TRACESYSGOOD
2395 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2397 # ifdef PTRACE_O_TRACEFORK
2398 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2400 # ifdef PTRACE_O_TRACEVFORK
2401 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2403 # ifdef PTRACE_O_TRACECLONE
2404 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2406 # ifdef PTRACE_O_TRACEEXEC
2407 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2409 # ifdef PTRACE_O_TRACEVFORKDONE
2410 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2412 # ifdef PTRACE_O_TRACEEXIT
2413 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2417 # endif /* PTRACE_SETOPTIONS */
2418 # endif /* !FREEBSD */
2421 const struct xlat struct_user_offsets[] = {
2423 # if defined(S390) || defined(S390X)
2424 { PT_PSWMASK, "psw_mask" },
2425 { PT_PSWADDR, "psw_addr" },
2426 { PT_GPR0, "gpr0" },
2427 { PT_GPR1, "gpr1" },
2428 { PT_GPR2, "gpr2" },
2429 { PT_GPR3, "gpr3" },
2430 { PT_GPR4, "gpr4" },
2431 { PT_GPR5, "gpr5" },
2432 { PT_GPR6, "gpr6" },
2433 { PT_GPR7, "gpr7" },
2434 { PT_GPR8, "gpr8" },
2435 { PT_GPR9, "gpr9" },
2436 { PT_GPR10, "gpr10" },
2437 { PT_GPR11, "gpr11" },
2438 { PT_GPR12, "gpr12" },
2439 { PT_GPR13, "gpr13" },
2440 { PT_GPR14, "gpr14" },
2441 { PT_GPR15, "gpr15" },
2442 { PT_ACR0, "acr0" },
2443 { PT_ACR1, "acr1" },
2444 { PT_ACR2, "acr2" },
2445 { PT_ACR3, "acr3" },
2446 { PT_ACR4, "acr4" },
2447 { PT_ACR5, "acr5" },
2448 { PT_ACR6, "acr6" },
2449 { PT_ACR7, "acr7" },
2450 { PT_ACR8, "acr8" },
2451 { PT_ACR9, "acr9" },
2452 { PT_ACR10, "acr10" },
2453 { PT_ACR11, "acr11" },
2454 { PT_ACR12, "acr12" },
2455 { PT_ACR13, "acr13" },
2456 { PT_ACR14, "acr14" },
2457 { PT_ACR15, "acr15" },
2458 { PT_ORIGGPR2, "orig_gpr2" },
2461 { PT_FPR0_HI, "fpr0.hi" },
2462 { PT_FPR0_LO, "fpr0.lo" },
2463 { PT_FPR1_HI, "fpr1.hi" },
2464 { PT_FPR1_LO, "fpr1.lo" },
2465 { PT_FPR2_HI, "fpr2.hi" },
2466 { PT_FPR2_LO, "fpr2.lo" },
2467 { PT_FPR3_HI, "fpr3.hi" },
2468 { PT_FPR3_LO, "fpr3.lo" },
2469 { PT_FPR4_HI, "fpr4.hi" },
2470 { PT_FPR4_LO, "fpr4.lo" },
2471 { PT_FPR5_HI, "fpr5.hi" },
2472 { PT_FPR5_LO, "fpr5.lo" },
2473 { PT_FPR6_HI, "fpr6.hi" },
2474 { PT_FPR6_LO, "fpr6.lo" },
2475 { PT_FPR7_HI, "fpr7.hi" },
2476 { PT_FPR7_LO, "fpr7.lo" },
2477 { PT_FPR8_HI, "fpr8.hi" },
2478 { PT_FPR8_LO, "fpr8.lo" },
2479 { PT_FPR9_HI, "fpr9.hi" },
2480 { PT_FPR9_LO, "fpr9.lo" },
2481 { PT_FPR10_HI, "fpr10.hi" },
2482 { PT_FPR10_LO, "fpr10.lo" },
2483 { PT_FPR11_HI, "fpr11.hi" },
2484 { PT_FPR11_LO, "fpr11.lo" },
2485 { PT_FPR12_HI, "fpr12.hi" },
2486 { PT_FPR12_LO, "fpr12.lo" },
2487 { PT_FPR13_HI, "fpr13.hi" },
2488 { PT_FPR13_LO, "fpr13.lo" },
2489 { PT_FPR14_HI, "fpr14.hi" },
2490 { PT_FPR14_LO, "fpr14.lo" },
2491 { PT_FPR15_HI, "fpr15.hi" },
2492 { PT_FPR15_LO, "fpr15.lo" },
2495 { PT_FPR0, "fpr0" },
2496 { PT_FPR1, "fpr1" },
2497 { PT_FPR2, "fpr2" },
2498 { PT_FPR3, "fpr3" },
2499 { PT_FPR4, "fpr4" },
2500 { PT_FPR5, "fpr5" },
2501 { PT_FPR6, "fpr6" },
2502 { PT_FPR7, "fpr7" },
2503 { PT_FPR8, "fpr8" },
2504 { PT_FPR9, "fpr9" },
2505 { PT_FPR10, "fpr10" },
2506 { PT_FPR11, "fpr11" },
2507 { PT_FPR12, "fpr12" },
2508 { PT_FPR13, "fpr13" },
2509 { PT_FPR14, "fpr14" },
2510 { PT_FPR15, "fpr15" },
2513 { PT_CR_10, "cr10" },
2514 { PT_CR_11, "cr11" },
2515 { PT_IEEE_IP, "ieee_exception_ip" },
2516 # elif defined(SPARC)
2517 /* XXX No support for these offsets yet. */
2518 # elif defined(HPPA)
2519 /* XXX No support for these offsets yet. */
2520 # elif defined(POWERPC)
2522 # define PT_ORIG_R3 34
2524 # define REGSIZE (sizeof(unsigned long))
2525 { REGSIZE*PT_R0, "r0" },
2526 { REGSIZE*PT_R1, "r1" },
2527 { REGSIZE*PT_R2, "r2" },
2528 { REGSIZE*PT_R3, "r3" },
2529 { REGSIZE*PT_R4, "r4" },
2530 { REGSIZE*PT_R5, "r5" },
2531 { REGSIZE*PT_R6, "r6" },
2532 { REGSIZE*PT_R7, "r7" },
2533 { REGSIZE*PT_R8, "r8" },
2534 { REGSIZE*PT_R9, "r9" },
2535 { REGSIZE*PT_R10, "r10" },
2536 { REGSIZE*PT_R11, "r11" },
2537 { REGSIZE*PT_R12, "r12" },
2538 { REGSIZE*PT_R13, "r13" },
2539 { REGSIZE*PT_R14, "r14" },
2540 { REGSIZE*PT_R15, "r15" },
2541 { REGSIZE*PT_R16, "r16" },
2542 { REGSIZE*PT_R17, "r17" },
2543 { REGSIZE*PT_R18, "r18" },
2544 { REGSIZE*PT_R19, "r19" },
2545 { REGSIZE*PT_R20, "r20" },
2546 { REGSIZE*PT_R21, "r21" },
2547 { REGSIZE*PT_R22, "r22" },
2548 { REGSIZE*PT_R23, "r23" },
2549 { REGSIZE*PT_R24, "r24" },
2550 { REGSIZE*PT_R25, "r25" },
2551 { REGSIZE*PT_R26, "r26" },
2552 { REGSIZE*PT_R27, "r27" },
2553 { REGSIZE*PT_R28, "r28" },
2554 { REGSIZE*PT_R29, "r29" },
2555 { REGSIZE*PT_R30, "r30" },
2556 { REGSIZE*PT_R31, "r31" },
2557 { REGSIZE*PT_NIP, "NIP" },
2558 { REGSIZE*PT_MSR, "MSR" },
2559 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2560 { REGSIZE*PT_CTR, "CTR" },
2561 { REGSIZE*PT_LNK, "LNK" },
2562 { REGSIZE*PT_XER, "XER" },
2563 { REGSIZE*PT_CCR, "CCR" },
2564 { REGSIZE*PT_FPR0, "FPR0" },
2566 # elif defined(ALPHA)
2632 # elif defined(IA64)
2633 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2634 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2635 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2636 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2637 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2638 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2639 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2640 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2641 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2642 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2643 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2644 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2645 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2646 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2647 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2648 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2649 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2650 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2651 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2652 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2653 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2654 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2655 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2656 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2657 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2658 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2659 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2660 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2661 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2662 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2663 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2664 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2666 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2667 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2668 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2669 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2670 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2671 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2672 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2673 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2674 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2675 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2676 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2677 { PT_B4, "b4" }, { PT_B5, "b5" },
2678 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2680 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2681 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2682 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2683 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2684 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2685 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2686 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2687 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2688 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2689 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2690 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2691 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2692 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2693 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2694 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2695 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2696 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2698 { PT_AR_CSD, "ar.csd" },
2701 { PT_AR_SSD, "ar.ssd" },
2703 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2704 # elif defined(I386)
2716 { 4*ORIG_EAX, "4*ORIG_EAX" },
2720 { 4*UESP, "4*UESP" },
2722 # elif defined(X86_64)
2744 { 8*ORIG_RAX, "8*ORIG_RAX" },
2747 { 8*EFLAGS, "8*EFL" },
2750 # elif defined(M68K)
2751 { 4*PT_D1, "4*PT_D1" },
2752 { 4*PT_D2, "4*PT_D2" },
2753 { 4*PT_D3, "4*PT_D3" },
2754 { 4*PT_D4, "4*PT_D4" },
2755 { 4*PT_D5, "4*PT_D5" },
2756 { 4*PT_D6, "4*PT_D6" },
2757 { 4*PT_D7, "4*PT_D7" },
2758 { 4*PT_A0, "4*PT_A0" },
2759 { 4*PT_A1, "4*PT_A1" },
2760 { 4*PT_A2, "4*PT_A2" },
2761 { 4*PT_A3, "4*PT_A3" },
2762 { 4*PT_A4, "4*PT_A4" },
2763 { 4*PT_A5, "4*PT_A5" },
2764 { 4*PT_A6, "4*PT_A6" },
2765 { 4*PT_D0, "4*PT_D0" },
2766 { 4*PT_USP, "4*PT_USP" },
2767 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2768 { 4*PT_SR, "4*PT_SR" },
2769 { 4*PT_PC, "4*PT_PC" },
2771 { 4*REG_REG0, "4*REG_REG0" },
2772 { 4*(REG_REG0+1), "4*REG_REG1" },
2773 { 4*(REG_REG0+2), "4*REG_REG2" },
2774 { 4*(REG_REG0+3), "4*REG_REG3" },
2775 { 4*(REG_REG0+4), "4*REG_REG4" },
2776 { 4*(REG_REG0+5), "4*REG_REG5" },
2777 { 4*(REG_REG0+6), "4*REG_REG6" },
2778 { 4*(REG_REG0+7), "4*REG_REG7" },
2779 { 4*(REG_REG0+8), "4*REG_REG8" },
2780 { 4*(REG_REG0+9), "4*REG_REG9" },
2781 { 4*(REG_REG0+10), "4*REG_REG10" },
2782 { 4*(REG_REG0+11), "4*REG_REG11" },
2783 { 4*(REG_REG0+12), "4*REG_REG12" },
2784 { 4*(REG_REG0+13), "4*REG_REG13" },
2785 { 4*(REG_REG0+14), "4*REG_REG14" },
2786 { 4*REG_REG15, "4*REG_REG15" },
2787 { 4*REG_PC, "4*REG_PC" },
2788 { 4*REG_PR, "4*REG_PR" },
2789 { 4*REG_SR, "4*REG_SR" },
2790 { 4*REG_GBR, "4*REG_GBR" },
2791 { 4*REG_MACH, "4*REG_MACH" },
2792 { 4*REG_MACL, "4*REG_MACL" },
2793 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2794 { 4*REG_FPUL, "4*REG_FPUL" },
2795 { 4*REG_FPREG0, "4*REG_FPREG0" },
2796 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2797 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2798 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2799 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2800 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2801 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2802 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2803 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2804 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2805 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2806 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2807 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2808 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2809 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2810 { 4*REG_FPREG15, "4*REG_FPREG15" },
2812 { 4*REG_XDREG0, "4*REG_XDREG0" },
2813 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2814 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2815 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2816 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2817 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2818 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2819 { 4*REG_XDREG14, "4*REG_XDREG14" },
2821 { 4*REG_FPSCR, "4*REG_FPSCR" },
2822 # elif defined(SH64)
2827 { 16, "syscall no.(L)" },
2828 { 20, "syscall_no.(U)" },
2971 /* This entry is in case pt_regs contains dregs (depends on
2972 the kernel build options). */
2973 { uoff(regs), "offsetof(struct user, regs)" },
2974 { uoff(fpu), "offsetof(struct user, fpu)" },
2976 { uoff(regs.ARM_r0), "r0" },
2977 { uoff(regs.ARM_r1), "r1" },
2978 { uoff(regs.ARM_r2), "r2" },
2979 { uoff(regs.ARM_r3), "r3" },
2980 { uoff(regs.ARM_r4), "r4" },
2981 { uoff(regs.ARM_r5), "r5" },
2982 { uoff(regs.ARM_r6), "r6" },
2983 { uoff(regs.ARM_r7), "r7" },
2984 { uoff(regs.ARM_r8), "r8" },
2985 { uoff(regs.ARM_r9), "r9" },
2986 { uoff(regs.ARM_r10), "r10" },
2987 { uoff(regs.ARM_fp), "fp" },
2988 { uoff(regs.ARM_ip), "ip" },
2989 { uoff(regs.ARM_sp), "sp" },
2990 { uoff(regs.ARM_lr), "lr" },
2991 { uoff(regs.ARM_pc), "pc" },
2992 { uoff(regs.ARM_cpsr), "cpsr" },
2993 # elif defined(AVR32)
2994 { uoff(regs.sr), "sr" },
2995 { uoff(regs.pc), "pc" },
2996 { uoff(regs.lr), "lr" },
2997 { uoff(regs.sp), "sp" },
2998 { uoff(regs.r12), "r12" },
2999 { uoff(regs.r11), "r11" },
3000 { uoff(regs.r10), "r10" },
3001 { uoff(regs.r9), "r9" },
3002 { uoff(regs.r8), "r8" },
3003 { uoff(regs.r7), "r7" },
3004 { uoff(regs.r6), "r6" },
3005 { uoff(regs.r5), "r5" },
3006 { uoff(regs.r4), "r4" },
3007 { uoff(regs.r3), "r3" },
3008 { uoff(regs.r2), "r2" },
3009 { uoff(regs.r1), "r1" },
3010 { uoff(regs.r0), "r0" },
3011 { uoff(regs.r12_orig), "orig_r12" },
3012 # elif defined(MIPS)
3086 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3087 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3088 { 4*PT_R13, "4*PT_R13" },
3089 { 4*PT_R12, "4*PT_R12" },
3090 { 4*PT_R11, "4*PT_R11" },
3091 { 4*PT_R10, "4*PT_R10" },
3092 { 4*PT_R9, "4*PT_R9" },
3093 { 4*PT_R8, "4*PT_R8" },
3094 { 4*PT_R7, "4*PT_R7" },
3095 { 4*PT_R6, "4*PT_R6" },
3096 { 4*PT_R5, "4*PT_R5" },
3097 { 4*PT_R4, "4*PT_R4" },
3098 { 4*PT_R3, "4*PT_R3" },
3099 { 4*PT_R2, "4*PT_R2" },
3100 { 4*PT_R1, "4*PT_R1" },
3101 { 4*PT_R0, "4*PT_R0" },
3102 { 4*PT_MOF, "4*PT_MOF" },
3103 { 4*PT_DCCR, "4*PT_DCCR" },
3104 { 4*PT_SRP, "4*PT_SRP" },
3105 { 4*PT_IRP, "4*PT_IRP" },
3106 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3107 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3108 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3109 { 4*PT_USP, "4*PT_USP" },
3112 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3113 { 4*PT_R0, "4*PT_R0" },
3114 { 4*PT_R1, "4*PT_R1" },
3115 { 4*PT_R2, "4*PT_R2" },
3116 { 4*PT_R3, "4*PT_R3" },
3117 { 4*PT_R4, "4*PT_R4" },
3118 { 4*PT_R5, "4*PT_R5" },
3119 { 4*PT_R6, "4*PT_R6" },
3120 { 4*PT_R7, "4*PT_R7" },
3121 { 4*PT_R8, "4*PT_R8" },
3122 { 4*PT_R9, "4*PT_R9" },
3123 { 4*PT_R10, "4*PT_R10" },
3124 { 4*PT_R11, "4*PT_R11" },
3125 { 4*PT_R12, "4*PT_R12" },
3126 { 4*PT_R13, "4*PT_R13" },
3127 { 4*PT_ACR, "4*PT_ACR" },
3128 { 4*PT_SRS, "4*PT_SRS" },
3129 { 4*PT_MOF, "4*PT_MOF" },
3130 { 4*PT_SPC, "4*PT_SPC" },
3131 { 4*PT_CCS, "4*PT_CCS" },
3132 { 4*PT_SRP, "4*PT_SRP" },
3133 { 4*PT_ERP, "4*PT_ERP" },
3134 { 4*PT_EXS, "4*PT_EXS" },
3135 { 4*PT_EDA, "4*PT_EDA" },
3136 { 4*PT_USP, "4*PT_USP" },
3137 { 4*PT_PPC, "4*PT_PPC" },
3138 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3139 { 4*PT_BP+4, "4*PT_BP+4" },
3140 { 4*PT_BP+8, "4*PT_BP+8" },
3141 { 4*PT_BP+12, "4*PT_BP+12" },
3142 { 4*PT_BP+16, "4*PT_BP+16" },
3143 { 4*PT_BP+20, "4*PT_BP+20" },
3144 { 4*PT_BP+24, "4*PT_BP+24" },
3145 { 4*PT_BP+28, "4*PT_BP+28" },
3146 { 4*PT_BP+32, "4*PT_BP+32" },
3147 { 4*PT_BP+36, "4*PT_BP+36" },
3148 { 4*PT_BP+40, "4*PT_BP+40" },
3149 { 4*PT_BP+44, "4*PT_BP+44" },
3150 { 4*PT_BP+48, "4*PT_BP+48" },
3151 { 4*PT_BP+52, "4*PT_BP+52" },
3152 { 4*PT_BP+56, "4*PT_BP+56" },
3155 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3156 && !defined(ALPHA) && !defined(IA64) \
3157 && !defined(CRISV10) && !defined(CRISV32)
3158 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN)
3159 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3161 # if defined(I386) || defined(X86_64)
3162 { uoff(i387), "offsetof(struct user, i387)" },
3165 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3167 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3168 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3169 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3170 # if !defined(SPARC64)
3171 { uoff(start_code), "offsetof(struct user, start_code)" },
3173 # if defined(AVR32) || defined(SH64)
3174 { uoff(start_data), "offsetof(struct user, start_data)" },
3176 # if !defined(SPARC64)
3177 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3179 { uoff(signal), "offsetof(struct user, signal)" },
3180 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64)
3181 { uoff(reserved), "offsetof(struct user, reserved)" },
3183 # if !defined(SPARC64)
3184 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3186 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN)
3187 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3189 { uoff(magic), "offsetof(struct user, magic)" },
3190 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3191 # if defined(I386) || defined(X86_64)
3192 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3194 # endif /* !defined(many arches) */
3199 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3200 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3201 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3202 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3203 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3204 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3205 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3206 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3207 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3208 { uoff(u_error), "offsetof(struct user, u_error)" },
3209 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3210 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3211 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3212 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3213 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3214 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3215 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3216 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3217 { uoff(u_code), "offsetof(struct user, u_code)" },
3218 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3219 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3220 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3221 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3222 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3223 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3224 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3225 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3226 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3227 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3228 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3229 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3230 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3231 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3232 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3233 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3234 { uoff(u_start), "offsetof(struct user, u_start)" },
3235 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3236 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3237 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3238 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3239 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3240 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3241 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3242 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3243 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3244 # endif /* SUNOS4 */
3246 { sizeof(struct user), "sizeof(struct user)" },
3250 # endif /* !FREEBSD */
3253 sys_ptrace(struct tcb *tcp)
3255 const struct xlat *x;
3258 if (entering(tcp)) {
3259 printxval(ptrace_cmds, tcp->u_arg[0],
3266 tprintf(", %lu, ", tcp->u_arg[1]);
3267 addr = tcp->u_arg[2];
3269 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3270 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3271 for (x = struct_user_offsets; x->str; x++) {
3276 tprintf("%#lx, ", addr);
3277 else if (x->val > addr && x != struct_user_offsets) {
3279 tprintf("%s + %ld, ", x->str, addr - x->val);
3282 tprintf("%s, ", x->str);
3286 tprintf("%#lx, ", tcp->u_arg[2]);
3288 switch (tcp->u_arg[0]) {
3290 case PTRACE_PEEKDATA:
3291 case PTRACE_PEEKTEXT:
3292 case PTRACE_PEEKUSER:
3296 case PTRACE_SINGLESTEP:
3297 case PTRACE_SYSCALL:
3299 printsignal(tcp->u_arg[3]);
3301 # ifdef PTRACE_SETOPTIONS
3302 case PTRACE_SETOPTIONS:
3303 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3306 # ifdef PTRACE_SETSIGINFO
3307 case PTRACE_SETSIGINFO: {
3311 else if (syserror(tcp))
3312 tprintf("%#lx", tcp->u_arg[3]);
3313 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3316 printsiginfo(&si, verbose(tcp));
3320 # ifdef PTRACE_GETSIGINFO
3321 case PTRACE_GETSIGINFO:
3322 /* Don't print anything, do it at syscall return. */
3326 tprintf("%#lx", tcp->u_arg[3]);
3330 switch (tcp->u_arg[0]) {
3331 case PTRACE_PEEKDATA:
3332 case PTRACE_PEEKTEXT:
3333 case PTRACE_PEEKUSER:
3337 printnum(tcp, tcp->u_arg[3], "%#lx");
3340 # ifdef PTRACE_GETSIGINFO
3341 case PTRACE_GETSIGINFO: {
3345 else if (syserror(tcp))
3346 tprintf("%#lx", tcp->u_arg[3]);
3347 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3350 printsiginfo(&si, verbose(tcp));
3358 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3359 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3360 tprintf("%lu, ", tcp->u_arg[3]);
3361 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3362 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3363 tcp->u_arg[0] != PTRACE_READTEXT) {
3364 tprintf("%#lx", tcp->u_arg[3]);
3367 if (tcp->u_arg[0] == PTRACE_READDATA ||
3368 tcp->u_arg[0] == PTRACE_READTEXT) {
3369 tprintf("%lu, ", tcp->u_arg[3]);
3370 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3373 # endif /* SUNOS4 */
3375 tprintf("%lu", tcp->u_arg[3]);
3377 # endif /* FREEBSD */
3384 # ifndef FUTEX_CMP_REQUEUE
3385 # define FUTEX_CMP_REQUEUE 4
3387 # ifndef FUTEX_WAKE_OP
3388 # define FUTEX_WAKE_OP 5
3390 # ifndef FUTEX_LOCK_PI
3391 # define FUTEX_LOCK_PI 6
3392 # define FUTEX_UNLOCK_PI 7
3393 # define FUTEX_TRYLOCK_PI 8
3395 # ifndef FUTEX_WAIT_BITSET
3396 # define FUTEX_WAIT_BITSET 9
3398 # ifndef FUTEX_WAKE_BITSET
3399 # define FUTEX_WAKE_BITSET 10
3401 # ifndef FUTEX_WAIT_REQUEUE_PI
3402 # define FUTEX_WAIT_REQUEUE_PI 11
3404 # ifndef FUTEX_CMP_REQUEUE_PI
3405 # define FUTEX_CMP_REQUEUE_PI 12
3407 # ifndef FUTEX_PRIVATE_FLAG
3408 # define FUTEX_PRIVATE_FLAG 128
3410 # ifndef FUTEX_CLOCK_REALTIME
3411 # define FUTEX_CLOCK_REALTIME 256
3413 static const struct xlat futexops[] = {
3414 { FUTEX_WAIT, "FUTEX_WAIT" },
3415 { FUTEX_WAKE, "FUTEX_WAKE" },
3416 { FUTEX_FD, "FUTEX_FD" },
3417 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3418 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3419 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3420 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3421 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3422 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3423 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3424 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3425 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3426 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3427 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3428 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3429 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3430 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3431 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3432 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3433 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3434 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3435 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3436 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3437 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3438 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3439 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3440 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3441 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3442 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3443 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3446 # ifndef FUTEX_OP_SET
3447 # define FUTEX_OP_SET 0
3448 # define FUTEX_OP_ADD 1
3449 # define FUTEX_OP_OR 2
3450 # define FUTEX_OP_ANDN 3
3451 # define FUTEX_OP_XOR 4
3452 # define FUTEX_OP_CMP_EQ 0
3453 # define FUTEX_OP_CMP_NE 1
3454 # define FUTEX_OP_CMP_LT 2
3455 # define FUTEX_OP_CMP_LE 3
3456 # define FUTEX_OP_CMP_GT 4
3457 # define FUTEX_OP_CMP_GE 5
3459 static const struct xlat futexwakeops[] = {
3460 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3461 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3462 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3463 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3464 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3467 static const struct xlat futexwakecmps[] = {
3468 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3469 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3470 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3471 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3472 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3473 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3478 sys_futex(struct tcb *tcp)
3480 if (entering(tcp)) {
3481 long int cmd = tcp->u_arg[1] & 127;
3482 tprintf("%p, ", (void *) tcp->u_arg[0]);
3483 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3484 tprintf(", %ld", tcp->u_arg[2]);
3485 if (cmd == FUTEX_WAKE_BITSET)
3486 tprintf(", %lx", tcp->u_arg[5]);
3487 else if (cmd == FUTEX_WAIT) {
3489 printtv(tcp, tcp->u_arg[3]);
3490 } else if (cmd == FUTEX_WAIT_BITSET) {
3492 printtv(tcp, tcp->u_arg[3]);
3493 tprintf(", %lx", tcp->u_arg[5]);
3494 } else if (cmd == FUTEX_REQUEUE)
3495 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3496 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3497 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3498 else if (cmd == FUTEX_WAKE_OP) {
3499 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3500 if ((tcp->u_arg[5] >> 28) & 8)
3501 tprintf("FUTEX_OP_OPARG_SHIFT|");
3502 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3503 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3504 if ((tcp->u_arg[5] >> 24) & 8)
3505 tprintf("FUTEX_OP_OPARG_SHIFT|");
3506 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3507 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3508 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3510 printtv(tcp, tcp->u_arg[3]);
3511 tprintf(", %p", (void *) tcp->u_arg[4]);
3518 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3521 unsigned long w, min_len;
3523 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3524 min_len = len - max_strlen * sizeof(w);
3527 for (; len >= sizeof(w) && len > min_len;
3528 len -= sizeof(w), list += sizeof(w)) {
3529 if (umove(tcp, list, &w) < 0)
3540 tprintf("%#lx", list);
3542 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3545 tprintf(first ? "{}" : "}");
3550 sys_sched_setaffinity(struct tcb *tcp)
3552 if (entering(tcp)) {
3553 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3554 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3560 sys_sched_getaffinity(struct tcb *tcp)
3562 if (entering(tcp)) {
3563 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3565 if (tcp->u_rval == -1)
3566 tprintf("%#lx", tcp->u_arg[2]);
3568 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3573 static const struct xlat schedulers[] = {
3574 { SCHED_OTHER, "SCHED_OTHER" },
3575 { SCHED_RR, "SCHED_RR" },
3576 { SCHED_FIFO, "SCHED_FIFO" },
3581 sys_sched_getscheduler(struct tcb *tcp)
3583 if (entering(tcp)) {
3584 tprintf("%d", (int) tcp->u_arg[0]);
3585 } else if (! syserror(tcp)) {
3586 tcp->auxstr = xlookup (schedulers, tcp->u_rval);
3587 if (tcp->auxstr != NULL)
3594 sys_sched_setscheduler(struct tcb *tcp)
3596 if (entering(tcp)) {
3597 struct sched_param p;
3598 tprintf("%d, ", (int) tcp->u_arg[0]);
3599 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3600 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3601 tprintf(", %#lx", tcp->u_arg[2]);
3603 tprintf(", { %d }", p.__sched_priority);
3609 sys_sched_getparam(struct tcb *tcp)
3611 if (entering(tcp)) {
3612 tprintf("%d, ", (int) tcp->u_arg[0]);
3614 struct sched_param p;
3615 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3616 tprintf("%#lx", tcp->u_arg[1]);
3618 tprintf("{ %d }", p.__sched_priority);
3624 sys_sched_setparam(struct tcb *tcp)
3626 if (entering(tcp)) {
3627 struct sched_param p;
3628 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3629 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3631 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3637 sys_sched_get_priority_min(struct tcb *tcp)
3639 if (entering(tcp)) {
3640 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3646 # include <asm/prctl.h>
3648 static const struct xlat archvals[] = {
3649 { ARCH_SET_GS, "ARCH_SET_GS" },
3650 { ARCH_SET_FS, "ARCH_SET_FS" },
3651 { ARCH_GET_FS, "ARCH_GET_FS" },
3652 { ARCH_GET_GS, "ARCH_GET_GS" },
3657 sys_arch_prctl(struct tcb *tcp)
3659 if (entering(tcp)) {
3660 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3661 if (tcp->u_arg[0] == ARCH_SET_GS
3662 || tcp->u_arg[0] == ARCH_SET_FS
3664 tprintf(", %#lx", tcp->u_arg[1]);
3667 if (tcp->u_arg[0] == ARCH_GET_GS
3668 || tcp->u_arg[0] == ARCH_GET_FS
3671 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3672 tprintf(", [%#lx]", v);
3674 tprintf(", %#lx", tcp->u_arg[1]);
3679 # endif /* X86_64 */
3683 sys_getcpu(struct tcb *tcp)
3687 if (tcp->u_arg[0] == 0)
3689 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3690 tprintf("%#lx, ", tcp->u_arg[0]);
3692 tprintf("[%u], ", u);
3693 if (tcp->u_arg[1] == 0)
3695 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3696 tprintf("%#lx, ", tcp->u_arg[1]);
3698 tprintf("[%u], ", u);
3699 tprintf("%#lx", tcp->u_arg[2]);