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 */
93 #warning: NSIG is not defined, using 32
97 /* Ugh. Is this really correct? ARM has no RT signals?! */
100 #undef NR_SYSCALL_BASE
101 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
107 /* Define these shorthand notations to simplify the syscallent files. */
108 #define TD TRACE_DESC
109 #define TF TRACE_FILE
111 #define TN TRACE_NETWORK
112 #define TP TRACE_PROCESS
113 #define TS TRACE_SIGNAL
114 #define NF SYSCALL_NEVER_FAILS
116 static const struct sysent sysent0[] = {
117 #include "syscallent.h"
119 static const int nsyscalls0 = ARRAY_SIZE(sysent0);
120 int qual_flags0[MAX_QUALS];
122 #if SUPPORTED_PERSONALITIES >= 2
123 static const struct sysent sysent1[] = {
124 #include "syscallent1.h"
126 static const int nsyscalls1 = ARRAY_SIZE(sysent1);
127 int qual_flags1[MAX_QUALS];
128 #endif /* SUPPORTED_PERSONALITIES >= 2 */
130 #if SUPPORTED_PERSONALITIES >= 3
131 static const struct sysent sysent2[] = {
132 #include "syscallent2.h"
134 static const int nsyscalls2 = ARRAY_SIZE(sysent2);
135 int qual_flags2[MAX_QUALS];
136 #endif /* SUPPORTED_PERSONALITIES >= 3 */
138 const struct sysent *sysent;
142 /* Now undef them since short defines cause wicked namespace pollution. */
151 static const char *const errnoent0[] = {
152 #include "errnoent.h"
154 static const int nerrnos0 = ARRAY_SIZE(errnoent0);
156 #if SUPPORTED_PERSONALITIES >= 2
157 static const char *const errnoent1[] = {
158 #include "errnoent1.h"
160 static const int nerrnos1 = ARRAY_SIZE(errnoent1);
161 #endif /* SUPPORTED_PERSONALITIES >= 2 */
163 #if SUPPORTED_PERSONALITIES >= 3
164 static const char *const errnoent2[] = {
165 #include "errnoent2.h"
167 static const int nerrnos2 = ARRAY_SIZE(errnoent2);
168 #endif /* SUPPORTED_PERSONALITIES >= 3 */
170 const char *const *errnoent;
173 int current_personality;
175 #ifndef PERSONALITY0_WORDSIZE
176 # define PERSONALITY0_WORDSIZE sizeof(long)
178 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
179 PERSONALITY0_WORDSIZE,
180 #if SUPPORTED_PERSONALITIES > 1
181 PERSONALITY1_WORDSIZE,
183 #if SUPPORTED_PERSONALITIES > 2
184 PERSONALITY2_WORDSIZE,
189 set_personality(int personality)
191 switch (personality) {
193 errnoent = errnoent0;
196 nsyscalls = nsyscalls0;
197 ioctlent = ioctlent0;
198 nioctlents = nioctlents0;
199 signalent = signalent0;
200 nsignals = nsignals0;
201 qual_flags = qual_flags0;
204 #if SUPPORTED_PERSONALITIES >= 2
206 errnoent = errnoent1;
209 nsyscalls = nsyscalls1;
210 ioctlent = ioctlent1;
211 nioctlents = nioctlents1;
212 signalent = signalent1;
213 nsignals = nsignals1;
214 qual_flags = qual_flags1;
218 #if SUPPORTED_PERSONALITIES >= 3
220 errnoent = errnoent2;
223 nsyscalls = nsyscalls2;
224 ioctlent = ioctlent2;
225 nioctlents = nioctlents2;
226 signalent = signalent2;
227 nsignals = nsignals2;
228 qual_flags = qual_flags2;
233 current_personality = personality;
237 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
239 static const struct qual_options {
241 const char *option_name;
242 int (*qualify)(const char *, int, int);
243 const char *argument_name;
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(int n, int bitflag, int not, int pers)
271 if (pers == 0 || pers < 0) {
273 qual_flags0[n] &= ~bitflag;
275 qual_flags0[n] |= bitflag;
278 #if SUPPORTED_PERSONALITIES >= 2
279 if (pers == 1 || pers < 0) {
281 qual_flags1[n] &= ~bitflag;
283 qual_flags1[n] |= bitflag;
285 #endif /* SUPPORTED_PERSONALITIES >= 2 */
287 #if SUPPORTED_PERSONALITIES >= 3
288 if (pers == 2 || pers < 0) {
290 qual_flags2[n] &= ~bitflag;
292 qual_flags2[n] |= bitflag;
294 #endif /* SUPPORTED_PERSONALITIES >= 3 */
298 qual_syscall(const char *s, int bitflag, int not)
303 if (isdigit((unsigned char)*s)) {
305 if (i < 0 || i >= MAX_QUALS)
307 qualify_one(i, bitflag, not, -1);
310 for (i = 0; i < nsyscalls0; i++)
311 if (strcmp(s, sysent0[i].sys_name) == 0) {
312 qualify_one(i, bitflag, not, 0);
316 #if SUPPORTED_PERSONALITIES >= 2
317 for (i = 0; i < nsyscalls1; i++)
318 if (strcmp(s, sysent1[i].sys_name) == 0) {
319 qualify_one(i, bitflag, not, 1);
322 #endif /* SUPPORTED_PERSONALITIES >= 2 */
324 #if SUPPORTED_PERSONALITIES >= 3
325 for (i = 0; i < nsyscalls2; i++)
326 if (strcmp(s, sysent2[i].sys_name) == 0) {
327 qualify_one(i, bitflag, not, 2);
330 #endif /* SUPPORTED_PERSONALITIES >= 3 */
336 qual_signal(const char *s, int bitflag, int not)
341 if (isdigit((unsigned char)*s)) {
343 if (signo < 0 || signo >= MAX_QUALS)
345 qualify_one(signo, bitflag, not, -1);
348 if (strlen(s) >= sizeof buf)
352 if (strncasecmp(s, "SIG", 3) == 0)
354 for (i = 0; i <= NSIG; i++)
355 if (strcasecmp(s, signame(i) + 3) == 0) {
356 qualify_one(i, bitflag, not, -1);
363 qual_fault(const char *s, int bitflag, int not)
369 qual_desc(const char *s, int bitflag, int not)
371 if (isdigit((unsigned char)*s)) {
373 if (desc < 0 || desc >= MAX_QUALS)
375 qualify_one(desc, bitflag, not, -1);
382 lookup_class(const char *s)
384 if (strcmp(s, "file") == 0)
386 if (strcmp(s, "ipc") == 0)
388 if (strcmp(s, "network") == 0)
389 return TRACE_NETWORK;
390 if (strcmp(s, "process") == 0)
391 return TRACE_PROCESS;
392 if (strcmp(s, "signal") == 0)
394 if (strcmp(s, "desc") == 0)
400 qualify(const char *s)
402 const struct qual_options *opt;
408 opt = &qual_options[0];
409 for (i = 0; (p = qual_options[i].option_name); i++) {
411 if (strncmp(s, p, n) == 0 && s[n] == '=') {
412 opt = &qual_options[i];
422 if (strcmp(s, "none") == 0) {
426 if (strcmp(s, "all") == 0) {
427 for (i = 0; i < MAX_QUALS; i++) {
428 qualify_one(i, opt->bitflag, not, -1);
432 for (i = 0; i < MAX_QUALS; i++) {
433 qualify_one(i, opt->bitflag, !not, -1);
435 if (!(copy = strdup(s))) {
436 fprintf(stderr, "out of memory\n");
439 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
440 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
441 for (i = 0; i < nsyscalls0; i++)
442 if (sysent0[i].sys_flags & n)
443 qualify_one(i, opt->bitflag, not, 0);
445 #if SUPPORTED_PERSONALITIES >= 2
446 for (i = 0; i < nsyscalls1; i++)
447 if (sysent1[i].sys_flags & n)
448 qualify_one(i, opt->bitflag, not, 1);
449 #endif /* SUPPORTED_PERSONALITIES >= 2 */
451 #if SUPPORTED_PERSONALITIES >= 3
452 for (i = 0; i < nsyscalls2; i++)
453 if (sysent2[i].sys_flags & n)
454 qualify_one(i, opt->bitflag, not, 2);
455 #endif /* SUPPORTED_PERSONALITIES >= 3 */
459 if (opt->qualify(p, opt->bitflag, not)) {
460 fprintf(stderr, "strace: invalid %s `%s'\n",
461 opt->argument_name, p);
470 dumpio(struct tcb *tcp)
474 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
476 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
478 if (sysent[tcp->scno].sys_func == printargs)
480 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
481 if (sysent[tcp->scno].sys_func == sys_read ||
482 sysent[tcp->scno].sys_func == sys_pread ||
483 sysent[tcp->scno].sys_func == sys_pread64 ||
484 sysent[tcp->scno].sys_func == sys_recv ||
485 sysent[tcp->scno].sys_func == sys_recvfrom)
486 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
487 else if (sysent[tcp->scno].sys_func == sys_readv)
488 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
491 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
492 if (sysent[tcp->scno].sys_func == sys_write ||
493 sysent[tcp->scno].sys_func == sys_pwrite ||
494 sysent[tcp->scno].sys_func == sys_pwrite64 ||
495 sysent[tcp->scno].sys_func == sys_send ||
496 sysent[tcp->scno].sys_func == sys_sendto)
497 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
498 else if (sysent[tcp->scno].sys_func == sys_writev)
499 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
505 enum subcall_style { shift_style, deref_style, mask_style, door_style };
507 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
515 static const struct subcall subcalls_table[] = {
516 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
518 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
520 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
522 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
526 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
529 decode_subcall(struct tcb *tcp, int subcall, int nsubcalls, enum subcall_style style)
531 unsigned long addr, mask;
533 int size = personality_wordsize[current_personality];
537 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
539 tcp->scno = subcall + tcp->u_arg[0];
540 if (sysent[tcp->scno].nargs != -1)
541 tcp->u_nargs = sysent[tcp->scno].nargs;
544 for (i = 0; i < tcp->u_nargs; i++)
545 tcp->u_arg[i] = tcp->u_arg[i + 1];
548 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
550 tcp->scno = subcall + tcp->u_arg[0];
551 addr = tcp->u_arg[1];
552 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
553 if (size == sizeof(int)) {
555 if (umove(tcp, addr, &arg) < 0)
559 else if (size == sizeof(long)) {
561 if (umove(tcp, addr, &arg) < 0)
569 tcp->u_nargs = sysent[tcp->scno].nargs;
572 mask = (tcp->u_arg[0] >> 8) & 0xff;
573 for (i = 0; mask; i++)
577 tcp->u_arg[0] &= 0xff;
578 tcp->scno = subcall + i;
579 if (sysent[tcp->scno].nargs != -1)
580 tcp->u_nargs = sysent[tcp->scno].nargs;
584 * Oh, yuck. The call code is the *sixth* argument.
585 * (don't you mean the *last* argument? - JH)
587 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
589 tcp->scno = subcall + tcp->u_arg[5];
590 if (sysent[tcp->scno].nargs != -1)
591 tcp->u_nargs = sysent[tcp->scno].nargs;
597 for (i = 0; i < ARRAY_SIZE(subcalls_table); i++)
598 if (subcalls_table[i].call == tcp->scno) break;
599 if (i < ARRAY_SIZE(subcalls_table) &&
600 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
601 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
602 for (i = 0; i < tcp->u_nargs; i++)
603 tcp->u_arg[i] = tcp->u_arg[i + 1];
611 struct tcb *tcp_last = NULL;
614 internal_syscall(struct tcb *tcp)
617 * We must always trace a few critical system calls in order to
618 * correctly support following forks in the presence of tracing
623 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
626 func = sysent[tcp->scno].sys_func;
628 if ( sys_fork == func
629 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
639 return internal_fork(tcp);
641 if ( sys_execve == func
642 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
646 || sys_rexecve == func
649 return internal_exec(tcp);
658 # elif defined (IA64)
659 long r8, r10, psr; /* TODO: make static? */
660 long ia32 = 0; /* not static */
661 # elif defined (POWERPC)
662 static long result, flags;
663 # elif defined (M68K)
668 static struct pt_regs regs;
669 # elif defined (ALPHA)
672 # elif defined(AVR32)
673 static struct pt_regs regs;
674 # elif defined (SPARC) || defined (SPARC64)
675 static struct pt_regs regs;
676 static unsigned long trap;
677 # elif defined(LINUX_MIPSN32)
683 # elif defined(S390) || defined(S390X)
686 static long syscall_mode;
693 # elif defined(X86_64)
695 # elif defined(CRISV10) || defined(CRISV32)
697 # elif defined(MICROBLAZE)
702 struct reg regs; /* TODO: make static? */
706 get_scno(struct tcb *tcp)
711 # if defined(S390) || defined(S390X)
712 if (tcp->flags & TCB_WAITEXECVE) {
714 * When the execve system call completes successfully, the
715 * new process still has -ENOSYS (old style) or __NR_execve
716 * (new style) in gpr2. We cannot recover the scno again
717 * by disassembly, because the image that executed the
718 * syscall is gone now. Fortunately, we don't want it. We
719 * leave the flag set so that syscall_fixup can fake the
722 if (tcp->flags & TCB_INSYSCALL)
725 * This is the SIGTRAP after execve. We cannot try to read
726 * the system call here either.
728 tcp->flags &= ~TCB_WAITEXECVE;
732 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
735 if (syscall_mode != -ENOSYS) {
737 * Since kernel version 2.5.44 the scno gets passed in gpr2.
742 * Old style of "passing" the scno via the SVC instruction.
745 long opcode, offset_reg, tmp;
747 static const int gpr_offset[16] = {
748 PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
749 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
750 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
751 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15
754 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
757 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
759 perror("peektext(pc-oneword)");
764 * We have to check if the SVC got executed directly or via an
765 * EXECUTE instruction. In case of EXECUTE it is necessary to do
766 * instruction decoding to derive the system call number.
767 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
768 * so that this doesn't work if a SVC opcode is part of an EXECUTE
769 * opcode. Since there is no way to find out the opcode size this
770 * is the best we can do...
773 if ((opcode & 0xff00) == 0x0a00) {
775 scno = opcode & 0xff;
778 /* SVC got executed by EXECUTE instruction */
781 * Do instruction decoding of EXECUTE. If you really want to
782 * understand this, read the Principles of Operations.
784 svc_addr = (void *) (opcode & 0xfff);
787 offset_reg = (opcode & 0x000f0000) >> 16;
788 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
793 offset_reg = (opcode & 0x0000f000) >> 12;
794 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
798 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
807 offset_reg = (opcode & 0x00f00000) >> 20;
808 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
811 scno = (scno | tmp) & 0xff;
814 # elif defined (POWERPC)
815 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
817 if (!(tcp->flags & TCB_INSYSCALL)) {
818 /* Check if we return from execve. */
819 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
820 tcp->flags &= ~TCB_WAITEXECVE;
826 if (!(tcp->flags & TCB_INSYSCALL)) {
827 /* TODO: speed up strace by not doing this at every syscall.
828 * We only need to do it after execve.
834 /* Check for 64/32 bit mode. */
835 if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0)
837 /* SF is bit 0 of MSR */
842 if (currpers != current_personality) {
843 static const char *const names[] = {"64 bit", "32 bit"};
844 set_personality(currpers);
845 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
846 pid, names[current_personality]);
850 # elif defined(AVR32)
852 * Read complete register set in one go.
854 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
858 * We only need to grab the syscall number on syscall entry.
860 if (!(tcp->flags & TCB_INSYSCALL)) {
863 /* Check if we return from execve. */
864 if (tcp->flags & TCB_WAITEXECVE) {
865 tcp->flags &= ~TCB_WAITEXECVE;
870 if (upeek(tcp, PT_ORIG_P0, &scno))
872 # elif defined (I386)
873 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
875 # elif defined (X86_64)
876 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
879 if (!(tcp->flags & TCB_INSYSCALL)) {
880 /* TODO: speed up strace by not doing this at every syscall.
881 * We only need to do it after execve.
887 /* Check CS register value. On x86-64 linux it is:
888 * 0x33 for long mode (64 bit)
889 * 0x23 for compatibility mode (32 bit)
890 * It takes only one ptrace and thus doesn't need
893 if (upeek(tcp, 8*CS, &val) < 0)
896 case 0x23: currpers = 1; break;
897 case 0x33: currpers = 0; break;
899 fprintf(stderr, "Unknown value CS=0x%02X while "
900 "detecting personality of process "
901 "PID=%d\n", (int)val, pid);
902 currpers = current_personality;
906 /* This version analyzes the opcode of a syscall instruction.
907 * (int 0x80 on i386 vs. syscall on x86-64)
908 * It works, but is too complicated.
910 unsigned long val, rip, i;
912 if (upeek(tcp, 8*RIP, &rip) < 0)
913 perror("upeek(RIP)");
915 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
919 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
921 fprintf(stderr, "ptrace_peektext failed: %s\n",
923 switch (call & 0xffff) {
924 /* x86-64: syscall = 0x0f 0x05 */
925 case 0x050f: currpers = 0; break;
926 /* i386: int 0x80 = 0xcd 0x80 */
927 case 0x80cd: currpers = 1; break;
929 currpers = current_personality;
931 "Unknown syscall opcode (0x%04X) while "
932 "detecting personality of process "
933 "PID=%d\n", (int)call, pid);
937 if (currpers != current_personality) {
938 static const char *const names[] = {"64 bit", "32 bit"};
939 set_personality(currpers);
940 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
941 pid, names[current_personality]);
945 # define IA64_PSR_IS ((long)1 << 34)
946 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0)
947 ia32 = (psr & IA64_PSR_IS) != 0;
948 if (!(tcp->flags & TCB_INSYSCALL)) {
950 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
953 if (upeek(tcp, PT_R15, &scno) < 0)
956 /* Check if we return from execve. */
957 if (tcp->flags & TCB_WAITEXECVE) {
958 tcp->flags &= ~TCB_WAITEXECVE;
962 /* syscall in progress */
963 if (upeek(tcp, PT_R8, &r8) < 0)
965 if (upeek(tcp, PT_R10, &r10) < 0)
970 * Read complete register set in one go.
972 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
976 * We only need to grab the syscall number on syscall entry.
978 if (regs.ARM_ip == 0) {
979 if (!(tcp->flags & TCB_INSYSCALL)) {
980 /* Check if we return from execve. */
981 if (tcp->flags & TCB_WAITEXECVE) {
982 tcp->flags &= ~TCB_WAITEXECVE;
988 * Note: we only deal with only 32-bit CPUs here.
990 if (regs.ARM_cpsr & 0x20) {
992 * Get the Thumb-mode system call number
997 * Get the ARM-mode system call number
1000 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1004 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1005 tcp->flags &= ~TCB_WAITEXECVE;
1009 /* Handle the EABI syscall convention. We do not
1010 bother converting structures between the two
1011 ABIs, but basic functionality should work even
1012 if strace and the traced program have different
1014 if (scno == 0xef000000) {
1017 if ((scno & 0x0ff00000) != 0x0f900000) {
1018 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1024 * Fixup the syscall number
1029 if (scno & 0x0f0000) {
1031 * Handle ARM specific syscall
1038 if (tcp->flags & TCB_INSYSCALL) {
1039 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1040 tcp->flags &= ~TCB_INSYSCALL;
1043 if (!(tcp->flags & TCB_INSYSCALL)) {
1044 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1045 tcp->flags |= TCB_INSYSCALL;
1048 # elif defined (M68K)
1049 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1051 # elif defined (LINUX_MIPSN32)
1052 unsigned long long regs[38];
1054 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1059 if (!(tcp->flags & TCB_INSYSCALL)) {
1062 /* Check if we return from execve. */
1063 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1064 tcp->flags &= ~TCB_WAITEXECVE;
1068 if (scno < 0 || scno > nsyscalls) {
1069 if (a3 == 0 || a3 == -1) {
1071 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
1076 # elif defined (MIPS)
1077 if (upeek(tcp, REG_A3, &a3) < 0)
1079 if (!(tcp->flags & TCB_INSYSCALL)) {
1080 if (upeek(tcp, REG_V0, &scno) < 0)
1083 /* Check if we return from execve. */
1084 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1085 tcp->flags &= ~TCB_WAITEXECVE;
1089 if (scno < 0 || scno > nsyscalls) {
1090 if (a3 == 0 || a3 == -1) {
1092 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
1097 if (upeek(tcp, REG_V0, &r2) < 0)
1100 # elif defined (ALPHA)
1101 if (upeek(tcp, REG_A3, &a3) < 0)
1104 if (!(tcp->flags & TCB_INSYSCALL)) {
1105 if (upeek(tcp, REG_R0, &scno) < 0)
1108 /* Check if we return from execve. */
1109 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1110 tcp->flags &= ~TCB_WAITEXECVE;
1115 * Do some sanity checks to figure out if it's
1116 * really a syscall entry
1118 if (scno < 0 || scno > nsyscalls) {
1119 if (a3 == 0 || a3 == -1) {
1121 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
1127 if (upeek(tcp, REG_R0, &r0) < 0)
1130 # elif defined (SPARC) || defined (SPARC64)
1131 /* Everything we need is in the current register set. */
1132 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1135 /* If we are entering, then disassemble the syscall trap. */
1136 if (!(tcp->flags & TCB_INSYSCALL)) {
1137 /* Retrieve the syscall trap instruction. */
1139 # if defined(SPARC64)
1140 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1143 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1148 /* Disassemble the trap to see what personality to use. */
1151 /* Linux/SPARC syscall trap. */
1155 /* Linux/SPARC64 syscall trap. */
1159 /* SunOS syscall trap. (pers 1) */
1160 fprintf(stderr, "syscall: SunOS no support\n");
1163 /* Solaris 2.x syscall trap. (per 2) */
1167 /* NetBSD/FreeBSD syscall trap. */
1168 fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n");
1171 /* Solaris 2.x gettimeofday */
1175 /* Unknown syscall trap. */
1176 if (tcp->flags & TCB_WAITEXECVE) {
1177 tcp->flags &= ~TCB_WAITEXECVE;
1180 # if defined (SPARC64)
1181 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1183 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1188 /* Extract the system call number from the registers. */
1189 if (trap == 0x91d02027)
1192 scno = regs.u_regs[U_REG_G1];
1194 scno = regs.u_regs[U_REG_O0];
1195 memmove(®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1198 # elif defined(HPPA)
1199 if (upeek(tcp, PT_GR20, &scno) < 0)
1201 if (!(tcp->flags & TCB_INSYSCALL)) {
1202 /* Check if we return from execve. */
1203 if ((tcp->flags & TCB_WAITEXECVE)) {
1204 tcp->flags &= ~TCB_WAITEXECVE;
1210 * In the new syscall ABI, the system call number is in R3.
1212 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1216 /* Odd as it may seem, a glibc bug has been known to cause
1217 glibc to issue bogus negative syscall numbers. So for
1218 our purposes, make strace print what it *should* have been */
1219 long correct_scno = (scno & 0xff);
1222 "Detected glibc bug: bogus system call"
1223 " number = %ld, correcting to %ld\n",
1226 scno = correct_scno;
1229 if (!(tcp->flags & TCB_INSYSCALL)) {
1230 /* Check if we return from execve. */
1231 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1232 tcp->flags &= ~TCB_WAITEXECVE;
1236 # elif defined(SH64)
1237 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1241 if (!(tcp->flags & TCB_INSYSCALL)) {
1242 /* Check if we return from execve. */
1243 if (tcp->flags & TCB_WAITEXECVE) {
1244 tcp->flags &= ~TCB_WAITEXECVE;
1248 # elif defined(CRISV10) || defined(CRISV32)
1249 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1251 # elif defined(TILE)
1252 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1255 if (!(tcp->flags & TCB_INSYSCALL)) {
1256 /* Check if we return from execve. */
1257 if (tcp->flags & TCB_WAITEXECVE) {
1258 tcp->flags &= ~TCB_WAITEXECVE;
1262 # elif defined(MICROBLAZE)
1263 if (upeek(tcp, 0, &scno) < 0)
1269 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1272 /* new syscall ABI returns result in R0 */
1273 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1276 /* ABI defines result returned in r9 */
1277 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1282 # ifdef HAVE_PR_SYSCALL
1283 scno = tcp->status.PR_SYSCALL;
1286 scno = tcp->status.PR_WHAT;
1288 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1292 switch (regs.r_eax) {
1295 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1301 # endif /* FREEBSD */
1302 # endif /* !HAVE_PR_SYSCALL */
1303 #endif /* USE_PROCFS */
1305 if (!(tcp->flags & TCB_INSYSCALL))
1312 known_scno(struct tcb *tcp)
1314 long scno = tcp->scno;
1315 #if SUPPORTED_PERSONALITIES > 1
1316 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1317 scno = sysent[scno].native_scno;
1320 scno += NR_SYSCALL_BASE;
1324 /* Called in trace_syscall() at each syscall entry and exit.
1326 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1327 * 1: ok, continue in trace_syscall().
1328 * other: error, trace_syscall() should print error indicator
1329 * ("????" etc) and bail out.
1332 syscall_fixup(struct tcb *tcp)
1335 int scno = known_scno(tcp);
1337 if (!(tcp->flags & TCB_INSYSCALL)) {
1338 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1342 || scno == SYS_vfork
1343 #endif /* SYS_vfork */
1345 || scno == SYS_fork1
1346 #endif /* SYS_fork1 */
1348 || scno == SYS_forkall
1349 #endif /* SYS_forkall */
1351 || scno == SYS_rfork1
1352 #endif /* SYS_fork1 */
1354 || scno == SYS_rforkall
1355 #endif /* SYS_rforkall */
1357 /* We are returning in the child, fake it. */
1358 tcp->status.PR_WHY = PR_SYSENTRY;
1360 tcp->status.PR_WHY = PR_SYSEXIT;
1363 fprintf(stderr, "syscall: missing entry\n");
1364 tcp->flags |= TCB_INSYSCALL;
1369 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1370 fprintf(stderr, "syscall: missing exit\n");
1371 tcp->flags &= ~TCB_INSYSCALL;
1374 #endif /* USE_PROCFS */
1376 if (!(tcp->flags & TCB_INSYSCALL)) {
1378 fprintf(stderr, "syscall: missing entry\n");
1379 tcp->flags |= TCB_INSYSCALL;
1386 * This happens when a signal handler
1387 * for a signal which interrupted a
1388 * a system call makes another system call.
1390 fprintf(stderr, "syscall: missing exit\n");
1392 tcp->flags &= ~TCB_INSYSCALL;
1398 if (upeek(tcp, 4*EAX, &eax) < 0)
1400 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1402 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1405 #elif defined (X86_64)
1406 if (upeek(tcp, 8*RAX, &rax) < 0)
1408 if (current_personality == 1)
1409 rax = (long int)(int)rax; /* sign extend from 32 bits */
1410 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1412 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1415 #elif defined (S390) || defined (S390X)
1416 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1418 if (syscall_mode != -ENOSYS)
1419 syscall_mode = tcp->scno;
1420 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1422 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1425 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1426 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1427 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1429 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1430 * flag set for the post-execve SIGTRAP to see and reset.
1434 #elif defined (POWERPC)
1435 # define SO_MASK 0x10000000
1436 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1438 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1440 if (flags & SO_MASK)
1442 #elif defined (M68K)
1443 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1445 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1447 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1455 if (upeek(tcp, PT_R0, &r0) < 0)
1457 #elif defined (HPPA)
1458 if (upeek(tcp, PT_GR28, &r28) < 0)
1461 if (upeek(tcp, PT_R10, &r10) < 0)
1463 if (upeek(tcp, PT_R8, &r8) < 0)
1465 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1467 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1470 #elif defined(CRISV10) || defined(CRISV32)
1471 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1473 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1475 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1478 #elif defined(MICROBLAZE)
1479 if (upeek(tcp, 3 * 4, &r3) < 0)
1481 if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1483 fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
1493 * Check the syscall return value register value for whether it is
1494 * a negated errno code indicating an error, or a success return value.
1497 is_negated_errno(unsigned long int val)
1499 unsigned long int max = -(long int) nerrnos;
1500 if (personality_wordsize[current_personality] < sizeof(val)) {
1501 val = (unsigned int) val;
1502 max = (unsigned int) max;
1509 get_error(struct tcb *tcp)
1513 int check_errno = 1;
1514 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
1515 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) {
1518 # if defined(S390) || defined(S390X)
1519 if (check_errno && is_negated_errno(gpr2)) {
1527 # elif defined(I386)
1528 if (check_errno && is_negated_errno(eax)) {
1536 # elif defined(X86_64)
1537 if (check_errno && is_negated_errno(rax)) {
1545 # elif defined(IA64)
1550 if (check_errno && is_negated_errno(err)) {
1559 if (check_errno && r10) {
1567 # elif defined(MIPS)
1568 if (check_errno && a3) {
1575 # elif defined(POWERPC)
1576 if (check_errno && is_negated_errno(result)) {
1581 tcp->u_rval = result;
1584 # elif defined(M68K)
1585 if (check_errno && is_negated_errno(d0)) {
1594 if (check_errno && is_negated_errno(regs.ARM_r0)) {
1596 u_error = -regs.ARM_r0;
1599 tcp->u_rval = regs.ARM_r0;
1602 # elif defined(AVR32)
1603 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1605 u_error = -regs.r12;
1608 tcp->u_rval = regs.r12;
1611 # elif defined(BFIN)
1612 if (check_errno && is_negated_errno(r0)) {
1619 # elif defined(ALPHA)
1620 if (check_errno && a3) {
1628 # elif defined(SPARC)
1629 if (check_errno && regs.psr & PSR_C) {
1631 u_error = regs.u_regs[U_REG_O0];
1634 tcp->u_rval = regs.u_regs[U_REG_O0];
1637 # elif defined(SPARC64)
1638 if (check_errno && regs.tstate & 0x1100000000UL) {
1640 u_error = regs.u_regs[U_REG_O0];
1643 tcp->u_rval = regs.u_regs[U_REG_O0];
1646 # elif defined(HPPA)
1647 if (check_errno && is_negated_errno(r28)) {
1656 /* interpret R0 as return value or error number */
1657 if (check_errno && is_negated_errno(r0)) {
1665 # elif defined(SH64)
1666 /* interpret result as return value or error number */
1667 if (check_errno && is_negated_errno(r9)) {
1675 # elif defined(CRISV10) || defined(CRISV32)
1676 if (check_errno && r10 && (unsigned) -r10 < nerrnos) {
1684 # elif defined(TILE)
1686 /* interpret result as return value or error number */
1687 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1689 if (check_errno && rval < 0 && rval > -nerrnos) {
1697 # elif defined(MICROBLAZE)
1698 /* interpret result as return value or error number */
1699 if (check_errno && is_negated_errno(r3)) {
1710 /* get error code from user struct */
1711 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1713 u_error >>= 24; /* u_error is a char */
1715 /* get system call return value */
1716 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1721 /* Judicious guessing goes a long way. */
1722 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1724 u_error = tcp->status.pr_reg[R_O0];
1727 tcp->u_rval = tcp->status.pr_reg[R_O0];
1732 /* Wanna know how to kill an hour single-stepping? */
1733 if (tcp->status.PR_REG[EFL] & 0x1) {
1735 u_error = tcp->status.PR_REG[EAX];
1738 tcp->u_rval = tcp->status.PR_REG[EAX];
1739 # ifdef HAVE_LONG_LONG
1741 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1742 tcp->status.PR_REG[EAX];
1748 /* Wanna know how to kill an hour single-stepping? */
1749 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1751 u_error = tcp->status.PR_REG[RAX];
1754 tcp->u_rval = tcp->status.PR_REG[RAX];
1757 # endif /* X86_64 */
1759 if (tcp->status.pr_reg[CTX_A3]) {
1761 u_error = tcp->status.pr_reg[CTX_V0];
1764 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1770 if (regs.r_eflags & PSL_C) {
1772 u_error = regs.r_eax;
1774 tcp->u_rval = regs.r_eax;
1776 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1779 #endif /* FREEBSD */
1780 tcp->u_error = u_error;
1785 force_result(struct tcb *tcp, int error, long rval)
1788 # if defined(S390) || defined(S390X)
1789 gpr2 = error ? -error : rval;
1790 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1792 # elif defined(I386)
1793 eax = error ? -error : rval;
1794 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1796 # elif defined(X86_64)
1797 rax = error ? -error : rval;
1798 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1800 # elif defined(IA64)
1802 r8 = error ? -error : rval;
1803 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1815 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1816 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1819 # elif defined(BFIN)
1820 r0 = error ? -error : rval;
1821 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1823 # elif defined(MIPS)
1832 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1833 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1834 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1836 # elif defined(POWERPC)
1837 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1847 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1848 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1850 # elif defined(M68K)
1851 d0 = error ? -error : rval;
1852 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1855 regs.ARM_r0 = error ? -error : rval;
1856 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1858 # elif defined(AVR32)
1859 regs.r12 = error ? -error : rval;
1860 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1862 # elif defined(ALPHA)
1871 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1872 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1874 # elif defined(SPARC)
1875 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1879 regs.u_regs[U_REG_O0] = error;
1883 regs.u_regs[U_REG_O0] = rval;
1885 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1887 # elif defined(SPARC64)
1888 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1891 regs.tstate |= 0x1100000000UL;
1892 regs.u_regs[U_REG_O0] = error;
1895 regs.tstate &= ~0x1100000000UL;
1896 regs.u_regs[U_REG_O0] = rval;
1898 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1900 # elif defined(HPPA)
1901 r28 = error ? -error : rval;
1902 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1905 r0 = error ? -error : rval;
1906 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1908 # elif defined(SH64)
1909 r9 = error ? -error : rval;
1910 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1916 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1918 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1928 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1933 regs.r_eflags |= PSL_C;
1937 regs.r_eflags &= ~PSL_C;
1940 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1944 #endif /* FREEBSD */
1946 /* All branches reach here on success (only). */
1947 tcp->u_error = error;
1953 syscall_enter(struct tcb *tcp)
1956 # if defined(S390) || defined(S390X)
1958 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1959 tcp->u_nargs = sysent[tcp->scno].nargs;
1961 tcp->u_nargs = MAX_ARGS;
1962 for (i = 0; i < tcp->u_nargs; i++) {
1963 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2 + i*sizeof(long), &tcp->u_arg[i]) < 0)
1966 # elif defined(ALPHA)
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 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1974 * for scno somewhere above here!
1976 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1979 # elif defined(IA64)
1981 unsigned long *out0, cfm, sof, sol, i;
1983 /* be backwards compatible with kernel < 2.4.4... */
1985 # define PT_RBS_END PT_AR_BSP
1988 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
1990 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1993 sof = (cfm >> 0) & 0x7f;
1994 sol = (cfm >> 7) & 0x7f;
1995 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
1997 if (tcp->scno >= 0 && tcp->scno < nsyscalls
1998 && sysent[tcp->scno].nargs != -1)
1999 tcp->u_nargs = sysent[tcp->scno].nargs;
2001 tcp->u_nargs = MAX_ARGS;
2002 for (i = 0; i < tcp->u_nargs; ++i) {
2003 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2004 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2010 if (/* EBX = out0 */
2011 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2013 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2015 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2017 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2019 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2021 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2024 for (i = 0; i < 6; ++i)
2025 /* truncate away IVE sign-extension */
2026 tcp->u_arg[i] &= 0xffffffff;
2028 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2029 && sysent[tcp->scno].nargs != -1)
2030 tcp->u_nargs = sysent[tcp->scno].nargs;
2034 # elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64)
2035 /* N32 and N64 both use up to six registers. */
2036 unsigned long long regs[38];
2038 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2039 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2041 nargs = tcp->u_nargs = MAX_ARGS;
2043 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2046 for (i = 0; i < nargs; i++) {
2047 tcp->u_arg[i] = regs[REG_A0 + i];
2048 # if defined(LINUX_MIPSN32)
2049 tcp->ext_arg[i] = regs[REG_A0 + i];
2052 # elif defined(MIPS)
2056 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2057 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2059 nargs = tcp->u_nargs = MAX_ARGS;
2061 if (upeek(tcp, REG_SP, &sp) < 0)
2063 for (i = 0; i < 4; i++) {
2064 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2067 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2068 (char *)(tcp->u_arg + 4));
2070 for (i = 0; i < nargs; i++) {
2071 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2075 # elif defined(POWERPC)
2077 # define PT_ORIG_R3 34
2080 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2081 tcp->u_nargs = sysent[tcp->scno].nargs;
2083 tcp->u_nargs = MAX_ARGS;
2084 for (i = 0; i < tcp->u_nargs; i++) {
2085 if (upeek(tcp, (i==0) ?
2086 (sizeof(unsigned long) * PT_ORIG_R3) :
2087 ((i+PT_R3) * sizeof(unsigned long)),
2088 &tcp->u_arg[i]) < 0)
2091 # elif defined(SPARC) || defined(SPARC64)
2093 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2094 tcp->u_nargs = sysent[tcp->scno].nargs;
2096 tcp->u_nargs = MAX_ARGS;
2097 for (i = 0; i < tcp->u_nargs; i++)
2098 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2099 # elif defined(HPPA)
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, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2111 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2112 tcp->u_nargs = sysent[tcp->scno].nargs;
2114 tcp->u_nargs = MAX_ARGS;
2115 for (i = 0; i < tcp->u_nargs; i++)
2116 tcp->u_arg[i] = regs.uregs[i];
2117 # elif defined(AVR32)
2118 tcp->u_nargs = sysent[tcp->scno].nargs;
2119 tcp->u_arg[0] = regs.r12;
2120 tcp->u_arg[1] = regs.r11;
2121 tcp->u_arg[2] = regs.r10;
2122 tcp->u_arg[3] = regs.r9;
2123 tcp->u_arg[4] = regs.r5;
2124 tcp->u_arg[5] = regs.r3;
2125 # elif defined(BFIN)
2127 static const int argreg[] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 };
2129 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2130 tcp->u_nargs = sysent[tcp->scno].nargs;
2132 tcp->u_nargs = ARRAY_SIZE(argreg);
2134 for (i = 0; i < tcp->u_nargs; ++i)
2135 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2139 static const int syscall_regs[] = {
2140 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6), 4 * (REG_REG0+7),
2141 4 * (REG_REG0 ), 4 * (REG_REG0+1), 4 * (REG_REG0+2)
2144 tcp->u_nargs = sysent[tcp->scno].nargs;
2145 for (i = 0; i < tcp->u_nargs; i++) {
2146 if (upeek(tcp, syscall_regs[i], &tcp->u_arg[i]) < 0)
2149 # elif defined(SH64)
2151 /* Registers used by SH5 Linux system calls for parameters */
2152 static const int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2155 * TODO: should also check that the number of arguments encoded
2156 * in the trap number matches the number strace expects.
2159 assert(sysent[tcp->scno].nargs < ARRAY_SIZE(syscall_regs));
2162 tcp->u_nargs = sysent[tcp->scno].nargs;
2163 for (i = 0; i < tcp->u_nargs; i++) {
2164 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2167 # elif defined(X86_64)
2169 static const int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2170 { 8 * RDI, 8 * RSI, 8 * RDX, 8 * R10, 8 * R8 , 8 * R9 }, /* x86-64 ABI */
2171 { 8 * RBX, 8 * RCX, 8 * RDX, 8 * RSI, 8 * RDI, 8 * RBP } /* i386 ABI */
2174 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2175 tcp->u_nargs = sysent[tcp->scno].nargs;
2177 tcp->u_nargs = MAX_ARGS;
2178 for (i = 0; i < tcp->u_nargs; i++) {
2179 if (upeek(tcp, argreg[current_personality][i], &tcp->u_arg[i]) < 0)
2182 # elif defined(MICROBLAZE)
2184 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2185 tcp->u_nargs = sysent[tcp->scno].nargs;
2188 for (i = 0; i < tcp->u_nargs; i++) {
2189 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
2192 # elif defined(CRISV10) || defined(CRISV32)
2194 static const int crisregs[] = {
2195 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2196 4*PT_R13 , 4*PT_MOF, 4*PT_SRP
2199 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2200 tcp->u_nargs = sysent[tcp->scno].nargs;
2203 for (i = 0; i < tcp->u_nargs; i++) {
2204 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2207 # elif defined(TILE)
2209 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2210 tcp->u_nargs = sysent[tcp->scno].nargs;
2212 tcp->u_nargs = MAX_ARGS;
2213 for (i = 0; i < tcp->u_nargs; ++i) {
2214 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2217 # elif defined(M68K)
2219 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2220 tcp->u_nargs = sysent[tcp->scno].nargs;
2222 tcp->u_nargs = MAX_ARGS;
2223 for (i = 0; i < tcp->u_nargs; i++) {
2224 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
2227 # else /* Other architecture (like i386) (32bits specific) */
2229 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2230 tcp->u_nargs = sysent[tcp->scno].nargs;
2232 tcp->u_nargs = MAX_ARGS;
2233 for (i = 0; i < tcp->u_nargs; i++) {
2234 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2241 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2242 tcp->u_nargs = sysent[tcp->scno].nargs;
2244 tcp->u_nargs = MAX_ARGS;
2245 for (i = 0; i < tcp->u_nargs; i++) {
2248 if (upeek(tcp, uoff(u_arg[0]) +
2249 (i * sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2256 * SGI is broken: even though it has pr_sysarg, it doesn't
2257 * set them on system call entry. Get a clue.
2259 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2260 tcp->u_nargs = sysent[tcp->scno].nargs;
2262 tcp->u_nargs = tcp->status.pr_nsysarg;
2263 if (tcp->u_nargs > 4) {
2264 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2265 4 * sizeof(tcp->u_arg[0]));
2266 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2267 (tcp->u_nargs - 4) * sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2270 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2271 tcp->u_nargs * sizeof(tcp->u_arg[0]));
2273 # elif UNIXWARE >= 2
2275 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2277 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2278 tcp->u_nargs = sysent[tcp->scno].nargs;
2280 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2281 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2282 tcp->u_nargs * sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2283 # elif defined(HAVE_PR_SYSCALL)
2285 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2286 tcp->u_nargs = sysent[tcp->scno].nargs;
2288 tcp->u_nargs = tcp->status.pr_nsysarg;
2289 for (i = 0; i < tcp->u_nargs; i++)
2290 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2291 # elif defined(I386)
2292 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2293 tcp->u_nargs = sysent[tcp->scno].nargs;
2296 if (tcp->u_nargs > 0)
2297 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2298 tcp->u_nargs * sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2300 I DONT KNOW WHAT TO DO
2304 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2305 sysent[tcp->scno].nargs > tcp->status.val)
2306 tcp->u_nargs = sysent[tcp->scno].nargs;
2308 tcp->u_nargs = tcp->status.val;
2309 if (tcp->u_nargs < 0)
2311 if (tcp->u_nargs > MAX_ARGS)
2312 tcp->u_nargs = MAX_ARGS;
2313 switch (regs.r_eax) {
2315 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2316 regs.r_esp + sizeof(int) + sizeof(quad_t));
2319 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2320 regs.r_esp + 2 * sizeof(int));
2323 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2324 regs.r_esp + sizeof(int));
2327 #endif /* FREEBSD */
2332 trace_syscall_exiting(struct tcb *tcp)
2339 /* Measure the exit time as early as possible to avoid errors. */
2341 gettimeofday(&tv, NULL);
2343 /* BTW, why we don't just memorize syscall no. on entry
2344 * in tcp->something?
2346 scno_good = res = get_scno(tcp);
2350 res = syscall_fixup(tcp);
2354 res = get_error(tcp);
2358 internal_syscall(tcp);
2360 if (res == 1 && filtered(tcp)) {
2361 tcp->flags &= ~TCB_INSYSCALL;
2365 if (tcp->flags & TCB_REPRINT) {
2370 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2371 tprintf("syscall_%lu", tcp->scno);
2373 tprintf("%s", sysent[tcp->scno].sys_name);
2374 tprintf(" resumed> ");
2378 struct timeval t = tv;
2379 int rc = count_syscall(tcp, &t);
2380 if (cflag == CFLAG_ONLY_STATS) {
2381 tcp->flags &= ~TCB_INSYSCALL;
2389 tprintf("= ? <unavailable>");
2391 tcp->flags &= ~TCB_INSYSCALL;
2395 if (tcp->scno >= nsyscalls || tcp->scno < 0
2396 || (qual_flags[tcp->scno] & QUAL_RAW))
2397 sys_res = printargs(tcp);
2399 if (not_failing_only && tcp->u_error)
2400 return 0; /* ignore failed syscalls */
2401 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2404 u_error = tcp->u_error;
2407 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2408 qual_flags[tcp->scno] & QUAL_RAW) {
2410 tprintf("= -1 (errno %ld)", u_error);
2412 tprintf("= %#lx", tcp->u_rval);
2414 else if (!(sys_res & RVAL_NONE) && u_error) {
2418 tprintf("= ? ERESTARTSYS (To be restarted)");
2420 case ERESTARTNOINTR:
2421 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2423 case ERESTARTNOHAND:
2424 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2426 case ERESTART_RESTARTBLOCK:
2427 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2433 tprintf("E??? (errno %ld)", u_error);
2434 else if (u_error < nerrnos)
2435 tprintf("%s (%s)", errnoent[u_error],
2438 tprintf("ERRNO_%ld (%s)", u_error,
2442 if ((sys_res & RVAL_STR) && tcp->auxstr)
2443 tprintf(" (%s)", tcp->auxstr);
2446 if (sys_res & RVAL_NONE)
2449 switch (sys_res & RVAL_MASK) {
2451 tprintf("= %#lx", tcp->u_rval);
2454 tprintf("= %#lo", tcp->u_rval);
2457 tprintf("= %lu", tcp->u_rval);
2460 tprintf("= %ld", tcp->u_rval);
2462 #ifdef HAVE_LONG_LONG
2464 tprintf("= %#llx", tcp->u_lrval);
2467 tprintf("= %#llo", tcp->u_lrval);
2469 case RVAL_LUDECIMAL:
2470 tprintf("= %llu", tcp->u_lrval);
2473 tprintf("= %lld", tcp->u_lrval);
2478 "invalid rval format\n");
2482 if ((sys_res & RVAL_STR) && tcp->auxstr)
2483 tprintf(" (%s)", tcp->auxstr);
2486 tv_sub(&tv, &tv, &tcp->etime);
2487 tprintf(" <%ld.%06ld>",
2488 (long) tv.tv_sec, (long) tv.tv_usec);
2493 if (fflush(tcp->outf) == EOF)
2495 tcp->flags &= ~TCB_INSYSCALL;
2500 trace_syscall_entering(struct tcb *tcp)
2505 scno_good = res = get_scno(tcp);
2509 res = syscall_fixup(tcp);
2513 res = syscall_enter(tcp);
2519 tcp->flags &= ~TCB_REPRINT;
2522 tprintf("????" /* anti-trigraph gap */ "(");
2523 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2524 tprintf("syscall_%lu(", tcp->scno);
2526 tprintf("%s(", sysent[tcp->scno].sys_name);
2528 * " <unavailable>" will be added later by the code which
2529 * detects ptrace errors.
2531 tcp->flags |= TCB_INSYSCALL;
2535 switch (known_scno(tcp)) {
2536 #ifdef SYS_socket_subcall
2537 case SYS_socketcall:
2538 decode_subcall(tcp, SYS_socket_subcall,
2539 SYS_socket_nsubcalls, deref_style);
2542 #ifdef SYS_ipc_subcall
2544 decode_subcall(tcp, SYS_ipc_subcall,
2545 SYS_ipc_nsubcalls, shift_style);
2549 #ifdef SYS_pgrpsys_subcall
2551 decode_subcall(tcp, SYS_pgrpsys_subcall,
2552 SYS_pgrpsys_nsubcalls, shift_style);
2554 #endif /* SYS_pgrpsys_subcall */
2555 #ifdef SYS_sigcall_subcall
2557 decode_subcall(tcp, SYS_sigcall_subcall,
2558 SYS_sigcall_nsubcalls, mask_style);
2560 #endif /* SYS_sigcall_subcall */
2562 decode_subcall(tcp, SYS_msgsys_subcall,
2563 SYS_msgsys_nsubcalls, shift_style);
2566 decode_subcall(tcp, SYS_shmsys_subcall,
2567 SYS_shmsys_nsubcalls, shift_style);
2570 decode_subcall(tcp, SYS_semsys_subcall,
2571 SYS_semsys_nsubcalls, shift_style);
2574 decode_subcall(tcp, SYS_sysfs_subcall,
2575 SYS_sysfs_nsubcalls, shift_style);
2578 decode_subcall(tcp, SYS_spcall_subcall,
2579 SYS_spcall_nsubcalls, shift_style);
2581 #ifdef SYS_context_subcall
2583 decode_subcall(tcp, SYS_context_subcall,
2584 SYS_context_nsubcalls, shift_style);
2586 #endif /* SYS_context_subcall */
2587 #ifdef SYS_door_subcall
2589 decode_subcall(tcp, SYS_door_subcall,
2590 SYS_door_nsubcalls, door_style);
2592 #endif /* SYS_door_subcall */
2593 #ifdef SYS_kaio_subcall
2595 decode_subcall(tcp, SYS_kaio_subcall,
2596 SYS_kaio_nsubcalls, shift_style);
2604 decode_subcall(tcp, 0, 0, table_style);
2609 decode_subcall(tcp, SYS_semsys_subcall,
2610 SYS_semsys_nsubcalls, shift_style);
2613 decode_subcall(tcp, SYS_msgsys_subcall,
2614 SYS_msgsys_nsubcalls, shift_style);
2617 decode_subcall(tcp, SYS_shmsys_subcall,
2618 SYS_shmsys_nsubcalls, shift_style);
2623 internal_syscall(tcp);
2625 if ((tcp->scno >= 0 && tcp->scno < nsyscalls &&
2626 !(qual_flags[tcp->scno] & QUAL_TRACE)) ||
2627 (tracing_paths && !pathtrace_match(tcp))) {
2628 tcp->flags |= TCB_INSYSCALL | TCB_FILTERED;
2632 tcp->flags &= ~TCB_FILTERED;
2634 if (cflag == CFLAG_ONLY_STATS) {
2635 tcp->flags |= TCB_INSYSCALL;
2636 gettimeofday(&tcp->etime, NULL);
2641 tcp->flags &= ~TCB_REPRINT;
2643 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2644 tprintf("syscall_%lu(", tcp->scno);
2646 tprintf("%s(", sysent[tcp->scno].sys_name);
2647 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2648 ((qual_flags[tcp->scno] & QUAL_RAW) &&
2649 sysent[tcp->scno].sys_func != sys_exit))
2650 sys_res = printargs(tcp);
2652 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2653 if (fflush(tcp->outf) == EOF)
2655 tcp->flags |= TCB_INSYSCALL;
2656 /* Measure the entrance time as late as possible to avoid errors. */
2658 gettimeofday(&tcp->etime, NULL);
2663 trace_syscall(struct tcb *tcp)
2665 return exiting(tcp) ?
2666 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2670 printargs(struct tcb *tcp)
2672 if (entering(tcp)) {
2675 for (i = 0; i < tcp->u_nargs; i++)
2676 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2682 getrval2(struct tcb *tcp)
2687 #if defined (SPARC) || defined (SPARC64)
2688 struct pt_regs regs;
2689 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
2691 val = regs.u_regs[U_REG_O1];
2693 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2696 if (upeek(tcp, PT_R9, &val) < 0)
2702 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2708 val = tcp->status.PR_REG[R_O1];
2711 val = tcp->status.PR_REG[EDX];
2714 val = tcp->status.PR_REG[RDX];
2717 val = tcp->status.PR_REG[CTX_V1];
2723 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2731 * Apparently, indirect system calls have already be converted by ptrace(2),
2732 * so if you see "indir" this program has gone astray.
2735 sys_indir(struct tcb *tcp)
2739 if (entering(tcp)) {
2740 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2741 fprintf(stderr, "Bogus syscall: %u\n", scno);
2744 nargs = sysent[scno].nargs;
2745 tprintf("%s", sysent[scno].sys_name);
2746 for (i = 0; i < nargs; i++)
2747 tprintf(", %#lx", tcp->u_arg[i+1]);
2754 is_restart_error(struct tcb *tcp)
2759 switch (tcp->u_error) {
2761 case ERESTARTNOINTR:
2762 case ERESTARTNOHAND:
2763 case ERESTART_RESTARTBLOCK: