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;
451 /* TCP is creating a child we want to follow.
452 If there will be space in tcbtab for it, set TCB_FOLLOWFORK and return 0.
453 If not, clear TCB_FOLLOWFORK, print an error, and return 1. */
455 fork_tcb(struct tcb *tcp)
457 if (nprocs == tcbtabsize)
460 tcp->flags |= TCB_FOLLOWFORK;
466 sys_fork(struct tcb *tcp)
468 if (exiting(tcp) && !syserror(tcp)) {
470 tcp->auxstr = "child process";
471 return RVAL_UDECIMAL | RVAL_STR;
480 sys_rfork(struct tcb *tcp)
483 tprintf("%ld", tcp->u_arg[0]);
485 else if (!syserror(tcp)) {
487 tcp->auxstr = "child process";
488 return RVAL_UDECIMAL | RVAL_STR;
497 internal_fork(struct tcb *tcp)
499 struct tcb *tcpchild;
503 if (known_scno(tcp) == SYS_rfork && !(tcp->u_arg[0]&RFPROC))
513 tcpchild = alloctcb(tcp->u_rval);
514 if (proc_open(tcpchild, 2) < 0)
520 #else /* !USE_PROCFS */
524 /* defines copied from linux/sched.h since we can't include that
525 * ourselves (it conflicts with *lots* of libc includes)
527 #define CSIGNAL 0x000000ff /* signal mask to be sent at exit */
528 #define CLONE_VM 0x00000100 /* set if VM shared between processes */
529 #define CLONE_FS 0x00000200 /* set if fs info shared between processes */
530 #define CLONE_FILES 0x00000400 /* set if open files shared between processes */
531 #define CLONE_SIGHAND 0x00000800 /* set if signal handlers shared */
532 #define CLONE_IDLETASK 0x00001000 /* kernel-only flag */
533 #define CLONE_PTRACE 0x00002000 /* set if we want to let tracing continue on the child too */
534 #define CLONE_VFORK 0x00004000 /* set if the parent wants the child to wake it up on mm_release */
535 #define CLONE_PARENT 0x00008000 /* set if we want to have the same parent as the cloner */
536 #define CLONE_THREAD 0x00010000 /* Same thread group? */
537 #define CLONE_NEWNS 0x00020000 /* New namespace group? */
538 #define CLONE_SYSVSEM 0x00040000 /* share system V SEM_UNDO semantics */
539 #define CLONE_SETTLS 0x00080000 /* create a new TLS for the child */
540 #define CLONE_PARENT_SETTID 0x00100000 /* set the TID in the parent */
541 #define CLONE_CHILD_CLEARTID 0x00200000 /* clear the TID in the child */
542 #define CLONE_UNTRACED 0x00800000 /* set if the tracing process can't force CLONE_PTRACE on this clone */
543 #define CLONE_CHILD_SETTID 0x01000000 /* set the TID in the child */
544 #define CLONE_STOPPED 0x02000000 /* Start in stopped state */
545 #define CLONE_NEWUTS 0x04000000 /* New utsname group? */
546 #define CLONE_NEWIPC 0x08000000 /* New ipcs */
547 #define CLONE_NEWUSER 0x10000000 /* New user namespace */
548 #define CLONE_NEWPID 0x20000000 /* New pid namespace */
549 #define CLONE_NEWNET 0x40000000 /* New network namespace */
550 #define CLONE_IO 0x80000000 /* Clone io context */
552 static const struct xlat clone_flags[] = {
553 { CLONE_VM, "CLONE_VM" },
554 { CLONE_FS, "CLONE_FS" },
555 { CLONE_FILES, "CLONE_FILES" },
556 { CLONE_SIGHAND, "CLONE_SIGHAND" },
557 { CLONE_IDLETASK, "CLONE_IDLETASK"},
558 { CLONE_PTRACE, "CLONE_PTRACE" },
559 { CLONE_VFORK, "CLONE_VFORK" },
560 { CLONE_PARENT, "CLONE_PARENT" },
561 { CLONE_THREAD, "CLONE_THREAD" },
562 { CLONE_NEWNS, "CLONE_NEWNS" },
563 { CLONE_SYSVSEM, "CLONE_SYSVSEM" },
564 { CLONE_SETTLS, "CLONE_SETTLS" },
565 { CLONE_PARENT_SETTID,"CLONE_PARENT_SETTID" },
566 { CLONE_CHILD_CLEARTID,"CLONE_CHILD_CLEARTID" },
567 { CLONE_UNTRACED, "CLONE_UNTRACED" },
568 { CLONE_CHILD_SETTID,"CLONE_CHILD_SETTID" },
569 { CLONE_STOPPED, "CLONE_STOPPED" },
570 { CLONE_NEWUTS, "CLONE_NEWUTS" },
571 { CLONE_NEWIPC, "CLONE_NEWIPC" },
572 { CLONE_NEWUSER, "CLONE_NEWUSER" },
573 { CLONE_NEWPID, "CLONE_NEWPID" },
574 { CLONE_NEWNET, "CLONE_NEWNET" },
575 { CLONE_IO, "CLONE_IO" },
580 # include <asm/ldt.h>
581 # ifdef HAVE_STRUCT_USER_DESC
582 # define modify_ldt_ldt_s user_desc
584 extern void print_ldt_entry();
590 # define ARG_STACKSIZE (known_scno(tcp) == SYS_clone2 ? 2 : -1)
591 # define ARG_PTID (known_scno(tcp) == SYS_clone2 ? 3 : 2)
592 # define ARG_CTID (known_scno(tcp) == SYS_clone2 ? 4 : 3)
593 # define ARG_TLS (known_scno(tcp) == SYS_clone2 ? 5 : 4)
594 # elif defined S390 || defined S390X || defined CRISV10 || defined CRISV32
600 # elif defined X86_64 || defined ALPHA
615 sys_clone(struct tcb *tcp)
618 const char *sep = "|";
619 unsigned long flags = tcp->u_arg[ARG_FLAGS];
620 tprintf("child_stack=%#lx, ", tcp->u_arg[ARG_STACK]);
621 # ifdef ARG_STACKSIZE
622 if (ARG_STACKSIZE != -1)
623 tprintf("stack_size=%#lx, ",
624 tcp->u_arg[ARG_STACKSIZE]);
627 if (!printflags(clone_flags, flags &~ CSIGNAL, NULL))
629 if ((flags & CSIGNAL) != 0)
630 tprintf("%s%s", sep, signame(flags & CSIGNAL));
631 if ((flags & (CLONE_PARENT_SETTID|CLONE_CHILD_SETTID
632 |CLONE_CHILD_CLEARTID|CLONE_SETTLS)) == 0)
634 if (flags & CLONE_PARENT_SETTID)
635 tprintf(", parent_tidptr=%#lx", tcp->u_arg[ARG_PTID]);
636 if (flags & CLONE_SETTLS) {
638 struct modify_ldt_ldt_s copy;
639 if (umove(tcp, tcp->u_arg[ARG_TLS], ©) != -1) {
640 tprintf(", {entry_number:%d, ",
645 print_ldt_entry(©);
649 tprintf(", tls=%#lx", tcp->u_arg[ARG_TLS]);
651 if (flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID))
652 tprintf(", child_tidptr=%#lx", tcp->u_arg[ARG_CTID]);
658 sys_unshare(struct tcb *tcp)
661 printflags(clone_flags, tcp->u_arg[0], "CLONE_???");
667 sys_fork(struct tcb *tcp)
670 return RVAL_UDECIMAL;
675 change_syscall(struct tcb *tcp, int new)
679 /* Attempt to make vfork into fork, which we can follow. */
680 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_EAX * 4), new) < 0)
683 #elif defined(X86_64)
684 /* Attempt to make vfork into fork, which we can follow. */
685 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(ORIG_RAX * 8), new) < 0)
688 #elif defined(POWERPC)
689 if (ptrace(PTRACE_POKEUSER, tcp->pid,
690 (char*)(sizeof(unsigned long)*PT_R0), new) < 0)
693 #elif defined(S390) || defined(S390X)
694 /* s390 linux after 2.4.7 has a hook in entry.S to allow this */
695 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR2), new) < 0)
699 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_ORIG_D0), new) < 0)
702 #elif defined(SPARC) || defined(SPARC64)
704 if (ptrace(PTRACE_GETREGS, tcp->pid, (char*)®s, 0) < 0)
706 regs.u_regs[U_REG_G1] = new;
707 if (ptrace(PTRACE_SETREGS, tcp->pid, (char*)®s, 0) < 0)
711 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), new) < 0)
715 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), new) < 0)
719 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R8), new) < 0)
723 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_P0), new) < 0)
730 break; /* x86 SYS_fork */
735 fprintf(stderr, "%s: unexpected syscall %d\n",
739 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R1), new) < 0)
741 } else if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R15), new) < 0)
745 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR20), new) < 0)
749 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*(REG_REG0+3)), new) < 0)
753 /* Top half of reg encodes the no. of args n as 0x1n.
754 Assume 0 args as kernel never actually checks... */
755 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_SYSCALL),
759 #elif defined(CRISV10) || defined(CRISV32)
760 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_R9), new) < 0)
764 /* Some kernels support this, some (pre-2.6.16 or so) don't. */
765 # ifndef PTRACE_SET_SYSCALL
766 # define PTRACE_SET_SYSCALL 23
769 if (ptrace(PTRACE_SET_SYSCALL, tcp->pid, 0, new & 0xffff) != 0)
774 if (ptrace(PTRACE_POKEUSER, tcp->pid,
775 (char*)PTREGS_OFFSET_REG(0),
779 #elif defined(MICROBLAZE)
780 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GPR(0)), new) < 0)
784 #warning Do not know how to handle change_syscall for this architecture
785 #endif /* architecture */
792 handle_new_child(struct tcb *tcp, int pid, int bpt)
794 struct tcb *tcpchild;
796 #ifdef CLONE_PTRACE /* See new setbpt code. */
797 tcpchild = pid2tcb(pid);
798 if (tcpchild != NULL) {
799 /* The child already reported its startup trap
800 before the parent reported its syscall return. */
802 & (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
803 != (TCB_STARTUP|TCB_ATTACHED|TCB_SUSPENDED))
805 [preattached child %d of %d in weird state!]\n",
809 #endif /* CLONE_PTRACE */
812 tcpchild = alloctcb(pid);
816 /* Attach to the new child */
817 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) < 0) {
820 perror("PTRACE_ATTACH");
821 fprintf(stderr, "Too late?\n");
825 #endif /* !CLONE_PTRACE */
830 tcpchild->flags |= TCB_ATTACHED;
831 /* Child has BPT too, must be removed on first occasion. */
833 tcpchild->flags |= TCB_BPTSET;
834 tcpchild->baddr = tcp->baddr;
835 memcpy(tcpchild->inst, tcp->inst,
836 sizeof tcpchild->inst);
838 tcpchild->parent = tcp;
839 if (tcpchild->flags & TCB_SUSPENDED) {
840 /* The child was born suspended, due to our having
841 forced CLONE_PTRACE. */
845 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
846 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
851 Process %u resumed (parent %d ready)\n",
856 fprintf(stderr, "Process %d attached\n", pid);
859 #ifdef TCB_CLONE_THREAD
860 if (sysent[tcp->scno].sys_func == sys_clone)
863 * Save the flags used in this call,
864 * in case we point TCP to our parent below.
866 int call_flags = tcp->u_arg[ARG_FLAGS];
867 if ((tcp->flags & TCB_CLONE_THREAD) &&
868 tcp->parent != NULL) {
869 /* The parent in this clone is itself a
870 thread belonging to another process.
871 There is no meaning to the parentage
872 relationship of the new child with the
873 thread, only with the process. We
874 associate the new thread with our
875 parent. Since this is done for every
876 new thread, there will never be a
877 TCB_CLONE_THREAD process that has
880 tcpchild->parent = tcp;
882 if (call_flags & CLONE_THREAD) {
883 tcpchild->flags |= TCB_CLONE_THREAD;
884 ++tcp->nclone_threads;
886 if ((call_flags & CLONE_PARENT) &&
887 !(call_flags & CLONE_THREAD)) {
888 tcpchild->parent = NULL;
889 if (tcp->parent != NULL) {
891 tcpchild->parent = tcp;
895 #endif /* TCB_CLONE_THREAD */
900 internal_fork(struct tcb *tcp)
902 if ((ptrace_setoptions
903 & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
904 == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
908 tcp->flags &= ~TCB_FOLLOWFORK;
912 * In occasion of using PTRACE_O_TRACECLONE, we won't see the
913 * new child if clone is called with flag CLONE_UNTRACED, so
914 * we keep the same logic with that option and don't trace it.
916 if ((sysent[tcp->scno].sys_func == sys_clone) &&
917 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
925 if (!(tcp->flags & TCB_FOLLOWFORK))
928 bpt = tcp->flags & TCB_BPTSET;
938 return handle_new_child(tcp, pid, bpt);
946 internal_fork(struct tcb *tcp)
948 struct tcb *tcpchild;
953 if (known_scno(tcp) == SYS_vfork) {
954 /* Attempt to make vfork into fork, which we can follow. */
955 if (change_syscall(tcp, SYS_fork) < 0)
960 if (!followfork || dont_follow)
966 int bpt = tcp->flags & TCB_BPTSET;
968 if (!(tcp->flags & TCB_FOLLOWFORK))
978 tcpchild = alloctcb(pid);
981 /* The child must have run before it can be attached. */
986 select(0, NULL, NULL, NULL, &tv);
988 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
989 perror("PTRACE_ATTACH");
990 fprintf(stderr, "Too late?\n");
995 /* Try to catch the new process as soon as possible. */
998 for (i = 0; i < 1024; i++)
999 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1002 perror("PTRACE_ATTACH");
1003 fprintf(stderr, "Too late?\n");
1008 #endif /* !oldway */
1010 tcpchild->flags |= TCB_ATTACHED;
1011 /* Child has BPT too, must be removed on first occasion */
1013 tcpchild->flags |= TCB_BPTSET;
1014 tcpchild->baddr = tcp->baddr;
1015 memcpy(tcpchild->inst, tcp->inst,
1016 sizeof tcpchild->inst);
1018 tcpchild->parent = tcp;
1020 fprintf(stderr, "Process %d attached\n", pid);
1027 #endif /* !USE_PROCFS */
1029 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1032 sys_vfork(struct tcb *tcp)
1035 return RVAL_UDECIMAL;
1039 #endif /* SUNOS4 || LINUX || FREEBSD */
1043 static char idstr[16];
1046 sys_getpid(struct tcb *tcp)
1049 sprintf(idstr, "ppid %lu", getrval2(tcp));
1050 tcp->auxstr = idstr;
1057 sys_getuid(struct tcb *tcp)
1060 sprintf(idstr, "euid %lu", getrval2(tcp));
1061 tcp->auxstr = idstr;
1068 sys_getgid(struct tcb *tcp)
1071 sprintf(idstr, "egid %lu", getrval2(tcp));
1072 tcp->auxstr = idstr;
1082 int sys_getuid(struct tcb *tcp)
1085 tcp->u_rval = (uid_t) tcp->u_rval;
1086 return RVAL_UDECIMAL;
1089 int sys_setfsuid(struct tcb *tcp)
1092 tprintf("%u", (uid_t) tcp->u_arg[0]);
1094 tcp->u_rval = (uid_t) tcp->u_rval;
1095 return RVAL_UDECIMAL;
1099 sys_setuid(struct tcb *tcp)
1101 if (entering(tcp)) {
1102 tprintf("%u", (uid_t) tcp->u_arg[0]);
1108 sys_setgid(struct tcb *tcp)
1110 if (entering(tcp)) {
1111 tprintf("%u", (gid_t) tcp->u_arg[0]);
1117 sys_getresuid(struct tcb *tcp)
1122 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1123 tcp->u_arg[1], tcp->u_arg[2]);
1125 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1126 tprintf("%#lx, ", tcp->u_arg[0]);
1128 tprintf("[%lu], ", (unsigned long) uid);
1129 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1130 tprintf("%#lx, ", tcp->u_arg[1]);
1132 tprintf("[%lu], ", (unsigned long) uid);
1133 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1134 tprintf("%#lx", tcp->u_arg[2]);
1136 tprintf("[%lu]", (unsigned long) uid);
1143 sys_getresgid(struct tcb *tcp)
1148 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1149 tcp->u_arg[1], tcp->u_arg[2]);
1151 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1152 tprintf("%#lx, ", tcp->u_arg[0]);
1154 tprintf("[%lu], ", (unsigned long) gid);
1155 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1156 tprintf("%#lx, ", tcp->u_arg[1]);
1158 tprintf("[%lu], ", (unsigned long) gid);
1159 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1160 tprintf("%#lx", tcp->u_arg[2]);
1162 tprintf("[%lu]", (unsigned long) gid);
1171 sys_setreuid(struct tcb *tcp)
1173 if (entering(tcp)) {
1174 printuid("", tcp->u_arg[0]);
1175 printuid(", ", tcp->u_arg[1]);
1181 sys_setregid(struct tcb *tcp)
1183 if (entering(tcp)) {
1184 printuid("", tcp->u_arg[0]);
1185 printuid(", ", tcp->u_arg[1]);
1190 #if defined(LINUX) || defined(FREEBSD)
1192 sys_setresuid(struct tcb *tcp)
1194 if (entering(tcp)) {
1195 printuid("", tcp->u_arg[0]);
1196 printuid(", ", tcp->u_arg[1]);
1197 printuid(", ", tcp->u_arg[2]);
1202 sys_setresgid(struct tcb *tcp)
1204 if (entering(tcp)) {
1205 printuid("", tcp->u_arg[0]);
1206 printuid(", ", tcp->u_arg[1]);
1207 printuid(", ", tcp->u_arg[2]);
1212 #endif /* LINUX || FREEBSD */
1215 sys_setgroups(struct tcb *tcp)
1217 if (entering(tcp)) {
1218 unsigned long len, size, start, cur, end, abbrev_end;
1222 len = tcp->u_arg[0];
1223 tprintf("%lu, ", len);
1228 start = tcp->u_arg[1];
1233 size = len * sizeof(gid);
1235 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1236 tprintf("%#lx", start);
1240 abbrev_end = start + max_strlen * sizeof(gid);
1241 if (abbrev_end < start)
1247 for (cur = start; cur < end; cur += sizeof(gid)) {
1250 if (cur >= abbrev_end) {
1254 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1259 tprintf("%lu", (unsigned long) gid);
1263 tprintf(" %#lx", tcp->u_arg[1]);
1269 sys_getgroups(struct tcb *tcp)
1273 if (entering(tcp)) {
1274 len = tcp->u_arg[0];
1275 tprintf("%lu, ", len);
1277 unsigned long size, start, cur, end, abbrev_end;
1286 start = tcp->u_arg[1];
1291 if (tcp->u_arg[0] == 0) {
1292 tprintf("%#lx", start);
1295 size = len * sizeof(gid);
1297 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1298 size / sizeof(gid) != len || end < start) {
1299 tprintf("%#lx", start);
1303 abbrev_end = start + max_strlen * sizeof(gid);
1304 if (abbrev_end < start)
1310 for (cur = start; cur < end; cur += sizeof(gid)) {
1313 if (cur >= abbrev_end) {
1317 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1322 tprintf("%lu", (unsigned long) gid);
1326 tprintf(" %#lx", tcp->u_arg[1]);
1333 sys_setgroups32(struct tcb *tcp)
1335 if (entering(tcp)) {
1336 unsigned long len, size, start, cur, end, abbrev_end;
1340 len = tcp->u_arg[0];
1341 tprintf("%lu, ", len);
1346 start = tcp->u_arg[1];
1351 size = len * sizeof(gid);
1353 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1354 tprintf("%#lx", start);
1358 abbrev_end = start + max_strlen * sizeof(gid);
1359 if (abbrev_end < start)
1365 for (cur = start; cur < end; cur += sizeof(gid)) {
1368 if (cur >= abbrev_end) {
1372 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1377 tprintf("%lu", (unsigned long) gid);
1381 tprintf(" %#lx", tcp->u_arg[1]);
1387 sys_getgroups32(struct tcb *tcp)
1391 if (entering(tcp)) {
1392 len = tcp->u_arg[0];
1393 tprintf("%lu, ", len);
1395 unsigned long size, start, cur, end, abbrev_end;
1404 start = tcp->u_arg[1];
1409 size = len * sizeof(gid);
1411 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1412 size / sizeof(gid) != len || end < start) {
1413 tprintf("%#lx", start);
1417 abbrev_end = start + max_strlen * sizeof(gid);
1418 if (abbrev_end < start)
1424 for (cur = start; cur < end; cur += sizeof(gid)) {
1427 if (cur >= abbrev_end) {
1431 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1436 tprintf("%lu", (unsigned long) gid);
1440 tprintf(" %#lx", tcp->u_arg[1]);
1446 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1448 sys_setpgrp(struct tcb *tcp)
1450 if (entering(tcp)) {
1452 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1457 #endif /* ALPHA || SUNOS4 || SVR4 */
1460 sys_getpgrp(struct tcb *tcp)
1462 if (entering(tcp)) {
1464 tprintf("%lu", tcp->u_arg[0]);
1471 sys_getsid(struct tcb *tcp)
1473 if (entering(tcp)) {
1474 tprintf("%lu", tcp->u_arg[0]);
1480 sys_setsid(struct tcb *tcp)
1486 sys_getpgid(struct tcb *tcp)
1488 if (entering(tcp)) {
1489 tprintf("%lu", tcp->u_arg[0]);
1495 sys_setpgid(struct tcb *tcp)
1497 if (entering(tcp)) {
1498 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1505 #include <sys/privilege.h>
1508 static const struct xlat procpriv_cmds[] = {
1509 { SETPRV, "SETPRV" },
1510 { CLRPRV, "CLRPRV" },
1511 { PUTPRV, "PUTPRV" },
1512 { GETPRV, "GETPRV" },
1513 { CNTPRV, "CNTPRV" },
1518 static const struct xlat procpriv_priv[] = {
1519 { P_OWNER, "P_OWNER" },
1520 { P_AUDIT, "P_AUDIT" },
1521 { P_COMPAT, "P_COMPAT" },
1522 { P_DACREAD, "P_DACREAD" },
1523 { P_DACWRITE, "P_DACWRITE" },
1525 { P_FILESYS, "P_FILESYS" },
1526 { P_MACREAD, "P_MACREAD" },
1527 { P_MACWRITE, "P_MACWRITE" },
1528 { P_MOUNT, "P_MOUNT" },
1529 { P_MULTIDIR, "P_MULTIDIR" },
1530 { P_SETPLEVEL, "P_SETPLEVEL" },
1531 { P_SETSPRIV, "P_SETSPRIV" },
1532 { P_SETUID, "P_SETUID" },
1533 { P_SYSOPS, "P_SYSOPS" },
1534 { P_SETUPRIV, "P_SETUPRIV" },
1535 { P_DRIVER, "P_DRIVER" },
1536 { P_RTIME, "P_RTIME" },
1537 { P_MACUPGRADE, "P_MACUPGRADE" },
1538 { P_FSYSRANGE, "P_FSYSRANGE" },
1539 { P_SETFLEVEL, "P_SETFLEVEL" },
1540 { P_AUDITWR, "P_AUDITWR" },
1541 { P_TSHAR, "P_TSHAR" },
1542 { P_PLOCK, "P_PLOCK" },
1543 { P_CORE, "P_CORE" },
1544 { P_LOADMOD, "P_LOADMOD" },
1545 { P_BIND, "P_BIND" },
1546 { P_ALLPRIVS, "P_ALLPRIVS" },
1551 static const struct xlat procpriv_type[] = {
1552 { PS_FIX, "PS_FIX" },
1553 { PS_INH, "PS_INH" },
1554 { PS_MAX, "PS_MAX" },
1555 { PS_WKG, "PS_WKG" },
1561 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1564 int max = verbose(tcp) ? ARRAY_SIZE(buf) : 10;
1565 int dots = len > max;
1568 if (len > max) len = max;
1571 umoven(tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1573 tprintf("%#lx", addr);
1579 for (i = 0; i < len; ++i) {
1582 if (i) tprintf(", ");
1584 if ((t = xlookup(procpriv_type, buf[i] & PS_TYPE)) &&
1585 (p = xlookup(procpriv_priv, buf[i] & ~PS_TYPE)))
1587 tprintf("%s|%s", t, p);
1590 tprintf("%#lx", buf[i]);
1594 if (dots) tprintf(" ...");
1601 sys_procpriv(struct tcb *tcp)
1603 if (entering(tcp)) {
1604 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1605 switch (tcp->u_arg[0]) {
1607 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1615 printpriv(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1616 tprintf(", %ld", tcp->u_arg[2]);
1619 else if (tcp->u_arg[0] == GETPRV) {
1620 if (syserror(tcp)) {
1621 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1625 printpriv(tcp, tcp->u_arg[1], tcp->u_rval);
1626 tprintf(", %ld", tcp->u_arg[2]);
1633 #endif /* UNIXWARE */
1637 printargv(struct tcb *tcp, long addr)
1642 char data[sizeof(long)];
1648 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1649 if (umoven(tcp, addr, personality_wordsize[current_personality],
1651 tprintf("%#lx", addr);
1654 if (personality_wordsize[current_personality] == 4)
1659 printstr(tcp, cp.p64, -1);
1660 addr += personality_wordsize[current_personality];
1663 tprintf("%s...", sep);
1667 printargc(const char *fmt, struct tcb *tcp, long addr)
1672 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1673 addr += sizeof(char *);
1675 tprintf(fmt, count, count == 1 ? "" : "s");
1678 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1680 sys_execv(struct tcb *tcp)
1682 if (entering(tcp)) {
1683 printpath(tcp, tcp->u_arg[0]);
1685 tprintf(", %#lx", tcp->u_arg[1]);
1688 printargv(tcp, tcp->u_arg[1]);
1694 #endif /* SPARC || SPARC64 || SUNOS4 */
1697 sys_execve(struct tcb *tcp)
1699 if (entering(tcp)) {
1700 printpath(tcp, tcp->u_arg[0]);
1702 tprintf(", %#lx", tcp->u_arg[1]);
1705 printargv(tcp, tcp->u_arg[1]);
1709 tprintf(", %#lx", tcp->u_arg[2]);
1710 else if (abbrev(tcp))
1711 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1714 printargv(tcp, tcp->u_arg[2]);
1723 int sys_rexecve(struct tcb *tcp)
1725 if (entering(tcp)) {
1727 tprintf(", %ld", tcp->u_arg[3]);
1735 internal_exec(struct tcb *tcp)
1738 if (exiting(tcp) && !syserror(tcp) && followfork)
1741 #if defined LINUX && defined TCB_WAITEXECVE
1742 if (exiting(tcp) && syserror(tcp))
1743 tcp->flags &= ~TCB_WAITEXECVE;
1745 /* Maybe we have post-execve SIGTRAP suppressed? */
1746 if (!(ptrace_setoptions & PTRACE_O_TRACEEXEC))
1747 tcp->flags |= TCB_WAITEXECVE; /* no */
1749 #endif /* LINUX && TCB_WAITEXECVE */
1755 #define __WNOTHREAD 0x20000000
1758 #define __WALL 0x40000000
1761 #define __WCLONE 0x80000000
1765 static const struct xlat wait4_options[] = {
1766 { WNOHANG, "WNOHANG" },
1768 { WUNTRACED, "WUNTRACED" },
1771 { WEXITED, "WEXITED" },
1774 { WTRAPPED, "WTRAPPED" },
1777 { WSTOPPED, "WSTOPPED" },
1780 { WCONTINUED, "WCONTINUED" },
1783 { WNOWAIT, "WNOWAIT" },
1786 { __WCLONE, "__WCLONE" },
1789 { __WALL, "__WALL" },
1792 { __WNOTHREAD, "__WNOTHREAD" },
1797 #if !defined WCOREFLAG && defined WCOREFLG
1798 # define WCOREFLAG WCOREFLG
1801 # define WCOREFLAG 0x80
1804 # define WCOREDUMP(status) ((status) & 0200)
1809 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1812 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1816 printstatus(int status)
1821 * Here is a tricky presentation problem. This solution
1822 * is still not entirely satisfactory but since there
1823 * are no wait status constructors it will have to do.
1825 if (WIFSTOPPED(status)) {
1826 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1827 signame(WSTOPSIG(status)));
1828 status &= ~W_STOPCODE(WSTOPSIG(status));
1830 else if (WIFSIGNALED(status)) {
1831 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1832 signame(WTERMSIG(status)),
1833 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1834 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1836 else if (WIFEXITED(status)) {
1837 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1838 WEXITSTATUS(status));
1840 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1843 tprintf("[%#x]", status);
1850 tprintf(" | %#x]", status);
1856 printwaitn(struct tcb *tcp, int n, int bitness)
1863 if (entering(tcp)) {
1865 /* On Linux, kernel-side pid_t is typedef'ed to int
1866 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1867 * pid argument to int on 64bit arches, producing,
1868 * for example, wait4(4294967295, ...) instead of -1
1869 * in strace. We have to use int here, not long.
1871 int pid = tcp->u_arg[0];
1872 tprintf("%d, ", pid);
1875 * Sign-extend a 32-bit value when that's what it is.
1877 long pid = tcp->u_arg[0];
1878 if (personality_wordsize[current_personality] < sizeof pid)
1879 pid = (long) (int) pid;
1880 tprintf("%ld, ", pid);
1886 else if (syserror(tcp) || tcp->u_rval == 0)
1887 tprintf("%#lx", tcp->u_arg[1]);
1888 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1894 printstatus(status);
1897 printflags(wait4_options, tcp->u_arg[2], "W???");
1904 else if (tcp->u_rval > 0) {
1907 printrusage32(tcp, tcp->u_arg[3]);
1910 printrusage(tcp, tcp->u_arg[3]);
1914 else if (tcp->u_rval > 0 && exited)
1915 printrusage(tcp, tcp->u_arg[3]);
1918 tprintf("%#lx", tcp->u_arg[3]);
1927 sys_wait(struct tcb *tcp)
1930 /* The library wrapper stuffs this into the user variable. */
1932 printstatus(getrval2(tcp));
1941 sys_wait(struct tcb *tcp)
1946 if (!syserror(tcp)) {
1947 if (umove(tcp, tcp->u_arg[0], &status) < 0)
1948 tprintf("%#lx", tcp->u_arg[0]);
1950 printstatus(status);
1958 sys_waitpid(struct tcb *tcp)
1960 return printwaitn(tcp, 3, 0);
1964 sys_wait4(struct tcb *tcp)
1966 return printwaitn(tcp, 4, 0);
1971 sys_osf_wait4(struct tcb *tcp)
1973 return printwaitn(tcp, 4, 1);
1977 #if defined SVR4 || defined LINUX
1979 static const struct xlat waitid_types[] = {
1982 { P_PPID, "P_PPID" },
1984 { P_PGID, "P_PGID" },
1999 { P_LWPID, "P_LWPID" },
2005 sys_waitid(struct tcb *tcp)
2009 if (entering(tcp)) {
2010 printxval(waitid_types, tcp->u_arg[0], "P_???");
2011 tprintf(", %ld, ", tcp->u_arg[1]);
2017 else if (syserror(tcp))
2018 tprintf("%#lx", tcp->u_arg[2]);
2019 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2022 printsiginfo(&si, verbose(tcp));
2025 printflags(wait4_options, tcp->u_arg[3], "W???");
2026 if (tcp->u_nargs > 4) {
2031 else if (tcp->u_error)
2032 tprintf("%#lx", tcp->u_arg[4]);
2034 printrusage(tcp, tcp->u_arg[4]);
2040 #endif /* SVR4 or LINUX */
2043 sys_alarm(struct tcb *tcp)
2046 tprintf("%lu", tcp->u_arg[0]);
2051 sys_uname(struct tcb *tcp)
2053 struct utsname uname;
2056 if (syserror(tcp) || !verbose(tcp))
2057 tprintf("%#lx", tcp->u_arg[0]);
2058 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2060 else if (!abbrev(tcp)) {
2062 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2063 uname.sysname, uname.nodename);
2064 tprintf("release=\"%s\", version=\"%s\", ",
2065 uname.release, uname.version);
2066 tprintf("machine=\"%s\"", uname.machine);
2069 tprintf(", domainname=\"%s\"", uname.domainname);
2075 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2076 uname.sysname, uname.nodename);
2083 static const struct xlat ptrace_cmds[] = {
2085 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2086 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2087 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2088 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2089 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2090 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2091 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2092 { PTRACE_CONT, "PTRACE_CONT" },
2093 { PTRACE_KILL, "PTRACE_KILL" },
2094 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2095 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2096 { PTRACE_DETACH, "PTRACE_DETACH" },
2097 # ifdef PTRACE_GETREGS
2098 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2100 # ifdef PTRACE_SETREGS
2101 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2103 # ifdef PTRACE_GETFPREGS
2104 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2106 # ifdef PTRACE_SETFPREGS
2107 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2109 # ifdef PTRACE_GETFPXREGS
2110 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2112 # ifdef PTRACE_SETFPXREGS
2113 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2115 # ifdef PTRACE_GETVRREGS
2116 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2118 # ifdef PTRACE_SETVRREGS
2119 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2121 # ifdef PTRACE_SETOPTIONS
2122 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2124 # ifdef PTRACE_GETEVENTMSG
2125 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2127 # ifdef PTRACE_GETSIGINFO
2128 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2130 # ifdef PTRACE_SETSIGINFO
2131 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2133 # ifdef PTRACE_GETREGSET
2134 { PTRACE_GETREGSET, "PTRACE_GETREGSET", },
2136 # ifdef PTRACE_SETREGSET
2137 { PTRACE_SETREGSET, "PTRACE_SETREGSET", },
2139 # ifdef PTRACE_SET_SYSCALL
2140 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2143 { PTRACE_READDATA, "PTRACE_READDATA" },
2144 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2145 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2146 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2147 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2148 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2150 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2151 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2153 { PTRACE_22, "PTRACE_22" },
2154 { PTRACE_23, "PTRACE_3" },
2155 # endif /* !SPARC */
2156 # endif /* SUNOS4 */
2157 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2159 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2161 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2162 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2163 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2165 { PTRACE_26, "PTRACE_26" },
2166 { PTRACE_27, "PTRACE_27" },
2167 { PTRACE_28, "PTRACE_28" },
2169 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2170 # endif /* SUNOS4 */
2172 # else /* FREEBSD */
2174 { PT_TRACE_ME, "PT_TRACE_ME" },
2175 { PT_READ_I, "PT_READ_I" },
2176 { PT_READ_D, "PT_READ_D" },
2177 { PT_WRITE_I, "PT_WRITE_I" },
2178 { PT_WRITE_D, "PT_WRITE_D" },
2180 { PT_READ_U, "PT_READ_U" },
2182 { PT_CONTINUE, "PT_CONTINUE" },
2183 { PT_KILL, "PT_KILL" },
2184 { PT_STEP, "PT_STEP" },
2185 { PT_ATTACH, "PT_ATTACH" },
2186 { PT_DETACH, "PT_DETACH" },
2187 { PT_GETREGS, "PT_GETREGS" },
2188 { PT_SETREGS, "PT_SETREGS" },
2189 { PT_GETFPREGS, "PT_GETFPREGS" },
2190 { PT_SETFPREGS, "PT_SETFPREGS" },
2191 { PT_GETDBREGS, "PT_GETDBREGS" },
2192 { PT_SETDBREGS, "PT_SETDBREGS" },
2193 # endif /* FREEBSD */
2198 # ifdef PTRACE_SETOPTIONS
2199 static const struct xlat ptrace_setoptions_flags[] = {
2200 # ifdef PTRACE_O_TRACESYSGOOD
2201 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2203 # ifdef PTRACE_O_TRACEFORK
2204 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2206 # ifdef PTRACE_O_TRACEVFORK
2207 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2209 # ifdef PTRACE_O_TRACECLONE
2210 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2212 # ifdef PTRACE_O_TRACEEXEC
2213 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2215 # ifdef PTRACE_O_TRACEVFORKDONE
2216 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2218 # ifdef PTRACE_O_TRACEEXIT
2219 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2223 # endif /* PTRACE_SETOPTIONS */
2224 # endif /* !FREEBSD */
2227 const struct xlat struct_user_offsets[] = {
2229 # if defined(S390) || defined(S390X)
2230 { PT_PSWMASK, "psw_mask" },
2231 { PT_PSWADDR, "psw_addr" },
2232 { PT_GPR0, "gpr0" },
2233 { PT_GPR1, "gpr1" },
2234 { PT_GPR2, "gpr2" },
2235 { PT_GPR3, "gpr3" },
2236 { PT_GPR4, "gpr4" },
2237 { PT_GPR5, "gpr5" },
2238 { PT_GPR6, "gpr6" },
2239 { PT_GPR7, "gpr7" },
2240 { PT_GPR8, "gpr8" },
2241 { PT_GPR9, "gpr9" },
2242 { PT_GPR10, "gpr10" },
2243 { PT_GPR11, "gpr11" },
2244 { PT_GPR12, "gpr12" },
2245 { PT_GPR13, "gpr13" },
2246 { PT_GPR14, "gpr14" },
2247 { PT_GPR15, "gpr15" },
2248 { PT_ACR0, "acr0" },
2249 { PT_ACR1, "acr1" },
2250 { PT_ACR2, "acr2" },
2251 { PT_ACR3, "acr3" },
2252 { PT_ACR4, "acr4" },
2253 { PT_ACR5, "acr5" },
2254 { PT_ACR6, "acr6" },
2255 { PT_ACR7, "acr7" },
2256 { PT_ACR8, "acr8" },
2257 { PT_ACR9, "acr9" },
2258 { PT_ACR10, "acr10" },
2259 { PT_ACR11, "acr11" },
2260 { PT_ACR12, "acr12" },
2261 { PT_ACR13, "acr13" },
2262 { PT_ACR14, "acr14" },
2263 { PT_ACR15, "acr15" },
2264 { PT_ORIGGPR2, "orig_gpr2" },
2267 { PT_FPR0_HI, "fpr0.hi" },
2268 { PT_FPR0_LO, "fpr0.lo" },
2269 { PT_FPR1_HI, "fpr1.hi" },
2270 { PT_FPR1_LO, "fpr1.lo" },
2271 { PT_FPR2_HI, "fpr2.hi" },
2272 { PT_FPR2_LO, "fpr2.lo" },
2273 { PT_FPR3_HI, "fpr3.hi" },
2274 { PT_FPR3_LO, "fpr3.lo" },
2275 { PT_FPR4_HI, "fpr4.hi" },
2276 { PT_FPR4_LO, "fpr4.lo" },
2277 { PT_FPR5_HI, "fpr5.hi" },
2278 { PT_FPR5_LO, "fpr5.lo" },
2279 { PT_FPR6_HI, "fpr6.hi" },
2280 { PT_FPR6_LO, "fpr6.lo" },
2281 { PT_FPR7_HI, "fpr7.hi" },
2282 { PT_FPR7_LO, "fpr7.lo" },
2283 { PT_FPR8_HI, "fpr8.hi" },
2284 { PT_FPR8_LO, "fpr8.lo" },
2285 { PT_FPR9_HI, "fpr9.hi" },
2286 { PT_FPR9_LO, "fpr9.lo" },
2287 { PT_FPR10_HI, "fpr10.hi" },
2288 { PT_FPR10_LO, "fpr10.lo" },
2289 { PT_FPR11_HI, "fpr11.hi" },
2290 { PT_FPR11_LO, "fpr11.lo" },
2291 { PT_FPR12_HI, "fpr12.hi" },
2292 { PT_FPR12_LO, "fpr12.lo" },
2293 { PT_FPR13_HI, "fpr13.hi" },
2294 { PT_FPR13_LO, "fpr13.lo" },
2295 { PT_FPR14_HI, "fpr14.hi" },
2296 { PT_FPR14_LO, "fpr14.lo" },
2297 { PT_FPR15_HI, "fpr15.hi" },
2298 { PT_FPR15_LO, "fpr15.lo" },
2301 { PT_FPR0, "fpr0" },
2302 { PT_FPR1, "fpr1" },
2303 { PT_FPR2, "fpr2" },
2304 { PT_FPR3, "fpr3" },
2305 { PT_FPR4, "fpr4" },
2306 { PT_FPR5, "fpr5" },
2307 { PT_FPR6, "fpr6" },
2308 { PT_FPR7, "fpr7" },
2309 { PT_FPR8, "fpr8" },
2310 { PT_FPR9, "fpr9" },
2311 { PT_FPR10, "fpr10" },
2312 { PT_FPR11, "fpr11" },
2313 { PT_FPR12, "fpr12" },
2314 { PT_FPR13, "fpr13" },
2315 { PT_FPR14, "fpr14" },
2316 { PT_FPR15, "fpr15" },
2319 { PT_CR_10, "cr10" },
2320 { PT_CR_11, "cr11" },
2321 { PT_IEEE_IP, "ieee_exception_ip" },
2322 # elif defined(SPARC)
2323 /* XXX No support for these offsets yet. */
2324 # elif defined(HPPA)
2325 /* XXX No support for these offsets yet. */
2326 # elif defined(POWERPC)
2328 # define PT_ORIG_R3 34
2330 # define REGSIZE (sizeof(unsigned long))
2331 { REGSIZE*PT_R0, "r0" },
2332 { REGSIZE*PT_R1, "r1" },
2333 { REGSIZE*PT_R2, "r2" },
2334 { REGSIZE*PT_R3, "r3" },
2335 { REGSIZE*PT_R4, "r4" },
2336 { REGSIZE*PT_R5, "r5" },
2337 { REGSIZE*PT_R6, "r6" },
2338 { REGSIZE*PT_R7, "r7" },
2339 { REGSIZE*PT_R8, "r8" },
2340 { REGSIZE*PT_R9, "r9" },
2341 { REGSIZE*PT_R10, "r10" },
2342 { REGSIZE*PT_R11, "r11" },
2343 { REGSIZE*PT_R12, "r12" },
2344 { REGSIZE*PT_R13, "r13" },
2345 { REGSIZE*PT_R14, "r14" },
2346 { REGSIZE*PT_R15, "r15" },
2347 { REGSIZE*PT_R16, "r16" },
2348 { REGSIZE*PT_R17, "r17" },
2349 { REGSIZE*PT_R18, "r18" },
2350 { REGSIZE*PT_R19, "r19" },
2351 { REGSIZE*PT_R20, "r20" },
2352 { REGSIZE*PT_R21, "r21" },
2353 { REGSIZE*PT_R22, "r22" },
2354 { REGSIZE*PT_R23, "r23" },
2355 { REGSIZE*PT_R24, "r24" },
2356 { REGSIZE*PT_R25, "r25" },
2357 { REGSIZE*PT_R26, "r26" },
2358 { REGSIZE*PT_R27, "r27" },
2359 { REGSIZE*PT_R28, "r28" },
2360 { REGSIZE*PT_R29, "r29" },
2361 { REGSIZE*PT_R30, "r30" },
2362 { REGSIZE*PT_R31, "r31" },
2363 { REGSIZE*PT_NIP, "NIP" },
2364 { REGSIZE*PT_MSR, "MSR" },
2365 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2366 { REGSIZE*PT_CTR, "CTR" },
2367 { REGSIZE*PT_LNK, "LNK" },
2368 { REGSIZE*PT_XER, "XER" },
2369 { REGSIZE*PT_CCR, "CCR" },
2370 { REGSIZE*PT_FPR0, "FPR0" },
2372 # elif defined(ALPHA)
2438 # elif defined(IA64)
2439 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2440 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2441 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2442 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2443 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2444 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2445 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2446 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2447 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2448 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2449 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2450 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2451 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2452 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2453 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2454 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2455 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2456 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2457 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2458 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2459 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2460 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2461 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2462 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2463 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2464 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2465 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2466 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2467 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2468 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2469 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2470 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2472 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2473 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2474 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2475 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2476 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2477 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2478 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2479 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2480 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2481 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2482 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2483 { PT_B4, "b4" }, { PT_B5, "b5" },
2484 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2486 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2487 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2488 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2489 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2490 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2491 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2492 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2493 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2494 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2495 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2496 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2497 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2498 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2499 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2500 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2501 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2502 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2504 { PT_AR_CSD, "ar.csd" },
2507 { PT_AR_SSD, "ar.ssd" },
2509 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2510 # elif defined(I386)
2522 { 4*ORIG_EAX, "4*ORIG_EAX" },
2526 { 4*UESP, "4*UESP" },
2528 # elif defined(X86_64)
2544 { 8*ORIG_RAX, "8*ORIG_RAX" },
2547 { 8*EFLAGS, "8*EFL" },
2550 # elif defined(M68K)
2551 { 4*PT_D1, "4*PT_D1" },
2552 { 4*PT_D2, "4*PT_D2" },
2553 { 4*PT_D3, "4*PT_D3" },
2554 { 4*PT_D4, "4*PT_D4" },
2555 { 4*PT_D5, "4*PT_D5" },
2556 { 4*PT_D6, "4*PT_D6" },
2557 { 4*PT_D7, "4*PT_D7" },
2558 { 4*PT_A0, "4*PT_A0" },
2559 { 4*PT_A1, "4*PT_A1" },
2560 { 4*PT_A2, "4*PT_A2" },
2561 { 4*PT_A3, "4*PT_A3" },
2562 { 4*PT_A4, "4*PT_A4" },
2563 { 4*PT_A5, "4*PT_A5" },
2564 { 4*PT_A6, "4*PT_A6" },
2565 { 4*PT_D0, "4*PT_D0" },
2566 { 4*PT_USP, "4*PT_USP" },
2567 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2568 { 4*PT_SR, "4*PT_SR" },
2569 { 4*PT_PC, "4*PT_PC" },
2571 { 4*REG_REG0, "4*REG_REG0" },
2572 { 4*(REG_REG0+1), "4*REG_REG1" },
2573 { 4*(REG_REG0+2), "4*REG_REG2" },
2574 { 4*(REG_REG0+3), "4*REG_REG3" },
2575 { 4*(REG_REG0+4), "4*REG_REG4" },
2576 { 4*(REG_REG0+5), "4*REG_REG5" },
2577 { 4*(REG_REG0+6), "4*REG_REG6" },
2578 { 4*(REG_REG0+7), "4*REG_REG7" },
2579 { 4*(REG_REG0+8), "4*REG_REG8" },
2580 { 4*(REG_REG0+9), "4*REG_REG9" },
2581 { 4*(REG_REG0+10), "4*REG_REG10" },
2582 { 4*(REG_REG0+11), "4*REG_REG11" },
2583 { 4*(REG_REG0+12), "4*REG_REG12" },
2584 { 4*(REG_REG0+13), "4*REG_REG13" },
2585 { 4*(REG_REG0+14), "4*REG_REG14" },
2586 { 4*REG_REG15, "4*REG_REG15" },
2587 { 4*REG_PC, "4*REG_PC" },
2588 { 4*REG_PR, "4*REG_PR" },
2589 { 4*REG_SR, "4*REG_SR" },
2590 { 4*REG_GBR, "4*REG_GBR" },
2591 { 4*REG_MACH, "4*REG_MACH" },
2592 { 4*REG_MACL, "4*REG_MACL" },
2593 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2594 { 4*REG_FPUL, "4*REG_FPUL" },
2595 { 4*REG_FPREG0, "4*REG_FPREG0" },
2596 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2597 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2598 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2599 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2600 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2601 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2602 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2603 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2604 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2605 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2606 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2607 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2608 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2609 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2610 { 4*REG_FPREG15, "4*REG_FPREG15" },
2612 { 4*REG_XDREG0, "4*REG_XDREG0" },
2613 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2614 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2615 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2616 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2617 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2618 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2619 { 4*REG_XDREG14, "4*REG_XDREG14" },
2621 { 4*REG_FPSCR, "4*REG_FPSCR" },
2622 # elif defined(SH64)
2627 { 16, "syscall no.(L)" },
2628 { 20, "syscall_no.(U)" },
2771 /* This entry is in case pt_regs contains dregs (depends on
2772 the kernel build options). */
2773 { uoff(regs), "offsetof(struct user, regs)" },
2774 { uoff(fpu), "offsetof(struct user, fpu)" },
2776 { uoff(regs.ARM_r0), "r0" },
2777 { uoff(regs.ARM_r1), "r1" },
2778 { uoff(regs.ARM_r2), "r2" },
2779 { uoff(regs.ARM_r3), "r3" },
2780 { uoff(regs.ARM_r4), "r4" },
2781 { uoff(regs.ARM_r5), "r5" },
2782 { uoff(regs.ARM_r6), "r6" },
2783 { uoff(regs.ARM_r7), "r7" },
2784 { uoff(regs.ARM_r8), "r8" },
2785 { uoff(regs.ARM_r9), "r9" },
2786 { uoff(regs.ARM_r10), "r10" },
2787 { uoff(regs.ARM_fp), "fp" },
2788 { uoff(regs.ARM_ip), "ip" },
2789 { uoff(regs.ARM_sp), "sp" },
2790 { uoff(regs.ARM_lr), "lr" },
2791 { uoff(regs.ARM_pc), "pc" },
2792 { uoff(regs.ARM_cpsr), "cpsr" },
2793 # elif defined(AVR32)
2794 { uoff(regs.sr), "sr" },
2795 { uoff(regs.pc), "pc" },
2796 { uoff(regs.lr), "lr" },
2797 { uoff(regs.sp), "sp" },
2798 { uoff(regs.r12), "r12" },
2799 { uoff(regs.r11), "r11" },
2800 { uoff(regs.r10), "r10" },
2801 { uoff(regs.r9), "r9" },
2802 { uoff(regs.r8), "r8" },
2803 { uoff(regs.r7), "r7" },
2804 { uoff(regs.r6), "r6" },
2805 { uoff(regs.r5), "r5" },
2806 { uoff(regs.r4), "r4" },
2807 { uoff(regs.r3), "r3" },
2808 { uoff(regs.r2), "r2" },
2809 { uoff(regs.r1), "r1" },
2810 { uoff(regs.r0), "r0" },
2811 { uoff(regs.r12_orig), "orig_r12" },
2812 # elif defined(MIPS)
2884 # elif defined(TILE)
2885 { PTREGS_OFFSET_REG(0), "r0" },
2886 { PTREGS_OFFSET_REG(1), "r1" },
2887 { PTREGS_OFFSET_REG(2), "r2" },
2888 { PTREGS_OFFSET_REG(3), "r3" },
2889 { PTREGS_OFFSET_REG(4), "r4" },
2890 { PTREGS_OFFSET_REG(5), "r5" },
2891 { PTREGS_OFFSET_REG(6), "r6" },
2892 { PTREGS_OFFSET_REG(7), "r7" },
2893 { PTREGS_OFFSET_REG(8), "r8" },
2894 { PTREGS_OFFSET_REG(9), "r9" },
2895 { PTREGS_OFFSET_REG(10), "r10" },
2896 { PTREGS_OFFSET_REG(11), "r11" },
2897 { PTREGS_OFFSET_REG(12), "r12" },
2898 { PTREGS_OFFSET_REG(13), "r13" },
2899 { PTREGS_OFFSET_REG(14), "r14" },
2900 { PTREGS_OFFSET_REG(15), "r15" },
2901 { PTREGS_OFFSET_REG(16), "r16" },
2902 { PTREGS_OFFSET_REG(17), "r17" },
2903 { PTREGS_OFFSET_REG(18), "r18" },
2904 { PTREGS_OFFSET_REG(19), "r19" },
2905 { PTREGS_OFFSET_REG(20), "r20" },
2906 { PTREGS_OFFSET_REG(21), "r21" },
2907 { PTREGS_OFFSET_REG(22), "r22" },
2908 { PTREGS_OFFSET_REG(23), "r23" },
2909 { PTREGS_OFFSET_REG(24), "r24" },
2910 { PTREGS_OFFSET_REG(25), "r25" },
2911 { PTREGS_OFFSET_REG(26), "r26" },
2912 { PTREGS_OFFSET_REG(27), "r27" },
2913 { PTREGS_OFFSET_REG(28), "r28" },
2914 { PTREGS_OFFSET_REG(29), "r29" },
2915 { PTREGS_OFFSET_REG(30), "r30" },
2916 { PTREGS_OFFSET_REG(31), "r31" },
2917 { PTREGS_OFFSET_REG(32), "r32" },
2918 { PTREGS_OFFSET_REG(33), "r33" },
2919 { PTREGS_OFFSET_REG(34), "r34" },
2920 { PTREGS_OFFSET_REG(35), "r35" },
2921 { PTREGS_OFFSET_REG(36), "r36" },
2922 { PTREGS_OFFSET_REG(37), "r37" },
2923 { PTREGS_OFFSET_REG(38), "r38" },
2924 { PTREGS_OFFSET_REG(39), "r39" },
2925 { PTREGS_OFFSET_REG(40), "r40" },
2926 { PTREGS_OFFSET_REG(41), "r41" },
2927 { PTREGS_OFFSET_REG(42), "r42" },
2928 { PTREGS_OFFSET_REG(43), "r43" },
2929 { PTREGS_OFFSET_REG(44), "r44" },
2930 { PTREGS_OFFSET_REG(45), "r45" },
2931 { PTREGS_OFFSET_REG(46), "r46" },
2932 { PTREGS_OFFSET_REG(47), "r47" },
2933 { PTREGS_OFFSET_REG(48), "r48" },
2934 { PTREGS_OFFSET_REG(49), "r49" },
2935 { PTREGS_OFFSET_REG(50), "r50" },
2936 { PTREGS_OFFSET_REG(51), "r51" },
2937 { PTREGS_OFFSET_REG(52), "r52" },
2938 { PTREGS_OFFSET_TP, "tp" },
2939 { PTREGS_OFFSET_SP, "sp" },
2940 { PTREGS_OFFSET_LR, "lr" },
2941 { PTREGS_OFFSET_PC, "pc" },
2942 { PTREGS_OFFSET_EX1, "ex1" },
2943 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
2944 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
2945 { PTREGS_OFFSET_FLAGS, "flags" },
2948 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
2949 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
2950 { 4*PT_R13, "4*PT_R13" },
2951 { 4*PT_R12, "4*PT_R12" },
2952 { 4*PT_R11, "4*PT_R11" },
2953 { 4*PT_R10, "4*PT_R10" },
2954 { 4*PT_R9, "4*PT_R9" },
2955 { 4*PT_R8, "4*PT_R8" },
2956 { 4*PT_R7, "4*PT_R7" },
2957 { 4*PT_R6, "4*PT_R6" },
2958 { 4*PT_R5, "4*PT_R5" },
2959 { 4*PT_R4, "4*PT_R4" },
2960 { 4*PT_R3, "4*PT_R3" },
2961 { 4*PT_R2, "4*PT_R2" },
2962 { 4*PT_R1, "4*PT_R1" },
2963 { 4*PT_R0, "4*PT_R0" },
2964 { 4*PT_MOF, "4*PT_MOF" },
2965 { 4*PT_DCCR, "4*PT_DCCR" },
2966 { 4*PT_SRP, "4*PT_SRP" },
2967 { 4*PT_IRP, "4*PT_IRP" },
2968 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
2969 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
2970 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
2971 { 4*PT_USP, "4*PT_USP" },
2974 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
2975 { 4*PT_R0, "4*PT_R0" },
2976 { 4*PT_R1, "4*PT_R1" },
2977 { 4*PT_R2, "4*PT_R2" },
2978 { 4*PT_R3, "4*PT_R3" },
2979 { 4*PT_R4, "4*PT_R4" },
2980 { 4*PT_R5, "4*PT_R5" },
2981 { 4*PT_R6, "4*PT_R6" },
2982 { 4*PT_R7, "4*PT_R7" },
2983 { 4*PT_R8, "4*PT_R8" },
2984 { 4*PT_R9, "4*PT_R9" },
2985 { 4*PT_R10, "4*PT_R10" },
2986 { 4*PT_R11, "4*PT_R11" },
2987 { 4*PT_R12, "4*PT_R12" },
2988 { 4*PT_R13, "4*PT_R13" },
2989 { 4*PT_ACR, "4*PT_ACR" },
2990 { 4*PT_SRS, "4*PT_SRS" },
2991 { 4*PT_MOF, "4*PT_MOF" },
2992 { 4*PT_SPC, "4*PT_SPC" },
2993 { 4*PT_CCS, "4*PT_CCS" },
2994 { 4*PT_SRP, "4*PT_SRP" },
2995 { 4*PT_ERP, "4*PT_ERP" },
2996 { 4*PT_EXS, "4*PT_EXS" },
2997 { 4*PT_EDA, "4*PT_EDA" },
2998 { 4*PT_USP, "4*PT_USP" },
2999 { 4*PT_PPC, "4*PT_PPC" },
3000 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3001 { 4*PT_BP+4, "4*PT_BP+4" },
3002 { 4*PT_BP+8, "4*PT_BP+8" },
3003 { 4*PT_BP+12, "4*PT_BP+12" },
3004 { 4*PT_BP+16, "4*PT_BP+16" },
3005 { 4*PT_BP+20, "4*PT_BP+20" },
3006 { 4*PT_BP+24, "4*PT_BP+24" },
3007 { 4*PT_BP+28, "4*PT_BP+28" },
3008 { 4*PT_BP+32, "4*PT_BP+32" },
3009 { 4*PT_BP+36, "4*PT_BP+36" },
3010 { 4*PT_BP+40, "4*PT_BP+40" },
3011 { 4*PT_BP+44, "4*PT_BP+44" },
3012 { 4*PT_BP+48, "4*PT_BP+48" },
3013 { 4*PT_BP+52, "4*PT_BP+52" },
3014 { 4*PT_BP+56, "4*PT_BP+56" },
3017 { PT_GPR(0), "r0" },
3018 { PT_GPR(1), "r1" },
3019 { PT_GPR(2), "r2" },
3020 { PT_GPR(3), "r3" },
3021 { PT_GPR(4), "r4" },
3022 { PT_GPR(5), "r5" },
3023 { PT_GPR(6), "r6" },
3024 { PT_GPR(7), "r7" },
3025 { PT_GPR(8), "r8" },
3026 { PT_GPR(9), "r9" },
3027 { PT_GPR(10), "r10" },
3028 { PT_GPR(11), "r11" },
3029 { PT_GPR(12), "r12" },
3030 { PT_GPR(13), "r13" },
3031 { PT_GPR(14), "r14" },
3032 { PT_GPR(15), "r15" },
3033 { PT_GPR(16), "r16" },
3034 { PT_GPR(17), "r17" },
3035 { PT_GPR(18), "r18" },
3036 { PT_GPR(19), "r19" },
3037 { PT_GPR(20), "r20" },
3038 { PT_GPR(21), "r21" },
3039 { PT_GPR(22), "r22" },
3040 { PT_GPR(23), "r23" },
3041 { PT_GPR(24), "r24" },
3042 { PT_GPR(25), "r25" },
3043 { PT_GPR(26), "r26" },
3044 { PT_GPR(27), "r27" },
3045 { PT_GPR(28), "r28" },
3046 { PT_GPR(29), "r29" },
3047 { PT_GPR(30), "r30" },
3048 { PT_GPR(31), "r31" },
3050 { PT_MSR, "rmsr", },
3051 { PT_EAR, "rear", },
3052 { PT_ESR, "resr", },
3053 { PT_FSR, "rfsr", },
3054 { PT_KERNEL_MODE, "kernel_mode", },
3057 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3058 && !defined(ALPHA) && !defined(IA64) \
3059 && !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
3060 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3061 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3063 # if defined(I386) || defined(X86_64)
3064 { uoff(i387), "offsetof(struct user, i387)" },
3067 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3069 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3070 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3071 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3072 # if !defined(SPARC64)
3073 { uoff(start_code), "offsetof(struct user, start_code)" },
3075 # if defined(AVR32) || defined(SH64)
3076 { uoff(start_data), "offsetof(struct user, start_data)" },
3078 # if !defined(SPARC64)
3079 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3081 { uoff(signal), "offsetof(struct user, signal)" },
3082 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3083 { uoff(reserved), "offsetof(struct user, reserved)" },
3085 # if !defined(SPARC64)
3086 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3088 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3089 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3091 { uoff(magic), "offsetof(struct user, magic)" },
3092 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3093 # if defined(I386) || defined(X86_64)
3094 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3096 # endif /* !defined(many arches) */
3101 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3102 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3103 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3104 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3105 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3106 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3107 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3108 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3109 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3110 { uoff(u_error), "offsetof(struct user, u_error)" },
3111 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3112 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3113 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3114 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3115 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3116 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3117 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3118 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3119 { uoff(u_code), "offsetof(struct user, u_code)" },
3120 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3121 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3122 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3123 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3124 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3125 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3126 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3127 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3128 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3129 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3130 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3131 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3132 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3133 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3134 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3135 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3136 { uoff(u_start), "offsetof(struct user, u_start)" },
3137 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3138 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3139 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3140 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3141 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3142 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3143 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3144 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3145 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3146 # endif /* SUNOS4 */
3148 { sizeof(struct user), "sizeof(struct user)" },
3152 # endif /* !FREEBSD */
3155 sys_ptrace(struct tcb *tcp)
3157 const struct xlat *x;
3160 if (entering(tcp)) {
3161 printxval(ptrace_cmds, tcp->u_arg[0],
3168 tprintf(", %lu, ", tcp->u_arg[1]);
3169 addr = tcp->u_arg[2];
3171 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3172 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3173 for (x = struct_user_offsets; x->str; x++) {
3178 tprintf("%#lx, ", addr);
3179 else if (x->val > addr && x != struct_user_offsets) {
3181 tprintf("%s + %ld, ", x->str, addr - x->val);
3184 tprintf("%s, ", x->str);
3188 tprintf("%#lx, ", tcp->u_arg[2]);
3190 switch (tcp->u_arg[0]) {
3192 case PTRACE_PEEKDATA:
3193 case PTRACE_PEEKTEXT:
3194 case PTRACE_PEEKUSER:
3198 case PTRACE_SINGLESTEP:
3199 case PTRACE_SYSCALL:
3201 printsignal(tcp->u_arg[3]);
3203 # ifdef PTRACE_SETOPTIONS
3204 case PTRACE_SETOPTIONS:
3205 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3208 # ifdef PTRACE_SETSIGINFO
3209 case PTRACE_SETSIGINFO: {
3213 else if (syserror(tcp))
3214 tprintf("%#lx", tcp->u_arg[3]);
3215 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3218 printsiginfo(&si, verbose(tcp));
3222 # ifdef PTRACE_GETSIGINFO
3223 case PTRACE_GETSIGINFO:
3224 /* Don't print anything, do it at syscall return. */
3228 tprintf("%#lx", tcp->u_arg[3]);
3232 switch (tcp->u_arg[0]) {
3233 case PTRACE_PEEKDATA:
3234 case PTRACE_PEEKTEXT:
3235 case PTRACE_PEEKUSER:
3239 printnum(tcp, tcp->u_arg[3], "%#lx");
3242 # ifdef PTRACE_GETSIGINFO
3243 case PTRACE_GETSIGINFO: {
3247 else if (syserror(tcp))
3248 tprintf("%#lx", tcp->u_arg[3]);
3249 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3252 printsiginfo(&si, verbose(tcp));
3260 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3261 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3262 tprintf("%lu, ", tcp->u_arg[3]);
3263 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3264 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3265 tcp->u_arg[0] != PTRACE_READTEXT) {
3266 tprintf("%#lx", tcp->u_arg[3]);
3269 if (tcp->u_arg[0] == PTRACE_READDATA ||
3270 tcp->u_arg[0] == PTRACE_READTEXT) {
3271 tprintf("%lu, ", tcp->u_arg[3]);
3272 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3275 # endif /* SUNOS4 */
3277 tprintf("%lu", tcp->u_arg[3]);
3279 # endif /* FREEBSD */
3286 # ifndef FUTEX_CMP_REQUEUE
3287 # define FUTEX_CMP_REQUEUE 4
3289 # ifndef FUTEX_WAKE_OP
3290 # define FUTEX_WAKE_OP 5
3292 # ifndef FUTEX_LOCK_PI
3293 # define FUTEX_LOCK_PI 6
3294 # define FUTEX_UNLOCK_PI 7
3295 # define FUTEX_TRYLOCK_PI 8
3297 # ifndef FUTEX_WAIT_BITSET
3298 # define FUTEX_WAIT_BITSET 9
3300 # ifndef FUTEX_WAKE_BITSET
3301 # define FUTEX_WAKE_BITSET 10
3303 # ifndef FUTEX_WAIT_REQUEUE_PI
3304 # define FUTEX_WAIT_REQUEUE_PI 11
3306 # ifndef FUTEX_CMP_REQUEUE_PI
3307 # define FUTEX_CMP_REQUEUE_PI 12
3309 # ifndef FUTEX_PRIVATE_FLAG
3310 # define FUTEX_PRIVATE_FLAG 128
3312 # ifndef FUTEX_CLOCK_REALTIME
3313 # define FUTEX_CLOCK_REALTIME 256
3315 static const struct xlat futexops[] = {
3316 { FUTEX_WAIT, "FUTEX_WAIT" },
3317 { FUTEX_WAKE, "FUTEX_WAKE" },
3318 { FUTEX_FD, "FUTEX_FD" },
3319 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3320 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3321 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3322 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3323 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3324 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3325 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3326 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3327 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3328 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3329 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3330 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3331 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3332 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3333 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3334 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3335 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3336 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3337 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3338 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3339 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3340 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3341 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3342 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3343 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3344 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3345 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3348 # ifndef FUTEX_OP_SET
3349 # define FUTEX_OP_SET 0
3350 # define FUTEX_OP_ADD 1
3351 # define FUTEX_OP_OR 2
3352 # define FUTEX_OP_ANDN 3
3353 # define FUTEX_OP_XOR 4
3354 # define FUTEX_OP_CMP_EQ 0
3355 # define FUTEX_OP_CMP_NE 1
3356 # define FUTEX_OP_CMP_LT 2
3357 # define FUTEX_OP_CMP_LE 3
3358 # define FUTEX_OP_CMP_GT 4
3359 # define FUTEX_OP_CMP_GE 5
3361 static const struct xlat futexwakeops[] = {
3362 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3363 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3364 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3365 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3366 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3369 static const struct xlat futexwakecmps[] = {
3370 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3371 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3372 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3373 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3374 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3375 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3380 sys_futex(struct tcb *tcp)
3382 if (entering(tcp)) {
3383 long int cmd = tcp->u_arg[1] & 127;
3384 tprintf("%p, ", (void *) tcp->u_arg[0]);
3385 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3386 tprintf(", %ld", tcp->u_arg[2]);
3387 if (cmd == FUTEX_WAKE_BITSET)
3388 tprintf(", %lx", tcp->u_arg[5]);
3389 else if (cmd == FUTEX_WAIT) {
3391 printtv(tcp, tcp->u_arg[3]);
3392 } else if (cmd == FUTEX_WAIT_BITSET) {
3394 printtv(tcp, tcp->u_arg[3]);
3395 tprintf(", %lx", tcp->u_arg[5]);
3396 } else if (cmd == FUTEX_REQUEUE)
3397 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3398 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3399 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3400 else if (cmd == FUTEX_WAKE_OP) {
3401 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3402 if ((tcp->u_arg[5] >> 28) & 8)
3403 tprintf("FUTEX_OP_OPARG_SHIFT|");
3404 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3405 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3406 if ((tcp->u_arg[5] >> 24) & 8)
3407 tprintf("FUTEX_OP_OPARG_SHIFT|");
3408 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3409 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3410 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3412 printtv(tcp, tcp->u_arg[3]);
3413 tprintf(", %p", (void *) tcp->u_arg[4]);
3420 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3423 unsigned long w, min_len;
3425 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3426 min_len = len - max_strlen * sizeof(w);
3429 for (; len >= sizeof(w) && len > min_len;
3430 len -= sizeof(w), list += sizeof(w)) {
3431 if (umove(tcp, list, &w) < 0)
3442 tprintf("%#lx", list);
3444 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3447 tprintf(first ? "{}" : "}");
3452 sys_sched_setaffinity(struct tcb *tcp)
3454 if (entering(tcp)) {
3455 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3456 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3462 sys_sched_getaffinity(struct tcb *tcp)
3464 if (entering(tcp)) {
3465 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3467 if (tcp->u_rval == -1)
3468 tprintf("%#lx", tcp->u_arg[2]);
3470 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3475 static const struct xlat schedulers[] = {
3476 { SCHED_OTHER, "SCHED_OTHER" },
3477 { SCHED_RR, "SCHED_RR" },
3478 { SCHED_FIFO, "SCHED_FIFO" },
3483 sys_sched_getscheduler(struct tcb *tcp)
3485 if (entering(tcp)) {
3486 tprintf("%d", (int) tcp->u_arg[0]);
3487 } else if (! syserror(tcp)) {
3488 tcp->auxstr = xlookup(schedulers, tcp->u_rval);
3489 if (tcp->auxstr != NULL)
3496 sys_sched_setscheduler(struct tcb *tcp)
3498 if (entering(tcp)) {
3499 struct sched_param p;
3500 tprintf("%d, ", (int) tcp->u_arg[0]);
3501 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3502 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3503 tprintf(", %#lx", tcp->u_arg[2]);
3505 tprintf(", { %d }", p.__sched_priority);
3511 sys_sched_getparam(struct tcb *tcp)
3513 if (entering(tcp)) {
3514 tprintf("%d, ", (int) tcp->u_arg[0]);
3516 struct sched_param p;
3517 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3518 tprintf("%#lx", tcp->u_arg[1]);
3520 tprintf("{ %d }", p.__sched_priority);
3526 sys_sched_setparam(struct tcb *tcp)
3528 if (entering(tcp)) {
3529 struct sched_param p;
3530 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3531 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3533 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3539 sys_sched_get_priority_min(struct tcb *tcp)
3541 if (entering(tcp)) {
3542 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3548 # include <asm/prctl.h>
3550 static const struct xlat archvals[] = {
3551 { ARCH_SET_GS, "ARCH_SET_GS" },
3552 { ARCH_SET_FS, "ARCH_SET_FS" },
3553 { ARCH_GET_FS, "ARCH_GET_FS" },
3554 { ARCH_GET_GS, "ARCH_GET_GS" },
3559 sys_arch_prctl(struct tcb *tcp)
3561 if (entering(tcp)) {
3562 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3563 if (tcp->u_arg[0] == ARCH_SET_GS
3564 || tcp->u_arg[0] == ARCH_SET_FS
3566 tprintf(", %#lx", tcp->u_arg[1]);
3569 if (tcp->u_arg[0] == ARCH_GET_GS
3570 || tcp->u_arg[0] == ARCH_GET_FS
3573 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3574 tprintf(", [%#lx]", v);
3576 tprintf(", %#lx", tcp->u_arg[1]);
3581 # endif /* X86_64 */
3585 sys_getcpu(struct tcb *tcp)
3589 if (tcp->u_arg[0] == 0)
3591 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3592 tprintf("%#lx, ", tcp->u_arg[0]);
3594 tprintf("[%u], ", u);
3595 if (tcp->u_arg[1] == 0)
3597 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3598 tprintf("%#lx, ", tcp->u_arg[1]);
3600 tprintf("[%u], ", u);
3601 tprintf("%#lx", tcp->u_arg[2]);