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>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/syscall.h>
43 #include <sys/param.h>
47 #ifndef PTRACE_PEEKUSR
48 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
50 #elif defined(HAVE_LINUX_PTRACE_H)
52 # ifdef HAVE_STRUCT_IA64_FPREG
53 # define ia64_fpreg XXX_ia64_fpreg
55 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
56 # define pt_all_user_regs XXX_pt_all_user_regs
58 #include <linux/ptrace.h>
60 # undef pt_all_user_regs
63 #if defined (LINUX) && defined (SPARC64)
64 # undef PTRACE_GETREGS
65 # define PTRACE_GETREGS PTRACE_GETREGS64
66 # undef PTRACE_SETREGS
67 # define PTRACE_SETREGS PTRACE_SETREGS64
68 #endif /* LINUX && SPARC64 */
70 #if defined(LINUX) && defined(IA64)
71 # include <asm/ptrace_offsets.h>
75 #define NR_SYSCALL_BASE 0
78 #define ERESTARTSYS 512
80 #ifndef ERESTARTNOINTR
81 #define ERESTARTNOINTR 513
83 #ifndef ERESTARTNOHAND
84 #define ERESTARTNOHAND 514 /* restart if no handler.. */
87 #define ENOIOCTLCMD 515 /* No ioctl command */
89 #ifndef ERESTART_RESTARTBLOCK
90 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
98 #undef NR_SYSCALL_BASE
99 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
105 /* Define these shorthand notations to simplify the syscallent files. */
106 #define TD TRACE_DESC
107 #define TF TRACE_FILE
109 #define TN TRACE_NETWORK
110 #define TP TRACE_PROCESS
111 #define TS TRACE_SIGNAL
113 static const struct sysent sysent0[] = {
114 #include "syscallent.h"
116 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
117 int qual_flags0[MAX_QUALS];
119 #if SUPPORTED_PERSONALITIES >= 2
120 static const struct sysent sysent1[] = {
121 #include "syscallent1.h"
123 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
124 int qual_flags1[MAX_QUALS];
125 #endif /* SUPPORTED_PERSONALITIES >= 2 */
127 #if SUPPORTED_PERSONALITIES >= 3
128 static const struct sysent sysent2[] = {
129 #include "syscallent2.h"
131 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
132 int qual_flags2[MAX_QUALS];
133 #endif /* SUPPORTED_PERSONALITIES >= 3 */
135 const struct sysent *sysent;
139 /* Now undef them since short defines cause wicked namespace pollution. */
147 static const char *const errnoent0[] = {
148 #include "errnoent.h"
150 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
152 #if SUPPORTED_PERSONALITIES >= 2
153 static const char *const errnoent1[] = {
154 #include "errnoent1.h"
156 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
157 #endif /* SUPPORTED_PERSONALITIES >= 2 */
159 #if SUPPORTED_PERSONALITIES >= 3
160 static const char *const errnoent2[] = {
161 #include "errnoent2.h"
163 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
164 #endif /* SUPPORTED_PERSONALITIES >= 3 */
166 const char *const *errnoent;
169 int current_personality;
171 #ifndef PERSONALITY0_WORDSIZE
172 # define PERSONALITY0_WORDSIZE sizeof(long)
174 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
175 PERSONALITY0_WORDSIZE,
176 #if SUPPORTED_PERSONALITIES > 1
177 PERSONALITY1_WORDSIZE,
179 #if SUPPORTED_PERSONALITIES > 2
180 PERSONALITY2_WORDSIZE,
185 set_personality(int personality)
187 switch (personality) {
189 errnoent = errnoent0;
192 nsyscalls = nsyscalls0;
193 ioctlent = ioctlent0;
194 nioctlents = nioctlents0;
195 signalent = signalent0;
196 nsignals = nsignals0;
197 qual_flags = qual_flags0;
200 #if SUPPORTED_PERSONALITIES >= 2
202 errnoent = errnoent1;
205 nsyscalls = nsyscalls1;
206 ioctlent = ioctlent1;
207 nioctlents = nioctlents1;
208 signalent = signalent1;
209 nsignals = nsignals1;
210 qual_flags = qual_flags1;
212 #endif /* SUPPORTED_PERSONALITIES >= 2 */
214 #if SUPPORTED_PERSONALITIES >= 3
216 errnoent = errnoent2;
219 nsyscalls = nsyscalls2;
220 ioctlent = ioctlent2;
221 nioctlents = nioctlents2;
222 signalent = signalent2;
223 nsignals = nsignals2;
224 qual_flags = qual_flags2;
226 #endif /* SUPPORTED_PERSONALITIES >= 3 */
232 current_personality = personality;
237 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
239 static const struct qual_options {
245 { QUAL_TRACE, "trace", qual_syscall, "system call" },
246 { QUAL_TRACE, "t", qual_syscall, "system call" },
247 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
248 { QUAL_ABBREV, "a", qual_syscall, "system call" },
249 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
250 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
251 { QUAL_RAW, "raw", qual_syscall, "system call" },
252 { QUAL_RAW, "x", qual_syscall, "system call" },
253 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
254 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
255 { QUAL_SIGNAL, "s", qual_signal, "signal" },
256 { QUAL_FAULT, "fault", qual_fault, "fault" },
257 { QUAL_FAULT, "faults", qual_fault, "fault" },
258 { QUAL_FAULT, "m", qual_fault, "fault" },
259 { QUAL_READ, "read", qual_desc, "descriptor" },
260 { QUAL_READ, "reads", qual_desc, "descriptor" },
261 { QUAL_READ, "r", qual_desc, "descriptor" },
262 { QUAL_WRITE, "write", qual_desc, "descriptor" },
263 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
264 { QUAL_WRITE, "w", qual_desc, "descriptor" },
265 { 0, NULL, NULL, NULL },
269 qualify_one(n, opt, not, pers)
271 const struct qual_options *opt;
275 if (pers == 0 || pers < 0) {
277 qual_flags0[n] &= ~opt->bitflag;
279 qual_flags0[n] |= opt->bitflag;
282 #if SUPPORTED_PERSONALITIES >= 2
283 if (pers == 1 || pers < 0) {
285 qual_flags1[n] &= ~opt->bitflag;
287 qual_flags1[n] |= opt->bitflag;
289 #endif /* SUPPORTED_PERSONALITIES >= 2 */
291 #if SUPPORTED_PERSONALITIES >= 3
292 if (pers == 2 || pers < 0) {
294 qual_flags2[n] &= ~opt->bitflag;
296 qual_flags2[n] |= opt->bitflag;
298 #endif /* SUPPORTED_PERSONALITIES >= 3 */
302 qual_syscall(s, opt, not)
304 const struct qual_options *opt;
310 if (isdigit((unsigned char)*s)) {
312 if (i < 0 || i >= MAX_QUALS)
314 qualify_one(i, opt, not, -1);
317 for (i = 0; i < nsyscalls0; i++)
318 if (strcmp(s, sysent0[i].sys_name) == 0) {
319 qualify_one(i, opt, not, 0);
323 #if SUPPORTED_PERSONALITIES >= 2
324 for (i = 0; i < nsyscalls1; i++)
325 if (strcmp(s, sysent1[i].sys_name) == 0) {
326 qualify_one(i, opt, not, 1);
329 #endif /* SUPPORTED_PERSONALITIES >= 2 */
331 #if SUPPORTED_PERSONALITIES >= 3
332 for (i = 0; i < nsyscalls2; i++)
333 if (strcmp(s, sysent2[i].sys_name) == 0) {
334 qualify_one(i, opt, not, 2);
337 #endif /* SUPPORTED_PERSONALITIES >= 3 */
343 qual_signal(s, opt, not)
345 const struct qual_options *opt;
351 if (isdigit((unsigned char)*s)) {
353 if (signo < 0 || signo >= MAX_QUALS)
355 qualify_one(signo, opt, not, -1);
358 if (strlen(s) >= sizeof buf)
362 for (i = 0; s[i]; i++)
363 s[i] = toupper((unsigned char)(s[i]));
364 if (strncmp(s, "SIG", 3) == 0)
366 for (i = 0; i <= NSIG; i++)
367 if (strcmp(s, signame(i) + 3) == 0) {
368 qualify_one(i, opt, not, -1);
375 qual_fault(s, opt, not)
377 const struct qual_options *opt;
384 qual_desc(s, opt, not)
386 const struct qual_options *opt;
389 if (isdigit((unsigned char)*s)) {
391 if (desc < 0 || desc >= MAX_QUALS)
393 qualify_one(desc, opt, not, -1);
403 if (strcmp(s, "file") == 0)
405 if (strcmp(s, "ipc") == 0)
407 if (strcmp(s, "network") == 0)
408 return TRACE_NETWORK;
409 if (strcmp(s, "process") == 0)
410 return TRACE_PROCESS;
411 if (strcmp(s, "signal") == 0)
413 if (strcmp(s, "desc") == 0)
422 const struct qual_options *opt;
427 opt = &qual_options[0];
428 for (i = 0; (p = qual_options[i].option_name); i++) {
430 if (strncmp(s, p, n) == 0 && s[n] == '=') {
431 opt = &qual_options[i];
441 if (strcmp(s, "none") == 0) {
445 if (strcmp(s, "all") == 0) {
446 for (i = 0; i < MAX_QUALS; i++) {
447 qualify_one(i, opt, not, -1);
451 for (i = 0; i < MAX_QUALS; i++) {
452 qualify_one(i, opt, !not, -1);
454 for (p = strtok(s, ","); p; p = strtok(NULL, ",")) {
455 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
456 for (i = 0; i < nsyscalls0; i++)
457 if (sysent0[i].sys_flags & n)
458 qualify_one(i, opt, not, 0);
460 #if SUPPORTED_PERSONALITIES >= 2
461 for (i = 0; i < nsyscalls1; i++)
462 if (sysent1[i].sys_flags & n)
463 qualify_one(i, opt, not, 1);
464 #endif /* SUPPORTED_PERSONALITIES >= 2 */
466 #if SUPPORTED_PERSONALITIES >= 3
467 for (i = 0; i < nsyscalls2; i++)
468 if (sysent2[i].sys_flags & n)
469 qualify_one(i, opt, not, 2);
470 #endif /* SUPPORTED_PERSONALITIES >= 3 */
474 if (opt->qualify(p, opt, not)) {
475 fprintf(stderr, "strace: invalid %s `%s'\n",
476 opt->argument_name, p);
489 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
491 switch (known_scno(tcp)) {
496 #if defined SYS_pread && SYS_pread64 != SYS_pread
501 #elif defined SYS_sub_recv
506 #elif defined SYS_sub_recvfrom
507 case SYS_sub_recvfrom:
509 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
510 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
516 #if defined SYS_pwrite && SYS_pwrite64 != SYS_pwrite
521 #elif defined SYS_sub_send
526 #elif defined SYS_sub_sendto
529 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
530 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
534 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
535 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
540 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
541 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
548 enum subcall_style { shift_style, deref_style, mask_style, door_style };
550 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
558 static const struct subcall subcalls_table[] = {
559 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
561 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
563 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
565 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
569 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
572 decode_subcall(tcp, subcall, nsubcalls, style)
576 enum subcall_style style;
578 unsigned long addr, mask;
580 int size = personality_wordsize[current_personality];
584 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
586 tcp->scno = subcall + tcp->u_arg[0];
587 if (sysent[tcp->scno].nargs != -1)
588 tcp->u_nargs = sysent[tcp->scno].nargs;
591 for (i = 0; i < tcp->u_nargs; i++)
592 tcp->u_arg[i] = tcp->u_arg[i + 1];
595 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
597 tcp->scno = subcall + tcp->u_arg[0];
598 addr = tcp->u_arg[1];
599 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
600 if (size == sizeof(int)) {
602 if (umove(tcp, addr, &arg) < 0)
606 else if (size == sizeof(long)) {
608 if (umove(tcp, addr, &arg) < 0)
616 tcp->u_nargs = sysent[tcp->scno].nargs;
619 mask = (tcp->u_arg[0] >> 8) & 0xff;
620 for (i = 0; mask; i++)
624 tcp->u_arg[0] &= 0xff;
625 tcp->scno = subcall + i;
626 if (sysent[tcp->scno].nargs != -1)
627 tcp->u_nargs = sysent[tcp->scno].nargs;
631 * Oh, yuck. The call code is the *sixth* argument.
632 * (don't you mean the *last* argument? - JH)
634 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
636 tcp->scno = subcall + tcp->u_arg[5];
637 if (sysent[tcp->scno].nargs != -1)
638 tcp->u_nargs = sysent[tcp->scno].nargs;
644 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
645 if (subcalls_table[i].call == tcp->scno) break;
646 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
647 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
648 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
649 for (i = 0; i < tcp->u_nargs; i++)
650 tcp->u_arg[i] = tcp->u_arg[i + 1];
658 struct tcb *tcp_last = NULL;
661 internal_syscall(struct tcb *tcp)
664 * We must always trace a few critical system calls in order to
665 * correctly support following forks in the presence of tracing
670 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
673 func = sysent[tcp->scno].sys_func;
675 if (sys_exit == func)
676 return internal_exit(tcp);
678 if ( sys_fork == func
679 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
689 return internal_fork(tcp);
691 if ( sys_execve == func
692 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
696 || sys_rexecve == func
699 return internal_exec(tcp);
701 if ( sys_waitpid == func
703 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
707 || sys_osf_wait4 == func
710 return internal_wait(tcp, 2);
712 #if defined(LINUX) || defined(SVR4)
713 if (sys_waitid == func)
714 return internal_wait(tcp, 3);
727 #elif defined (POWERPC)
728 static long result,flags;
734 static struct pt_regs regs;
735 #elif defined (ALPHA)
739 static struct pt_regs regs;
740 #elif defined (SPARC) || defined (SPARC64)
741 static struct pt_regs regs;
742 static unsigned long trap;
743 #elif defined(LINUX_MIPSN32)
749 #elif defined(S390) || defined(S390X)
752 static long syscall_mode;
759 #elif defined(X86_64)
761 #elif defined(CRISV10) || defined(CRISV32)
770 get_scno(struct tcb *tcp)
775 # if defined(S390) || defined(S390X)
776 if (tcp->flags & TCB_WAITEXECVE) {
778 * When the execve system call completes successfully, the
779 * new process still has -ENOSYS (old style) or __NR_execve
780 * (new style) in gpr2. We cannot recover the scno again
781 * by disassembly, because the image that executed the
782 * syscall is gone now. Fortunately, we don't want it. We
783 * leave the flag set so that syscall_fixup can fake the
786 if (tcp->flags & TCB_INSYSCALL)
789 * This is the SIGTRAP after execve. We cannot try to read
790 * the system call here either.
792 tcp->flags &= ~TCB_WAITEXECVE;
796 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
799 if (syscall_mode != -ENOSYS) {
801 * Since kernel version 2.5.44 the scno gets passed in gpr2.
806 * Old style of "passing" the scno via the SVC instruction.
809 long opcode, offset_reg, tmp;
811 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
812 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
813 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
814 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
816 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
819 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
821 perror("peektext(pc-oneword)");
826 * We have to check if the SVC got executed directly or via an
827 * EXECUTE instruction. In case of EXECUTE it is necessary to do
828 * instruction decoding to derive the system call number.
829 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
830 * so that this doesn't work if a SVC opcode is part of an EXECUTE
831 * opcode. Since there is no way to find out the opcode size this
832 * is the best we can do...
835 if ((opcode & 0xff00) == 0x0a00) {
837 scno = opcode & 0xff;
840 /* SVC got executed by EXECUTE instruction */
843 * Do instruction decoding of EXECUTE. If you really want to
844 * understand this, read the Principles of Operations.
846 svc_addr = (void *) (opcode & 0xfff);
849 offset_reg = (opcode & 0x000f0000) >> 16;
850 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
855 offset_reg = (opcode & 0x0000f000) >> 12;
856 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
860 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
869 offset_reg = (opcode & 0x00f00000) >> 20;
870 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
873 scno = (scno | tmp) & 0xff;
876 # elif defined (POWERPC)
877 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
879 if (!(tcp->flags & TCB_INSYSCALL)) {
880 /* Check if we return from execve. */
881 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
882 tcp->flags &= ~TCB_WAITEXECVE;
886 # elif defined(AVR32)
888 * Read complete register set in one go.
890 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
894 * We only need to grab the syscall number on syscall entry.
896 if (!(tcp->flags & TCB_INSYSCALL)) {
899 /* Check if we return from execve. */
900 if (tcp->flags & TCB_WAITEXECVE) {
901 tcp->flags &= ~TCB_WAITEXECVE;
906 if (upeek(tcp, PT_ORIG_P0, &scno))
908 # elif defined (I386)
909 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
911 # elif defined (X86_64)
912 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
915 if (!(tcp->flags & TCB_INSYSCALL)) {
916 static int currpers = -1;
920 /* Check CS register value. On x86-64 linux it is:
921 * 0x33 for long mode (64 bit)
922 * 0x23 for compatibility mode (32 bit)
923 * It takes only one ptrace and thus doesn't need
926 if (upeek(tcp, 8*CS, &val) < 0)
929 case 0x23: currpers = 1; break;
930 case 0x33: currpers = 0; break;
932 fprintf(stderr, "Unknown value CS=0x%02X while "
933 "detecting personality of process "
934 "PID=%d\n", (int)val, pid);
935 currpers = current_personality;
939 /* This version analyzes the opcode of a syscall instruction.
940 * (int 0x80 on i386 vs. syscall on x86-64)
941 * It works, but is too complicated.
943 unsigned long val, rip, i;
945 if (upeek(tcp, 8*RIP, &rip) < 0)
946 perror("upeek(RIP)");
948 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
952 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
954 printf("ptrace_peektext failed: %s\n",
956 switch (call & 0xffff) {
957 /* x86-64: syscall = 0x0f 0x05 */
958 case 0x050f: currpers = 0; break;
959 /* i386: int 0x80 = 0xcd 0x80 */
960 case 0x80cd: currpers = 1; break;
962 currpers = current_personality;
964 "Unknown syscall opcode (0x%04X) while "
965 "detecting personality of process "
966 "PID=%d\n", (int)call, pid);
970 if (currpers != current_personality) {
971 static const char *const names[] = {"64 bit", "32 bit"};
972 set_personality(currpers);
973 printf("[ Process PID=%d runs in %s mode. ]\n",
974 pid, names[current_personality]);
978 # define IA64_PSR_IS ((long)1 << 34)
979 if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
980 ia32 = (psr & IA64_PSR_IS) != 0;
981 if (!(tcp->flags & TCB_INSYSCALL)) {
983 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
986 if (upeek (tcp, PT_R15, &scno) < 0)
989 /* Check if we return from execve. */
990 if (tcp->flags & TCB_WAITEXECVE) {
991 tcp->flags &= ~TCB_WAITEXECVE;
995 /* syscall in progress */
996 if (upeek (tcp, PT_R8, &r8) < 0)
998 if (upeek (tcp, PT_R10, &r10) < 0)
1001 # elif defined (ARM)
1003 * Read complete register set in one go.
1005 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
1009 * We only need to grab the syscall number on syscall entry.
1011 if (regs.ARM_ip == 0) {
1012 if (!(tcp->flags & TCB_INSYSCALL)) {
1013 /* Check if we return from execve. */
1014 if (tcp->flags & TCB_WAITEXECVE) {
1015 tcp->flags &= ~TCB_WAITEXECVE;
1021 * Note: we only deal with only 32-bit CPUs here.
1023 if (regs.ARM_cpsr & 0x20) {
1025 * Get the Thumb-mode system call number
1030 * Get the ARM-mode system call number
1033 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1037 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1038 tcp->flags &= ~TCB_WAITEXECVE;
1042 /* Handle the EABI syscall convention. We do not
1043 bother converting structures between the two
1044 ABIs, but basic functionality should work even
1045 if strace and the traced program have different
1047 if (scno == 0xef000000) {
1050 if ((scno & 0x0ff00000) != 0x0f900000) {
1051 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1057 * Fixup the syscall number
1062 if (scno & 0x0f0000) {
1064 * Handle ARM specific syscall
1071 if (tcp->flags & TCB_INSYSCALL) {
1072 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1073 tcp->flags &= ~TCB_INSYSCALL;
1076 if (!(tcp->flags & TCB_INSYSCALL)) {
1077 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1078 tcp->flags |= TCB_INSYSCALL;
1081 # elif defined (M68K)
1082 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1084 # elif defined (LINUX_MIPSN32)
1085 unsigned long long regs[38];
1087 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1092 if(!(tcp->flags & TCB_INSYSCALL)) {
1095 /* Check if we return from execve. */
1096 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1097 tcp->flags &= ~TCB_WAITEXECVE;
1101 if (scno < 0 || scno > nsyscalls) {
1102 if(a3 == 0 || a3 == -1) {
1104 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1109 # elif defined (MIPS)
1110 if (upeek(tcp, REG_A3, &a3) < 0)
1112 if(!(tcp->flags & TCB_INSYSCALL)) {
1113 if (upeek(tcp, REG_V0, &scno) < 0)
1116 /* Check if we return from execve. */
1117 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1118 tcp->flags &= ~TCB_WAITEXECVE;
1122 if (scno < 0 || scno > nsyscalls) {
1123 if(a3 == 0 || a3 == -1) {
1125 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1130 if (upeek(tcp, REG_V0, &r2) < 0)
1133 # elif defined (ALPHA)
1134 if (upeek(tcp, REG_A3, &a3) < 0)
1137 if (!(tcp->flags & TCB_INSYSCALL)) {
1138 if (upeek(tcp, REG_R0, &scno) < 0)
1141 /* Check if we return from execve. */
1142 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1143 tcp->flags &= ~TCB_WAITEXECVE;
1148 * Do some sanity checks to figure out if it's
1149 * really a syscall entry
1151 if (scno < 0 || scno > nsyscalls) {
1152 if (a3 == 0 || a3 == -1) {
1154 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1160 if (upeek(tcp, REG_R0, &r0) < 0)
1163 # elif defined (SPARC) || defined (SPARC64)
1164 /* Everything we need is in the current register set. */
1165 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1168 /* If we are entering, then disassemble the syscall trap. */
1169 if (!(tcp->flags & TCB_INSYSCALL)) {
1170 /* Retrieve the syscall trap instruction. */
1172 # if defined(SPARC64)
1173 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1176 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1181 /* Disassemble the trap to see what personality to use. */
1184 /* Linux/SPARC syscall trap. */
1188 /* Linux/SPARC64 syscall trap. */
1192 /* SunOS syscall trap. (pers 1) */
1193 fprintf(stderr,"syscall: SunOS no support\n");
1196 /* Solaris 2.x syscall trap. (per 2) */
1200 /* NetBSD/FreeBSD syscall trap. */
1201 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1204 /* Solaris 2.x gettimeofday */
1208 /* Unknown syscall trap. */
1209 if(tcp->flags & TCB_WAITEXECVE) {
1210 tcp->flags &= ~TCB_WAITEXECVE;
1213 # if defined (SPARC64)
1214 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1216 fprintf(stderr,"syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1221 /* Extract the system call number from the registers. */
1222 if (trap == 0x91d02027)
1225 scno = regs.u_regs[U_REG_G1];
1227 scno = regs.u_regs[U_REG_O0];
1228 memmove (®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1231 # elif defined(HPPA)
1232 if (upeek(tcp, PT_GR20, &scno) < 0)
1234 if (!(tcp->flags & TCB_INSYSCALL)) {
1235 /* Check if we return from execve. */
1236 if ((tcp->flags & TCB_WAITEXECVE)) {
1237 tcp->flags &= ~TCB_WAITEXECVE;
1243 * In the new syscall ABI, the system call number is in R3.
1245 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1249 /* Odd as it may seem, a glibc bug has been known to cause
1250 glibc to issue bogus negative syscall numbers. So for
1251 our purposes, make strace print what it *should* have been */
1252 long correct_scno = (scno & 0xff);
1255 "Detected glibc bug: bogus system call"
1256 " number = %ld, correcting to %ld\n",
1259 scno = correct_scno;
1262 if (!(tcp->flags & TCB_INSYSCALL)) {
1263 /* Check if we return from execve. */
1264 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1265 tcp->flags &= ~TCB_WAITEXECVE;
1269 # elif defined(SH64)
1270 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1274 if (!(tcp->flags & TCB_INSYSCALL)) {
1275 /* Check if we return from execve. */
1276 if (tcp->flags & TCB_WAITEXECVE) {
1277 tcp->flags &= ~TCB_WAITEXECVE;
1281 # elif defined(CRISV10) || defined(CRISV32)
1282 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1284 # elif defined(TILE)
1285 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1288 if (!(tcp->flags & TCB_INSYSCALL)) {
1289 /* Check if we return from execve. */
1290 if (tcp->flags & TCB_WAITEXECVE) {
1291 tcp->flags &= ~TCB_WAITEXECVE;
1299 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1302 /* new syscall ABI returns result in R0 */
1303 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1306 /* ABI defines result returned in r9 */
1307 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1312 # ifdef HAVE_PR_SYSCALL
1313 scno = tcp->status.PR_SYSCALL;
1316 scno = tcp->status.PR_WHAT;
1318 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1322 switch (regs.r_eax) {
1325 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1331 # endif /* FREEBSD */
1332 # endif /* !HAVE_PR_SYSCALL */
1333 #endif /* USE_PROCFS */
1335 if (!(tcp->flags & TCB_INSYSCALL))
1345 long scno = tcp->scno;
1346 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1347 scno = sysent[scno].native_scno;
1349 scno += NR_SYSCALL_BASE;
1353 /* Called in trace_syscall() at each syscall entry and exit.
1355 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1356 * 1: ok, continue in trace_syscall().
1357 * other: error, trace_syscall() should print error indicator
1358 * ("????" etc) and bail out.
1361 syscall_fixup(struct tcb *tcp)
1364 int scno = known_scno(tcp);
1366 if (!(tcp->flags & TCB_INSYSCALL)) {
1367 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1371 || scno == SYS_vfork
1372 #endif /* SYS_vfork */
1374 || scno == SYS_fork1
1375 #endif /* SYS_fork1 */
1377 || scno == SYS_forkall
1378 #endif /* SYS_forkall */
1380 || scno == SYS_rfork1
1381 #endif /* SYS_fork1 */
1383 || scno == SYS_rforkall
1384 #endif /* SYS_rforkall */
1386 /* We are returning in the child, fake it. */
1387 tcp->status.PR_WHY = PR_SYSENTRY;
1389 tcp->status.PR_WHY = PR_SYSEXIT;
1392 fprintf(stderr, "syscall: missing entry\n");
1393 tcp->flags |= TCB_INSYSCALL;
1398 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1399 fprintf(stderr, "syscall: missing exit\n");
1400 tcp->flags &= ~TCB_INSYSCALL;
1403 #endif /* USE_PROCFS */
1405 if (!(tcp->flags & TCB_INSYSCALL)) {
1407 fprintf(stderr, "syscall: missing entry\n");
1408 tcp->flags |= TCB_INSYSCALL;
1415 * This happens when a signal handler
1416 * for a signal which interrupted a
1417 * a system call makes another system call.
1419 fprintf(stderr, "syscall: missing exit\n");
1421 tcp->flags &= ~TCB_INSYSCALL;
1427 if (upeek(tcp, 4*EAX, &eax) < 0)
1429 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1431 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1434 #elif defined (X86_64)
1435 if (upeek(tcp, 8*RAX, &rax) < 0)
1437 if (current_personality == 1)
1438 rax = (long int)(int)rax; /* sign extend from 32 bits */
1439 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1441 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1444 #elif defined (S390) || defined (S390X)
1445 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1447 if (syscall_mode != -ENOSYS)
1448 syscall_mode = tcp->scno;
1449 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1451 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1454 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1455 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1456 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1458 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1459 * flag set for the post-execve SIGTRAP to see and reset.
1463 #elif defined (POWERPC)
1464 # define SO_MASK 0x10000000
1465 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1467 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1469 if (flags & SO_MASK)
1471 #elif defined (M68K)
1472 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1474 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1476 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1484 if (upeek(tcp, PT_R0, &r0) < 0)
1486 #elif defined (HPPA)
1487 if (upeek(tcp, PT_GR28, &r28) < 0)
1490 if (upeek(tcp, PT_R10, &r10) < 0)
1492 if (upeek(tcp, PT_R8, &r8) < 0)
1494 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1496 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1499 #elif defined(CRISV10) || defined(CRISV32)
1500 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1502 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1504 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1514 * Check the syscall return value register value for whether it is
1515 * a negated errno code indicating an error, or a success return value.
1518 is_negated_errno(unsigned long int val)
1520 unsigned long int max = -(long int) nerrnos;
1521 if (personality_wordsize[current_personality] < sizeof(val)) {
1522 val = (unsigned int) val;
1523 max = (unsigned int) max;
1530 get_error(struct tcb *tcp)
1534 # if defined(S390) || defined(S390X)
1535 if (is_negated_errno(gpr2)) {
1543 # elif defined(I386)
1544 if (is_negated_errno(eax)) {
1552 # elif defined(X86_64)
1553 if (is_negated_errno(rax)) {
1561 # elif defined(IA64)
1566 if (is_negated_errno(err)) {
1583 # elif defined(MIPS)
1591 # elif defined(POWERPC)
1592 if (is_negated_errno(result)) {
1597 tcp->u_rval = result;
1600 # elif defined(M68K)
1601 if (is_negated_errno(d0)) {
1610 if (is_negated_errno(regs.ARM_r0)) {
1612 u_error = -regs.ARM_r0;
1615 tcp->u_rval = regs.ARM_r0;
1618 # elif defined(AVR32)
1619 if (regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1621 u_error = -regs.r12;
1624 tcp->u_rval = regs.r12;
1627 # elif defined(BFIN)
1628 if (is_negated_errno(r0)) {
1635 # elif defined(ALPHA)
1644 # elif defined(SPARC)
1645 if (regs.psr & PSR_C) {
1647 u_error = regs.u_regs[U_REG_O0];
1650 tcp->u_rval = regs.u_regs[U_REG_O0];
1653 # elif defined(SPARC64)
1654 if (regs.tstate & 0x1100000000UL) {
1656 u_error = regs.u_regs[U_REG_O0];
1659 tcp->u_rval = regs.u_regs[U_REG_O0];
1662 # elif defined(HPPA)
1663 if (is_negated_errno(r28)) {
1672 /* interpret R0 as return value or error number */
1673 if (is_negated_errno(r0)) {
1681 # elif defined(SH64)
1682 /* interpret result as return value or error number */
1683 if (is_negated_errno(r9)) {
1691 # elif defined(CRISV10) || defined(CRISV32)
1692 if (r10 && (unsigned) -r10 < nerrnos) {
1700 # elif defined(TILE)
1702 /* interpret result as return value or error number */
1703 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1705 if (rval < 0 && rval > -nerrnos) {
1716 /* get error code from user struct */
1717 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1719 u_error >>= 24; /* u_error is a char */
1721 /* get system call return value */
1722 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1727 /* Judicious guessing goes a long way. */
1728 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1730 u_error = tcp->status.pr_reg[R_O0];
1733 tcp->u_rval = tcp->status.pr_reg[R_O0];
1738 /* Wanna know how to kill an hour single-stepping? */
1739 if (tcp->status.PR_REG[EFL] & 0x1) {
1741 u_error = tcp->status.PR_REG[EAX];
1744 tcp->u_rval = tcp->status.PR_REG[EAX];
1745 #ifdef HAVE_LONG_LONG
1747 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1748 tcp->status.PR_REG[EAX];
1754 /* Wanna know how to kill an hour single-stepping? */
1755 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1757 u_error = tcp->status.PR_REG[RAX];
1760 tcp->u_rval = tcp->status.PR_REG[RAX];
1765 if (tcp->status.pr_reg[CTX_A3]) {
1767 u_error = tcp->status.pr_reg[CTX_V0];
1770 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1776 if (regs.r_eflags & PSL_C) {
1778 u_error = regs.r_eax;
1780 tcp->u_rval = regs.r_eax;
1782 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1785 #endif /* FREEBSD */
1786 tcp->u_error = u_error;
1791 force_result(tcp, error, rval)
1797 # if defined(S390) || defined(S390X)
1798 gpr2 = error ? -error : rval;
1799 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1801 # elif defined(I386)
1802 eax = error ? -error : rval;
1803 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1805 # elif defined(X86_64)
1806 rax = error ? -error : rval;
1807 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1809 # elif defined(IA64)
1811 r8 = error ? -error : rval;
1812 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1824 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1825 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1828 # elif defined(BFIN)
1829 r0 = error ? -error : rval;
1830 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1832 # elif defined(MIPS)
1841 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1842 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1843 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1845 # elif defined(POWERPC)
1846 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1856 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1857 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1859 # elif defined(M68K)
1860 d0 = error ? -error : rval;
1861 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1864 regs.ARM_r0 = error ? -error : rval;
1865 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1867 # elif defined(AVR32)
1868 regs.r12 = error ? -error : rval;
1869 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1871 # elif defined(ALPHA)
1880 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1881 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1883 # elif defined(SPARC)
1884 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1888 regs.u_regs[U_REG_O0] = error;
1892 regs.u_regs[U_REG_O0] = rval;
1894 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1896 # elif defined(SPARC64)
1897 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1900 regs.tstate |= 0x1100000000UL;
1901 regs.u_regs[U_REG_O0] = error;
1904 regs.tstate &= ~0x1100000000UL;
1905 regs.u_regs[U_REG_O0] = rval;
1907 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1909 # elif defined(HPPA)
1910 r28 = error ? -error : rval;
1911 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1914 r0 = error ? -error : rval;
1915 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1917 # elif defined(SH64)
1918 r9 = error ? -error : rval;
1919 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1925 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1927 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1937 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1942 regs.r_eflags |= PSL_C;
1946 regs.r_eflags &= ~PSL_C;
1949 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1953 #endif /* FREEBSD */
1955 /* All branches reach here on success (only). */
1956 tcp->u_error = error;
1962 syscall_enter(struct tcb *tcp)
1965 #if defined(S390) || defined(S390X)
1968 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1969 tcp->u_nargs = sysent[tcp->scno].nargs;
1971 tcp->u_nargs = MAX_ARGS;
1972 for (i = 0; i < tcp->u_nargs; i++) {
1973 if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1977 #elif defined (ALPHA)
1980 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1981 tcp->u_nargs = sysent[tcp->scno].nargs;
1983 tcp->u_nargs = MAX_ARGS;
1984 for (i = 0; i < tcp->u_nargs; i++) {
1985 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1986 * for scno somewhere above here!
1988 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1992 #elif defined (IA64)
1995 unsigned long *out0, cfm, sof, sol, i;
1997 /* be backwards compatible with kernel < 2.4.4... */
1999 # define PT_RBS_END PT_AR_BSP
2002 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
2004 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2007 sof = (cfm >> 0) & 0x7f;
2008 sol = (cfm >> 7) & 0x7f;
2009 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2011 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2012 && sysent[tcp->scno].nargs != -1)
2013 tcp->u_nargs = sysent[tcp->scno].nargs;
2015 tcp->u_nargs = MAX_ARGS;
2016 for (i = 0; i < tcp->u_nargs; ++i) {
2017 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2018 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2024 if (/* EBX = out0 */
2025 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2027 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2029 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2031 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2033 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2035 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2038 for (i = 0; i < 6; ++i)
2039 /* truncate away IVE sign-extension */
2040 tcp->u_arg[i] &= 0xffffffff;
2042 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2043 && sysent[tcp->scno].nargs != -1)
2044 tcp->u_nargs = sysent[tcp->scno].nargs;
2049 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2050 /* N32 and N64 both use up to six registers. */
2052 unsigned long long regs[38];
2055 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2056 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2058 nargs = tcp->u_nargs = MAX_ARGS;
2060 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2063 for(i = 0; i < nargs; i++) {
2064 tcp->u_arg[i] = regs[REG_A0 + i];
2065 # if defined (LINUX_MIPSN32)
2066 tcp->ext_arg[i] = regs[REG_A0 + i];
2070 #elif defined (MIPS)
2075 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2076 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2078 nargs = tcp->u_nargs = MAX_ARGS;
2080 if(upeek(tcp, REG_SP, &sp) < 0)
2082 for(i = 0; i < 4; i++) {
2083 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2086 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2087 (char *)(tcp->u_arg + 4));
2089 for(i = 0; i < nargs; i++) {
2090 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2095 #elif defined (POWERPC)
2097 # define PT_ORIG_R3 34
2101 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2102 tcp->u_nargs = sysent[tcp->scno].nargs;
2104 tcp->u_nargs = MAX_ARGS;
2105 for (i = 0; i < tcp->u_nargs; i++) {
2106 if (upeek(tcp, (i==0) ?
2107 (sizeof(unsigned long)*PT_ORIG_R3) :
2108 ((i+PT_R3)*sizeof(unsigned long)),
2109 &tcp->u_arg[i]) < 0)
2113 #elif defined (SPARC) || defined (SPARC64)
2117 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2118 tcp->u_nargs = sysent[tcp->scno].nargs;
2120 tcp->u_nargs = MAX_ARGS;
2121 for (i = 0; i < tcp->u_nargs; i++)
2122 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2124 #elif defined (HPPA)
2128 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2129 tcp->u_nargs = sysent[tcp->scno].nargs;
2131 tcp->u_nargs = MAX_ARGS;
2132 for (i = 0; i < tcp->u_nargs; i++) {
2133 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2141 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2142 tcp->u_nargs = sysent[tcp->scno].nargs;
2144 tcp->u_nargs = MAX_ARGS;
2145 for (i = 0; i < tcp->u_nargs; i++)
2146 tcp->u_arg[i] = regs.uregs[i];
2148 #elif defined(AVR32)
2149 tcp->u_nargs = sysent[tcp->scno].nargs;
2150 tcp->u_arg[0] = regs.r12;
2151 tcp->u_arg[1] = regs.r11;
2152 tcp->u_arg[2] = regs.r10;
2153 tcp->u_arg[3] = regs.r9;
2154 tcp->u_arg[4] = regs.r5;
2155 tcp->u_arg[5] = regs.r3;
2159 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2161 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2162 tcp->u_nargs = sysent[tcp->scno].nargs;
2164 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2166 for (i = 0; i < tcp->u_nargs; ++i)
2167 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2173 static int syscall_regs[] = {
2174 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2175 REG_REG0, REG_REG0+1, REG_REG0+2
2178 tcp->u_nargs = sysent[tcp->scno].nargs;
2179 for (i = 0; i < tcp->u_nargs; i++) {
2180 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2187 /* Registers used by SH5 Linux system calls for parameters */
2188 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2191 * TODO: should also check that the number of arguments encoded
2192 * in the trap number matches the number strace expects.
2195 assert(sysent[tcp->scno].nargs <
2196 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2199 tcp->u_nargs = sysent[tcp->scno].nargs;
2200 for (i = 0; i < tcp->u_nargs; i++) {
2201 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2206 #elif defined(X86_64)
2209 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2210 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2211 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2214 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2215 tcp->u_nargs = sysent[tcp->scno].nargs;
2217 tcp->u_nargs = MAX_ARGS;
2218 for (i = 0; i < tcp->u_nargs; i++) {
2219 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2223 #elif defined(CRISV10) || defined(CRISV32)
2226 static const int crisregs[] = {
2227 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2228 4*PT_R13, 4*PT_MOF, 4*PT_SRP
2231 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2232 tcp->u_nargs = sysent[tcp->scno].nargs;
2235 for (i = 0; i < tcp->u_nargs; i++) {
2236 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2243 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2244 tcp->u_nargs = sysent[tcp->scno].nargs;
2246 tcp->u_nargs = MAX_ARGS;
2247 for (i = 0; i < tcp->u_nargs; ++i) {
2248 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2252 #else /* Other architecture (like i386) (32bits specific) */
2255 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2256 tcp->u_nargs = sysent[tcp->scno].nargs;
2258 tcp->u_nargs = MAX_ARGS;
2259 for (i = 0; i < tcp->u_nargs; i++) {
2260 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2269 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2270 tcp->u_nargs = sysent[tcp->scno].nargs;
2272 tcp->u_nargs = MAX_ARGS;
2273 for (i = 0; i < tcp->u_nargs; i++) {
2276 if (upeek(tcp, uoff(u_arg[0]) +
2277 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2285 * SGI is broken: even though it has pr_sysarg, it doesn't
2286 * set them on system call entry. Get a clue.
2288 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2289 tcp->u_nargs = sysent[tcp->scno].nargs;
2291 tcp->u_nargs = tcp->status.pr_nsysarg;
2292 if (tcp->u_nargs > 4) {
2293 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2294 4*sizeof(tcp->u_arg[0]));
2295 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2296 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2299 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2300 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2304 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2306 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2307 tcp->u_nargs = sysent[tcp->scno].nargs;
2309 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2310 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2311 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2312 #elif defined (HAVE_PR_SYSCALL)
2313 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2314 tcp->u_nargs = sysent[tcp->scno].nargs;
2316 tcp->u_nargs = tcp->status.pr_nsysarg;
2319 for (i = 0; i < tcp->u_nargs; i++)
2320 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2322 #elif defined (I386)
2323 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2324 tcp->u_nargs = sysent[tcp->scno].nargs;
2327 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2328 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2330 I DONT KNOW WHAT TO DO
2331 #endif /* !HAVE_PR_SYSCALL */
2334 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2335 sysent[tcp->scno].nargs > tcp->status.val)
2336 tcp->u_nargs = sysent[tcp->scno].nargs;
2338 tcp->u_nargs = tcp->status.val;
2339 if (tcp->u_nargs < 0)
2341 if (tcp->u_nargs > MAX_ARGS)
2342 tcp->u_nargs = MAX_ARGS;
2343 switch(regs.r_eax) {
2345 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2346 regs.r_esp + sizeof(int) + sizeof(quad_t));
2349 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2350 regs.r_esp + 2 * sizeof(int));
2353 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2354 regs.r_esp + sizeof(int));
2357 #endif /* FREEBSD */
2362 trace_syscall_exiting(struct tcb *tcp)
2369 /* Measure the exit time as early as possible to avoid errors. */
2371 gettimeofday(&tv, NULL);
2373 /* BTW, why we don't just memorize syscall no. on entry
2374 * in tcp->something?
2376 scno_good = res = get_scno(tcp);
2380 res = syscall_fixup(tcp);
2384 res = get_error(tcp);
2388 internal_syscall(tcp);
2390 if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2391 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2392 tcp->flags &= ~TCB_INSYSCALL;
2396 if (tcp->flags & TCB_REPRINT) {
2401 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2402 tprintf("syscall_%lu", tcp->scno);
2404 tprintf("%s", sysent[tcp->scno].sys_name);
2405 tprintf(" resumed> ");
2409 struct timeval t = tv;
2410 int rc = count_syscall(tcp, &t);
2411 if (cflag == CFLAG_ONLY_STATS)
2413 tcp->flags &= ~TCB_INSYSCALL;
2421 tprintf("= ? <unavailable>");
2423 tcp->flags &= ~TCB_INSYSCALL;
2427 if (tcp->scno >= nsyscalls || tcp->scno < 0
2428 || (qual_flags[tcp->scno] & QUAL_RAW))
2429 sys_res = printargs(tcp);
2431 if (not_failing_only && tcp->u_error)
2432 return 0; /* ignore failed syscalls */
2433 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2436 u_error = tcp->u_error;
2439 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2440 qual_flags[tcp->scno] & QUAL_RAW) {
2442 tprintf("= -1 (errno %ld)", u_error);
2444 tprintf("= %#lx", tcp->u_rval);
2446 else if (!(sys_res & RVAL_NONE) && u_error) {
2450 tprintf("= ? ERESTARTSYS (To be restarted)");
2452 case ERESTARTNOINTR:
2453 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2455 case ERESTARTNOHAND:
2456 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2458 case ERESTART_RESTARTBLOCK:
2459 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2465 tprintf("E??? (errno %ld)", u_error);
2466 else if (u_error < nerrnos)
2467 tprintf("%s (%s)", errnoent[u_error],
2470 tprintf("ERRNO_%ld (%s)", u_error,
2474 if ((sys_res & RVAL_STR) && tcp->auxstr)
2475 tprintf(" (%s)", tcp->auxstr);
2478 if (sys_res & RVAL_NONE)
2481 switch (sys_res & RVAL_MASK) {
2483 tprintf("= %#lx", tcp->u_rval);
2486 tprintf("= %#lo", tcp->u_rval);
2489 tprintf("= %lu", tcp->u_rval);
2492 tprintf("= %ld", tcp->u_rval);
2494 #ifdef HAVE_LONG_LONG
2496 tprintf("= %#llx", tcp->u_lrval);
2499 tprintf("= %#llo", tcp->u_lrval);
2501 case RVAL_LUDECIMAL:
2502 tprintf("= %llu", tcp->u_lrval);
2505 tprintf("= %lld", tcp->u_lrval);
2510 "invalid rval format\n");
2514 if ((sys_res & RVAL_STR) && tcp->auxstr)
2515 tprintf(" (%s)", tcp->auxstr);
2518 tv_sub(&tv, &tv, &tcp->etime);
2519 tprintf(" <%ld.%06ld>",
2520 (long) tv.tv_sec, (long) tv.tv_usec);
2525 if (fflush(tcp->outf) == EOF)
2527 tcp->flags &= ~TCB_INSYSCALL;
2532 trace_syscall_entering(struct tcb *tcp)
2537 scno_good = res = get_scno(tcp);
2541 res = syscall_fixup(tcp);
2545 res = syscall_enter(tcp);
2551 tcp->flags &= ~TCB_REPRINT;
2554 tprintf("????" /* anti-trigraph gap */ "(");
2555 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2556 tprintf("syscall_%lu(", tcp->scno);
2558 tprintf("%s(", sysent[tcp->scno].sys_name);
2560 * " <unavailable>" will be added later by the code which
2561 * detects ptrace errors.
2563 tcp->flags |= TCB_INSYSCALL;
2567 switch (known_scno(tcp)) {
2568 #ifdef SYS_socket_subcall
2569 case SYS_socketcall:
2570 decode_subcall(tcp, SYS_socket_subcall,
2571 SYS_socket_nsubcalls, deref_style);
2574 #ifdef SYS_ipc_subcall
2576 decode_subcall(tcp, SYS_ipc_subcall,
2577 SYS_ipc_nsubcalls, shift_style);
2581 #ifdef SYS_pgrpsys_subcall
2583 decode_subcall(tcp, SYS_pgrpsys_subcall,
2584 SYS_pgrpsys_nsubcalls, shift_style);
2586 #endif /* SYS_pgrpsys_subcall */
2587 #ifdef SYS_sigcall_subcall
2589 decode_subcall(tcp, SYS_sigcall_subcall,
2590 SYS_sigcall_nsubcalls, mask_style);
2592 #endif /* SYS_sigcall_subcall */
2594 decode_subcall(tcp, SYS_msgsys_subcall,
2595 SYS_msgsys_nsubcalls, shift_style);
2598 decode_subcall(tcp, SYS_shmsys_subcall,
2599 SYS_shmsys_nsubcalls, shift_style);
2602 decode_subcall(tcp, SYS_semsys_subcall,
2603 SYS_semsys_nsubcalls, shift_style);
2606 decode_subcall(tcp, SYS_sysfs_subcall,
2607 SYS_sysfs_nsubcalls, shift_style);
2610 decode_subcall(tcp, SYS_spcall_subcall,
2611 SYS_spcall_nsubcalls, shift_style);
2613 #ifdef SYS_context_subcall
2615 decode_subcall(tcp, SYS_context_subcall,
2616 SYS_context_nsubcalls, shift_style);
2618 #endif /* SYS_context_subcall */
2619 #ifdef SYS_door_subcall
2621 decode_subcall(tcp, SYS_door_subcall,
2622 SYS_door_nsubcalls, door_style);
2624 #endif /* SYS_door_subcall */
2625 #ifdef SYS_kaio_subcall
2627 decode_subcall(tcp, SYS_kaio_subcall,
2628 SYS_kaio_nsubcalls, shift_style);
2636 decode_subcall(tcp, 0, 0, table_style);
2641 decode_subcall(tcp, SYS_semsys_subcall,
2642 SYS_semsys_nsubcalls, shift_style);
2645 decode_subcall(tcp, SYS_msgsys_subcall,
2646 SYS_msgsys_nsubcalls, shift_style);
2649 decode_subcall(tcp, SYS_shmsys_subcall,
2650 SYS_shmsys_nsubcalls, shift_style);
2655 internal_syscall(tcp);
2656 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2657 tcp->flags |= TCB_INSYSCALL;
2661 if (cflag == CFLAG_ONLY_STATS) {
2662 tcp->flags |= TCB_INSYSCALL;
2663 gettimeofday(&tcp->etime, NULL);
2668 tcp->flags &= ~TCB_REPRINT;
2670 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2671 tprintf("syscall_%lu(", tcp->scno);
2673 tprintf("%s(", sysent[tcp->scno].sys_name);
2674 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2675 ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2676 sys_res = printargs(tcp);
2678 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2679 if (fflush(tcp->outf) == EOF)
2681 tcp->flags |= TCB_INSYSCALL;
2682 /* Measure the entrance time as late as possible to avoid errors. */
2684 gettimeofday(&tcp->etime, NULL);
2689 trace_syscall(struct tcb *tcp)
2691 return exiting(tcp) ?
2692 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2699 if (entering(tcp)) {
2702 for (i = 0; i < tcp->u_nargs; i++)
2703 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2715 #if defined (SPARC) || defined (SPARC64)
2716 struct pt_regs regs;
2717 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2719 val = regs.u_regs[U_REG_O1];
2721 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2724 if (upeek(tcp, PT_R9, &val) < 0)
2730 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2736 val = tcp->status.PR_REG[R_O1];
2739 val = tcp->status.PR_REG[EDX];
2742 val = tcp->status.PR_REG[RDX];
2745 val = tcp->status.PR_REG[CTX_V1];
2751 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2759 * Apparently, indirect system calls have already be converted by ptrace(2),
2760 * so if you see "indir" this program has gone astray.
2768 if (entering(tcp)) {
2769 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2770 fprintf(stderr, "Bogus syscall: %u\n", scno);
2773 nargs = sysent[scno].nargs;
2774 tprintf("%s", sysent[scno].sys_name);
2775 for (i = 0; i < nargs; i++)
2776 tprintf(", %#lx", tcp->u_arg[i+1]);
2783 is_restart_error(struct tcb *tcp)
2788 switch (tcp->u_error) {
2790 case ERESTARTNOINTR:
2791 case ERESTARTNOHAND:
2792 case ERESTART_RESTARTBLOCK: