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;
840 if (tcpchild->flags & TCB_SUSPENDED) {
841 /* The child was born suspended, due to our having
842 forced CLONE_PTRACE. */
846 tcpchild->flags &= ~(TCB_SUSPENDED|TCB_STARTUP);
847 if (ptrace_restart(PTRACE_SYSCALL, tcpchild, 0) < 0)
852 Process %u resumed (parent %d ready)\n",
857 fprintf(stderr, "Process %d attached\n", pid);
860 #ifdef TCB_CLONE_THREAD
861 if (sysent[tcp->scno].sys_func == sys_clone)
864 * Save the flags used in this call,
865 * in case we point TCP to our parent below.
867 int call_flags = tcp->u_arg[ARG_FLAGS];
868 if ((tcp->flags & TCB_CLONE_THREAD) &&
869 tcp->parent != NULL) {
870 /* The parent in this clone is itself a
871 thread belonging to another process.
872 There is no meaning to the parentage
873 relationship of the new child with the
874 thread, only with the process. We
875 associate the new thread with our
876 parent. Since this is done for every
877 new thread, there will never be a
878 TCB_CLONE_THREAD process that has
882 tcpchild->parent = tcp;
885 if (call_flags & CLONE_THREAD) {
886 tcpchild->flags |= TCB_CLONE_THREAD;
887 ++tcp->nclone_threads;
889 if ((call_flags & CLONE_PARENT) &&
890 !(call_flags & CLONE_THREAD)) {
892 tcpchild->parent = NULL;
893 if (tcp->parent != NULL) {
895 tcpchild->parent = tcp;
900 #endif /* TCB_CLONE_THREAD */
905 internal_fork(struct tcb *tcp)
907 if ((ptrace_setoptions_followfork
908 & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
909 == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK))
913 tcp->flags &= ~TCB_FOLLOWFORK;
917 * In occasion of using PTRACE_O_TRACECLONE, we won't see the
918 * new child if clone is called with flag CLONE_UNTRACED, so
919 * we keep the same logic with that option and don't trace it.
921 if ((sysent[tcp->scno].sys_func == sys_clone) &&
922 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED))
931 if (!(tcp->flags & TCB_FOLLOWFORK))
934 bpt = tcp->flags & TCB_BPTSET;
944 return handle_new_child(tcp, pid, bpt);
952 internal_fork(struct tcb *tcp)
954 struct tcb *tcpchild;
959 if (known_scno(tcp) == SYS_vfork) {
960 /* Attempt to make vfork into fork, which we can follow. */
961 if (change_syscall(tcp, SYS_fork) < 0)
966 if (!followfork || dont_follow)
973 int bpt = tcp->flags & TCB_BPTSET;
975 if (!(tcp->flags & TCB_FOLLOWFORK))
985 tcpchild = alloctcb(pid);
988 /* The child must have run before it can be attached. */
993 select(0, NULL, NULL, NULL, &tv);
995 if (ptrace(PTRACE_ATTACH, pid, (char *)1, 0) < 0) {
996 perror("PTRACE_ATTACH");
997 fprintf(stderr, "Too late?\n");
1002 /* Try to catch the new process as soon as possible. */
1005 for (i = 0; i < 1024; i++)
1006 if (ptrace(PTRACE_ATTACH, pid, (char *) 1, 0) >= 0)
1009 perror("PTRACE_ATTACH");
1010 fprintf(stderr, "Too late?\n");
1015 #endif /* !oldway */
1017 tcpchild->flags |= TCB_ATTACHED;
1018 /* Child has BPT too, must be removed on first occasion */
1020 tcpchild->flags |= TCB_BPTSET;
1021 tcpchild->baddr = tcp->baddr;
1022 memcpy(tcpchild->inst, tcp->inst,
1023 sizeof tcpchild->inst);
1025 tcpchild->parent = tcp;
1028 fprintf(stderr, "Process %d attached\n", pid);
1035 #endif /* !USE_PROCFS */
1037 #if defined(SUNOS4) || defined(LINUX) || defined(FREEBSD)
1040 sys_vfork(struct tcb *tcp)
1043 return RVAL_UDECIMAL;
1047 #endif /* SUNOS4 || LINUX || FREEBSD */
1051 static char idstr[16];
1054 sys_getpid(struct tcb *tcp)
1057 sprintf(idstr, "ppid %lu", getrval2(tcp));
1058 tcp->auxstr = idstr;
1065 sys_getuid(struct tcb *tcp)
1068 sprintf(idstr, "euid %lu", getrval2(tcp));
1069 tcp->auxstr = idstr;
1076 sys_getgid(struct tcb *tcp)
1079 sprintf(idstr, "egid %lu", getrval2(tcp));
1080 tcp->auxstr = idstr;
1090 int sys_getuid(struct tcb *tcp)
1093 tcp->u_rval = (uid_t) tcp->u_rval;
1094 return RVAL_UDECIMAL;
1097 int sys_setfsuid(struct tcb *tcp)
1100 tprintf("%u", (uid_t) tcp->u_arg[0]);
1102 tcp->u_rval = (uid_t) tcp->u_rval;
1103 return RVAL_UDECIMAL;
1107 sys_setuid(struct tcb *tcp)
1109 if (entering(tcp)) {
1110 tprintf("%u", (uid_t) tcp->u_arg[0]);
1116 sys_setgid(struct tcb *tcp)
1118 if (entering(tcp)) {
1119 tprintf("%u", (gid_t) tcp->u_arg[0]);
1125 sys_getresuid(struct tcb *tcp)
1130 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1131 tcp->u_arg[1], tcp->u_arg[2]);
1133 if (umove(tcp, tcp->u_arg[0], &uid) < 0)
1134 tprintf("%#lx, ", tcp->u_arg[0]);
1136 tprintf("[%lu], ", (unsigned long) uid);
1137 if (umove(tcp, tcp->u_arg[1], &uid) < 0)
1138 tprintf("%#lx, ", tcp->u_arg[1]);
1140 tprintf("[%lu], ", (unsigned long) uid);
1141 if (umove(tcp, tcp->u_arg[2], &uid) < 0)
1142 tprintf("%#lx", tcp->u_arg[2]);
1144 tprintf("[%lu]", (unsigned long) uid);
1151 sys_getresgid(struct tcb *tcp)
1156 tprintf("%#lx, %#lx, %#lx", tcp->u_arg[0],
1157 tcp->u_arg[1], tcp->u_arg[2]);
1159 if (umove(tcp, tcp->u_arg[0], &gid) < 0)
1160 tprintf("%#lx, ", tcp->u_arg[0]);
1162 tprintf("[%lu], ", (unsigned long) gid);
1163 if (umove(tcp, tcp->u_arg[1], &gid) < 0)
1164 tprintf("%#lx, ", tcp->u_arg[1]);
1166 tprintf("[%lu], ", (unsigned long) gid);
1167 if (umove(tcp, tcp->u_arg[2], &gid) < 0)
1168 tprintf("%#lx", tcp->u_arg[2]);
1170 tprintf("[%lu]", (unsigned long) gid);
1179 sys_setreuid(struct tcb *tcp)
1181 if (entering(tcp)) {
1182 printuid("", tcp->u_arg[0]);
1183 printuid(", ", tcp->u_arg[1]);
1189 sys_setregid(struct tcb *tcp)
1191 if (entering(tcp)) {
1192 printuid("", tcp->u_arg[0]);
1193 printuid(", ", tcp->u_arg[1]);
1198 #if defined(LINUX) || defined(FREEBSD)
1200 sys_setresuid(struct tcb *tcp)
1202 if (entering(tcp)) {
1203 printuid("", tcp->u_arg[0]);
1204 printuid(", ", tcp->u_arg[1]);
1205 printuid(", ", tcp->u_arg[2]);
1210 sys_setresgid(struct tcb *tcp)
1212 if (entering(tcp)) {
1213 printuid("", tcp->u_arg[0]);
1214 printuid(", ", tcp->u_arg[1]);
1215 printuid(", ", tcp->u_arg[2]);
1220 #endif /* LINUX || FREEBSD */
1223 sys_setgroups(struct tcb *tcp)
1225 if (entering(tcp)) {
1226 unsigned long len, size, start, cur, end, abbrev_end;
1230 len = tcp->u_arg[0];
1231 tprintf("%lu, ", len);
1236 start = tcp->u_arg[1];
1241 size = len * sizeof(gid);
1243 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1244 tprintf("%#lx", start);
1248 abbrev_end = start + max_strlen * sizeof(gid);
1249 if (abbrev_end < start)
1255 for (cur = start; cur < end; cur += sizeof(gid)) {
1258 if (cur >= abbrev_end) {
1262 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1267 tprintf("%lu", (unsigned long) gid);
1271 tprintf(" %#lx", tcp->u_arg[1]);
1277 sys_getgroups(struct tcb *tcp)
1281 if (entering(tcp)) {
1282 len = tcp->u_arg[0];
1283 tprintf("%lu, ", len);
1285 unsigned long size, start, cur, end, abbrev_end;
1294 start = tcp->u_arg[1];
1299 if (tcp->u_arg[0] == 0) {
1300 tprintf("%#lx", start);
1303 size = len * sizeof(gid);
1305 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1306 size / sizeof(gid) != len || end < start) {
1307 tprintf("%#lx", start);
1311 abbrev_end = start + max_strlen * sizeof(gid);
1312 if (abbrev_end < start)
1318 for (cur = start; cur < end; cur += sizeof(gid)) {
1321 if (cur >= abbrev_end) {
1325 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1330 tprintf("%lu", (unsigned long) gid);
1334 tprintf(" %#lx", tcp->u_arg[1]);
1341 sys_setgroups32(struct tcb *tcp)
1343 if (entering(tcp)) {
1344 unsigned long len, size, start, cur, end, abbrev_end;
1348 len = tcp->u_arg[0];
1349 tprintf("%lu, ", len);
1354 start = tcp->u_arg[1];
1359 size = len * sizeof(gid);
1361 if (!verbose(tcp) || size / sizeof(gid) != len || end < start) {
1362 tprintf("%#lx", start);
1366 abbrev_end = start + max_strlen * sizeof(gid);
1367 if (abbrev_end < start)
1373 for (cur = start; cur < end; cur += sizeof(gid)) {
1376 if (cur >= abbrev_end) {
1380 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1385 tprintf("%lu", (unsigned long) gid);
1389 tprintf(" %#lx", tcp->u_arg[1]);
1395 sys_getgroups32(struct tcb *tcp)
1399 if (entering(tcp)) {
1400 len = tcp->u_arg[0];
1401 tprintf("%lu, ", len);
1403 unsigned long size, start, cur, end, abbrev_end;
1412 start = tcp->u_arg[1];
1417 size = len * sizeof(gid);
1419 if (!verbose(tcp) || tcp->u_arg[0] == 0 ||
1420 size / sizeof(gid) != len || end < start) {
1421 tprintf("%#lx", start);
1425 abbrev_end = start + max_strlen * sizeof(gid);
1426 if (abbrev_end < start)
1432 for (cur = start; cur < end; cur += sizeof(gid)) {
1435 if (cur >= abbrev_end) {
1439 if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
1444 tprintf("%lu", (unsigned long) gid);
1448 tprintf(" %#lx", tcp->u_arg[1]);
1454 #if defined(ALPHA) || defined(SUNOS4) || defined(SVR4)
1456 sys_setpgrp(struct tcb *tcp)
1458 if (entering(tcp)) {
1460 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1465 #endif /* ALPHA || SUNOS4 || SVR4 */
1468 sys_getpgrp(struct tcb *tcp)
1470 if (entering(tcp)) {
1472 tprintf("%lu", tcp->u_arg[0]);
1479 sys_getsid(struct tcb *tcp)
1481 if (entering(tcp)) {
1482 tprintf("%lu", tcp->u_arg[0]);
1488 sys_setsid(struct tcb *tcp)
1494 sys_getpgid(struct tcb *tcp)
1496 if (entering(tcp)) {
1497 tprintf("%lu", tcp->u_arg[0]);
1503 sys_setpgid(struct tcb *tcp)
1505 if (entering(tcp)) {
1506 tprintf("%lu, %lu", tcp->u_arg[0], tcp->u_arg[1]);
1513 #include <sys/privilege.h>
1516 static const struct xlat procpriv_cmds[] = {
1517 { SETPRV, "SETPRV" },
1518 { CLRPRV, "CLRPRV" },
1519 { PUTPRV, "PUTPRV" },
1520 { GETPRV, "GETPRV" },
1521 { CNTPRV, "CNTPRV" },
1526 static const struct xlat procpriv_priv[] = {
1527 { P_OWNER, "P_OWNER" },
1528 { P_AUDIT, "P_AUDIT" },
1529 { P_COMPAT, "P_COMPAT" },
1530 { P_DACREAD, "P_DACREAD" },
1531 { P_DACWRITE, "P_DACWRITE" },
1533 { P_FILESYS, "P_FILESYS" },
1534 { P_MACREAD, "P_MACREAD" },
1535 { P_MACWRITE, "P_MACWRITE" },
1536 { P_MOUNT, "P_MOUNT" },
1537 { P_MULTIDIR, "P_MULTIDIR" },
1538 { P_SETPLEVEL, "P_SETPLEVEL" },
1539 { P_SETSPRIV, "P_SETSPRIV" },
1540 { P_SETUID, "P_SETUID" },
1541 { P_SYSOPS, "P_SYSOPS" },
1542 { P_SETUPRIV, "P_SETUPRIV" },
1543 { P_DRIVER, "P_DRIVER" },
1544 { P_RTIME, "P_RTIME" },
1545 { P_MACUPGRADE, "P_MACUPGRADE" },
1546 { P_FSYSRANGE, "P_FSYSRANGE" },
1547 { P_SETFLEVEL, "P_SETFLEVEL" },
1548 { P_AUDITWR, "P_AUDITWR" },
1549 { P_TSHAR, "P_TSHAR" },
1550 { P_PLOCK, "P_PLOCK" },
1551 { P_CORE, "P_CORE" },
1552 { P_LOADMOD, "P_LOADMOD" },
1553 { P_BIND, "P_BIND" },
1554 { P_ALLPRIVS, "P_ALLPRIVS" },
1559 static const struct xlat procpriv_type[] = {
1560 { PS_FIX, "PS_FIX" },
1561 { PS_INH, "PS_INH" },
1562 { PS_MAX, "PS_MAX" },
1563 { PS_WKG, "PS_WKG" },
1569 printpriv(struct tcb *tcp, long addr, int len, const struct xlat *opt)
1572 int max = verbose(tcp) ? sizeof buf / sizeof buf[0] : 10;
1573 int dots = len > max;
1576 if (len > max) len = max;
1579 umoven(tcp, addr, len * sizeof buf[0], (char *) buf) < 0)
1581 tprintf("%#lx", addr);
1587 for (i = 0; i < len; ++i) {
1590 if (i) tprintf(", ");
1592 if ((t = xlookup(procpriv_type, buf[i] & PS_TYPE)) &&
1593 (p = xlookup(procpriv_priv, buf[i] & ~PS_TYPE)))
1595 tprintf("%s|%s", t, p);
1598 tprintf("%#lx", buf[i]);
1602 if (dots) tprintf(" ...");
1609 sys_procpriv(struct tcb *tcp)
1611 if (entering(tcp)) {
1612 printxval(procpriv_cmds, tcp->u_arg[0], "???PRV");
1613 switch (tcp->u_arg[0]) {
1615 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1623 printpriv(tcp, tcp->u_arg[1], tcp->u_arg[2]);
1624 tprintf(", %ld", tcp->u_arg[2]);
1627 else if (tcp->u_arg[0] == GETPRV) {
1628 if (syserror(tcp)) {
1629 tprintf(", %#lx, %ld", tcp->u_arg[1], tcp->u_arg[2]);
1633 printpriv(tcp, tcp->u_arg[1], tcp->u_rval);
1634 tprintf(", %ld", tcp->u_arg[2]);
1641 #endif /* UNIXWARE */
1645 printargv(struct tcb *tcp, long addr)
1650 char data[sizeof(long)];
1656 for (sep = ""; !abbrev(tcp) || n < max_strlen / 2; sep = ", ", ++n) {
1657 if (umoven(tcp, addr, personality_wordsize[current_personality],
1659 tprintf("%#lx", addr);
1662 if (personality_wordsize[current_personality] == 4)
1667 printstr(tcp, cp.p64, -1);
1668 addr += personality_wordsize[current_personality];
1671 tprintf("%s...", sep);
1675 printargc(const char *fmt, struct tcb *tcp, long addr)
1680 for (count = 0; umove(tcp, addr, &cp) >= 0 && cp != NULL; count++) {
1681 addr += sizeof(char *);
1683 tprintf(fmt, count, count == 1 ? "" : "s");
1686 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
1688 sys_execv(struct tcb *tcp)
1690 if (entering(tcp)) {
1691 printpath(tcp, tcp->u_arg[0]);
1693 tprintf(", %#lx", tcp->u_arg[1]);
1696 printargv(tcp, tcp->u_arg[1]);
1702 #endif /* SPARC || SPARC64 || SUNOS4 */
1705 sys_execve(struct tcb *tcp)
1707 if (entering(tcp)) {
1708 printpath(tcp, tcp->u_arg[0]);
1710 tprintf(", %#lx", tcp->u_arg[1]);
1713 printargv(tcp, tcp->u_arg[1]);
1717 tprintf(", %#lx", tcp->u_arg[2]);
1718 else if (abbrev(tcp))
1719 printargc(", [/* %d var%s */]", tcp, tcp->u_arg[2]);
1722 printargv(tcp, tcp->u_arg[2]);
1731 int sys_rexecve(struct tcb *tcp)
1733 if (entering(tcp)) {
1735 tprintf(", %ld", tcp->u_arg[3]);
1743 internal_exec(struct tcb *tcp)
1746 if (exiting(tcp) && !syserror(tcp) && followfork)
1749 #if defined LINUX && defined TCB_WAITEXECVE
1750 if (exiting(tcp) && syserror(tcp))
1751 tcp->flags &= ~TCB_WAITEXECVE;
1753 /* Maybe we have post-execve SIGTRAP suppressed? */
1754 if (!(ptrace_setoptions_for_all & PTRACE_O_TRACEEXEC))
1755 tcp->flags |= TCB_WAITEXECVE; /* no */
1757 #endif /* LINUX && TCB_WAITEXECVE */
1763 #define __WNOTHREAD 0x20000000
1766 #define __WALL 0x40000000
1769 #define __WCLONE 0x80000000
1773 static const struct xlat wait4_options[] = {
1774 { WNOHANG, "WNOHANG" },
1776 { WUNTRACED, "WUNTRACED" },
1779 { WEXITED, "WEXITED" },
1782 { WTRAPPED, "WTRAPPED" },
1785 { WSTOPPED, "WSTOPPED" },
1788 { WCONTINUED, "WCONTINUED" },
1791 { WNOWAIT, "WNOWAIT" },
1794 { __WCLONE, "__WCLONE" },
1797 { __WALL, "__WALL" },
1800 { __WNOTHREAD, "__WNOTHREAD" },
1805 #if !defined WCOREFLAG && defined WCOREFLG
1806 # define WCOREFLAG WCOREFLG
1809 # define WCOREFLAG 0x80
1812 # define WCOREDUMP(status) ((status) & 0200)
1817 #define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
1820 #define W_EXITCODE(ret, sig) ((ret) << 8 | (sig))
1824 printstatus(int status)
1829 * Here is a tricky presentation problem. This solution
1830 * is still not entirely satisfactory but since there
1831 * are no wait status constructors it will have to do.
1833 if (WIFSTOPPED(status)) {
1834 tprintf("[{WIFSTOPPED(s) && WSTOPSIG(s) == %s}",
1835 signame(WSTOPSIG(status)));
1836 status &= ~W_STOPCODE(WSTOPSIG(status));
1838 else if (WIFSIGNALED(status)) {
1839 tprintf("[{WIFSIGNALED(s) && WTERMSIG(s) == %s%s}",
1840 signame(WTERMSIG(status)),
1841 WCOREDUMP(status) ? " && WCOREDUMP(s)" : "");
1842 status &= ~(W_EXITCODE(0, WTERMSIG(status)) | WCOREFLAG);
1844 else if (WIFEXITED(status)) {
1845 tprintf("[{WIFEXITED(s) && WEXITSTATUS(s) == %d}",
1846 WEXITSTATUS(status));
1848 status &= ~W_EXITCODE(WEXITSTATUS(status), 0);
1851 tprintf("[%#x]", status);
1858 tprintf(" | %#x]", status);
1864 printwaitn(struct tcb *tcp, int n, int bitness)
1871 if (entering(tcp)) {
1873 /* On Linux, kernel-side pid_t is typedef'ed to int
1874 * on all arches. Also, glibc-2.8 truncates wait3 and wait4
1875 * pid argument to int on 64bit arches, producing,
1876 * for example, wait4(4294967295, ...) instead of -1
1877 * in strace. We have to use int here, not long.
1879 int pid = tcp->u_arg[0];
1880 tprintf("%d, ", pid);
1883 * Sign-extend a 32-bit value when that's what it is.
1885 long pid = tcp->u_arg[0];
1886 if (personality_wordsize[current_personality] < sizeof pid)
1887 pid = (long) (int) pid;
1888 tprintf("%ld, ", pid);
1894 else if (syserror(tcp) || tcp->u_rval == 0)
1895 tprintf("%#lx", tcp->u_arg[1]);
1896 else if (umove(tcp, tcp->u_arg[1], &status) < 0)
1902 printstatus(status);
1905 printflags(wait4_options, tcp->u_arg[2], "W???");
1912 else if (tcp->u_rval > 0) {
1915 printrusage32(tcp, tcp->u_arg[3]);
1918 printrusage(tcp, tcp->u_arg[3]);
1922 else if (tcp->u_rval > 0 && exited)
1923 printrusage(tcp, tcp->u_arg[3]);
1926 tprintf("%#lx", tcp->u_arg[3]);
1933 internal_wait(struct tcb *tcp, int flagarg)
1937 #ifdef TCB_CLONE_THREAD
1938 if (tcp->flags & TCB_CLONE_THREAD)
1939 /* The children we wait for are our parent's children. */
1940 got_kids = (tcp->parent->nchildren
1941 > tcp->parent->nclone_threads);
1943 got_kids = (tcp->nchildren > tcp->nclone_threads);
1945 got_kids = tcp->nchildren > 0;
1948 if (entering(tcp) && got_kids) {
1949 /* There are children that this parent should block for.
1950 But ptrace made us the parent of the traced children
1951 and the real parent will get ECHILD from the wait call.
1953 XXX If we attached with strace -f -p PID, then there
1954 may be untraced dead children the parent could be reaping
1955 now, but we make him block. */
1957 /* ??? WTA: fix bug with hanging children */
1959 if (!(tcp->u_arg[flagarg] & WNOHANG)) {
1961 * There are traced children. We'll make the parent
1962 * block to avoid a false ECHILD error due to our
1963 * ptrace having stolen the children. However,
1964 * we shouldn't block if there are zombies to reap.
1965 * XXX doesn't handle pgrp matches (u_arg[0]==0,<-1)
1967 struct tcb *child = NULL;
1968 if (tcp->nzombies > 0 &&
1969 (tcp->u_arg[0] == -1 ||
1970 (child = pid2tcb(tcp->u_arg[0])) == NULL))
1972 if (tcp->u_arg[0] > 0) {
1974 * If the parent waits for a specified child
1975 * PID, then it must get ECHILD right away
1976 * if that PID is not one of its children.
1977 * Make sure that the requested PID matches
1978 * one of the parent's children that we are
1979 * tracing, and don't suspend it otherwise.
1982 child = pid2tcb(tcp->u_arg[0]);
1983 if (child == NULL || child->parent != (
1984 #ifdef TCB_CLONE_THREAD
1985 (tcp->flags & TCB_CLONE_THREAD)
1989 (child->flags & TCB_EXITING))
1992 tcp->flags |= TCB_SUSPENDED;
1993 tcp->waitpid = tcp->u_arg[0];
1994 #ifdef TCB_CLONE_THREAD
1995 if (tcp->flags & TCB_CLONE_THREAD)
1996 tcp->parent->nclone_waiting++;
2000 if (exiting(tcp) && tcp->u_error == ECHILD && got_kids) {
2001 if (tcp->u_arg[flagarg] & WNOHANG) {
2002 /* We must force a fake result of 0 instead of
2003 the ECHILD error. */
2004 return force_result(tcp, 0, 0);
2007 else if (exiting(tcp) && tcp->u_error == 0 && tcp->u_rval > 0 &&
2008 tcp->nzombies > 0 && pid2tcb(tcp->u_rval) == NULL) {
2010 * We just reaped a child we don't know about,
2011 * presumably a zombie we already droptcb'd.
2021 sys_wait(struct tcb *tcp)
2024 /* The library wrapper stuffs this into the user variable. */
2026 printstatus(getrval2(tcp));
2035 sys_wait(struct tcb *tcp)
2040 if (!syserror(tcp)) {
2041 if (umove(tcp, tcp->u_arg[0], &status) < 0)
2042 tprintf("%#lx", tcp->u_arg[0]);
2044 printstatus(status);
2052 sys_waitpid(struct tcb *tcp)
2054 return printwaitn(tcp, 3, 0);
2058 sys_wait4(struct tcb *tcp)
2060 return printwaitn(tcp, 4, 0);
2065 sys_osf_wait4(struct tcb *tcp)
2067 return printwaitn(tcp, 4, 1);
2071 #if defined SVR4 || defined LINUX
2073 static const struct xlat waitid_types[] = {
2076 { P_PPID, "P_PPID" },
2078 { P_PGID, "P_PGID" },
2093 { P_LWPID, "P_LWPID" },
2099 sys_waitid(struct tcb *tcp)
2103 if (entering(tcp)) {
2104 printxval(waitid_types, tcp->u_arg[0], "P_???");
2105 tprintf(", %ld, ", tcp->u_arg[1]);
2111 else if (syserror(tcp))
2112 tprintf("%#lx", tcp->u_arg[2]);
2113 else if (umove(tcp, tcp->u_arg[2], &si) < 0)
2116 printsiginfo(&si, verbose(tcp));
2119 printflags(wait4_options, tcp->u_arg[3], "W???");
2120 if (tcp->u_nargs > 4) {
2125 else if (tcp->u_error)
2126 tprintf("%#lx", tcp->u_arg[4]);
2128 printrusage(tcp, tcp->u_arg[4]);
2134 #endif /* SVR4 or LINUX */
2137 sys_alarm(struct tcb *tcp)
2140 tprintf("%lu", tcp->u_arg[0]);
2145 sys_uname(struct tcb *tcp)
2147 struct utsname uname;
2150 if (syserror(tcp) || !verbose(tcp))
2151 tprintf("%#lx", tcp->u_arg[0]);
2152 else if (umove(tcp, tcp->u_arg[0], &uname) < 0)
2154 else if (!abbrev(tcp)) {
2156 tprintf("{sysname=\"%s\", nodename=\"%s\", ",
2157 uname.sysname, uname.nodename);
2158 tprintf("release=\"%s\", version=\"%s\", ",
2159 uname.release, uname.version);
2160 tprintf("machine=\"%s\"", uname.machine);
2163 tprintf(", domainname=\"%s\"", uname.domainname);
2169 tprintf("{sys=\"%s\", node=\"%s\", ...}",
2170 uname.sysname, uname.nodename);
2177 static const struct xlat ptrace_cmds[] = {
2179 { PTRACE_TRACEME, "PTRACE_TRACEME" },
2180 { PTRACE_PEEKTEXT, "PTRACE_PEEKTEXT", },
2181 { PTRACE_PEEKDATA, "PTRACE_PEEKDATA", },
2182 { PTRACE_PEEKUSER, "PTRACE_PEEKUSER", },
2183 { PTRACE_POKETEXT, "PTRACE_POKETEXT", },
2184 { PTRACE_POKEDATA, "PTRACE_POKEDATA", },
2185 { PTRACE_POKEUSER, "PTRACE_POKEUSER", },
2186 { PTRACE_CONT, "PTRACE_CONT" },
2187 { PTRACE_KILL, "PTRACE_KILL" },
2188 { PTRACE_SINGLESTEP, "PTRACE_SINGLESTEP" },
2189 { PTRACE_ATTACH, "PTRACE_ATTACH" },
2190 { PTRACE_DETACH, "PTRACE_DETACH" },
2191 # ifdef PTRACE_GETREGS
2192 { PTRACE_GETREGS, "PTRACE_GETREGS" },
2194 # ifdef PTRACE_SETREGS
2195 { PTRACE_SETREGS, "PTRACE_SETREGS" },
2197 # ifdef PTRACE_GETFPREGS
2198 { PTRACE_GETFPREGS, "PTRACE_GETFPREGS", },
2200 # ifdef PTRACE_SETFPREGS
2201 { PTRACE_SETFPREGS, "PTRACE_SETFPREGS", },
2203 # ifdef PTRACE_GETFPXREGS
2204 { PTRACE_GETFPXREGS, "PTRACE_GETFPXREGS", },
2206 # ifdef PTRACE_SETFPXREGS
2207 { PTRACE_SETFPXREGS, "PTRACE_SETFPXREGS", },
2209 # ifdef PTRACE_GETVRREGS
2210 { PTRACE_GETVRREGS, "PTRACE_GETVRREGS", },
2212 # ifdef PTRACE_SETVRREGS
2213 { PTRACE_SETVRREGS, "PTRACE_SETVRREGS", },
2215 # ifdef PTRACE_SETOPTIONS
2216 { PTRACE_SETOPTIONS, "PTRACE_SETOPTIONS", },
2218 # ifdef PTRACE_GETEVENTMSG
2219 { PTRACE_GETEVENTMSG, "PTRACE_GETEVENTMSG", },
2221 # ifdef PTRACE_GETSIGINFO
2222 { PTRACE_GETSIGINFO, "PTRACE_GETSIGINFO", },
2224 # ifdef PTRACE_SETSIGINFO
2225 { PTRACE_SETSIGINFO, "PTRACE_SETSIGINFO", },
2227 # ifdef PTRACE_GETREGSET
2228 { PTRACE_GETREGSET, "PTRACE_GETREGSET", },
2230 # ifdef PTRACE_SETREGSET
2231 { PTRACE_SETREGSET, "PTRACE_SETREGSET", },
2233 # ifdef PTRACE_SET_SYSCALL
2234 { PTRACE_SET_SYSCALL, "PTRACE_SET_SYSCALL", },
2237 { PTRACE_READDATA, "PTRACE_READDATA" },
2238 { PTRACE_WRITEDATA, "PTRACE_WRITEDATA" },
2239 { PTRACE_READTEXT, "PTRACE_READTEXT" },
2240 { PTRACE_WRITETEXT, "PTRACE_WRITETEXT" },
2241 { PTRACE_GETFPAREGS, "PTRACE_GETFPAREGS" },
2242 { PTRACE_SETFPAREGS, "PTRACE_SETFPAREGS" },
2244 { PTRACE_GETWINDOW, "PTRACE_GETWINDOW" },
2245 { PTRACE_SETWINDOW, "PTRACE_SETWINDOW" },
2247 { PTRACE_22, "PTRACE_22" },
2248 { PTRACE_23, "PTRACE_3" },
2249 # endif /* !SPARC */
2250 # endif /* SUNOS4 */
2251 { PTRACE_SYSCALL, "PTRACE_SYSCALL" },
2253 { PTRACE_DUMPCORE, "PTRACE_DUMPCORE" },
2255 { PTRACE_SETWRBKPT, "PTRACE_SETWRBKPT" },
2256 { PTRACE_SETACBKPT, "PTRACE_SETACBKPT" },
2257 { PTRACE_CLRDR7, "PTRACE_CLRDR7" },
2259 { PTRACE_26, "PTRACE_26" },
2260 { PTRACE_27, "PTRACE_27" },
2261 { PTRACE_28, "PTRACE_28" },
2263 { PTRACE_GETUCODE, "PTRACE_GETUCODE" },
2264 # endif /* SUNOS4 */
2266 # else /* FREEBSD */
2268 { PT_TRACE_ME, "PT_TRACE_ME" },
2269 { PT_READ_I, "PT_READ_I" },
2270 { PT_READ_D, "PT_READ_D" },
2271 { PT_WRITE_I, "PT_WRITE_I" },
2272 { PT_WRITE_D, "PT_WRITE_D" },
2274 { PT_READ_U, "PT_READ_U" },
2276 { PT_CONTINUE, "PT_CONTINUE" },
2277 { PT_KILL, "PT_KILL" },
2278 { PT_STEP, "PT_STEP" },
2279 { PT_ATTACH, "PT_ATTACH" },
2280 { PT_DETACH, "PT_DETACH" },
2281 { PT_GETREGS, "PT_GETREGS" },
2282 { PT_SETREGS, "PT_SETREGS" },
2283 { PT_GETFPREGS, "PT_GETFPREGS" },
2284 { PT_SETFPREGS, "PT_SETFPREGS" },
2285 { PT_GETDBREGS, "PT_GETDBREGS" },
2286 { PT_SETDBREGS, "PT_SETDBREGS" },
2287 # endif /* FREEBSD */
2292 # ifdef PTRACE_SETOPTIONS
2293 static const struct xlat ptrace_setoptions_flags[] = {
2294 # ifdef PTRACE_O_TRACESYSGOOD
2295 { PTRACE_O_TRACESYSGOOD,"PTRACE_O_TRACESYSGOOD" },
2297 # ifdef PTRACE_O_TRACEFORK
2298 { PTRACE_O_TRACEFORK, "PTRACE_O_TRACEFORK" },
2300 # ifdef PTRACE_O_TRACEVFORK
2301 { PTRACE_O_TRACEVFORK, "PTRACE_O_TRACEVFORK" },
2303 # ifdef PTRACE_O_TRACECLONE
2304 { PTRACE_O_TRACECLONE, "PTRACE_O_TRACECLONE" },
2306 # ifdef PTRACE_O_TRACEEXEC
2307 { PTRACE_O_TRACEEXEC, "PTRACE_O_TRACEEXEC" },
2309 # ifdef PTRACE_O_TRACEVFORKDONE
2310 { PTRACE_O_TRACEVFORKDONE,"PTRACE_O_TRACEVFORKDONE"},
2312 # ifdef PTRACE_O_TRACEEXIT
2313 { PTRACE_O_TRACEEXIT, "PTRACE_O_TRACEEXIT" },
2317 # endif /* PTRACE_SETOPTIONS */
2318 # endif /* !FREEBSD */
2321 const struct xlat struct_user_offsets[] = {
2323 # if defined(S390) || defined(S390X)
2324 { PT_PSWMASK, "psw_mask" },
2325 { PT_PSWADDR, "psw_addr" },
2326 { PT_GPR0, "gpr0" },
2327 { PT_GPR1, "gpr1" },
2328 { PT_GPR2, "gpr2" },
2329 { PT_GPR3, "gpr3" },
2330 { PT_GPR4, "gpr4" },
2331 { PT_GPR5, "gpr5" },
2332 { PT_GPR6, "gpr6" },
2333 { PT_GPR7, "gpr7" },
2334 { PT_GPR8, "gpr8" },
2335 { PT_GPR9, "gpr9" },
2336 { PT_GPR10, "gpr10" },
2337 { PT_GPR11, "gpr11" },
2338 { PT_GPR12, "gpr12" },
2339 { PT_GPR13, "gpr13" },
2340 { PT_GPR14, "gpr14" },
2341 { PT_GPR15, "gpr15" },
2342 { PT_ACR0, "acr0" },
2343 { PT_ACR1, "acr1" },
2344 { PT_ACR2, "acr2" },
2345 { PT_ACR3, "acr3" },
2346 { PT_ACR4, "acr4" },
2347 { PT_ACR5, "acr5" },
2348 { PT_ACR6, "acr6" },
2349 { PT_ACR7, "acr7" },
2350 { PT_ACR8, "acr8" },
2351 { PT_ACR9, "acr9" },
2352 { PT_ACR10, "acr10" },
2353 { PT_ACR11, "acr11" },
2354 { PT_ACR12, "acr12" },
2355 { PT_ACR13, "acr13" },
2356 { PT_ACR14, "acr14" },
2357 { PT_ACR15, "acr15" },
2358 { PT_ORIGGPR2, "orig_gpr2" },
2361 { PT_FPR0_HI, "fpr0.hi" },
2362 { PT_FPR0_LO, "fpr0.lo" },
2363 { PT_FPR1_HI, "fpr1.hi" },
2364 { PT_FPR1_LO, "fpr1.lo" },
2365 { PT_FPR2_HI, "fpr2.hi" },
2366 { PT_FPR2_LO, "fpr2.lo" },
2367 { PT_FPR3_HI, "fpr3.hi" },
2368 { PT_FPR3_LO, "fpr3.lo" },
2369 { PT_FPR4_HI, "fpr4.hi" },
2370 { PT_FPR4_LO, "fpr4.lo" },
2371 { PT_FPR5_HI, "fpr5.hi" },
2372 { PT_FPR5_LO, "fpr5.lo" },
2373 { PT_FPR6_HI, "fpr6.hi" },
2374 { PT_FPR6_LO, "fpr6.lo" },
2375 { PT_FPR7_HI, "fpr7.hi" },
2376 { PT_FPR7_LO, "fpr7.lo" },
2377 { PT_FPR8_HI, "fpr8.hi" },
2378 { PT_FPR8_LO, "fpr8.lo" },
2379 { PT_FPR9_HI, "fpr9.hi" },
2380 { PT_FPR9_LO, "fpr9.lo" },
2381 { PT_FPR10_HI, "fpr10.hi" },
2382 { PT_FPR10_LO, "fpr10.lo" },
2383 { PT_FPR11_HI, "fpr11.hi" },
2384 { PT_FPR11_LO, "fpr11.lo" },
2385 { PT_FPR12_HI, "fpr12.hi" },
2386 { PT_FPR12_LO, "fpr12.lo" },
2387 { PT_FPR13_HI, "fpr13.hi" },
2388 { PT_FPR13_LO, "fpr13.lo" },
2389 { PT_FPR14_HI, "fpr14.hi" },
2390 { PT_FPR14_LO, "fpr14.lo" },
2391 { PT_FPR15_HI, "fpr15.hi" },
2392 { PT_FPR15_LO, "fpr15.lo" },
2395 { PT_FPR0, "fpr0" },
2396 { PT_FPR1, "fpr1" },
2397 { PT_FPR2, "fpr2" },
2398 { PT_FPR3, "fpr3" },
2399 { PT_FPR4, "fpr4" },
2400 { PT_FPR5, "fpr5" },
2401 { PT_FPR6, "fpr6" },
2402 { PT_FPR7, "fpr7" },
2403 { PT_FPR8, "fpr8" },
2404 { PT_FPR9, "fpr9" },
2405 { PT_FPR10, "fpr10" },
2406 { PT_FPR11, "fpr11" },
2407 { PT_FPR12, "fpr12" },
2408 { PT_FPR13, "fpr13" },
2409 { PT_FPR14, "fpr14" },
2410 { PT_FPR15, "fpr15" },
2413 { PT_CR_10, "cr10" },
2414 { PT_CR_11, "cr11" },
2415 { PT_IEEE_IP, "ieee_exception_ip" },
2416 # elif defined(SPARC)
2417 /* XXX No support for these offsets yet. */
2418 # elif defined(HPPA)
2419 /* XXX No support for these offsets yet. */
2420 # elif defined(POWERPC)
2422 # define PT_ORIG_R3 34
2424 # define REGSIZE (sizeof(unsigned long))
2425 { REGSIZE*PT_R0, "r0" },
2426 { REGSIZE*PT_R1, "r1" },
2427 { REGSIZE*PT_R2, "r2" },
2428 { REGSIZE*PT_R3, "r3" },
2429 { REGSIZE*PT_R4, "r4" },
2430 { REGSIZE*PT_R5, "r5" },
2431 { REGSIZE*PT_R6, "r6" },
2432 { REGSIZE*PT_R7, "r7" },
2433 { REGSIZE*PT_R8, "r8" },
2434 { REGSIZE*PT_R9, "r9" },
2435 { REGSIZE*PT_R10, "r10" },
2436 { REGSIZE*PT_R11, "r11" },
2437 { REGSIZE*PT_R12, "r12" },
2438 { REGSIZE*PT_R13, "r13" },
2439 { REGSIZE*PT_R14, "r14" },
2440 { REGSIZE*PT_R15, "r15" },
2441 { REGSIZE*PT_R16, "r16" },
2442 { REGSIZE*PT_R17, "r17" },
2443 { REGSIZE*PT_R18, "r18" },
2444 { REGSIZE*PT_R19, "r19" },
2445 { REGSIZE*PT_R20, "r20" },
2446 { REGSIZE*PT_R21, "r21" },
2447 { REGSIZE*PT_R22, "r22" },
2448 { REGSIZE*PT_R23, "r23" },
2449 { REGSIZE*PT_R24, "r24" },
2450 { REGSIZE*PT_R25, "r25" },
2451 { REGSIZE*PT_R26, "r26" },
2452 { REGSIZE*PT_R27, "r27" },
2453 { REGSIZE*PT_R28, "r28" },
2454 { REGSIZE*PT_R29, "r29" },
2455 { REGSIZE*PT_R30, "r30" },
2456 { REGSIZE*PT_R31, "r31" },
2457 { REGSIZE*PT_NIP, "NIP" },
2458 { REGSIZE*PT_MSR, "MSR" },
2459 { REGSIZE*PT_ORIG_R3, "ORIG_R3" },
2460 { REGSIZE*PT_CTR, "CTR" },
2461 { REGSIZE*PT_LNK, "LNK" },
2462 { REGSIZE*PT_XER, "XER" },
2463 { REGSIZE*PT_CCR, "CCR" },
2464 { REGSIZE*PT_FPR0, "FPR0" },
2466 # elif defined(ALPHA)
2532 # elif defined(IA64)
2533 { PT_F32, "f32" }, { PT_F33, "f33" }, { PT_F34, "f34" },
2534 { PT_F35, "f35" }, { PT_F36, "f36" }, { PT_F37, "f37" },
2535 { PT_F38, "f38" }, { PT_F39, "f39" }, { PT_F40, "f40" },
2536 { PT_F41, "f41" }, { PT_F42, "f42" }, { PT_F43, "f43" },
2537 { PT_F44, "f44" }, { PT_F45, "f45" }, { PT_F46, "f46" },
2538 { PT_F47, "f47" }, { PT_F48, "f48" }, { PT_F49, "f49" },
2539 { PT_F50, "f50" }, { PT_F51, "f51" }, { PT_F52, "f52" },
2540 { PT_F53, "f53" }, { PT_F54, "f54" }, { PT_F55, "f55" },
2541 { PT_F56, "f56" }, { PT_F57, "f57" }, { PT_F58, "f58" },
2542 { PT_F59, "f59" }, { PT_F60, "f60" }, { PT_F61, "f61" },
2543 { PT_F62, "f62" }, { PT_F63, "f63" }, { PT_F64, "f64" },
2544 { PT_F65, "f65" }, { PT_F66, "f66" }, { PT_F67, "f67" },
2545 { PT_F68, "f68" }, { PT_F69, "f69" }, { PT_F70, "f70" },
2546 { PT_F71, "f71" }, { PT_F72, "f72" }, { PT_F73, "f73" },
2547 { PT_F74, "f74" }, { PT_F75, "f75" }, { PT_F76, "f76" },
2548 { PT_F77, "f77" }, { PT_F78, "f78" }, { PT_F79, "f79" },
2549 { PT_F80, "f80" }, { PT_F81, "f81" }, { PT_F82, "f82" },
2550 { PT_F83, "f83" }, { PT_F84, "f84" }, { PT_F85, "f85" },
2551 { PT_F86, "f86" }, { PT_F87, "f87" }, { PT_F88, "f88" },
2552 { PT_F89, "f89" }, { PT_F90, "f90" }, { PT_F91, "f91" },
2553 { PT_F92, "f92" }, { PT_F93, "f93" }, { PT_F94, "f94" },
2554 { PT_F95, "f95" }, { PT_F96, "f96" }, { PT_F97, "f97" },
2555 { PT_F98, "f98" }, { PT_F99, "f99" }, { PT_F100, "f100" },
2556 { PT_F101, "f101" }, { PT_F102, "f102" }, { PT_F103, "f103" },
2557 { PT_F104, "f104" }, { PT_F105, "f105" }, { PT_F106, "f106" },
2558 { PT_F107, "f107" }, { PT_F108, "f108" }, { PT_F109, "f109" },
2559 { PT_F110, "f110" }, { PT_F111, "f111" }, { PT_F112, "f112" },
2560 { PT_F113, "f113" }, { PT_F114, "f114" }, { PT_F115, "f115" },
2561 { PT_F116, "f116" }, { PT_F117, "f117" }, { PT_F118, "f118" },
2562 { PT_F119, "f119" }, { PT_F120, "f120" }, { PT_F121, "f121" },
2563 { PT_F122, "f122" }, { PT_F123, "f123" }, { PT_F124, "f124" },
2564 { PT_F125, "f125" }, { PT_F126, "f126" }, { PT_F127, "f127" },
2566 { PT_F2, "f2" }, { PT_F3, "f3" }, { PT_F4, "f4" },
2567 { PT_F5, "f5" }, { PT_F10, "f10" }, { PT_F11, "f11" },
2568 { PT_F12, "f12" }, { PT_F13, "f13" }, { PT_F14, "f14" },
2569 { PT_F15, "f15" }, { PT_F16, "f16" }, { PT_F17, "f17" },
2570 { PT_F18, "f18" }, { PT_F19, "f19" }, { PT_F20, "f20" },
2571 { PT_F21, "f21" }, { PT_F22, "f22" }, { PT_F23, "f23" },
2572 { PT_F24, "f24" }, { PT_F25, "f25" }, { PT_F26, "f26" },
2573 { PT_F27, "f27" }, { PT_F28, "f28" }, { PT_F29, "f29" },
2574 { PT_F30, "f30" }, { PT_F31, "f31" }, { PT_R4, "r4" },
2575 { PT_R5, "r5" }, { PT_R6, "r6" }, { PT_R7, "r7" },
2576 { PT_B1, "b1" }, { PT_B2, "b2" }, { PT_B3, "b3" },
2577 { PT_B4, "b4" }, { PT_B5, "b5" },
2578 { PT_AR_EC, "ar.ec" }, { PT_AR_LC, "ar.lc" },
2580 { PT_CR_IPSR, "psr" }, { PT_CR_IIP, "ip" },
2581 { PT_CFM, "cfm" }, { PT_AR_UNAT, "ar.unat" },
2582 { PT_AR_PFS, "ar.pfs" }, { PT_AR_RSC, "ar.rsc" },
2583 { PT_AR_RNAT, "ar.rnat" }, { PT_AR_BSPSTORE, "ar.bspstore" },
2584 { PT_PR, "pr" }, { PT_B6, "b6" }, { PT_AR_BSP, "ar.bsp" },
2585 { PT_R1, "r1" }, { PT_R2, "r2" }, { PT_R3, "r3" },
2586 { PT_R12, "r12" }, { PT_R13, "r13" }, { PT_R14, "r14" },
2587 { PT_R15, "r15" }, { PT_R8, "r8" }, { PT_R9, "r9" },
2588 { PT_R10, "r10" }, { PT_R11, "r11" }, { PT_R16, "r16" },
2589 { PT_R17, "r17" }, { PT_R18, "r18" }, { PT_R19, "r19" },
2590 { PT_R20, "r20" }, { PT_R21, "r21" }, { PT_R22, "r22" },
2591 { PT_R23, "r23" }, { PT_R24, "r24" }, { PT_R25, "r25" },
2592 { PT_R26, "r26" }, { PT_R27, "r27" }, { PT_R28, "r28" },
2593 { PT_R29, "r29" }, { PT_R30, "r30" }, { PT_R31, "r31" },
2594 { PT_AR_CCV, "ar.ccv" }, { PT_AR_FPSR, "ar.fpsr" },
2595 { PT_B0, "b0" }, { PT_B7, "b7" }, { PT_F6, "f6" },
2596 { PT_F7, "f7" }, { PT_F8, "f8" }, { PT_F9, "f9" },
2598 { PT_AR_CSD, "ar.csd" },
2601 { PT_AR_SSD, "ar.ssd" },
2603 { PT_DBR, "dbr" }, { PT_IBR, "ibr" }, { PT_PMD, "pmd" },
2604 # elif defined(I386)
2616 { 4*ORIG_EAX, "4*ORIG_EAX" },
2620 { 4*UESP, "4*UESP" },
2622 # elif defined(X86_64)
2638 { 8*ORIG_RAX, "8*ORIG_RAX" },
2641 { 8*EFLAGS, "8*EFL" },
2644 # elif defined(M68K)
2645 { 4*PT_D1, "4*PT_D1" },
2646 { 4*PT_D2, "4*PT_D2" },
2647 { 4*PT_D3, "4*PT_D3" },
2648 { 4*PT_D4, "4*PT_D4" },
2649 { 4*PT_D5, "4*PT_D5" },
2650 { 4*PT_D6, "4*PT_D6" },
2651 { 4*PT_D7, "4*PT_D7" },
2652 { 4*PT_A0, "4*PT_A0" },
2653 { 4*PT_A1, "4*PT_A1" },
2654 { 4*PT_A2, "4*PT_A2" },
2655 { 4*PT_A3, "4*PT_A3" },
2656 { 4*PT_A4, "4*PT_A4" },
2657 { 4*PT_A5, "4*PT_A5" },
2658 { 4*PT_A6, "4*PT_A6" },
2659 { 4*PT_D0, "4*PT_D0" },
2660 { 4*PT_USP, "4*PT_USP" },
2661 { 4*PT_ORIG_D0, "4*PT_ORIG_D0" },
2662 { 4*PT_SR, "4*PT_SR" },
2663 { 4*PT_PC, "4*PT_PC" },
2665 { 4*REG_REG0, "4*REG_REG0" },
2666 { 4*(REG_REG0+1), "4*REG_REG1" },
2667 { 4*(REG_REG0+2), "4*REG_REG2" },
2668 { 4*(REG_REG0+3), "4*REG_REG3" },
2669 { 4*(REG_REG0+4), "4*REG_REG4" },
2670 { 4*(REG_REG0+5), "4*REG_REG5" },
2671 { 4*(REG_REG0+6), "4*REG_REG6" },
2672 { 4*(REG_REG0+7), "4*REG_REG7" },
2673 { 4*(REG_REG0+8), "4*REG_REG8" },
2674 { 4*(REG_REG0+9), "4*REG_REG9" },
2675 { 4*(REG_REG0+10), "4*REG_REG10" },
2676 { 4*(REG_REG0+11), "4*REG_REG11" },
2677 { 4*(REG_REG0+12), "4*REG_REG12" },
2678 { 4*(REG_REG0+13), "4*REG_REG13" },
2679 { 4*(REG_REG0+14), "4*REG_REG14" },
2680 { 4*REG_REG15, "4*REG_REG15" },
2681 { 4*REG_PC, "4*REG_PC" },
2682 { 4*REG_PR, "4*REG_PR" },
2683 { 4*REG_SR, "4*REG_SR" },
2684 { 4*REG_GBR, "4*REG_GBR" },
2685 { 4*REG_MACH, "4*REG_MACH" },
2686 { 4*REG_MACL, "4*REG_MACL" },
2687 { 4*REG_SYSCALL, "4*REG_SYSCALL" },
2688 { 4*REG_FPUL, "4*REG_FPUL" },
2689 { 4*REG_FPREG0, "4*REG_FPREG0" },
2690 { 4*(REG_FPREG0+1), "4*REG_FPREG1" },
2691 { 4*(REG_FPREG0+2), "4*REG_FPREG2" },
2692 { 4*(REG_FPREG0+3), "4*REG_FPREG3" },
2693 { 4*(REG_FPREG0+4), "4*REG_FPREG4" },
2694 { 4*(REG_FPREG0+5), "4*REG_FPREG5" },
2695 { 4*(REG_FPREG0+6), "4*REG_FPREG6" },
2696 { 4*(REG_FPREG0+7), "4*REG_FPREG7" },
2697 { 4*(REG_FPREG0+8), "4*REG_FPREG8" },
2698 { 4*(REG_FPREG0+9), "4*REG_FPREG9" },
2699 { 4*(REG_FPREG0+10), "4*REG_FPREG10" },
2700 { 4*(REG_FPREG0+11), "4*REG_FPREG11" },
2701 { 4*(REG_FPREG0+12), "4*REG_FPREG12" },
2702 { 4*(REG_FPREG0+13), "4*REG_FPREG13" },
2703 { 4*(REG_FPREG0+14), "4*REG_FPREG14" },
2704 { 4*REG_FPREG15, "4*REG_FPREG15" },
2706 { 4*REG_XDREG0, "4*REG_XDREG0" },
2707 { 4*(REG_XDREG0+2), "4*REG_XDREG2" },
2708 { 4*(REG_XDREG0+4), "4*REG_XDREG4" },
2709 { 4*(REG_XDREG0+6), "4*REG_XDREG6" },
2710 { 4*(REG_XDREG0+8), "4*REG_XDREG8" },
2711 { 4*(REG_XDREG0+10), "4*REG_XDREG10" },
2712 { 4*(REG_XDREG0+12), "4*REG_XDREG12" },
2713 { 4*REG_XDREG14, "4*REG_XDREG14" },
2715 { 4*REG_FPSCR, "4*REG_FPSCR" },
2716 # elif defined(SH64)
2721 { 16, "syscall no.(L)" },
2722 { 20, "syscall_no.(U)" },
2865 /* This entry is in case pt_regs contains dregs (depends on
2866 the kernel build options). */
2867 { uoff(regs), "offsetof(struct user, regs)" },
2868 { uoff(fpu), "offsetof(struct user, fpu)" },
2870 { uoff(regs.ARM_r0), "r0" },
2871 { uoff(regs.ARM_r1), "r1" },
2872 { uoff(regs.ARM_r2), "r2" },
2873 { uoff(regs.ARM_r3), "r3" },
2874 { uoff(regs.ARM_r4), "r4" },
2875 { uoff(regs.ARM_r5), "r5" },
2876 { uoff(regs.ARM_r6), "r6" },
2877 { uoff(regs.ARM_r7), "r7" },
2878 { uoff(regs.ARM_r8), "r8" },
2879 { uoff(regs.ARM_r9), "r9" },
2880 { uoff(regs.ARM_r10), "r10" },
2881 { uoff(regs.ARM_fp), "fp" },
2882 { uoff(regs.ARM_ip), "ip" },
2883 { uoff(regs.ARM_sp), "sp" },
2884 { uoff(regs.ARM_lr), "lr" },
2885 { uoff(regs.ARM_pc), "pc" },
2886 { uoff(regs.ARM_cpsr), "cpsr" },
2887 # elif defined(AVR32)
2888 { uoff(regs.sr), "sr" },
2889 { uoff(regs.pc), "pc" },
2890 { uoff(regs.lr), "lr" },
2891 { uoff(regs.sp), "sp" },
2892 { uoff(regs.r12), "r12" },
2893 { uoff(regs.r11), "r11" },
2894 { uoff(regs.r10), "r10" },
2895 { uoff(regs.r9), "r9" },
2896 { uoff(regs.r8), "r8" },
2897 { uoff(regs.r7), "r7" },
2898 { uoff(regs.r6), "r6" },
2899 { uoff(regs.r5), "r5" },
2900 { uoff(regs.r4), "r4" },
2901 { uoff(regs.r3), "r3" },
2902 { uoff(regs.r2), "r2" },
2903 { uoff(regs.r1), "r1" },
2904 { uoff(regs.r0), "r0" },
2905 { uoff(regs.r12_orig), "orig_r12" },
2906 # elif defined(MIPS)
2978 # elif defined(TILE)
2979 { PTREGS_OFFSET_REG(0), "r0" },
2980 { PTREGS_OFFSET_REG(1), "r1" },
2981 { PTREGS_OFFSET_REG(2), "r2" },
2982 { PTREGS_OFFSET_REG(3), "r3" },
2983 { PTREGS_OFFSET_REG(4), "r4" },
2984 { PTREGS_OFFSET_REG(5), "r5" },
2985 { PTREGS_OFFSET_REG(6), "r6" },
2986 { PTREGS_OFFSET_REG(7), "r7" },
2987 { PTREGS_OFFSET_REG(8), "r8" },
2988 { PTREGS_OFFSET_REG(9), "r9" },
2989 { PTREGS_OFFSET_REG(10), "r10" },
2990 { PTREGS_OFFSET_REG(11), "r11" },
2991 { PTREGS_OFFSET_REG(12), "r12" },
2992 { PTREGS_OFFSET_REG(13), "r13" },
2993 { PTREGS_OFFSET_REG(14), "r14" },
2994 { PTREGS_OFFSET_REG(15), "r15" },
2995 { PTREGS_OFFSET_REG(16), "r16" },
2996 { PTREGS_OFFSET_REG(17), "r17" },
2997 { PTREGS_OFFSET_REG(18), "r18" },
2998 { PTREGS_OFFSET_REG(19), "r19" },
2999 { PTREGS_OFFSET_REG(20), "r20" },
3000 { PTREGS_OFFSET_REG(21), "r21" },
3001 { PTREGS_OFFSET_REG(22), "r22" },
3002 { PTREGS_OFFSET_REG(23), "r23" },
3003 { PTREGS_OFFSET_REG(24), "r24" },
3004 { PTREGS_OFFSET_REG(25), "r25" },
3005 { PTREGS_OFFSET_REG(26), "r26" },
3006 { PTREGS_OFFSET_REG(27), "r27" },
3007 { PTREGS_OFFSET_REG(28), "r28" },
3008 { PTREGS_OFFSET_REG(29), "r29" },
3009 { PTREGS_OFFSET_REG(30), "r30" },
3010 { PTREGS_OFFSET_REG(31), "r31" },
3011 { PTREGS_OFFSET_REG(32), "r32" },
3012 { PTREGS_OFFSET_REG(33), "r33" },
3013 { PTREGS_OFFSET_REG(34), "r34" },
3014 { PTREGS_OFFSET_REG(35), "r35" },
3015 { PTREGS_OFFSET_REG(36), "r36" },
3016 { PTREGS_OFFSET_REG(37), "r37" },
3017 { PTREGS_OFFSET_REG(38), "r38" },
3018 { PTREGS_OFFSET_REG(39), "r39" },
3019 { PTREGS_OFFSET_REG(40), "r40" },
3020 { PTREGS_OFFSET_REG(41), "r41" },
3021 { PTREGS_OFFSET_REG(42), "r42" },
3022 { PTREGS_OFFSET_REG(43), "r43" },
3023 { PTREGS_OFFSET_REG(44), "r44" },
3024 { PTREGS_OFFSET_REG(45), "r45" },
3025 { PTREGS_OFFSET_REG(46), "r46" },
3026 { PTREGS_OFFSET_REG(47), "r47" },
3027 { PTREGS_OFFSET_REG(48), "r48" },
3028 { PTREGS_OFFSET_REG(49), "r49" },
3029 { PTREGS_OFFSET_REG(50), "r50" },
3030 { PTREGS_OFFSET_REG(51), "r51" },
3031 { PTREGS_OFFSET_REG(52), "r52" },
3032 { PTREGS_OFFSET_TP, "tp" },
3033 { PTREGS_OFFSET_SP, "sp" },
3034 { PTREGS_OFFSET_LR, "lr" },
3035 { PTREGS_OFFSET_PC, "pc" },
3036 { PTREGS_OFFSET_EX1, "ex1" },
3037 { PTREGS_OFFSET_FAULTNUM, "faultnum" },
3038 { PTREGS_OFFSET_ORIG_R0, "orig_r0" },
3039 { PTREGS_OFFSET_FLAGS, "flags" },
3042 { 4*PT_FRAMETYPE, "4*PT_FRAMETYPE" },
3043 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3044 { 4*PT_R13, "4*PT_R13" },
3045 { 4*PT_R12, "4*PT_R12" },
3046 { 4*PT_R11, "4*PT_R11" },
3047 { 4*PT_R10, "4*PT_R10" },
3048 { 4*PT_R9, "4*PT_R9" },
3049 { 4*PT_R8, "4*PT_R8" },
3050 { 4*PT_R7, "4*PT_R7" },
3051 { 4*PT_R6, "4*PT_R6" },
3052 { 4*PT_R5, "4*PT_R5" },
3053 { 4*PT_R4, "4*PT_R4" },
3054 { 4*PT_R3, "4*PT_R3" },
3055 { 4*PT_R2, "4*PT_R2" },
3056 { 4*PT_R1, "4*PT_R1" },
3057 { 4*PT_R0, "4*PT_R0" },
3058 { 4*PT_MOF, "4*PT_MOF" },
3059 { 4*PT_DCCR, "4*PT_DCCR" },
3060 { 4*PT_SRP, "4*PT_SRP" },
3061 { 4*PT_IRP, "4*PT_IRP" },
3062 { 4*PT_CSRINSTR, "4*PT_CSRINSTR" },
3063 { 4*PT_CSRADDR, "4*PT_CSRADDR" },
3064 { 4*PT_CSRDATA, "4*PT_CSRDATA" },
3065 { 4*PT_USP, "4*PT_USP" },
3068 { 4*PT_ORIG_R10, "4*PT_ORIG_R10" },
3069 { 4*PT_R0, "4*PT_R0" },
3070 { 4*PT_R1, "4*PT_R1" },
3071 { 4*PT_R2, "4*PT_R2" },
3072 { 4*PT_R3, "4*PT_R3" },
3073 { 4*PT_R4, "4*PT_R4" },
3074 { 4*PT_R5, "4*PT_R5" },
3075 { 4*PT_R6, "4*PT_R6" },
3076 { 4*PT_R7, "4*PT_R7" },
3077 { 4*PT_R8, "4*PT_R8" },
3078 { 4*PT_R9, "4*PT_R9" },
3079 { 4*PT_R10, "4*PT_R10" },
3080 { 4*PT_R11, "4*PT_R11" },
3081 { 4*PT_R12, "4*PT_R12" },
3082 { 4*PT_R13, "4*PT_R13" },
3083 { 4*PT_ACR, "4*PT_ACR" },
3084 { 4*PT_SRS, "4*PT_SRS" },
3085 { 4*PT_MOF, "4*PT_MOF" },
3086 { 4*PT_SPC, "4*PT_SPC" },
3087 { 4*PT_CCS, "4*PT_CCS" },
3088 { 4*PT_SRP, "4*PT_SRP" },
3089 { 4*PT_ERP, "4*PT_ERP" },
3090 { 4*PT_EXS, "4*PT_EXS" },
3091 { 4*PT_EDA, "4*PT_EDA" },
3092 { 4*PT_USP, "4*PT_USP" },
3093 { 4*PT_PPC, "4*PT_PPC" },
3094 { 4*PT_BP_CTRL, "4*PT_BP_CTRL" },
3095 { 4*PT_BP+4, "4*PT_BP+4" },
3096 { 4*PT_BP+8, "4*PT_BP+8" },
3097 { 4*PT_BP+12, "4*PT_BP+12" },
3098 { 4*PT_BP+16, "4*PT_BP+16" },
3099 { 4*PT_BP+20, "4*PT_BP+20" },
3100 { 4*PT_BP+24, "4*PT_BP+24" },
3101 { 4*PT_BP+28, "4*PT_BP+28" },
3102 { 4*PT_BP+32, "4*PT_BP+32" },
3103 { 4*PT_BP+36, "4*PT_BP+36" },
3104 { 4*PT_BP+40, "4*PT_BP+40" },
3105 { 4*PT_BP+44, "4*PT_BP+44" },
3106 { 4*PT_BP+48, "4*PT_BP+48" },
3107 { 4*PT_BP+52, "4*PT_BP+52" },
3108 { 4*PT_BP+56, "4*PT_BP+56" },
3111 { PT_GPR(0), "r0" },
3112 { PT_GPR(1), "r1" },
3113 { PT_GPR(2), "r2" },
3114 { PT_GPR(3), "r3" },
3115 { PT_GPR(4), "r4" },
3116 { PT_GPR(5), "r5" },
3117 { PT_GPR(6), "r6" },
3118 { PT_GPR(7), "r7" },
3119 { PT_GPR(8), "r8" },
3120 { PT_GPR(9), "r9" },
3121 { PT_GPR(10), "r10" },
3122 { PT_GPR(11), "r11" },
3123 { PT_GPR(12), "r12" },
3124 { PT_GPR(13), "r13" },
3125 { PT_GPR(14), "r14" },
3126 { PT_GPR(15), "r15" },
3127 { PT_GPR(16), "r16" },
3128 { PT_GPR(17), "r17" },
3129 { PT_GPR(18), "r18" },
3130 { PT_GPR(19), "r19" },
3131 { PT_GPR(20), "r20" },
3132 { PT_GPR(21), "r21" },
3133 { PT_GPR(22), "r22" },
3134 { PT_GPR(23), "r23" },
3135 { PT_GPR(24), "r24" },
3136 { PT_GPR(25), "r25" },
3137 { PT_GPR(26), "r26" },
3138 { PT_GPR(27), "r27" },
3139 { PT_GPR(28), "r28" },
3140 { PT_GPR(29), "r29" },
3141 { PT_GPR(30), "r30" },
3142 { PT_GPR(31), "r31" },
3144 { PT_MSR, "rmsr", },
3145 { PT_EAR, "rear", },
3146 { PT_ESR, "resr", },
3147 { PT_FSR, "rfsr", },
3148 { PT_KERNEL_MODE, "kernel_mode", },
3151 # if !defined(SPARC) && !defined(HPPA) && !defined(POWERPC) \
3152 && !defined(ALPHA) && !defined(IA64) \
3153 && !defined(CRISV10) && !defined(CRISV32) && !defined(MICROBLAZE)
3154 # if !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SPARC64) && !defined(AVR32) && !defined(BFIN) && !defined(TILE)
3155 { uoff(u_fpvalid), "offsetof(struct user, u_fpvalid)" },
3157 # if defined(I386) || defined(X86_64)
3158 { uoff(i387), "offsetof(struct user, i387)" },
3161 { uoff(m68kfp), "offsetof(struct user, m68kfp)" },
3163 { uoff(u_tsize), "offsetof(struct user, u_tsize)" },
3164 { uoff(u_dsize), "offsetof(struct user, u_dsize)" },
3165 { uoff(u_ssize), "offsetof(struct user, u_ssize)" },
3166 # if !defined(SPARC64)
3167 { uoff(start_code), "offsetof(struct user, start_code)" },
3169 # if defined(AVR32) || defined(SH64)
3170 { uoff(start_data), "offsetof(struct user, start_data)" },
3172 # if !defined(SPARC64)
3173 { uoff(start_stack), "offsetof(struct user, start_stack)" },
3175 { uoff(signal), "offsetof(struct user, signal)" },
3176 # if !defined(AVR32) && !defined(S390) && !defined(S390X) && !defined(MIPS) && !defined(SH) && !defined(SH64) && !defined(SPARC64) && !defined(TILE)
3177 { uoff(reserved), "offsetof(struct user, reserved)" },
3179 # if !defined(SPARC64)
3180 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3182 # if !defined(ARM) && !defined(AVR32) && !defined(MIPS) && !defined(S390) && !defined(S390X) && !defined(SPARC64) && !defined(BFIN) && !defined(TILE)
3183 { uoff(u_fpstate), "offsetof(struct user, u_fpstate)" },
3185 { uoff(magic), "offsetof(struct user, magic)" },
3186 { uoff(u_comm), "offsetof(struct user, u_comm)" },
3187 # if defined(I386) || defined(X86_64)
3188 { uoff(u_debugreg), "offsetof(struct user, u_debugreg)" },
3190 # endif /* !defined(many arches) */
3195 { uoff(u_pcb), "offsetof(struct user, u_pcb)" },
3196 { uoff(u_procp), "offsetof(struct user, u_procp)" },
3197 { uoff(u_ar0), "offsetof(struct user, u_ar0)" },
3198 { uoff(u_comm[0]), "offsetof(struct user, u_comm[0])" },
3199 { uoff(u_arg[0]), "offsetof(struct user, u_arg[0])" },
3200 { uoff(u_ap), "offsetof(struct user, u_ap)" },
3201 { uoff(u_qsave), "offsetof(struct user, u_qsave)" },
3202 { uoff(u_rval1), "offsetof(struct user, u_rval1)" },
3203 { uoff(u_rval2), "offsetof(struct user, u_rval2)" },
3204 { uoff(u_error), "offsetof(struct user, u_error)" },
3205 { uoff(u_eosys), "offsetof(struct user, u_eosys)" },
3206 { uoff(u_ssave), "offsetof(struct user, u_ssave)" },
3207 { uoff(u_signal[0]), "offsetof(struct user, u_signal)" },
3208 { uoff(u_sigmask[0]), "offsetof(struct user, u_sigmask)" },
3209 { uoff(u_sigonstack), "offsetof(struct user, u_sigonstack)" },
3210 { uoff(u_sigintr), "offsetof(struct user, u_sigintr)" },
3211 { uoff(u_sigreset), "offsetof(struct user, u_sigreset)" },
3212 { uoff(u_oldmask), "offsetof(struct user, u_oldmask)" },
3213 { uoff(u_code), "offsetof(struct user, u_code)" },
3214 { uoff(u_addr), "offsetof(struct user, u_addr)" },
3215 { uoff(u_sigstack), "offsetof(struct user, u_sigstack)" },
3216 { uoff(u_ofile), "offsetof(struct user, u_ofile)" },
3217 { uoff(u_pofile), "offsetof(struct user, u_pofile)" },
3218 { uoff(u_ofile_arr[0]), "offsetof(struct user, u_ofile_arr[0])" },
3219 { uoff(u_pofile_arr[0]),"offsetof(struct user, u_pofile_arr[0])"},
3220 { uoff(u_lastfile), "offsetof(struct user, u_lastfile)" },
3221 { uoff(u_cwd), "offsetof(struct user, u_cwd)" },
3222 { uoff(u_cdir), "offsetof(struct user, u_cdir)" },
3223 { uoff(u_rdir), "offsetof(struct user, u_rdir)" },
3224 { uoff(u_cmask), "offsetof(struct user, u_cmask)" },
3225 { uoff(u_ru), "offsetof(struct user, u_ru)" },
3226 { uoff(u_cru), "offsetof(struct user, u_cru)" },
3227 { uoff(u_timer[0]), "offsetof(struct user, u_timer[0])" },
3228 { uoff(u_XXX[0]), "offsetof(struct user, u_XXX[0])" },
3229 { uoff(u_ioch), "offsetof(struct user, u_ioch)" },
3230 { uoff(u_start), "offsetof(struct user, u_start)" },
3231 { uoff(u_acflag), "offsetof(struct user, u_acflag)" },
3232 { uoff(u_prof.pr_base), "offsetof(struct user, u_prof.pr_base)" },
3233 { uoff(u_prof.pr_size), "offsetof(struct user, u_prof.pr_size)" },
3234 { uoff(u_prof.pr_off), "offsetof(struct user, u_prof.pr_off)" },
3235 { uoff(u_prof.pr_scale),"offsetof(struct user, u_prof.pr_scale)"},
3236 { uoff(u_rlimit[0]), "offsetof(struct user, u_rlimit)" },
3237 { uoff(u_exdata.Ux_A), "offsetof(struct user, u_exdata.Ux_A)" },
3238 { uoff(u_exdata.ux_shell[0]),"offsetof(struct user, u_exdata.ux_shell[0])"},
3239 { uoff(u_lofault), "offsetof(struct user, u_lofault)" },
3240 # endif /* SUNOS4 */
3242 { sizeof(struct user), "sizeof(struct user)" },
3246 # endif /* !FREEBSD */
3249 sys_ptrace(struct tcb *tcp)
3251 const struct xlat *x;
3254 if (entering(tcp)) {
3255 printxval(ptrace_cmds, tcp->u_arg[0],
3262 tprintf(", %lu, ", tcp->u_arg[1]);
3263 addr = tcp->u_arg[2];
3265 if (tcp->u_arg[0] == PTRACE_PEEKUSER
3266 || tcp->u_arg[0] == PTRACE_POKEUSER) {
3267 for (x = struct_user_offsets; x->str; x++) {
3272 tprintf("%#lx, ", addr);
3273 else if (x->val > addr && x != struct_user_offsets) {
3275 tprintf("%s + %ld, ", x->str, addr - x->val);
3278 tprintf("%s, ", x->str);
3282 tprintf("%#lx, ", tcp->u_arg[2]);
3284 switch (tcp->u_arg[0]) {
3286 case PTRACE_PEEKDATA:
3287 case PTRACE_PEEKTEXT:
3288 case PTRACE_PEEKUSER:
3292 case PTRACE_SINGLESTEP:
3293 case PTRACE_SYSCALL:
3295 printsignal(tcp->u_arg[3]);
3297 # ifdef PTRACE_SETOPTIONS
3298 case PTRACE_SETOPTIONS:
3299 printflags(ptrace_setoptions_flags, tcp->u_arg[3], "PTRACE_O_???");
3302 # ifdef PTRACE_SETSIGINFO
3303 case PTRACE_SETSIGINFO: {
3307 else if (syserror(tcp))
3308 tprintf("%#lx", tcp->u_arg[3]);
3309 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3312 printsiginfo(&si, verbose(tcp));
3316 # ifdef PTRACE_GETSIGINFO
3317 case PTRACE_GETSIGINFO:
3318 /* Don't print anything, do it at syscall return. */
3322 tprintf("%#lx", tcp->u_arg[3]);
3326 switch (tcp->u_arg[0]) {
3327 case PTRACE_PEEKDATA:
3328 case PTRACE_PEEKTEXT:
3329 case PTRACE_PEEKUSER:
3333 printnum(tcp, tcp->u_arg[3], "%#lx");
3336 # ifdef PTRACE_GETSIGINFO
3337 case PTRACE_GETSIGINFO: {
3341 else if (syserror(tcp))
3342 tprintf("%#lx", tcp->u_arg[3]);
3343 else if (umove(tcp, tcp->u_arg[3], &si) < 0)
3346 printsiginfo(&si, verbose(tcp));
3354 if (tcp->u_arg[0] == PTRACE_WRITEDATA ||
3355 tcp->u_arg[0] == PTRACE_WRITETEXT) {
3356 tprintf("%lu, ", tcp->u_arg[3]);
3357 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3358 } else if (tcp->u_arg[0] != PTRACE_READDATA &&
3359 tcp->u_arg[0] != PTRACE_READTEXT) {
3360 tprintf("%#lx", tcp->u_arg[3]);
3363 if (tcp->u_arg[0] == PTRACE_READDATA ||
3364 tcp->u_arg[0] == PTRACE_READTEXT) {
3365 tprintf("%lu, ", tcp->u_arg[3]);
3366 printstr(tcp, tcp->u_arg[4], tcp->u_arg[3]);
3369 # endif /* SUNOS4 */
3371 tprintf("%lu", tcp->u_arg[3]);
3373 # endif /* FREEBSD */
3380 # ifndef FUTEX_CMP_REQUEUE
3381 # define FUTEX_CMP_REQUEUE 4
3383 # ifndef FUTEX_WAKE_OP
3384 # define FUTEX_WAKE_OP 5
3386 # ifndef FUTEX_LOCK_PI
3387 # define FUTEX_LOCK_PI 6
3388 # define FUTEX_UNLOCK_PI 7
3389 # define FUTEX_TRYLOCK_PI 8
3391 # ifndef FUTEX_WAIT_BITSET
3392 # define FUTEX_WAIT_BITSET 9
3394 # ifndef FUTEX_WAKE_BITSET
3395 # define FUTEX_WAKE_BITSET 10
3397 # ifndef FUTEX_WAIT_REQUEUE_PI
3398 # define FUTEX_WAIT_REQUEUE_PI 11
3400 # ifndef FUTEX_CMP_REQUEUE_PI
3401 # define FUTEX_CMP_REQUEUE_PI 12
3403 # ifndef FUTEX_PRIVATE_FLAG
3404 # define FUTEX_PRIVATE_FLAG 128
3406 # ifndef FUTEX_CLOCK_REALTIME
3407 # define FUTEX_CLOCK_REALTIME 256
3409 static const struct xlat futexops[] = {
3410 { FUTEX_WAIT, "FUTEX_WAIT" },
3411 { FUTEX_WAKE, "FUTEX_WAKE" },
3412 { FUTEX_FD, "FUTEX_FD" },
3413 { FUTEX_REQUEUE, "FUTEX_REQUEUE" },
3414 { FUTEX_CMP_REQUEUE, "FUTEX_CMP_REQUEUE" },
3415 { FUTEX_WAKE_OP, "FUTEX_WAKE_OP" },
3416 { FUTEX_LOCK_PI, "FUTEX_LOCK_PI" },
3417 { FUTEX_UNLOCK_PI, "FUTEX_UNLOCK_PI" },
3418 { FUTEX_TRYLOCK_PI, "FUTEX_TRYLOCK_PI" },
3419 { FUTEX_WAIT_BITSET, "FUTEX_WAIT_BITSET" },
3420 { FUTEX_WAKE_BITSET, "FUTEX_WAKE_BITSET" },
3421 { FUTEX_WAIT_REQUEUE_PI, "FUTEX_WAIT_REQUEUE_PI" },
3422 { FUTEX_CMP_REQUEUE_PI, "FUTEX_CMP_REQUEUE_PI" },
3423 { FUTEX_WAIT|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_PRIVATE" },
3424 { FUTEX_WAKE|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_PRIVATE" },
3425 { FUTEX_FD|FUTEX_PRIVATE_FLAG, "FUTEX_FD_PRIVATE" },
3426 { FUTEX_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_REQUEUE_PRIVATE" },
3427 { FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PRIVATE" },
3428 { FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_OP_PRIVATE" },
3429 { FUTEX_LOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_LOCK_PI_PRIVATE" },
3430 { FUTEX_UNLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_UNLOCK_PI_PRIVATE" },
3431 { FUTEX_TRYLOCK_PI|FUTEX_PRIVATE_FLAG, "FUTEX_TRYLOCK_PI_PRIVATE" },
3432 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_BITSET_PRIVATE" },
3433 { FUTEX_WAKE_BITSET|FUTEX_PRIVATE_FLAG, "FUTEX_WAKE_BITSET_PRIVATE" },
3434 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_WAIT_REQUEUE_PI_PRIVATE" },
3435 { FUTEX_CMP_REQUEUE_PI|FUTEX_PRIVATE_FLAG, "FUTEX_CMP_REQUEUE_PI_PRIVATE" },
3436 { FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET|FUTEX_CLOCK_REALTIME" },
3437 { FUTEX_WAIT_BITSET|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME" },
3438 { FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI|FUTEX_CLOCK_REALTIME" },
3439 { FUTEX_WAIT_REQUEUE_PI|FUTEX_PRIVATE_FLAG|FUTEX_CLOCK_REALTIME, "FUTEX_WAIT_REQUEUE_PI_PRIVATE|FUTEX_CLOCK_REALTIME" },
3442 # ifndef FUTEX_OP_SET
3443 # define FUTEX_OP_SET 0
3444 # define FUTEX_OP_ADD 1
3445 # define FUTEX_OP_OR 2
3446 # define FUTEX_OP_ANDN 3
3447 # define FUTEX_OP_XOR 4
3448 # define FUTEX_OP_CMP_EQ 0
3449 # define FUTEX_OP_CMP_NE 1
3450 # define FUTEX_OP_CMP_LT 2
3451 # define FUTEX_OP_CMP_LE 3
3452 # define FUTEX_OP_CMP_GT 4
3453 # define FUTEX_OP_CMP_GE 5
3455 static const struct xlat futexwakeops[] = {
3456 { FUTEX_OP_SET, "FUTEX_OP_SET" },
3457 { FUTEX_OP_ADD, "FUTEX_OP_ADD" },
3458 { FUTEX_OP_OR, "FUTEX_OP_OR" },
3459 { FUTEX_OP_ANDN, "FUTEX_OP_ANDN" },
3460 { FUTEX_OP_XOR, "FUTEX_OP_XOR" },
3463 static const struct xlat futexwakecmps[] = {
3464 { FUTEX_OP_CMP_EQ, "FUTEX_OP_CMP_EQ" },
3465 { FUTEX_OP_CMP_NE, "FUTEX_OP_CMP_NE" },
3466 { FUTEX_OP_CMP_LT, "FUTEX_OP_CMP_LT" },
3467 { FUTEX_OP_CMP_LE, "FUTEX_OP_CMP_LE" },
3468 { FUTEX_OP_CMP_GT, "FUTEX_OP_CMP_GT" },
3469 { FUTEX_OP_CMP_GE, "FUTEX_OP_CMP_GE" },
3474 sys_futex(struct tcb *tcp)
3476 if (entering(tcp)) {
3477 long int cmd = tcp->u_arg[1] & 127;
3478 tprintf("%p, ", (void *) tcp->u_arg[0]);
3479 printxval(futexops, tcp->u_arg[1], "FUTEX_???");
3480 tprintf(", %ld", tcp->u_arg[2]);
3481 if (cmd == FUTEX_WAKE_BITSET)
3482 tprintf(", %lx", tcp->u_arg[5]);
3483 else if (cmd == FUTEX_WAIT) {
3485 printtv(tcp, tcp->u_arg[3]);
3486 } else if (cmd == FUTEX_WAIT_BITSET) {
3488 printtv(tcp, tcp->u_arg[3]);
3489 tprintf(", %lx", tcp->u_arg[5]);
3490 } else if (cmd == FUTEX_REQUEUE)
3491 tprintf(", %ld, %p", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3492 else if (cmd == FUTEX_CMP_REQUEUE || cmd == FUTEX_CMP_REQUEUE_PI)
3493 tprintf(", %ld, %p, %ld", tcp->u_arg[3], (void *) tcp->u_arg[4], tcp->u_arg[5]);
3494 else if (cmd == FUTEX_WAKE_OP) {
3495 tprintf(", %ld, %p, {", tcp->u_arg[3], (void *) tcp->u_arg[4]);
3496 if ((tcp->u_arg[5] >> 28) & 8)
3497 tprintf("FUTEX_OP_OPARG_SHIFT|");
3498 printxval(futexwakeops, (tcp->u_arg[5] >> 28) & 0x7, "FUTEX_OP_???");
3499 tprintf(", %ld, ", (tcp->u_arg[5] >> 12) & 0xfff);
3500 if ((tcp->u_arg[5] >> 24) & 8)
3501 tprintf("FUTEX_OP_OPARG_SHIFT|");
3502 printxval(futexwakecmps, (tcp->u_arg[5] >> 24) & 0x7, "FUTEX_OP_CMP_???");
3503 tprintf(", %ld}", tcp->u_arg[5] & 0xfff);
3504 } else if (cmd == FUTEX_WAIT_REQUEUE_PI) {
3506 printtv(tcp, tcp->u_arg[3]);
3507 tprintf(", %p", (void *) tcp->u_arg[4]);
3514 print_affinitylist(struct tcb *tcp, long list, unsigned int len)
3517 unsigned long w, min_len;
3519 if (abbrev(tcp) && len / sizeof(w) > max_strlen)
3520 min_len = len - max_strlen * sizeof(w);
3523 for (; len >= sizeof(w) && len > min_len;
3524 len -= sizeof(w), list += sizeof(w)) {
3525 if (umove(tcp, list, &w) < 0)
3536 tprintf("%#lx", list);
3538 tprintf(", %s}", (len >= sizeof(w) && len > min_len ?
3541 tprintf(first ? "{}" : "}");
3546 sys_sched_setaffinity(struct tcb *tcp)
3548 if (entering(tcp)) {
3549 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3550 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_arg[1]);
3556 sys_sched_getaffinity(struct tcb *tcp)
3558 if (entering(tcp)) {
3559 tprintf("%ld, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
3561 if (tcp->u_rval == -1)
3562 tprintf("%#lx", tcp->u_arg[2]);
3564 print_affinitylist(tcp, tcp->u_arg[2], tcp->u_rval);
3569 static const struct xlat schedulers[] = {
3570 { SCHED_OTHER, "SCHED_OTHER" },
3571 { SCHED_RR, "SCHED_RR" },
3572 { SCHED_FIFO, "SCHED_FIFO" },
3577 sys_sched_getscheduler(struct tcb *tcp)
3579 if (entering(tcp)) {
3580 tprintf("%d", (int) tcp->u_arg[0]);
3581 } else if (! syserror(tcp)) {
3582 tcp->auxstr = xlookup(schedulers, tcp->u_rval);
3583 if (tcp->auxstr != NULL)
3590 sys_sched_setscheduler(struct tcb *tcp)
3592 if (entering(tcp)) {
3593 struct sched_param p;
3594 tprintf("%d, ", (int) tcp->u_arg[0]);
3595 printxval(schedulers, tcp->u_arg[1], "SCHED_???");
3596 if (umove(tcp, tcp->u_arg[2], &p) < 0)
3597 tprintf(", %#lx", tcp->u_arg[2]);
3599 tprintf(", { %d }", p.__sched_priority);
3605 sys_sched_getparam(struct tcb *tcp)
3607 if (entering(tcp)) {
3608 tprintf("%d, ", (int) tcp->u_arg[0]);
3610 struct sched_param p;
3611 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3612 tprintf("%#lx", tcp->u_arg[1]);
3614 tprintf("{ %d }", p.__sched_priority);
3620 sys_sched_setparam(struct tcb *tcp)
3622 if (entering(tcp)) {
3623 struct sched_param p;
3624 if (umove(tcp, tcp->u_arg[1], &p) < 0)
3625 tprintf("%d, %#lx", (int) tcp->u_arg[0], tcp->u_arg[1]);
3627 tprintf("%d, { %d }", (int) tcp->u_arg[0], p.__sched_priority);
3633 sys_sched_get_priority_min(struct tcb *tcp)
3635 if (entering(tcp)) {
3636 printxval(schedulers, tcp->u_arg[0], "SCHED_???");
3642 # include <asm/prctl.h>
3644 static const struct xlat archvals[] = {
3645 { ARCH_SET_GS, "ARCH_SET_GS" },
3646 { ARCH_SET_FS, "ARCH_SET_FS" },
3647 { ARCH_GET_FS, "ARCH_GET_FS" },
3648 { ARCH_GET_GS, "ARCH_GET_GS" },
3653 sys_arch_prctl(struct tcb *tcp)
3655 if (entering(tcp)) {
3656 printxval(archvals, tcp->u_arg[0], "ARCH_???");
3657 if (tcp->u_arg[0] == ARCH_SET_GS
3658 || tcp->u_arg[0] == ARCH_SET_FS
3660 tprintf(", %#lx", tcp->u_arg[1]);
3663 if (tcp->u_arg[0] == ARCH_GET_GS
3664 || tcp->u_arg[0] == ARCH_GET_FS
3667 if (!syserror(tcp) && umove(tcp, tcp->u_arg[1], &v) != -1)
3668 tprintf(", [%#lx]", v);
3670 tprintf(", %#lx", tcp->u_arg[1]);
3675 # endif /* X86_64 */
3679 sys_getcpu(struct tcb *tcp)
3683 if (tcp->u_arg[0] == 0)
3685 else if (umove(tcp, tcp->u_arg[0], &u) < 0)
3686 tprintf("%#lx, ", tcp->u_arg[0]);
3688 tprintf("[%u], ", u);
3689 if (tcp->u_arg[1] == 0)
3691 else if (umove(tcp, tcp->u_arg[1], &u) < 0)
3692 tprintf("%#lx, ", tcp->u_arg[1]);
3694 tprintf("[%u], ", u);
3695 tprintf("%#lx", tcp->u_arg[2]);