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>
125 static const struct xlat prctl_options[] = {
127 { PR_MAXPROCS, "PR_MAXPROCS" },
130 { PR_ISBLOCKED, "PR_ISBLOCKED" },
132 #ifdef PR_SETSTACKSIZE
133 { PR_SETSTACKSIZE, "PR_SETSTACKSIZE" },
135 #ifdef PR_GETSTACKSIZE
136 { PR_GETSTACKSIZE, "PR_GETSTACKSIZE" },
139 { PR_MAXPPROCS, "PR_MAXPPROCS" },
141 #ifdef PR_UNBLKONEXEC
142 { PR_UNBLKONEXEC, "PR_UNBLKONEXEC" },
145 { PR_ATOMICSIM, "PR_ATOMICSIM" },
148 { PR_SETEXITSIG, "PR_SETEXITSIG" },
151 { PR_RESIDENT, "PR_RESIDENT" },
154 { PR_ATTACHADDR, "PR_ATTACHADDR" },
157 { PR_DETACHADDR, "PR_DETACHADDR" },
160 { PR_TERMCHILD, "PR_TERMCHILD" },
163 { PR_GETSHMASK, "PR_GETSHMASK" },
166 { PR_GETNSHARE, "PR_GETNSHARE" },
169 { PR_COREPID, "PR_COREPID" },
171 #ifdef PR_ATTACHADDRPERM
172 { PR_ATTACHADDRPERM, "PR_ATTACHADDRPERM" },
174 #ifdef PR_PTHREADEXIT
175 { PR_PTHREADEXIT, "PR_PTHREADEXIT" },
177 #ifdef PR_SET_PDEATHSIG
178 { PR_SET_PDEATHSIG, "PR_SET_PDEATHSIG" },
180 #ifdef PR_GET_PDEATHSIG
181 { PR_GET_PDEATHSIG, "PR_GET_PDEATHSIG" },
183 #ifdef PR_GET_DUMPABLE
184 { PR_GET_DUMPABLE, "PR_GET_DUMPABLE" },
186 #ifdef PR_SET_DUMPABLE
187 { PR_SET_DUMPABLE, "PR_SET_DUMPABLE" },
189 #ifdef PR_GET_UNALIGN
190 { PR_GET_UNALIGN, "PR_GET_UNALIGN" },
192 #ifdef PR_SET_UNALIGN
193 { PR_SET_UNALIGN, "PR_SET_UNALIGN" },
195 #ifdef PR_GET_KEEPCAPS
196 { PR_GET_KEEPCAPS, "PR_GET_KEEPCAPS" },
198 #ifdef PR_SET_KEEPCAPS
199 { PR_SET_KEEPCAPS, "PR_SET_KEEPCAPS" },
202 { PR_GET_FPEMU, "PR_GET_FPEMU" },
205 { PR_SET_FPEMU, "PR_SET_FPEMU" },
208 { PR_GET_FPEXC, "PR_GET_FPEXC" },
211 { PR_SET_FPEXC, "PR_SET_FPEXC" },
214 { PR_GET_TIMING, "PR_GET_TIMING" },
217 { PR_SET_TIMING, "PR_SET_TIMING" },
220 { PR_SET_NAME, "PR_SET_NAME" },
223 { PR_GET_NAME, "PR_GET_NAME" },
226 { PR_GET_ENDIAN, "PR_GET_ENDIAN" },
229 { PR_SET_ENDIAN, "PR_SET_ENDIAN" },
231 #ifdef PR_GET_SECCOMP
232 { PR_GET_SECCOMP, "PR_GET_SECCOMP" },
234 #ifdef PR_SET_SECCOMP
235 { PR_SET_SECCOMP, "PR_SET_SECCOMP" },
238 { PR_GET_TSC, "PR_GET_TSC" },
241 { PR_SET_TSC, "PR_SET_TSC" },
243 #ifdef PR_GET_SECUREBITS
244 { PR_GET_SECUREBITS, "PR_GET_SECUREBITS" },
246 #ifdef PR_SET_SECUREBITS
247 { PR_SET_SECUREBITS, "PR_SET_SECUREBITS" },
254 unalignctl_string(unsigned int ctl)
259 #ifdef PR_UNALIGN_NOPRINT
260 case PR_UNALIGN_NOPRINT:
263 #ifdef PR_UNALIGN_SIGBUS
264 case PR_UNALIGN_SIGBUS:
270 sprintf(buf, "%x", ctl);
276 sys_prctl(struct tcb *tcp)
281 printxval(prctl_options, tcp->u_arg[0], "PR_???");
282 switch (tcp->u_arg[0]) {
287 #ifdef PR_SET_PDEATHSIG
288 case PR_SET_PDEATHSIG:
289 tprintf(", %lu", tcp->u_arg[1]);
292 #ifdef PR_GET_PDEATHSIG
293 case PR_GET_PDEATHSIG:
296 #ifdef PR_SET_DUMPABLE
297 case PR_SET_DUMPABLE:
298 tprintf(", %lu", tcp->u_arg[1]);
301 #ifdef PR_GET_DUMPABLE
302 case PR_GET_DUMPABLE:
305 #ifdef PR_SET_UNALIGN
307 tprintf(", %s", unalignctl_string(tcp->u_arg[1]));
310 #ifdef PR_GET_UNALIGN
312 tprintf(", %#lx", tcp->u_arg[1]);
315 #ifdef PR_SET_KEEPCAPS
316 case PR_SET_KEEPCAPS:
317 tprintf(", %lu", tcp->u_arg[1]);
320 #ifdef PR_GET_KEEPCAPS
321 case PR_GET_KEEPCAPS:
325 for (i = 1; i < tcp->u_nargs; i++)
326 tprintf(", %#lx", tcp->u_arg[i]);
330 switch (tcp->u_arg[0]) {
331 #ifdef PR_GET_PDEATHSIG
332 case PR_GET_PDEATHSIG:
333 if (umove(tcp, tcp->u_arg[1], &i) < 0)
334 tprintf(", %#lx", tcp->u_arg[1]);
336 tprintf(", {%u}", i);
339 #ifdef PR_GET_DUMPABLE
340 case PR_GET_DUMPABLE:
341 return RVAL_UDECIMAL;
343 #ifdef PR_GET_UNALIGN
345 if (syserror(tcp) || umove(tcp, tcp->u_arg[1], &i) < 0)
347 tcp->auxstr = unalignctl_string(i);
350 #ifdef PR_GET_KEEPCAPS
351 case PR_GET_KEEPCAPS:
352 return RVAL_UDECIMAL;
360 #endif /* HAVE_PRCTL */
362 #if defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
364 sys_gethostid(struct tcb *tcp)
370 #endif /* FREEBSD || SUNOS4 || SVR4 */
373 sys_sethostname(struct tcb *tcp)
376 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
377 tprintf(", %lu", tcp->u_arg[1]);
382 #if defined(ALPHA) || defined(FREEBSD) || defined(SUNOS4) || defined(SVR4)
384 sys_gethostname(struct tcb *tcp)
388 tprintf("%#lx", tcp->u_arg[0]);
390 printpath(tcp, tcp->u_arg[0]);
391 tprintf(", %lu", tcp->u_arg[1]);
395 #endif /* ALPHA || FREEBSD || SUNOS4 || SVR4 */
398 sys_setdomainname(struct tcb *tcp)
401 printpathn(tcp, tcp->u_arg[0], tcp->u_arg[1]);
402 tprintf(", %lu", tcp->u_arg[1]);
410 sys_getdomainname(struct tcb *tcp)
414 tprintf("%#lx", tcp->u_arg[0]);
416 printpath(tcp, tcp->u_arg[0]);
417 tprintf(", %lu", tcp->u_arg[1]);
424 sys_exit(struct tcb *tcp)
427 fprintf(stderr, "_exit returned!\n");
430 /* special case: we stop tracing this process, finish line now */
431 tprintf("%ld) ", tcp->u_arg[0]);
439 internal_exit(struct tcb *tcp)
442 tcp->flags |= TCB_EXITING;
443 #ifdef __NR_exit_group
444 if (known_scno(tcp) == __NR_exit_group)
445 tcp->flags |= TCB_GROUP_EXITING;
454 sys_fork(struct tcb *tcp)
456 if (exiting(tcp) && !syserror(tcp)) {
458 tcp->auxstr = "child process";
459 return RVAL_UDECIMAL | RVAL_STR;
468 sys_rfork(struct tcb *tcp)
471 tprintf("%ld", tcp->u_arg[0]);
473 else if (!syserror(tcp)) {
475 tcp->auxstr = "child process";
476 return RVAL_UDECIMAL | RVAL_STR;
485 internal_fork(struct tcb *tcp)
487 struct tcb *tcpchild;
491 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
500 tcpchild = alloctcb(tcp->u_rval);
501 if (proc_open(tcpchild, 2) < 0)
507 #else /* !USE_PROCFS */
511 /* defines copied from linux/sched.h since we can't include that
512 * ourselves (it conflicts with *lots* of libc includes)
514 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
515 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
516 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
517 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
518 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
519 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
520 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
521 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
522 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
523 #define CLONE_THREAD 0x00010000 /* Same thread group? */
524 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
525 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
526 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
527 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
528 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
529 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
530 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
531 #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
532 #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
533 #define CLONE_NEWIPC 0x08000000 /* New ipcs */
534 #define CLONE_NEWUSER 0x10000000 /* New user namespace */
535 #define CLONE_NEWPID 0x20000000 /* New pid namespace */
536 #define CLONE_NEWNET 0x40000000 /* New network namespace */
537 #define CLONE_IO 0x80000000 /* Clone io context */
539 static const struct xlat clone_flags[] = {
540 { CLONE_VM, "CLONE_VM" },
541 { CLONE_FS, "CLONE_FS" },
542 { CLONE_FILES, "CLONE_FILES" },
543 { CLONE_SIGHAND, "CLONE_SIGHAND" },
544 { CLONE_IDLETASK, "CLONE_IDLETASK"},
545 { CLONE_PTRACE, "CLONE_PTRACE" },
546 { CLONE_VFORK, "CLONE_VFORK" },
547 { CLONE_PARENT, "CLONE_PARENT" },
548 { CLONE_THREAD, "CLONE_THREAD" },
549 { CLONE_NEWNS, "CLONE_NEWNS" },
550 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
551 { CLONE_SETTLS, "CLONE_SETTLS" },
552 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
553 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
554 { CLONE_UNTRACED, "CLONE_UNTRACED" },
555 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
556 { CLONE_STOPPED, "CLONE_STOPPED" },
557 { CLONE_NEWUTS, "CLONE_NEWUTS" },
558 { CLONE_NEWIPC, "CLONE_NEWIPC" },
559 { CLONE_NEWUSER, "CLONE_NEWUSER" },
560 { CLONE_NEWPID, "CLONE_NEWPID" },
561 { CLONE_NEWNET, "CLONE_NEWNET" },
562 { CLONE_IO, "CLONE_IO" },
567 # include <asm/ldt.h>
568 # ifdef HAVE_STRUCT_USER_DESC
569 # define modify_ldt_ldt_s user_desc
571 extern void print_ldt_entry();
577 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
578 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
579 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
580 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
581 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
587 # elif defined X86_64 || defined ALPHA
602 sys_clone(struct tcb *tcp)
605 const char *sep = "|";
606 unsigned long flags = tcp->u_arg[ARG_FLAGS];
607 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
608 # ifdef ARG_STACKSIZE
609 if (ARG_STACKSIZE != -1)
610 tprintf("stack_size=%#lx, ",
611 tcp->u_arg[ARG_STACKSIZE]);
614 if (!printflags(clone_flags, flags &~ CSIGNAL, NULL))
616 if ((flags & CSIGNAL) != 0)
617 tprintf("%s%s", sep, signame(flags & CSIGNAL));
618 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
619 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
621 if (flags & CLONE_PARENT_SETTID)
622 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
623 if (flags & CLONE_SETTLS) {
625 struct modify_ldt_ldt_s copy;
626 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
627 tprintf(", {entry_number:%d, ",
632 print_ldt_entry(©);
636 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
638 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
639 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
645 sys_unshare(struct tcb *tcp)
648 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
654 sys_fork(struct tcb *tcp)
657 return RVAL_UDECIMAL;
662 change_syscall(struct tcb *tcp, int new)
666 /* Attempt to make vfork into fork, which we can follow. */
667 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
670 #elif defined(X86_64)
671 /* Attempt to make vfork into fork, which we can follow. */
672 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
675 #elif defined(POWERPC)
676 if (ptrace(PTRACE_POKEUSER, tcp->pid,
677 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
680 #elif defined(S390) || defined(S390X)
681 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
682 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new) < 0)
686 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new) < 0)
689 #elif defined(SPARC) || defined(SPARC64)
691 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0) < 0)
693 regs.u_regs[U_REG_G1] = new;
694 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0) < 0)
698 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new) < 0)
702 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new) < 0)
706 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
710 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new) < 0)
717 break; /* x86 SYS_fork */
722 fprintf(stderr, "%s: unexpected syscall %d\n",
726 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new) < 0)
728 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new) < 0)
732 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new) < 0)
736 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new) < 0)
740 /* Top half of reg encodes the no. of args n as 0x1n.
741 Assume 0 args as kernel never actually checks... */
742 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
746 #elif defined(CRISV10) || defined(CRISV32)
747 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
751 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
752 # ifndef PTRACE_SET_SYSCALL
753 # define PTRACE_SET_SYSCALL 23
756 if (ptrace(PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
761 if (ptrace(PTRACE_POKEUSER, tcp->pid,
762 (char*)PTREGS_OFFSET_REG(0),
766 #elif defined(MICROBLAZE)
767 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR(0)), new) < 0)
771 #warning Do not know how to handle change_syscall for this architecture
772 #endif /* architecture */
779 handle_new_child(struct tcb *tcp, int pid, int bpt)
781 struct tcb *tcpchild;
783 tcpchild = pid2tcb(pid);
784 if (tcpchild != NULL) {
785 /* The child already reported its startup trap
786 before the parent reported its syscall return. */
788 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
789 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
791 [preattached child %d of %d in weird state!]\n",
795 tcpchild = alloctcb(pid);
798 tcpchild->flags |= TCB_ATTACHED;
802 /* Child has BPT too, must be removed on first occasion. */
803 tcpchild->flags |= TCB_BPTSET;
804 tcpchild->baddr = tcp->baddr;
805 memcpy(tcpchild->inst, tcp->inst,
806 sizeof tcpchild->inst);
808 tcpchild->parent = tcp;
809 if (tcpchild->flags & TCB_SUSPENDED) {
810 /* The child was born suspended, due to our having
811 forced CLONE_PTRACE. */
815 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
816 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
821 Process %u resumed (parent %d ready)\n",
826 fprintf(stderr, "Process %d attached\n", pid);
829 #ifdef TCB_CLONE_THREAD
830 if (sysent[tcp->scno].sys_func == sys_clone) {
832 * Save the flags used in this call,
833 * in case we point TCP to our parent below.
835 int call_flags = tcp->u_arg[ARG_FLAGS];
836 if ((tcp->flags & TCB_CLONE_THREAD) &&
837 tcp->parent != NULL) {
838 /* The parent in this clone is itself a
839 thread belonging to another process.
840 There is no meaning to the parentage
841 relationship of the new child with the
842 thread, only with the process. We
843 associate the new thread with our
844 parent. Since this is done for every
845 new thread, there will never be a
846 TCB_CLONE_THREAD process that has
849 tcpchild->parent = tcp;
851 if (call_flags & CLONE_THREAD) {
852 tcpchild->flags |= TCB_CLONE_THREAD;
853 ++tcp->nclone_threads;
855 if ((call_flags & CLONE_PARENT) &&
856 !(call_flags & CLONE_THREAD)) {
857 tcpchild->parent = NULL;
858 if (tcp->parent != NULL) {
860 tcpchild->parent = tcp;
864 #endif /* TCB_CLONE_THREAD */
869 internal_fork(struct tcb *tcp)
871 if ((ptrace_setoptions
872 & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
873 == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
881 * In occasion of using PTRACE_O_TRACECLONE, we won't see the
882 * new child if clone is called with flag CLONE_UNTRACED, so
883 * we keep the same logic with that option and don't trace it.
885 if ((sysent[tcp->scno].sys_func == sys_clone) &&
886 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
893 bpt = tcp->flags & TCB_BPTSET;
903 return handle_new_child(tcp, pid, bpt);
911 internal_fork(struct tcb *tcp)
913 struct tcb *tcpchild;
918 if (known_scno(tcp) == SYS_vfork) {
919 /* Attempt to make vfork into fork, which we can follow. */
920 if (change_syscall(tcp, SYS_fork) < 0)
934 int bpt = tcp->flags & TCB_BPTSET;
943 tcpchild = alloctcb(pid);
946 /* The child must have run before it can be attached. */
951 select(0, NULL, NULL, NULL, &tv);
953 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
954 perror("PTRACE_ATTACH");
955 fprintf(stderr, "Too late?\n");
960 /* Try to catch the new process as soon as possible. */
963 for (i = 0; i < 1024; i++)
964 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
967 perror("PTRACE_ATTACH");
968 fprintf(stderr, "Too late?\n");
975 tcpchild->flags |= TCB_ATTACHED;
976 /* Child has BPT too, must be removed on first occasion */
978 tcpchild->flags |= TCB_BPTSET;
979 tcpchild->baddr = tcp->baddr;
980 memcpy(tcpchild->inst, tcp->inst,
981 sizeof tcpchild->inst);
983 tcpchild->parent = tcp;
985 fprintf(stderr, "Process %d attached\n", pid);
992 #endif /* !USE_PROCFS */
994 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
997 sys_vfork(struct tcb *tcp)
1000 return RVAL_UDECIMAL;
1004 #endif /* SUNOS4 || LINUX || FREEBSD */
1008 static char idstr[16];
1011 sys_getpid(struct tcb *tcp)
1014 sprintf(idstr, "ppid %lu", getrval2(tcp));
1015 tcp->auxstr = idstr;
1022 sys_getuid(struct tcb *tcp)
1025 sprintf(idstr, "euid %lu", getrval2(tcp));
1026 tcp->auxstr = idstr;
1033 sys_getgid(struct tcb *tcp)
1036 sprintf(idstr, "egid %lu", getrval2(tcp));
1037 tcp->auxstr = idstr;
1047 int sys_getuid(struct tcb *tcp)
1050 tcp->u_rval = (uid_t) tcp->u_rval;
1051 return RVAL_UDECIMAL;
1054 int sys_setfsuid(struct tcb *tcp)
1057 tprintf("%u", (uid_t) tcp->u_arg[0]);
1059 tcp->u_rval = (uid_t) tcp->u_rval;
1060 return RVAL_UDECIMAL;
1064 sys_setuid(struct tcb *tcp)
1066 if (entering(tcp)) {
1067 tprintf("%u", (uid_t) tcp->u_arg[0]);
1073 sys_setgid(struct tcb *tcp)
1075 if (entering(tcp)) {
1076 tprintf("%u", (gid_t) tcp->u_arg[0]);
1082 sys_getresuid(struct tcb *tcp)
1087 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1088 tcp->u_arg[1], tcp->u_arg[2]);
1090 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1091 tprintf("%#lx, ", tcp->u_arg[0]);
1093 tprintf("[%lu], ", (unsigned long) uid);
1094 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1095 tprintf("%#lx, ", tcp->u_arg[1]);
1097 tprintf("[%lu], ", (unsigned long) uid);
1098 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1099 tprintf("%#lx", tcp->u_arg[2]);
1101 tprintf("[%lu]", (unsigned long) uid);
1108 sys_getresgid(struct tcb *tcp)
1113 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1114 tcp->u_arg[1], tcp->u_arg[2]);
1116 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1117 tprintf("%#lx, ", tcp->u_arg[0]);
1119 tprintf("[%lu], ", (unsigned long) gid);
1120 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1121 tprintf("%#lx, ", tcp->u_arg[1]);
1123 tprintf("[%lu], ", (unsigned long) gid);
1124 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1125 tprintf("%#lx", tcp->u_arg[2]);
1127 tprintf("[%lu]", (unsigned long) gid);
1136 sys_setreuid(struct tcb *tcp)
1138 if (entering(tcp)) {
1139 printuid("", tcp->u_arg[0]);
1140 printuid(", ", tcp->u_arg[1]);
1146 sys_setregid(struct tcb *tcp)
1148 if (entering(tcp)) {
1149 printuid("", tcp->u_arg[0]);
1150 printuid(", ", tcp->u_arg[1]);
1155 #if defined(LINUX) || defined(FREEBSD)
1157 sys_setresuid(struct tcb *tcp)
1159 if (entering(tcp)) {
1160 printuid("", tcp->u_arg[0]);
1161 printuid(", ", tcp->u_arg[1]);
1162 printuid(", ", tcp->u_arg[2]);
1167 sys_setresgid(struct tcb *tcp)
1169 if (entering(tcp)) {
1170 printuid("", tcp->u_arg[0]);
1171 printuid(", ", tcp->u_arg[1]);
1172 printuid(", ", tcp->u_arg[2]);
1177 #endif /* LINUX || FREEBSD */
1180 sys_setgroups(struct tcb *tcp)
1182 if (entering(tcp)) {
1183 unsigned long len, size, start, cur, end, abbrev_end;
1187 len = tcp->u_arg[0];
1188 tprintf("%lu, ", len);
1193 start = tcp->u_arg[1];
1198 size = len * sizeof(gid);
1200 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1201 tprintf("%#lx", start);
1205 abbrev_end = start + max_strlen * sizeof(gid);
1206 if (abbrev_end < start)
1212 for (cur = start; cur < end; cur += sizeof(gid)) {
1215 if (cur >= abbrev_end) {
1219 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1224 tprintf("%lu", (unsigned long) gid);
1228 tprintf(" %#lx", tcp->u_arg[1]);
1234 sys_getgroups(struct tcb *tcp)
1238 if (entering(tcp)) {
1239 len = tcp->u_arg[0];
1240 tprintf("%lu, ", len);
1242 unsigned long size, start, cur, end, abbrev_end;
1251 start = tcp->u_arg[1];
1256 if (tcp->u_arg[0] == 0) {
1257 tprintf("%#lx", start);
1260 size = len * sizeof(gid);
1262 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1263 size / sizeof(gid) != len || end < start) {
1264 tprintf("%#lx", start);
1268 abbrev_end = start + max_strlen * sizeof(gid);
1269 if (abbrev_end < start)
1275 for (cur = start; cur < end; cur += sizeof(gid)) {
1278 if (cur >= abbrev_end) {
1282 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1287 tprintf("%lu", (unsigned long) gid);
1291 tprintf(" %#lx", tcp->u_arg[1]);
1298 sys_setgroups32(struct tcb *tcp)
1300 if (entering(tcp)) {
1301 unsigned long len, size, start, cur, end, abbrev_end;
1305 len = tcp->u_arg[0];
1306 tprintf("%lu, ", len);
1311 start = tcp->u_arg[1];
1316 size = len * sizeof(gid);
1318 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1319 tprintf("%#lx", start);
1323 abbrev_end = start + max_strlen * sizeof(gid);
1324 if (abbrev_end < start)
1330 for (cur = start; cur < end; cur += sizeof(gid)) {
1333 if (cur >= abbrev_end) {
1337 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1342 tprintf("%lu", (unsigned long) gid);
1346 tprintf(" %#lx", tcp->u_arg[1]);
1352 sys_getgroups32(struct tcb *tcp)
1356 if (entering(tcp)) {
1357 len = tcp->u_arg[0];
1358 tprintf("%lu, ", len);
1360 unsigned long size, start, cur, end, abbrev_end;
1369 start = tcp->u_arg[1];
1374 size = len * sizeof(gid);
1376 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1377 size / sizeof(gid) != len || end < start) {
1378 tprintf("%#lx", start);
1382 abbrev_end = start + max_strlen * sizeof(gid);
1383 if (abbrev_end < start)
1389 for (cur = start; cur < end; cur += sizeof(gid)) {
1392 if (cur >= abbrev_end) {
1396 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1401 tprintf("%lu", (unsigned long) gid);
1405 tprintf(" %#lx", tcp->u_arg[1]);
1411 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1413 sys_setpgrp(struct tcb *tcp)
1415 if (entering(tcp)) {
1417 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1422 #endif /* ALPHA || SUNOS4 || SVR4 */
1425 sys_getpgrp(struct tcb *tcp)
1427 if (entering(tcp)) {
1429 tprintf("%lu", tcp->u_arg[0]);
1436 sys_getsid(struct tcb *tcp)
1438 if (entering(tcp)) {
1439 tprintf("%lu", tcp->u_arg[0]);
1445 sys_setsid(struct tcb *tcp)
1451 sys_getpgid(struct tcb *tcp)
1453 if (entering(tcp)) {
1454 tprintf("%lu", tcp->u_arg[0]);
1460 sys_setpgid(struct tcb *tcp)
1462 if (entering(tcp)) {
1463 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1470 #include <sys/privilege.h>
1473 static const struct xlat procpriv_cmds[] = {
1474 { SETPRV, "SETPRV" },
1475 { CLRPRV, "CLRPRV" },
1476 { PUTPRV, "PUTPRV" },
1477 { GETPRV, "GETPRV" },
1478 { CNTPRV, "CNTPRV" },
1483 static const struct xlat procpriv_priv[] = {
1484 { P_OWNER, "P_OWNER" },
1485 { P_AUDIT, "P_AUDIT" },
1486 { P_COMPAT, "P_COMPAT" },
1487 { P_DACREAD, "P_DACREAD" },
1488 { P_DACWRITE, "P_DACWRITE" },
1490 { P_FILESYS, "P_FILESYS" },
1491 { P_MACREAD, "P_MACREAD" },
1492 { P_MACWRITE, "P_MACWRITE" },
1493 { P_MOUNT, "P_MOUNT" },
1494 { P_MULTIDIR, "P_MULTIDIR" },
1495 { P_SETPLEVEL, "P_SETPLEVEL" },
1496 { P_SETSPRIV, "P_SETSPRIV" },
1497 { P_SETUID, "P_SETUID" },
1498 { P_SYSOPS, "P_SYSOPS" },
1499 { P_SETUPRIV, "P_SETUPRIV" },
1500 { P_DRIVER, "P_DRIVER" },
1501 { P_RTIME, "P_RTIME" },
1502 { P_MACUPGRADE, "P_MACUPGRADE" },
1503 { P_FSYSRANGE, "P_FSYSRANGE" },
1504 { P_SETFLEVEL, "P_SETFLEVEL" },
1505 { P_AUDITWR, "P_AUDITWR" },
1506 { P_TSHAR, "P_TSHAR" },
1507 { P_PLOCK, "P_PLOCK" },
1508 { P_CORE, "P_CORE" },
1509 { P_LOADMOD, "P_LOADMOD" },
1510 { P_BIND, "P_BIND" },
1511 { P_ALLPRIVS, "P_ALLPRIVS" },
1516 static const struct xlat procpriv_type[] = {
1517 { PS_FIX, "PS_FIX" },
1518 { PS_INH, "PS_INH" },
1519 { PS_MAX, "PS_MAX" },
1520 { PS_WKG, "PS_WKG" },
1526 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1529 int max = verbose(tcp) ? ARRAY_SIZE(buf) : 10;
1530 int dots = len > max;
1533 if (len > max) len = max;
1536 umoven(tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1538 tprintf("%#lx", addr);
1544 for (i = 0; i < len; ++i) {
1547 if (i) tprintf(", ");
1549 if ((t = xlookup(procpriv_type, buf[i] & PS_TYPE)) &&
1550 (p = xlookup(procpriv_priv, buf[i] & ~PS_TYPE)))
1552 tprintf("%s|%s", t, p);
1555 tprintf("%#lx", buf[i]);
1559 if (dots) tprintf(" ...");
1566 sys_procpriv(struct tcb *tcp)
1568 if (entering(tcp)) {
1569 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1570 switch (tcp->u_arg[0]) {
1572 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1580 printpriv(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1581 tprintf(", %ld", tcp->u_arg[2]);
1584 else if (tcp->u_arg[0] == GETPRV) {
1585 if (syserror(tcp)) {
1586 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1590 printpriv(tcp, tcp->u_arg[1], tcp->u_rval);
1591 tprintf(", %ld", tcp->u_arg[2]);
1598 #endif /* UNIXWARE */
1602 printargv(struct tcb *tcp, long addr)
1607 char data[sizeof(long)];
1613 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1614 if (umoven(tcp, addr, personality_wordsize[current_personality],
1616 tprintf("%#lx", addr);
1619 if (personality_wordsize[current_personality] == 4)
1624 printstr(tcp, cp.p64, -1);
1625 addr += personality_wordsize[current_personality];
1628 tprintf("%s...", sep);
1632 printargc(const char *fmt, struct tcb *tcp, long addr)
1637 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1638 addr += sizeof(char *);
1640 tprintf(fmt, count, count == 1 ? "" : "s");
1643 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1645 sys_execv(struct tcb *tcp)
1647 if (entering(tcp)) {
1648 printpath(tcp, tcp->u_arg[0]);
1650 tprintf(", %#lx", tcp->u_arg[1]);
1653 printargv(tcp, tcp->u_arg[1]);
1659 #endif /* SPARC || SPARC64 || SUNOS4 */
1662 sys_execve(struct tcb *tcp)
1664 if (entering(tcp)) {
1665 printpath(tcp, tcp->u_arg[0]);
1667 tprintf(", %#lx", tcp->u_arg[1]);
1670 printargv(tcp, tcp->u_arg[1]);
1674 tprintf(", %#lx", tcp->u_arg[2]);
1675 else if (abbrev(tcp))
1676 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1679 printargv(tcp, tcp->u_arg[2]);
1688 int sys_rexecve(struct tcb *tcp)
1690 if (entering(tcp)) {
1692 tprintf(", %ld", tcp->u_arg[3]);
1700 internal_exec(struct tcb *tcp)
1703 if (exiting(tcp) && !syserror(tcp) && followfork)
1706 #if defined LINUX && defined TCB_WAITEXECVE
1707 if (exiting(tcp) && syserror(tcp))
1708 tcp->flags &= ~TCB_WAITEXECVE;
1710 /* Maybe we have post-execve SIGTRAP suppressed? */
1711 if (!(ptrace_setoptions & PTRACE_O_TRACEEXEC))
1712 tcp->flags |= TCB_WAITEXECVE; /* no */
1714 #endif /* LINUX && TCB_WAITEXECVE */
1720 #define __WNOTHREAD 0x20000000
1723 #define __WALL 0x40000000
1726 #define __WCLONE 0x80000000
1730 static const struct xlat wait4_options[] = {
1731 { WNOHANG, "WNOHANG" },
1733 { WUNTRACED, "WUNTRACED" },
1736 { WEXITED, "WEXITED" },
1739 { WTRAPPED, "WTRAPPED" },
1742 { WSTOPPED, "WSTOPPED" },
1745 { WCONTINUED, "WCONTINUED" },
1748 { WNOWAIT, "WNOWAIT" },
1751 { __WCLONE, "__WCLONE" },
1754 { __WALL, "__WALL" },
1757 { __WNOTHREAD, "__WNOTHREAD" },
1762 #if !defined WCOREFLAG && defined WCOREFLG
1763 # define WCOREFLAG WCOREFLG
1766 # define WCOREFLAG 0x80
1769 # define WCOREDUMP(status) ((status) & 0200)
1774 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1777 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1781 printstatus(int status)
1786 * Here is a tricky presentation problem. This solution
1787 * is still not entirely satisfactory but since there
1788 * are no wait status constructors it will have to do.
1790 if (WIFSTOPPED(status)) {
1791 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1792 signame(WSTOPSIG(status)));
1793 status &= ~W_STOPCODE(WSTOPSIG(status));
1795 else if (WIFSIGNALED(status)) {
1796 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1797 signame(WTERMSIG(status)),
1798 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1799 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1801 else if (WIFEXITED(status)) {
1802 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1803 WEXITSTATUS(status));
1805 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1808 tprintf("[%#x]", status);
1815 tprintf(" | %#x]", status);
1821 printwaitn(struct tcb *tcp, int n, int bitness)
1828 if (entering(tcp)) {
1830 /* On Linux, kernel-side pid_t is typedef'ed to int
1831 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1832 * pid argument to int on 64bit arches, producing,
1833 * for example, wait4(4294967295, ...) instead of -1
1834 * in strace. We have to use int here, not long.
1836 int pid = tcp->u_arg[0];
1837 tprintf("%d, ", pid);
1840 * Sign-extend a 32-bit value when that's what it is.
1842 long pid = tcp->u_arg[0];
1843 if (personality_wordsize[current_personality] < sizeof pid)
1844 pid = (long) (int) pid;
1845 tprintf("%ld, ", pid);
1851 else if (syserror(tcp) || tcp->u_rval == 0)
1852 tprintf("%#lx", tcp->u_arg[1]);
1853 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1859 printstatus(status);
1862 printflags(wait4_options, tcp->u_arg[2], "W???");
1869 else if (tcp->u_rval > 0) {
1872 printrusage32(tcp, tcp->u_arg[3]);
1875 printrusage(tcp, tcp->u_arg[3]);
1879 else if (tcp->u_rval > 0 && exited)
1880 printrusage(tcp, tcp->u_arg[3]);
1883 tprintf("%#lx", tcp->u_arg[3]);
1892 sys_wait(struct tcb *tcp)
1895 /* The library wrapper stuffs this into the user variable. */
1897 printstatus(getrval2(tcp));
1906 sys_wait(struct tcb *tcp)
1911 if (!syserror(tcp)) {
1912 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1913 tprintf("%#lx", tcp->u_arg[0]);
1915 printstatus(status);
1923 sys_waitpid(struct tcb *tcp)
1925 return printwaitn(tcp, 3, 0);
1929 sys_wait4(struct tcb *tcp)
1931 return printwaitn(tcp, 4, 0);
1936 sys_osf_wait4(struct tcb *tcp)
1938 return printwaitn(tcp, 4, 1);
1942 #if defined SVR4 || defined LINUX
1944 static const struct xlat waitid_types[] = {
1947 { P_PPID, "P_PPID" },
1949 { P_PGID, "P_PGID" },
1964 { P_LWPID, "P_LWPID" },
1970 sys_waitid(struct tcb *tcp)
1974 if (entering(tcp)) {
1975 printxval(waitid_types, tcp->u_arg[0], "P_???");
1976 tprintf(", %ld, ", tcp->u_arg[1]);
1982 else if (syserror(tcp))
1983 tprintf("%#lx", tcp->u_arg[2]);
1984 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
1987 printsiginfo(&si, verbose(tcp));
1990 printflags(wait4_options, tcp->u_arg[3], "W???");
1991 if (tcp->u_nargs > 4) {
1996 else if (tcp->u_error)
1997 tprintf("%#lx", tcp->u_arg[4]);
1999 printrusage(tcp, tcp->u_arg[4]);
2005 #endif /* SVR4 or LINUX */
2008 sys_alarm(struct tcb *tcp)
2011 tprintf("%lu", tcp->u_arg[0]);
2016 sys_uname(struct tcb *tcp)
2018 struct utsname uname;
2021 if (syserror(tcp) || !verbose(tcp))
2022 tprintf("%#lx", tcp->u_arg[0]);
2023 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2025 else if (!abbrev(tcp)) {
2027 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2028 uname.sysname, uname.nodename);
2029 tprintf("release=\"%s\", version=\"%s\", ",
2030 uname.release, uname.version);
2031 tprintf("machine=\"%s\"", uname.machine);
2034 tprintf(", domainname=\"%s\"", uname.domainname);
2040 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2041 uname.sysname, uname.nodename);
2048 static const struct xlat ptrace_cmds[] = {
2050 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2051 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2052 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2053 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2054 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2055 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2056 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2057 { PTRACE_CONT, "PTRACE_CONT" },
2058 { PTRACE_KILL, "PTRACE_KILL" },
2059 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2060 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2061 { PTRACE_DETACH, "PTRACE_DETACH" },
2062 # ifdef PTRACE_GETREGS
2063 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2065 # ifdef PTRACE_SETREGS
2066 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2068 # ifdef PTRACE_GETFPREGS
2069 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2071 # ifdef PTRACE_SETFPREGS
2072 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2074 # ifdef PTRACE_GETFPXREGS
2075 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2077 # ifdef PTRACE_SETFPXREGS
2078 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2080 # ifdef PTRACE_GETVRREGS
2081 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2083 # ifdef PTRACE_SETVRREGS
2084 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2086 # ifdef PTRACE_SETOPTIONS
2087 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2089 # ifdef PTRACE_GETEVENTMSG
2090 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2092 # ifdef PTRACE_GETSIGINFO
2093 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2095 # ifdef PTRACE_SETSIGINFO
2096 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2098 # ifdef PTRACE_GETREGSET
2099 { PTRACE_GETREGSET, "PTRACE_GETREGSET", },
2101 # ifdef PTRACE_SETREGSET
2102 { PTRACE_SETREGSET, "PTRACE_SETREGSET", },
2104 # ifdef PTRACE_SET_SYSCALL
2105 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2108 { PTRACE_READDATA, "PTRACE_READDATA" },
2109 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2110 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2111 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2112 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2113 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2115 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2116 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2118 { PTRACE_22, "PTRACE_22" },
2119 { PTRACE_23, "PTRACE_3" },
2120 # endif /* !SPARC */
2121 # endif /* SUNOS4 */
2122 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2124 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2126 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2127 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2128 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2130 { PTRACE_26, "PTRACE_26" },
2131 { PTRACE_27, "PTRACE_27" },
2132 { PTRACE_28, "PTRACE_28" },
2134 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2135 # endif /* SUNOS4 */
2137 # else /* FREEBSD */
2139 { PT_TRACE_ME, "PT_TRACE_ME" },
2140 { PT_READ_I, "PT_READ_I" },
2141 { PT_READ_D, "PT_READ_D" },
2142 { PT_WRITE_I, "PT_WRITE_I" },
2143 { PT_WRITE_D, "PT_WRITE_D" },
2145 { PT_READ_U, "PT_READ_U" },
2147 { PT_CONTINUE, "PT_CONTINUE" },
2148 { PT_KILL, "PT_KILL" },
2149 { PT_STEP, "PT_STEP" },
2150 { PT_ATTACH, "PT_ATTACH" },
2151 { PT_DETACH, "PT_DETACH" },
2152 { PT_GETREGS, "PT_GETREGS" },
2153 { PT_SETREGS, "PT_SETREGS" },
2154 { PT_GETFPREGS, "PT_GETFPREGS" },
2155 { PT_SETFPREGS, "PT_SETFPREGS" },
2156 { PT_GETDBREGS, "PT_GETDBREGS" },
2157 { PT_SETDBREGS, "PT_SETDBREGS" },
2158 # endif /* FREEBSD */
2163 # ifdef PTRACE_SETOPTIONS
2164 static const struct xlat ptrace_setoptions_flags[] = {
2165 # ifdef PTRACE_O_TRACESYSGOOD
2166 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2168 # ifdef PTRACE_O_TRACEFORK
2169 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2171 # ifdef PTRACE_O_TRACEVFORK
2172 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2174 # ifdef PTRACE_O_TRACECLONE
2175 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2177 # ifdef PTRACE_O_TRACEEXEC
2178 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2180 # ifdef PTRACE_O_TRACEVFORKDONE
2181 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2183 # ifdef PTRACE_O_TRACEEXIT
2184 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2188 # endif /* PTRACE_SETOPTIONS */
2189 # endif /* !FREEBSD */
2192 const struct xlat struct_user_offsets[] = {
2194 # if defined(S390) || defined(S390X)
2195 { PT_PSWMASK, "psw_mask" },
2196 { PT_PSWADDR, "psw_addr" },
2197 { PT_GPR0, "gpr0" },
2198 { PT_GPR1, "gpr1" },
2199 { PT_GPR2, "gpr2" },
2200 { PT_GPR3, "gpr3" },
2201 { PT_GPR4, "gpr4" },
2202 { PT_GPR5, "gpr5" },
2203 { PT_GPR6, "gpr6" },
2204 { PT_GPR7, "gpr7" },
2205 { PT_GPR8, "gpr8" },
2206 { PT_GPR9, "gpr9" },
2207 { PT_GPR10, "gpr10" },
2208 { PT_GPR11, "gpr11" },
2209 { PT_GPR12, "gpr12" },
2210 { PT_GPR13, "gpr13" },
2211 { PT_GPR14, "gpr14" },
2212 { PT_GPR15, "gpr15" },
2213 { PT_ACR0, "acr0" },
2214 { PT_ACR1, "acr1" },
2215 { PT_ACR2, "acr2" },
2216 { PT_ACR3, "acr3" },
2217 { PT_ACR4, "acr4" },
2218 { PT_ACR5, "acr5" },
2219 { PT_ACR6, "acr6" },
2220 { PT_ACR7, "acr7" },
2221 { PT_ACR8, "acr8" },
2222 { PT_ACR9, "acr9" },
2223 { PT_ACR10, "acr10" },
2224 { PT_ACR11, "acr11" },
2225 { PT_ACR12, "acr12" },
2226 { PT_ACR13, "acr13" },
2227 { PT_ACR14, "acr14" },
2228 { PT_ACR15, "acr15" },
2229 { PT_ORIGGPR2, "orig_gpr2" },
2232 { PT_FPR0_HI, "fpr0.hi" },
2233 { PT_FPR0_LO, "fpr0.lo" },
2234 { PT_FPR1_HI, "fpr1.hi" },
2235 { PT_FPR1_LO, "fpr1.lo" },
2236 { PT_FPR2_HI, "fpr2.hi" },
2237 { PT_FPR2_LO, "fpr2.lo" },
2238 { PT_FPR3_HI, "fpr3.hi" },
2239 { PT_FPR3_LO, "fpr3.lo" },
2240 { PT_FPR4_HI, "fpr4.hi" },
2241 { PT_FPR4_LO, "fpr4.lo" },
2242 { PT_FPR5_HI, "fpr5.hi" },
2243 { PT_FPR5_LO, "fpr5.lo" },
2244 { PT_FPR6_HI, "fpr6.hi" },
2245 { PT_FPR6_LO, "fpr6.lo" },
2246 { PT_FPR7_HI, "fpr7.hi" },
2247 { PT_FPR7_LO, "fpr7.lo" },
2248 { PT_FPR8_HI, "fpr8.hi" },
2249 { PT_FPR8_LO, "fpr8.lo" },
2250 { PT_FPR9_HI, "fpr9.hi" },
2251 { PT_FPR9_LO, "fpr9.lo" },
2252 { PT_FPR10_HI, "fpr10.hi" },
2253 { PT_FPR10_LO, "fpr10.lo" },
2254 { PT_FPR11_HI, "fpr11.hi" },
2255 { PT_FPR11_LO, "fpr11.lo" },
2256 { PT_FPR12_HI, "fpr12.hi" },
2257 { PT_FPR12_LO, "fpr12.lo" },
2258 { PT_FPR13_HI, "fpr13.hi" },
2259 { PT_FPR13_LO, "fpr13.lo" },
2260 { PT_FPR14_HI, "fpr14.hi" },
2261 { PT_FPR14_LO, "fpr14.lo" },
2262 { PT_FPR15_HI, "fpr15.hi" },
2263 { PT_FPR15_LO, "fpr15.lo" },
2266 { PT_FPR0, "fpr0" },
2267 { PT_FPR1, "fpr1" },
2268 { PT_FPR2, "fpr2" },
2269 { PT_FPR3, "fpr3" },
2270 { PT_FPR4, "fpr4" },
2271 { PT_FPR5, "fpr5" },
2272 { PT_FPR6, "fpr6" },
2273 { PT_FPR7, "fpr7" },
2274 { PT_FPR8, "fpr8" },
2275 { PT_FPR9, "fpr9" },
2276 { PT_FPR10, "fpr10" },
2277 { PT_FPR11, "fpr11" },
2278 { PT_FPR12, "fpr12" },
2279 { PT_FPR13, "fpr13" },
2280 { PT_FPR14, "fpr14" },
2281 { PT_FPR15, "fpr15" },
2284 { PT_CR_10, "cr10" },
2285 { PT_CR_11, "cr11" },
2286 { PT_IEEE_IP, "ieee_exception_ip" },
2287 # elif defined(SPARC)
2288 /* XXX No support for these offsets yet. */
2289 # elif defined(HPPA)
2290 /* XXX No support for these offsets yet. */
2291 # elif defined(POWERPC)
2293 # define PT_ORIG_R3 34
2295 # define REGSIZE (sizeof(unsigned long))
2296 { REGSIZE*PT_R0, "r0" },
2297 { REGSIZE*PT_R1, "r1" },
2298 { REGSIZE*PT_R2, "r2" },
2299 { REGSIZE*PT_R3, "r3" },
2300 { REGSIZE*PT_R4, "r4" },
2301 { REGSIZE*PT_R5, "r5" },
2302 { REGSIZE*PT_R6, "r6" },
2303 { REGSIZE*PT_R7, "r7" },
2304 { REGSIZE*PT_R8, "r8" },
2305 { REGSIZE*PT_R9, "r9" },
2306 { REGSIZE*PT_R10, "r10" },
2307 { REGSIZE*PT_R11, "r11" },
2308 { REGSIZE*PT_R12, "r12" },
2309 { REGSIZE*PT_R13, "r13" },
2310 { REGSIZE*PT_R14, "r14" },
2311 { REGSIZE*PT_R15, "r15" },
2312 { REGSIZE*PT_R16, "r16" },
2313 { REGSIZE*PT_R17, "r17" },
2314 { REGSIZE*PT_R18, "r18" },
2315 { REGSIZE*PT_R19, "r19" },
2316 { REGSIZE*PT_R20, "r20" },
2317 { REGSIZE*PT_R21, "r21" },
2318 { REGSIZE*PT_R22, "r22" },
2319 { REGSIZE*PT_R23, "r23" },
2320 { REGSIZE*PT_R24, "r24" },
2321 { REGSIZE*PT_R25, "r25" },
2322 { REGSIZE*PT_R26, "r26" },
2323 { REGSIZE*PT_R27, "r27" },
2324 { REGSIZE*PT_R28, "r28" },
2325 { REGSIZE*PT_R29, "r29" },
2326 { REGSIZE*PT_R30, "r30" },
2327 { REGSIZE*PT_R31, "r31" },
2328 { REGSIZE*PT_NIP, "NIP" },
2329 { REGSIZE*PT_MSR, "MSR" },
2330 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2331 { REGSIZE*PT_CTR, "CTR" },
2332 { REGSIZE*PT_LNK, "LNK" },
2333 { REGSIZE*PT_XER, "XER" },
2334 { REGSIZE*PT_CCR, "CCR" },
2335 { REGSIZE*PT_FPR0, "FPR0" },
2337 # elif defined(ALPHA)
2403 # elif defined(IA64)
2404 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2405 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2406 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2407 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2408 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2409 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2410 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2411 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2412 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2413 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2414 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2415 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2416 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2417 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2418 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2419 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2420 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2421 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2422 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2423 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2424 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2425 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2426 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2427 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2428 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2429 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2430 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2431 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2432 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2433 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2434 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2435 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2437 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2438 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2439 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2440 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2441 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2442 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2443 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2444 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2445 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2446 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2447 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2448 { PT_B4, "b4" }, { PT_B5, "b5" },
2449 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2451 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2452 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2453 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2454 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2455 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2456 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2457 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2458 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2459 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2460 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2461 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2462 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2463 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2464 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2465 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2466 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2467 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2469 { PT_AR_CSD, "ar.csd" },
2472 { PT_AR_SSD, "ar.ssd" },
2474 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2475 # elif defined(I386)
2487 { 4*ORIG_EAX, "4*ORIG_EAX" },
2491 { 4*UESP, "4*UESP" },
2493 # elif defined(X86_64)
2509 { 8*ORIG_RAX, "8*ORIG_RAX" },
2512 { 8*EFLAGS, "8*EFL" },
2515 # elif defined(M68K)
2516 { 4*PT_D1, "4*PT_D1" },
2517 { 4*PT_D2, "4*PT_D2" },
2518 { 4*PT_D3, "4*PT_D3" },
2519 { 4*PT_D4, "4*PT_D4" },
2520 { 4*PT_D5, "4*PT_D5" },
2521 { 4*PT_D6, "4*PT_D6" },
2522 { 4*PT_D7, "4*PT_D7" },
2523 { 4*PT_A0, "4*PT_A0" },
2524 { 4*PT_A1, "4*PT_A1" },
2525 { 4*PT_A2, "4*PT_A2" },
2526 { 4*PT_A3, "4*PT_A3" },
2527 { 4*PT_A4, "4*PT_A4" },
2528 { 4*PT_A5, "4*PT_A5" },
2529 { 4*PT_A6, "4*PT_A6" },
2530 { 4*PT_D0, "4*PT_D0" },
2531 { 4*PT_USP, "4*PT_USP" },
2532 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2533 { 4*PT_SR, "4*PT_SR" },
2534 { 4*PT_PC, "4*PT_PC" },
2536 { 4*REG_REG0, "4*REG_REG0" },
2537 { 4*(REG_REG0+1), "4*REG_REG1" },
2538 { 4*(REG_REG0+2), "4*REG_REG2" },
2539 { 4*(REG_REG0+3), "4*REG_REG3" },
2540 { 4*(REG_REG0+4), "4*REG_REG4" },
2541 { 4*(REG_REG0+5), "4*REG_REG5" },
2542 { 4*(REG_REG0+6), "4*REG_REG6" },
2543 { 4*(REG_REG0+7), "4*REG_REG7" },
2544 { 4*(REG_REG0+8), "4*REG_REG8" },
2545 { 4*(REG_REG0+9), "4*REG_REG9" },
2546 { 4*(REG_REG0+10), "4*REG_REG10" },
2547 { 4*(REG_REG0+11), "4*REG_REG11" },
2548 { 4*(REG_REG0+12), "4*REG_REG12" },
2549 { 4*(REG_REG0+13), "4*REG_REG13" },
2550 { 4*(REG_REG0+14), "4*REG_REG14" },
2551 { 4*REG_REG15, "4*REG_REG15" },
2552 { 4*REG_PC, "4*REG_PC" },
2553 { 4*REG_PR, "4*REG_PR" },
2554 { 4*REG_SR, "4*REG_SR" },
2555 { 4*REG_GBR, "4*REG_GBR" },
2556 { 4*REG_MACH, "4*REG_MACH" },
2557 { 4*REG_MACL, "4*REG_MACL" },
2558 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2559 { 4*REG_FPUL, "4*REG_FPUL" },
2560 { 4*REG_FPREG0, "4*REG_FPREG0" },
2561 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2562 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2563 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2564 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2565 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2566 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2567 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2568 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2569 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2570 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2571 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2572 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2573 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2574 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2575 { 4*REG_FPREG15, "4*REG_FPREG15" },
2577 { 4*REG_XDREG0, "4*REG_XDREG0" },
2578 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2579 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2580 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2581 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2582 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2583 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2584 { 4*REG_XDREG14, "4*REG_XDREG14" },
2586 { 4*REG_FPSCR, "4*REG_FPSCR" },
2587 # elif defined(SH64)
2592 { 16, "syscall no.(L)" },
2593 { 20, "syscall_no.(U)" },
2736 /* This entry is in case pt_regs contains dregs (depends on
2737 the kernel build options). */
2738 { uoff(regs), "offsetof(struct user, regs)" },
2739 { uoff(fpu), "offsetof(struct user, fpu)" },
2741 { uoff(regs.ARM_r0), "r0" },
2742 { uoff(regs.ARM_r1), "r1" },
2743 { uoff(regs.ARM_r2), "r2" },
2744 { uoff(regs.ARM_r3), "r3" },
2745 { uoff(regs.ARM_r4), "r4" },
2746 { uoff(regs.ARM_r5), "r5" },
2747 { uoff(regs.ARM_r6), "r6" },
2748 { uoff(regs.ARM_r7), "r7" },
2749 { uoff(regs.ARM_r8), "r8" },
2750 { uoff(regs.ARM_r9), "r9" },
2751 { uoff(regs.ARM_r10), "r10" },
2752 { uoff(regs.ARM_fp), "fp" },
2753 { uoff(regs.ARM_ip), "ip" },
2754 { uoff(regs.ARM_sp), "sp" },
2755 { uoff(regs.ARM_lr), "lr" },
2756 { uoff(regs.ARM_pc), "pc" },
2757 { uoff(regs.ARM_cpsr), "cpsr" },
2758 # elif defined(AVR32)
2759 { uoff(regs.sr), "sr" },
2760 { uoff(regs.pc), "pc" },
2761 { uoff(regs.lr), "lr" },
2762 { uoff(regs.sp), "sp" },
2763 { uoff(regs.r12), "r12" },
2764 { uoff(regs.r11), "r11" },
2765 { uoff(regs.r10), "r10" },
2766 { uoff(regs.r9), "r9" },
2767 { uoff(regs.r8), "r8" },
2768 { uoff(regs.r7), "r7" },
2769 { uoff(regs.r6), "r6" },
2770 { uoff(regs.r5), "r5" },
2771 { uoff(regs.r4), "r4" },
2772 { uoff(regs.r3), "r3" },
2773 { uoff(regs.r2), "r2" },
2774 { uoff(regs.r1), "r1" },
2775 { uoff(regs.r0), "r0" },
2776 { uoff(regs.r12_orig), "orig_r12" },
2777 # elif defined(MIPS)
2849 # elif defined(TILE)
2850 { PTREGS_OFFSET_REG(0), "r0" },
2851 { PTREGS_OFFSET_REG(1), "r1" },
2852 { PTREGS_OFFSET_REG(2), "r2" },
2853 { PTREGS_OFFSET_REG(3), "r3" },
2854 { PTREGS_OFFSET_REG(4), "r4" },
2855 { PTREGS_OFFSET_REG(5), "r5" },
2856 { PTREGS_OFFSET_REG(6), "r6" },
2857 { PTREGS_OFFSET_REG(7), "r7" },
2858 { PTREGS_OFFSET_REG(8), "r8" },
2859 { PTREGS_OFFSET_REG(9), "r9" },
2860 { PTREGS_OFFSET_REG(10), "r10" },
2861 { PTREGS_OFFSET_REG(11), "r11" },
2862 { PTREGS_OFFSET_REG(12), "r12" },
2863 { PTREGS_OFFSET_REG(13), "r13" },
2864 { PTREGS_OFFSET_REG(14), "r14" },
2865 { PTREGS_OFFSET_REG(15), "r15" },
2866 { PTREGS_OFFSET_REG(16), "r16" },
2867 { PTREGS_OFFSET_REG(17), "r17" },
2868 { PTREGS_OFFSET_REG(18), "r18" },
2869 { PTREGS_OFFSET_REG(19), "r19" },
2870 { PTREGS_OFFSET_REG(20), "r20" },
2871 { PTREGS_OFFSET_REG(21), "r21" },
2872 { PTREGS_OFFSET_REG(22), "r22" },
2873 { PTREGS_OFFSET_REG(23), "r23" },
2874 { PTREGS_OFFSET_REG(24), "r24" },
2875 { PTREGS_OFFSET_REG(25), "r25" },
2876 { PTREGS_OFFSET_REG(26), "r26" },
2877 { PTREGS_OFFSET_REG(27), "r27" },
2878 { PTREGS_OFFSET_REG(28), "r28" },
2879 { PTREGS_OFFSET_REG(29), "r29" },
2880 { PTREGS_OFFSET_REG(30), "r30" },
2881 { PTREGS_OFFSET_REG(31), "r31" },
2882 { PTREGS_OFFSET_REG(32), "r32" },
2883 { PTREGS_OFFSET_REG(33), "r33" },
2884 { PTREGS_OFFSET_REG(34), "r34" },
2885 { PTREGS_OFFSET_REG(35), "r35" },
2886 { PTREGS_OFFSET_REG(36), "r36" },
2887 { PTREGS_OFFSET_REG(37), "r37" },
2888 { PTREGS_OFFSET_REG(38), "r38" },
2889 { PTREGS_OFFSET_REG(39), "r39" },
2890 { PTREGS_OFFSET_REG(40), "r40" },
2891 { PTREGS_OFFSET_REG(41), "r41" },
2892 { PTREGS_OFFSET_REG(42), "r42" },
2893 { PTREGS_OFFSET_REG(43), "r43" },
2894 { PTREGS_OFFSET_REG(44), "r44" },
2895 { PTREGS_OFFSET_REG(45), "r45" },
2896 { PTREGS_OFFSET_REG(46), "r46" },
2897 { PTREGS_OFFSET_REG(47), "r47" },
2898 { PTREGS_OFFSET_REG(48), "r48" },
2899 { PTREGS_OFFSET_REG(49), "r49" },
2900 { PTREGS_OFFSET_REG(50), "r50" },
2901 { PTREGS_OFFSET_REG(51), "r51" },
2902 { PTREGS_OFFSET_REG(52), "r52" },
2903 { PTREGS_OFFSET_TP, "tp" },
2904 { PTREGS_OFFSET_SP, "sp" },
2905 { PTREGS_OFFSET_LR, "lr" },
2906 { PTREGS_OFFSET_PC, "pc" },
2907 { PTREGS_OFFSET_EX1, "ex1" },
2908 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
2909 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
2910 { PTREGS_OFFSET_FLAGS, "flags" },
2913 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
2914 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
2915 { 4*PT_R13, "4*PT_R13" },
2916 { 4*PT_R12, "4*PT_R12" },
2917 { 4*PT_R11, "4*PT_R11" },
2918 { 4*PT_R10, "4*PT_R10" },
2919 { 4*PT_R9, "4*PT_R9" },
2920 { 4*PT_R8, "4*PT_R8" },
2921 { 4*PT_R7, "4*PT_R7" },
2922 { 4*PT_R6, "4*PT_R6" },
2923 { 4*PT_R5, "4*PT_R5" },
2924 { 4*PT_R4, "4*PT_R4" },
2925 { 4*PT_R3, "4*PT_R3" },
2926 { 4*PT_R2, "4*PT_R2" },
2927 { 4*PT_R1, "4*PT_R1" },
2928 { 4*PT_R0, "4*PT_R0" },
2929 { 4*PT_MOF, "4*PT_MOF" },
2930 { 4*PT_DCCR, "4*PT_DCCR" },
2931 { 4*PT_SRP, "4*PT_SRP" },
2932 { 4*PT_IRP, "4*PT_IRP" },
2933 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
2934 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
2935 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
2936 { 4*PT_USP, "4*PT_USP" },
2939 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
2940 { 4*PT_R0, "4*PT_R0" },
2941 { 4*PT_R1, "4*PT_R1" },
2942 { 4*PT_R2, "4*PT_R2" },
2943 { 4*PT_R3, "4*PT_R3" },
2944 { 4*PT_R4, "4*PT_R4" },
2945 { 4*PT_R5, "4*PT_R5" },
2946 { 4*PT_R6, "4*PT_R6" },
2947 { 4*PT_R7, "4*PT_R7" },
2948 { 4*PT_R8, "4*PT_R8" },
2949 { 4*PT_R9, "4*PT_R9" },
2950 { 4*PT_R10, "4*PT_R10" },
2951 { 4*PT_R11, "4*PT_R11" },
2952 { 4*PT_R12, "4*PT_R12" },
2953 { 4*PT_R13, "4*PT_R13" },
2954 { 4*PT_ACR, "4*PT_ACR" },
2955 { 4*PT_SRS, "4*PT_SRS" },
2956 { 4*PT_MOF, "4*PT_MOF" },
2957 { 4*PT_SPC, "4*PT_SPC" },
2958 { 4*PT_CCS, "4*PT_CCS" },
2959 { 4*PT_SRP, "4*PT_SRP" },
2960 { 4*PT_ERP, "4*PT_ERP" },
2961 { 4*PT_EXS, "4*PT_EXS" },
2962 { 4*PT_EDA, "4*PT_EDA" },
2963 { 4*PT_USP, "4*PT_USP" },
2964 { 4*PT_PPC, "4*PT_PPC" },
2965 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
2966 { 4*PT_BP+4, "4*PT_BP+4" },
2967 { 4*PT_BP+8, "4*PT_BP+8" },
2968 { 4*PT_BP+12, "4*PT_BP+12" },
2969 { 4*PT_BP+16, "4*PT_BP+16" },
2970 { 4*PT_BP+20, "4*PT_BP+20" },
2971 { 4*PT_BP+24, "4*PT_BP+24" },
2972 { 4*PT_BP+28, "4*PT_BP+28" },
2973 { 4*PT_BP+32, "4*PT_BP+32" },
2974 { 4*PT_BP+36, "4*PT_BP+36" },
2975 { 4*PT_BP+40, "4*PT_BP+40" },
2976 { 4*PT_BP+44, "4*PT_BP+44" },
2977 { 4*PT_BP+48, "4*PT_BP+48" },
2978 { 4*PT_BP+52, "4*PT_BP+52" },
2979 { 4*PT_BP+56, "4*PT_BP+56" },
2982 { PT_GPR(0), "r0" },
2983 { PT_GPR(1), "r1" },
2984 { PT_GPR(2), "r2" },
2985 { PT_GPR(3), "r3" },
2986 { PT_GPR(4), "r4" },
2987 { PT_GPR(5), "r5" },
2988 { PT_GPR(6), "r6" },
2989 { PT_GPR(7), "r7" },
2990 { PT_GPR(8), "r8" },
2991 { PT_GPR(9), "r9" },
2992 { PT_GPR(10), "r10" },
2993 { PT_GPR(11), "r11" },
2994 { PT_GPR(12), "r12" },
2995 { PT_GPR(13), "r13" },
2996 { PT_GPR(14), "r14" },
2997 { PT_GPR(15), "r15" },
2998 { PT_GPR(16), "r16" },
2999 { PT_GPR(17), "r17" },
3000 { PT_GPR(18), "r18" },
3001 { PT_GPR(19), "r19" },
3002 { PT_GPR(20), "r20" },
3003 { PT_GPR(21), "r21" },
3004 { PT_GPR(22), "r22" },
3005 { PT_GPR(23), "r23" },
3006 { PT_GPR(24), "r24" },
3007 { PT_GPR(25), "r25" },
3008 { PT_GPR(26), "r26" },
3009 { PT_GPR(27), "r27" },
3010 { PT_GPR(28), "r28" },
3011 { PT_GPR(29), "r29" },
3012 { PT_GPR(30), "r30" },
3013 { PT_GPR(31), "r31" },
3015 { PT_MSR, "rmsr", },
3016 { PT_EAR, "rear", },
3017 { PT_ESR, "resr", },
3018 { PT_FSR, "rfsr", },
3019 { PT_KERNEL_MODE, "kernel_mode", },
3022 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3023 && !defined(ALPHA) && !defined(IA64) \
3024 && !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
3025 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3026 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3028 # if defined(I386) || defined(X86_64)
3029 { uoff(i387), "offsetof(struct user, i387)" },
3032 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3034 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3035 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3036 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3037 # if !defined(SPARC64)
3038 { uoff(start_code), "offsetof(struct user, start_code)" },
3040 # if defined(AVR32) || defined(SH64)
3041 { uoff(start_data), "offsetof(struct user, start_data)" },
3043 # if !defined(SPARC64)
3044 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3046 { uoff(signal), "offsetof(struct user, signal)" },
3047 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3048 { uoff(reserved), "offsetof(struct user, reserved)" },
3050 # if !defined(SPARC64)
3051 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3053 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3054 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3056 { uoff(magic), "offsetof(struct user, magic)" },
3057 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3058 # if defined(I386) || defined(X86_64)
3059 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3061 # endif /* !defined(many arches) */
3066 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3067 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3068 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3069 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3070 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3071 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3072 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3073 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3074 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3075 { uoff(u_error), "offsetof(struct user, u_error)" },
3076 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3077 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3078 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3079 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3080 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3081 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3082 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3083 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3084 { uoff(u_code), "offsetof(struct user, u_code)" },
3085 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3086 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3087 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3088 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3089 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3090 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3091 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3092 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3093 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3094 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3095 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3096 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3097 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3098 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3099 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3100 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3101 { uoff(u_start), "offsetof(struct user, u_start)" },
3102 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3103 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3104 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3105 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3106 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3107 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3108 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3109 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3110 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3111 # endif /* SUNOS4 */
3113 { sizeof(struct user), "sizeof(struct user)" },
3117 # endif /* !FREEBSD */
3120 sys_ptrace(struct tcb *tcp)
3122 const struct xlat *x;
3125 if (entering(tcp)) {
3126 printxval(ptrace_cmds, tcp->u_arg[0],
3133 tprintf(", %lu, ", tcp->u_arg[1]);
3134 addr = tcp->u_arg[2];
3136 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3137 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3138 for (x = struct_user_offsets; x->str; x++) {
3143 tprintf("%#lx, ", addr);
3144 else if (x->val > addr && x != struct_user_offsets) {
3146 tprintf("%s + %ld, ", x->str, addr - x->val);
3149 tprintf("%s, ", x->str);
3153 tprintf("%#lx, ", tcp->u_arg[2]);
3155 switch (tcp->u_arg[0]) {
3157 case PTRACE_PEEKDATA:
3158 case PTRACE_PEEKTEXT:
3159 case PTRACE_PEEKUSER:
3163 case PTRACE_SINGLESTEP:
3164 case PTRACE_SYSCALL:
3166 printsignal(tcp->u_arg[3]);
3168 # ifdef PTRACE_SETOPTIONS
3169 case PTRACE_SETOPTIONS:
3170 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3173 # ifdef PTRACE_SETSIGINFO
3174 case PTRACE_SETSIGINFO: {
3178 else if (syserror(tcp))
3179 tprintf("%#lx", tcp->u_arg[3]);
3180 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3183 printsiginfo(&si, verbose(tcp));
3187 # ifdef PTRACE_GETSIGINFO
3188 case PTRACE_GETSIGINFO:
3189 /* Don't print anything, do it at syscall return. */
3193 tprintf("%#lx", tcp->u_arg[3]);
3197 switch (tcp->u_arg[0]) {
3198 case PTRACE_PEEKDATA:
3199 case PTRACE_PEEKTEXT:
3200 case PTRACE_PEEKUSER:
3204 printnum(tcp, tcp->u_arg[3], "%#lx");
3207 # ifdef PTRACE_GETSIGINFO
3208 case PTRACE_GETSIGINFO: {
3212 else if (syserror(tcp))
3213 tprintf("%#lx", tcp->u_arg[3]);
3214 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3217 printsiginfo(&si, verbose(tcp));
3225 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3226 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3227 tprintf("%lu, ", tcp->u_arg[3]);
3228 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3229 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3230 tcp->u_arg[0] != PTRACE_READTEXT) {
3231 tprintf("%#lx", tcp->u_arg[3]);
3234 if (tcp->u_arg[0] == PTRACE_READDATA ||
3235 tcp->u_arg[0] == PTRACE_READTEXT) {
3236 tprintf("%lu, ", tcp->u_arg[3]);
3237 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3240 # endif /* SUNOS4 */
3242 tprintf("%lu", tcp->u_arg[3]);
3244 # endif /* FREEBSD */
3251 # ifndef FUTEX_CMP_REQUEUE
3252 # define FUTEX_CMP_REQUEUE 4
3254 # ifndef FUTEX_WAKE_OP
3255 # define FUTEX_WAKE_OP 5
3257 # ifndef FUTEX_LOCK_PI
3258 # define FUTEX_LOCK_PI 6
3259 # define FUTEX_UNLOCK_PI 7
3260 # define FUTEX_TRYLOCK_PI 8
3262 # ifndef FUTEX_WAIT_BITSET
3263 # define FUTEX_WAIT_BITSET 9
3265 # ifndef FUTEX_WAKE_BITSET
3266 # define FUTEX_WAKE_BITSET 10
3268 # ifndef FUTEX_WAIT_REQUEUE_PI
3269 # define FUTEX_WAIT_REQUEUE_PI 11
3271 # ifndef FUTEX_CMP_REQUEUE_PI
3272 # define FUTEX_CMP_REQUEUE_PI 12
3274 # ifndef FUTEX_PRIVATE_FLAG
3275 # define FUTEX_PRIVATE_FLAG 128
3277 # ifndef FUTEX_CLOCK_REALTIME
3278 # define FUTEX_CLOCK_REALTIME 256
3280 static const struct xlat futexops[] = {
3281 { FUTEX_WAIT, "FUTEX_WAIT" },
3282 { FUTEX_WAKE, "FUTEX_WAKE" },
3283 { FUTEX_FD, "FUTEX_FD" },
3284 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3285 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3286 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3287 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3288 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3289 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3290 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3291 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3292 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3293 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3294 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3295 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3296 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3297 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3298 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3299 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3300 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3301 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3302 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3303 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3304 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3305 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3306 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3307 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3308 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3309 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3310 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3313 # ifndef FUTEX_OP_SET
3314 # define FUTEX_OP_SET 0
3315 # define FUTEX_OP_ADD 1
3316 # define FUTEX_OP_OR 2
3317 # define FUTEX_OP_ANDN 3
3318 # define FUTEX_OP_XOR 4
3319 # define FUTEX_OP_CMP_EQ 0
3320 # define FUTEX_OP_CMP_NE 1
3321 # define FUTEX_OP_CMP_LT 2
3322 # define FUTEX_OP_CMP_LE 3
3323 # define FUTEX_OP_CMP_GT 4
3324 # define FUTEX_OP_CMP_GE 5
3326 static const struct xlat futexwakeops[] = {
3327 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3328 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3329 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3330 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3331 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3334 static const struct xlat futexwakecmps[] = {
3335 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3336 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3337 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3338 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3339 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3340 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3345 sys_futex(struct tcb *tcp)
3347 if (entering(tcp)) {
3348 long int cmd = tcp->u_arg[1] & 127;
3349 tprintf("%p, ", (void *) tcp->u_arg[0]);
3350 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3351 tprintf(", %ld", tcp->u_arg[2]);
3352 if (cmd == FUTEX_WAKE_BITSET)
3353 tprintf(", %lx", tcp->u_arg[5]);
3354 else if (cmd == FUTEX_WAIT) {
3356 printtv(tcp, tcp->u_arg[3]);
3357 } else if (cmd == FUTEX_WAIT_BITSET) {
3359 printtv(tcp, tcp->u_arg[3]);
3360 tprintf(", %lx", tcp->u_arg[5]);
3361 } else if (cmd == FUTEX_REQUEUE)
3362 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3363 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3364 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3365 else if (cmd == FUTEX_WAKE_OP) {
3366 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3367 if ((tcp->u_arg[5] >> 28) & 8)
3368 tprintf("FUTEX_OP_OPARG_SHIFT|");
3369 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3370 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3371 if ((tcp->u_arg[5] >> 24) & 8)
3372 tprintf("FUTEX_OP_OPARG_SHIFT|");
3373 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3374 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3375 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3377 printtv(tcp, tcp->u_arg[3]);
3378 tprintf(", %p", (void *) tcp->u_arg[4]);
3385 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3388 unsigned long w, min_len;
3390 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3391 min_len = len - max_strlen * sizeof(w);
3394 for (; len >= sizeof(w) && len > min_len;
3395 len -= sizeof(w), list += sizeof(w)) {
3396 if (umove(tcp, list, &w) < 0)
3407 tprintf("%#lx", list);
3409 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3412 tprintf(first ? "{}" : "}");
3417 sys_sched_setaffinity(struct tcb *tcp)
3419 if (entering(tcp)) {
3420 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3421 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3427 sys_sched_getaffinity(struct tcb *tcp)
3429 if (entering(tcp)) {
3430 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3432 if (tcp->u_rval == -1)
3433 tprintf("%#lx", tcp->u_arg[2]);
3435 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3440 static const struct xlat schedulers[] = {
3441 { SCHED_OTHER, "SCHED_OTHER" },
3442 { SCHED_RR, "SCHED_RR" },
3443 { SCHED_FIFO, "SCHED_FIFO" },
3448 sys_sched_getscheduler(struct tcb *tcp)
3450 if (entering(tcp)) {
3451 tprintf("%d", (int) tcp->u_arg[0]);
3452 } else if (! syserror(tcp)) {
3453 tcp->auxstr = xlookup(schedulers, tcp->u_rval);
3454 if (tcp->auxstr != NULL)
3461 sys_sched_setscheduler(struct tcb *tcp)
3463 if (entering(tcp)) {
3464 struct sched_param p;
3465 tprintf("%d, ", (int) tcp->u_arg[0]);
3466 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3467 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3468 tprintf(", %#lx", tcp->u_arg[2]);
3470 tprintf(", { %d }", p.__sched_priority);
3476 sys_sched_getparam(struct tcb *tcp)
3478 if (entering(tcp)) {
3479 tprintf("%d, ", (int) tcp->u_arg[0]);
3481 struct sched_param p;
3482 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3483 tprintf("%#lx", tcp->u_arg[1]);
3485 tprintf("{ %d }", p.__sched_priority);
3491 sys_sched_setparam(struct tcb *tcp)
3493 if (entering(tcp)) {
3494 struct sched_param p;
3495 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3496 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3498 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3504 sys_sched_get_priority_min(struct tcb *tcp)
3506 if (entering(tcp)) {
3507 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3513 # include <asm/prctl.h>
3515 static const struct xlat archvals[] = {
3516 { ARCH_SET_GS, "ARCH_SET_GS" },
3517 { ARCH_SET_FS, "ARCH_SET_FS" },
3518 { ARCH_GET_FS, "ARCH_GET_FS" },
3519 { ARCH_GET_GS, "ARCH_GET_GS" },
3524 sys_arch_prctl(struct tcb *tcp)
3526 if (entering(tcp)) {
3527 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3528 if (tcp->u_arg[0] == ARCH_SET_GS
3529 || tcp->u_arg[0] == ARCH_SET_FS
3531 tprintf(", %#lx", tcp->u_arg[1]);
3534 if (tcp->u_arg[0] == ARCH_GET_GS
3535 || tcp->u_arg[0] == ARCH_GET_FS
3538 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3539 tprintf(", [%#lx]", v);
3541 tprintf(", %#lx", tcp->u_arg[1]);
3546 # endif /* X86_64 */
3550 sys_getcpu(struct tcb *tcp)
3554 if (tcp->u_arg[0] == 0)
3556 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3557 tprintf("%#lx, ", tcp->u_arg[0]);
3559 tprintf("[%u], ", u);
3560 if (tcp->u_arg[1] == 0)
3562 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3563 tprintf("%#lx, ", tcp->u_arg[1]);
3565 tprintf("[%u], ", u);
3566 tprintf("%#lx", tcp->u_arg[2]);