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;
216 #endif /* SUPPORTED_PERSONALITIES >= 2 */
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;
230 #endif /* SUPPORTED_PERSONALITIES >= 3 */
236 current_personality = personality;
241 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
243 static const struct qual_options {
245 const char *option_name;
246 int (*qualify)(const char *, int, int);
247 const char *argument_name;
249 { QUAL_TRACE, "trace", qual_syscall, "system call" },
250 { QUAL_TRACE, "t", qual_syscall, "system call" },
251 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
252 { QUAL_ABBREV, "a", qual_syscall, "system call" },
253 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
254 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
255 { QUAL_RAW, "raw", qual_syscall, "system call" },
256 { QUAL_RAW, "x", qual_syscall, "system call" },
257 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
258 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
259 { QUAL_SIGNAL, "s", qual_signal, "signal" },
260 { QUAL_FAULT, "fault", qual_fault, "fault" },
261 { QUAL_FAULT, "faults", qual_fault, "fault" },
262 { QUAL_FAULT, "m", qual_fault, "fault" },
263 { QUAL_READ, "read", qual_desc, "descriptor" },
264 { QUAL_READ, "reads", qual_desc, "descriptor" },
265 { QUAL_READ, "r", qual_desc, "descriptor" },
266 { QUAL_WRITE, "write", qual_desc, "descriptor" },
267 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
268 { QUAL_WRITE, "w", qual_desc, "descriptor" },
269 { 0, NULL, NULL, NULL },
273 qualify_one(int n, int bitflag, int not, int pers)
275 if (pers == 0 || pers < 0) {
277 qual_flags0[n] &= ~bitflag;
279 qual_flags0[n] |= bitflag;
282 #if SUPPORTED_PERSONALITIES >= 2
283 if (pers == 1 || pers < 0) {
285 qual_flags1[n] &= ~bitflag;
287 qual_flags1[n] |= bitflag;
289 #endif /* SUPPORTED_PERSONALITIES >= 2 */
291 #if SUPPORTED_PERSONALITIES >= 3
292 if (pers == 2 || pers < 0) {
294 qual_flags2[n] &= ~bitflag;
296 qual_flags2[n] |= bitflag;
298 #endif /* SUPPORTED_PERSONALITIES >= 3 */
302 qual_syscall(const char *s, int bitflag, int not)
307 if (isdigit((unsigned char)*s)) {
309 if (i < 0 || i >= MAX_QUALS)
311 qualify_one(i, bitflag, not, -1);
314 for (i = 0; i < nsyscalls0; i++)
315 if (strcmp(s, sysent0[i].sys_name) == 0) {
316 qualify_one(i, bitflag, not, 0);
320 #if SUPPORTED_PERSONALITIES >= 2
321 for (i = 0; i < nsyscalls1; i++)
322 if (strcmp(s, sysent1[i].sys_name) == 0) {
323 qualify_one(i, bitflag, not, 1);
326 #endif /* SUPPORTED_PERSONALITIES >= 2 */
328 #if SUPPORTED_PERSONALITIES >= 3
329 for (i = 0; i < nsyscalls2; i++)
330 if (strcmp(s, sysent2[i].sys_name) == 0) {
331 qualify_one(i, bitflag, not, 2);
334 #endif /* SUPPORTED_PERSONALITIES >= 3 */
340 qual_signal(const char *s, int bitflag, int not)
345 if (isdigit((unsigned char)*s)) {
347 if (signo < 0 || signo >= MAX_QUALS)
349 qualify_one(signo, bitflag, not, -1);
352 if (strlen(s) >= sizeof buf)
356 if (strncasecmp(s, "SIG", 3) == 0)
358 for (i = 0; i <= NSIG; i++)
359 if (strcasecmp(s, signame(i) + 3) == 0) {
360 qualify_one(i, bitflag, not, -1);
367 qual_fault(const char *s, int bitflag, int not)
373 qual_desc(const char *s, int bitflag, int not)
375 if (isdigit((unsigned char)*s)) {
377 if (desc < 0 || desc >= MAX_QUALS)
379 qualify_one(desc, bitflag, not, -1);
386 lookup_class(const char *s)
388 if (strcmp(s, "file") == 0)
390 if (strcmp(s, "ipc") == 0)
392 if (strcmp(s, "network") == 0)
393 return TRACE_NETWORK;
394 if (strcmp(s, "process") == 0)
395 return TRACE_PROCESS;
396 if (strcmp(s, "signal") == 0)
398 if (strcmp(s, "desc") == 0)
404 qualify(const char *s)
406 const struct qual_options *opt;
412 opt = &qual_options[0];
413 for (i = 0; (p = qual_options[i].option_name); i++) {
415 if (strncmp(s, p, n) == 0 && s[n] == '=') {
416 opt = &qual_options[i];
426 if (strcmp(s, "none") == 0) {
430 if (strcmp(s, "all") == 0) {
431 for (i = 0; i < MAX_QUALS; i++) {
432 qualify_one(i, opt->bitflag, not, -1);
436 for (i = 0; i < MAX_QUALS; i++) {
437 qualify_one(i, opt->bitflag, !not, -1);
439 if (!(copy = strdup(s))) {
440 fprintf(stderr, "out of memory\n");
443 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
444 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
445 for (i = 0; i < nsyscalls0; i++)
446 if (sysent0[i].sys_flags & n)
447 qualify_one(i, opt->bitflag, not, 0);
449 #if SUPPORTED_PERSONALITIES >= 2
450 for (i = 0; i < nsyscalls1; i++)
451 if (sysent1[i].sys_flags & n)
452 qualify_one(i, opt->bitflag, not, 1);
453 #endif /* SUPPORTED_PERSONALITIES >= 2 */
455 #if SUPPORTED_PERSONALITIES >= 3
456 for (i = 0; i < nsyscalls2; i++)
457 if (sysent2[i].sys_flags & n)
458 qualify_one(i, opt->bitflag, not, 2);
459 #endif /* SUPPORTED_PERSONALITIES >= 3 */
463 if (opt->qualify(p, opt->bitflag, not)) {
464 fprintf(stderr, "strace: invalid %s `%s'\n",
465 opt->argument_name, p);
474 dumpio(struct tcb *tcp)
478 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
480 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
482 if (sysent[tcp->scno].sys_func == printargs)
484 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
485 if (sysent[tcp->scno].sys_func == sys_read ||
486 sysent[tcp->scno].sys_func == sys_pread ||
487 sysent[tcp->scno].sys_func == sys_pread64 ||
488 sysent[tcp->scno].sys_func == sys_recv ||
489 sysent[tcp->scno].sys_func == sys_recvfrom)
490 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
491 else if (sysent[tcp->scno].sys_func == sys_readv)
492 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
495 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
496 if (sysent[tcp->scno].sys_func == sys_write ||
497 sysent[tcp->scno].sys_func == sys_pwrite ||
498 sysent[tcp->scno].sys_func == sys_pwrite64 ||
499 sysent[tcp->scno].sys_func == sys_send ||
500 sysent[tcp->scno].sys_func == sys_sendto)
501 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
502 else if (sysent[tcp->scno].sys_func == sys_writev)
503 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
509 enum subcall_style { shift_style, deref_style, mask_style, door_style };
511 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
519 static const struct subcall subcalls_table[] = {
520 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
522 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
524 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
526 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
530 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
533 decode_subcall(struct tcb *tcp, int subcall, int nsubcalls, enum subcall_style style)
535 unsigned long addr, mask;
537 int size = personality_wordsize[current_personality];
541 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
543 tcp->scno = subcall + tcp->u_arg[0];
544 if (sysent[tcp->scno].nargs != -1)
545 tcp->u_nargs = sysent[tcp->scno].nargs;
548 for (i = 0; i < tcp->u_nargs; i++)
549 tcp->u_arg[i] = tcp->u_arg[i + 1];
552 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
554 tcp->scno = subcall + tcp->u_arg[0];
555 addr = tcp->u_arg[1];
556 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
557 if (size == sizeof(int)) {
559 if (umove(tcp, addr, &arg) < 0)
563 else if (size == sizeof(long)) {
565 if (umove(tcp, addr, &arg) < 0)
573 tcp->u_nargs = sysent[tcp->scno].nargs;
576 mask = (tcp->u_arg[0] >> 8) & 0xff;
577 for (i = 0; mask; i++)
581 tcp->u_arg[0] &= 0xff;
582 tcp->scno = subcall + i;
583 if (sysent[tcp->scno].nargs != -1)
584 tcp->u_nargs = sysent[tcp->scno].nargs;
588 * Oh, yuck. The call code is the *sixth* argument.
589 * (don't you mean the *last* argument? - JH)
591 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
593 tcp->scno = subcall + tcp->u_arg[5];
594 if (sysent[tcp->scno].nargs != -1)
595 tcp->u_nargs = sysent[tcp->scno].nargs;
601 for (i = 0; i < ARRAY_SIZE(subcalls_table); i++)
602 if (subcalls_table[i].call == tcp->scno) break;
603 if (i < ARRAY_SIZE(subcalls_table) &&
604 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
605 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
606 for (i = 0; i < tcp->u_nargs; i++)
607 tcp->u_arg[i] = tcp->u_arg[i + 1];
615 struct tcb *tcp_last = NULL;
618 internal_syscall(struct tcb *tcp)
621 * We must always trace a few critical system calls in order to
622 * correctly support following forks in the presence of tracing
627 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
630 func = sysent[tcp->scno].sys_func;
632 if ( sys_fork == func
633 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
643 return internal_fork(tcp);
645 if ( sys_execve == func
646 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
650 || sys_rexecve == func
653 return internal_exec(tcp);
662 # elif defined (IA64)
663 long r8, r10, psr; /* TODO: make static? */
664 long ia32 = 0; /* not static */
665 # elif defined (POWERPC)
666 static long result, flags;
667 # elif defined (M68K)
672 static struct pt_regs regs;
673 # elif defined (ALPHA)
676 # elif defined(AVR32)
677 static struct pt_regs regs;
678 # elif defined (SPARC) || defined (SPARC64)
679 static struct pt_regs regs;
680 static unsigned long trap;
681 # elif defined(LINUX_MIPSN32)
687 # elif defined(S390) || defined(S390X)
690 static long syscall_mode;
697 # elif defined(X86_64)
699 # elif defined(CRISV10) || defined(CRISV32)
701 # elif defined(MICROBLAZE)
706 struct reg regs; /* TODO: make static? */
710 get_scno(struct tcb *tcp)
715 # if defined(S390) || defined(S390X)
716 if (tcp->flags & TCB_WAITEXECVE) {
718 * When the execve system call completes successfully, the
719 * new process still has -ENOSYS (old style) or __NR_execve
720 * (new style) in gpr2. We cannot recover the scno again
721 * by disassembly, because the image that executed the
722 * syscall is gone now. Fortunately, we don't want it. We
723 * leave the flag set so that syscall_fixup can fake the
726 if (tcp->flags & TCB_INSYSCALL)
729 * This is the SIGTRAP after execve. We cannot try to read
730 * the system call here either.
732 tcp->flags &= ~TCB_WAITEXECVE;
736 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
739 if (syscall_mode != -ENOSYS) {
741 * Since kernel version 2.5.44 the scno gets passed in gpr2.
746 * Old style of "passing" the scno via the SVC instruction.
749 long opcode, offset_reg, tmp;
751 static const int gpr_offset[16] = {
752 PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
753 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
754 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
755 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15
758 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
761 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
763 perror("peektext(pc-oneword)");
768 * We have to check if the SVC got executed directly or via an
769 * EXECUTE instruction. In case of EXECUTE it is necessary to do
770 * instruction decoding to derive the system call number.
771 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
772 * so that this doesn't work if a SVC opcode is part of an EXECUTE
773 * opcode. Since there is no way to find out the opcode size this
774 * is the best we can do...
777 if ((opcode & 0xff00) == 0x0a00) {
779 scno = opcode & 0xff;
782 /* SVC got executed by EXECUTE instruction */
785 * Do instruction decoding of EXECUTE. If you really want to
786 * understand this, read the Principles of Operations.
788 svc_addr = (void *) (opcode & 0xfff);
791 offset_reg = (opcode & 0x000f0000) >> 16;
792 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
797 offset_reg = (opcode & 0x0000f000) >> 12;
798 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
802 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
811 offset_reg = (opcode & 0x00f00000) >> 20;
812 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
815 scno = (scno | tmp) & 0xff;
818 # elif defined (POWERPC)
819 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
821 if (!(tcp->flags & TCB_INSYSCALL)) {
822 /* Check if we return from execve. */
823 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
824 tcp->flags &= ~TCB_WAITEXECVE;
830 if (!(tcp->flags & TCB_INSYSCALL)) {
831 static int currpers = -1;
835 /* Check for 64/32 bit mode. */
836 if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0)
838 /* SF is bit 0 of MSR */
843 if (currpers != current_personality) {
844 static const char *const names[] = {"64 bit", "32 bit"};
845 set_personality(currpers);
846 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
847 pid, names[current_personality]);
851 # elif defined(AVR32)
853 * Read complete register set in one go.
855 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
859 * We only need to grab the syscall number on syscall entry.
861 if (!(tcp->flags & TCB_INSYSCALL)) {
864 /* Check if we return from execve. */
865 if (tcp->flags & TCB_WAITEXECVE) {
866 tcp->flags &= ~TCB_WAITEXECVE;
871 if (upeek(tcp, PT_ORIG_P0, &scno))
873 # elif defined (I386)
874 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
876 # elif defined (X86_64)
877 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
880 if (!(tcp->flags & TCB_INSYSCALL)) {
881 static int currpers = -1;
885 /* Check CS register value. On x86-64 linux it is:
886 * 0x33 for long mode (64 bit)
887 * 0x23 for compatibility mode (32 bit)
888 * It takes only one ptrace and thus doesn't need
891 if (upeek(tcp, 8*CS, &val) < 0)
894 case 0x23: currpers = 1; break;
895 case 0x33: currpers = 0; break;
897 fprintf(stderr, "Unknown value CS=0x%02X while "
898 "detecting personality of process "
899 "PID=%d\n", (int)val, pid);
900 currpers = current_personality;
904 /* This version analyzes the opcode of a syscall instruction.
905 * (int 0x80 on i386 vs. syscall on x86-64)
906 * It works, but is too complicated.
908 unsigned long val, rip, i;
910 if (upeek(tcp, 8*RIP, &rip) < 0)
911 perror("upeek(RIP)");
913 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
917 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
919 fprintf(stderr, "ptrace_peektext failed: %s\n",
921 switch (call & 0xffff) {
922 /* x86-64: syscall = 0x0f 0x05 */
923 case 0x050f: currpers = 0; break;
924 /* i386: int 0x80 = 0xcd 0x80 */
925 case 0x80cd: currpers = 1; break;
927 currpers = current_personality;
929 "Unknown syscall opcode (0x%04X) while "
930 "detecting personality of process "
931 "PID=%d\n", (int)call, pid);
935 if (currpers != current_personality) {
936 static const char *const names[] = {"64 bit", "32 bit"};
937 set_personality(currpers);
938 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
939 pid, names[current_personality]);
943 # define IA64_PSR_IS ((long)1 << 34)
944 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0)
945 ia32 = (psr & IA64_PSR_IS) != 0;
946 if (!(tcp->flags & TCB_INSYSCALL)) {
948 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
951 if (upeek(tcp, PT_R15, &scno) < 0)
954 /* Check if we return from execve. */
955 if (tcp->flags & TCB_WAITEXECVE) {
956 tcp->flags &= ~TCB_WAITEXECVE;
960 /* syscall in progress */
961 if (upeek(tcp, PT_R8, &r8) < 0)
963 if (upeek(tcp, PT_R10, &r10) < 0)
968 * Read complete register set in one go.
970 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
974 * We only need to grab the syscall number on syscall entry.
976 if (regs.ARM_ip == 0) {
977 if (!(tcp->flags & TCB_INSYSCALL)) {
978 /* Check if we return from execve. */
979 if (tcp->flags & TCB_WAITEXECVE) {
980 tcp->flags &= ~TCB_WAITEXECVE;
986 * Note: we only deal with only 32-bit CPUs here.
988 if (regs.ARM_cpsr & 0x20) {
990 * Get the Thumb-mode system call number
995 * Get the ARM-mode system call number
998 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1002 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1003 tcp->flags &= ~TCB_WAITEXECVE;
1007 /* Handle the EABI syscall convention. We do not
1008 bother converting structures between the two
1009 ABIs, but basic functionality should work even
1010 if strace and the traced program have different
1012 if (scno == 0xef000000) {
1015 if ((scno & 0x0ff00000) != 0x0f900000) {
1016 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1022 * Fixup the syscall number
1027 if (scno & 0x0f0000) {
1029 * Handle ARM specific syscall
1036 if (tcp->flags & TCB_INSYSCALL) {
1037 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1038 tcp->flags &= ~TCB_INSYSCALL;
1041 if (!(tcp->flags & TCB_INSYSCALL)) {
1042 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1043 tcp->flags |= TCB_INSYSCALL;
1046 # elif defined (M68K)
1047 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1049 # elif defined (LINUX_MIPSN32)
1050 unsigned long long regs[38];
1052 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1057 if (!(tcp->flags & TCB_INSYSCALL)) {
1060 /* Check if we return from execve. */
1061 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1062 tcp->flags &= ~TCB_WAITEXECVE;
1066 if (scno < 0 || scno > nsyscalls) {
1067 if (a3 == 0 || a3 == -1) {
1069 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
1074 # elif defined (MIPS)
1075 if (upeek(tcp, REG_A3, &a3) < 0)
1077 if (!(tcp->flags & TCB_INSYSCALL)) {
1078 if (upeek(tcp, REG_V0, &scno) < 0)
1081 /* Check if we return from execve. */
1082 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1083 tcp->flags &= ~TCB_WAITEXECVE;
1087 if (scno < 0 || scno > nsyscalls) {
1088 if (a3 == 0 || a3 == -1) {
1090 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
1095 if (upeek(tcp, REG_V0, &r2) < 0)
1098 # elif defined (ALPHA)
1099 if (upeek(tcp, REG_A3, &a3) < 0)
1102 if (!(tcp->flags & TCB_INSYSCALL)) {
1103 if (upeek(tcp, REG_R0, &scno) < 0)
1106 /* Check if we return from execve. */
1107 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1108 tcp->flags &= ~TCB_WAITEXECVE;
1113 * Do some sanity checks to figure out if it's
1114 * really a syscall entry
1116 if (scno < 0 || scno > nsyscalls) {
1117 if (a3 == 0 || a3 == -1) {
1119 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
1125 if (upeek(tcp, REG_R0, &r0) < 0)
1128 # elif defined (SPARC) || defined (SPARC64)
1129 /* Everything we need is in the current register set. */
1130 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1133 /* If we are entering, then disassemble the syscall trap. */
1134 if (!(tcp->flags & TCB_INSYSCALL)) {
1135 /* Retrieve the syscall trap instruction. */
1137 # if defined(SPARC64)
1138 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1141 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1146 /* Disassemble the trap to see what personality to use. */
1149 /* Linux/SPARC syscall trap. */
1153 /* Linux/SPARC64 syscall trap. */
1157 /* SunOS syscall trap. (pers 1) */
1158 fprintf(stderr, "syscall: SunOS no support\n");
1161 /* Solaris 2.x syscall trap. (per 2) */
1165 /* NetBSD/FreeBSD syscall trap. */
1166 fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n");
1169 /* Solaris 2.x gettimeofday */
1173 /* Unknown syscall trap. */
1174 if (tcp->flags & TCB_WAITEXECVE) {
1175 tcp->flags &= ~TCB_WAITEXECVE;
1178 # if defined (SPARC64)
1179 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1181 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1186 /* Extract the system call number from the registers. */
1187 if (trap == 0x91d02027)
1190 scno = regs.u_regs[U_REG_G1];
1192 scno = regs.u_regs[U_REG_O0];
1193 memmove(®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1196 # elif defined(HPPA)
1197 if (upeek(tcp, PT_GR20, &scno) < 0)
1199 if (!(tcp->flags & TCB_INSYSCALL)) {
1200 /* Check if we return from execve. */
1201 if ((tcp->flags & TCB_WAITEXECVE)) {
1202 tcp->flags &= ~TCB_WAITEXECVE;
1208 * In the new syscall ABI, the system call number is in R3.
1210 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1214 /* Odd as it may seem, a glibc bug has been known to cause
1215 glibc to issue bogus negative syscall numbers. So for
1216 our purposes, make strace print what it *should* have been */
1217 long correct_scno = (scno & 0xff);
1220 "Detected glibc bug: bogus system call"
1221 " number = %ld, correcting to %ld\n",
1224 scno = correct_scno;
1227 if (!(tcp->flags & TCB_INSYSCALL)) {
1228 /* Check if we return from execve. */
1229 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1230 tcp->flags &= ~TCB_WAITEXECVE;
1234 # elif defined(SH64)
1235 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1239 if (!(tcp->flags & TCB_INSYSCALL)) {
1240 /* Check if we return from execve. */
1241 if (tcp->flags & TCB_WAITEXECVE) {
1242 tcp->flags &= ~TCB_WAITEXECVE;
1246 # elif defined(CRISV10) || defined(CRISV32)
1247 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1249 # elif defined(TILE)
1250 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1253 if (!(tcp->flags & TCB_INSYSCALL)) {
1254 /* Check if we return from execve. */
1255 if (tcp->flags & TCB_WAITEXECVE) {
1256 tcp->flags &= ~TCB_WAITEXECVE;
1260 # elif defined(MICROBLAZE)
1261 if (upeek(tcp, 0, &scno) < 0)
1267 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1270 /* new syscall ABI returns result in R0 */
1271 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1274 /* ABI defines result returned in r9 */
1275 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1280 # ifdef HAVE_PR_SYSCALL
1281 scno = tcp->status.PR_SYSCALL;
1284 scno = tcp->status.PR_WHAT;
1286 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1290 switch (regs.r_eax) {
1293 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1299 # endif /* FREEBSD */
1300 # endif /* !HAVE_PR_SYSCALL */
1301 #endif /* USE_PROCFS */
1303 if (!(tcp->flags & TCB_INSYSCALL))
1310 known_scno(struct tcb *tcp)
1312 long scno = tcp->scno;
1313 #if SUPPORTED_PERSONALITIES > 1
1314 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1315 scno = sysent[scno].native_scno;
1318 scno += NR_SYSCALL_BASE;
1322 /* Called in trace_syscall() at each syscall entry and exit.
1324 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1325 * 1: ok, continue in trace_syscall().
1326 * other: error, trace_syscall() should print error indicator
1327 * ("????" etc) and bail out.
1330 syscall_fixup(struct tcb *tcp)
1333 int scno = known_scno(tcp);
1335 if (!(tcp->flags & TCB_INSYSCALL)) {
1336 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1340 || scno == SYS_vfork
1341 #endif /* SYS_vfork */
1343 || scno == SYS_fork1
1344 #endif /* SYS_fork1 */
1346 || scno == SYS_forkall
1347 #endif /* SYS_forkall */
1349 || scno == SYS_rfork1
1350 #endif /* SYS_fork1 */
1352 || scno == SYS_rforkall
1353 #endif /* SYS_rforkall */
1355 /* We are returning in the child, fake it. */
1356 tcp->status.PR_WHY = PR_SYSENTRY;
1358 tcp->status.PR_WHY = PR_SYSEXIT;
1361 fprintf(stderr, "syscall: missing entry\n");
1362 tcp->flags |= TCB_INSYSCALL;
1367 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1368 fprintf(stderr, "syscall: missing exit\n");
1369 tcp->flags &= ~TCB_INSYSCALL;
1372 #endif /* USE_PROCFS */
1374 if (!(tcp->flags & TCB_INSYSCALL)) {
1376 fprintf(stderr, "syscall: missing entry\n");
1377 tcp->flags |= TCB_INSYSCALL;
1384 * This happens when a signal handler
1385 * for a signal which interrupted a
1386 * a system call makes another system call.
1388 fprintf(stderr, "syscall: missing exit\n");
1390 tcp->flags &= ~TCB_INSYSCALL;
1396 if (upeek(tcp, 4*EAX, &eax) < 0)
1398 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1400 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1403 #elif defined (X86_64)
1404 if (upeek(tcp, 8*RAX, &rax) < 0)
1406 if (current_personality == 1)
1407 rax = (long int)(int)rax; /* sign extend from 32 bits */
1408 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1410 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1413 #elif defined (S390) || defined (S390X)
1414 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1416 if (syscall_mode != -ENOSYS)
1417 syscall_mode = tcp->scno;
1418 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1420 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1423 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1424 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1425 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1427 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1428 * flag set for the post-execve SIGTRAP to see and reset.
1432 #elif defined (POWERPC)
1433 # define SO_MASK 0x10000000
1434 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1436 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1438 if (flags & SO_MASK)
1440 #elif defined (M68K)
1441 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1443 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1445 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1453 if (upeek(tcp, PT_R0, &r0) < 0)
1455 #elif defined (HPPA)
1456 if (upeek(tcp, PT_GR28, &r28) < 0)
1459 if (upeek(tcp, PT_R10, &r10) < 0)
1461 if (upeek(tcp, PT_R8, &r8) < 0)
1463 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1465 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1468 #elif defined(CRISV10) || defined(CRISV32)
1469 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1471 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1473 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1476 #elif defined(MICROBLAZE)
1477 if (upeek(tcp, 3 * 4, &r3) < 0)
1479 if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1481 fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
1491 * Check the syscall return value register value for whether it is
1492 * a negated errno code indicating an error, or a success return value.
1495 is_negated_errno(unsigned long int val)
1497 unsigned long int max = -(long int) nerrnos;
1498 if (personality_wordsize[current_personality] < sizeof(val)) {
1499 val = (unsigned int) val;
1500 max = (unsigned int) max;
1507 get_error(struct tcb *tcp)
1511 int check_errno = 1;
1512 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
1513 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) {
1516 # if defined(S390) || defined(S390X)
1517 if (check_errno && is_negated_errno(gpr2)) {
1525 # elif defined(I386)
1526 if (check_errno && is_negated_errno(eax)) {
1534 # elif defined(X86_64)
1535 if (check_errno && is_negated_errno(rax)) {
1543 # elif defined(IA64)
1548 if (check_errno && is_negated_errno(err)) {
1557 if (check_errno && r10) {
1565 # elif defined(MIPS)
1566 if (check_errno && a3) {
1573 # elif defined(POWERPC)
1574 if (check_errno && is_negated_errno(result)) {
1579 tcp->u_rval = result;
1582 # elif defined(M68K)
1583 if (check_errno && is_negated_errno(d0)) {
1592 if (check_errno && is_negated_errno(regs.ARM_r0)) {
1594 u_error = -regs.ARM_r0;
1597 tcp->u_rval = regs.ARM_r0;
1600 # elif defined(AVR32)
1601 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1603 u_error = -regs.r12;
1606 tcp->u_rval = regs.r12;
1609 # elif defined(BFIN)
1610 if (check_errno && is_negated_errno(r0)) {
1617 # elif defined(ALPHA)
1618 if (check_errno && a3) {
1626 # elif defined(SPARC)
1627 if (check_errno && regs.psr & PSR_C) {
1629 u_error = regs.u_regs[U_REG_O0];
1632 tcp->u_rval = regs.u_regs[U_REG_O0];
1635 # elif defined(SPARC64)
1636 if (check_errno && regs.tstate & 0x1100000000UL) {
1638 u_error = regs.u_regs[U_REG_O0];
1641 tcp->u_rval = regs.u_regs[U_REG_O0];
1644 # elif defined(HPPA)
1645 if (check_errno && is_negated_errno(r28)) {
1654 /* interpret R0 as return value or error number */
1655 if (check_errno && is_negated_errno(r0)) {
1663 # elif defined(SH64)
1664 /* interpret result as return value or error number */
1665 if (check_errno && is_negated_errno(r9)) {
1673 # elif defined(CRISV10) || defined(CRISV32)
1674 if (check_errno && r10 && (unsigned) -r10 < nerrnos) {
1682 # elif defined(TILE)
1684 /* interpret result as return value or error number */
1685 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1687 if (check_errno && rval < 0 && rval > -nerrnos) {
1695 # elif defined(MICROBLAZE)
1696 /* interpret result as return value or error number */
1697 if (check_errno && is_negated_errno(r3)) {
1708 /* get error code from user struct */
1709 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1711 u_error >>= 24; /* u_error is a char */
1713 /* get system call return value */
1714 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1719 /* Judicious guessing goes a long way. */
1720 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1722 u_error = tcp->status.pr_reg[R_O0];
1725 tcp->u_rval = tcp->status.pr_reg[R_O0];
1730 /* Wanna know how to kill an hour single-stepping? */
1731 if (tcp->status.PR_REG[EFL] & 0x1) {
1733 u_error = tcp->status.PR_REG[EAX];
1736 tcp->u_rval = tcp->status.PR_REG[EAX];
1737 # ifdef HAVE_LONG_LONG
1739 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1740 tcp->status.PR_REG[EAX];
1746 /* Wanna know how to kill an hour single-stepping? */
1747 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1749 u_error = tcp->status.PR_REG[RAX];
1752 tcp->u_rval = tcp->status.PR_REG[RAX];
1755 # endif /* X86_64 */
1757 if (tcp->status.pr_reg[CTX_A3]) {
1759 u_error = tcp->status.pr_reg[CTX_V0];
1762 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1768 if (regs.r_eflags & PSL_C) {
1770 u_error = regs.r_eax;
1772 tcp->u_rval = regs.r_eax;
1774 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1777 #endif /* FREEBSD */
1778 tcp->u_error = u_error;
1783 force_result(struct tcb *tcp, int error, long rval)
1786 # if defined(S390) || defined(S390X)
1787 gpr2 = error ? -error : rval;
1788 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1790 # elif defined(I386)
1791 eax = error ? -error : rval;
1792 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1794 # elif defined(X86_64)
1795 rax = error ? -error : rval;
1796 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1798 # elif defined(IA64)
1800 r8 = error ? -error : rval;
1801 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1813 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1814 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1817 # elif defined(BFIN)
1818 r0 = error ? -error : rval;
1819 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1821 # elif defined(MIPS)
1830 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1831 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1832 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1834 # elif defined(POWERPC)
1835 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1845 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1846 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1848 # elif defined(M68K)
1849 d0 = error ? -error : rval;
1850 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1853 regs.ARM_r0 = error ? -error : rval;
1854 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1856 # elif defined(AVR32)
1857 regs.r12 = error ? -error : rval;
1858 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1860 # elif defined(ALPHA)
1869 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1870 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1872 # elif defined(SPARC)
1873 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1877 regs.u_regs[U_REG_O0] = error;
1881 regs.u_regs[U_REG_O0] = rval;
1883 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1885 # elif defined(SPARC64)
1886 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1889 regs.tstate |= 0x1100000000UL;
1890 regs.u_regs[U_REG_O0] = error;
1893 regs.tstate &= ~0x1100000000UL;
1894 regs.u_regs[U_REG_O0] = rval;
1896 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1898 # elif defined(HPPA)
1899 r28 = error ? -error : rval;
1900 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1903 r0 = error ? -error : rval;
1904 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1906 # elif defined(SH64)
1907 r9 = error ? -error : rval;
1908 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1914 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1916 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1926 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1931 regs.r_eflags |= PSL_C;
1935 regs.r_eflags &= ~PSL_C;
1938 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1942 #endif /* FREEBSD */
1944 /* All branches reach here on success (only). */
1945 tcp->u_error = error;
1951 syscall_enter(struct tcb *tcp)
1954 # if defined(S390) || defined(S390X)
1956 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1957 tcp->u_nargs = sysent[tcp->scno].nargs;
1959 tcp->u_nargs = MAX_ARGS;
1960 for (i = 0; i < tcp->u_nargs; i++) {
1961 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2 + i*sizeof(long), &tcp->u_arg[i]) < 0)
1964 # elif defined(ALPHA)
1966 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1967 tcp->u_nargs = sysent[tcp->scno].nargs;
1969 tcp->u_nargs = MAX_ARGS;
1970 for (i = 0; i < tcp->u_nargs; i++) {
1971 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1972 * for scno somewhere above here!
1974 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1977 # elif defined(IA64)
1979 unsigned long *out0, cfm, sof, sol, i;
1981 /* be backwards compatible with kernel < 2.4.4... */
1983 # define PT_RBS_END PT_AR_BSP
1986 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
1988 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1991 sof = (cfm >> 0) & 0x7f;
1992 sol = (cfm >> 7) & 0x7f;
1993 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
1995 if (tcp->scno >= 0 && tcp->scno < nsyscalls
1996 && sysent[tcp->scno].nargs != -1)
1997 tcp->u_nargs = sysent[tcp->scno].nargs;
1999 tcp->u_nargs = MAX_ARGS;
2000 for (i = 0; i < tcp->u_nargs; ++i) {
2001 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2002 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2008 if (/* EBX = out0 */
2009 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2011 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2013 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2015 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2017 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2019 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2022 for (i = 0; i < 6; ++i)
2023 /* truncate away IVE sign-extension */
2024 tcp->u_arg[i] &= 0xffffffff;
2026 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2027 && sysent[tcp->scno].nargs != -1)
2028 tcp->u_nargs = sysent[tcp->scno].nargs;
2032 # elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64)
2033 /* N32 and N64 both use up to six registers. */
2034 unsigned long long regs[38];
2036 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2037 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2039 nargs = tcp->u_nargs = MAX_ARGS;
2041 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2044 for (i = 0; i < nargs; i++) {
2045 tcp->u_arg[i] = regs[REG_A0 + i];
2046 # if defined(LINUX_MIPSN32)
2047 tcp->ext_arg[i] = regs[REG_A0 + i];
2050 # elif defined(MIPS)
2054 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2055 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2057 nargs = tcp->u_nargs = MAX_ARGS;
2059 if (upeek(tcp, REG_SP, &sp) < 0)
2061 for (i = 0; i < 4; i++) {
2062 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2065 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2066 (char *)(tcp->u_arg + 4));
2068 for (i = 0; i < nargs; i++) {
2069 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2073 # elif defined(POWERPC)
2075 # define PT_ORIG_R3 34
2078 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2079 tcp->u_nargs = sysent[tcp->scno].nargs;
2081 tcp->u_nargs = MAX_ARGS;
2082 for (i = 0; i < tcp->u_nargs; i++) {
2083 if (upeek(tcp, (i==0) ?
2084 (sizeof(unsigned long) * PT_ORIG_R3) :
2085 ((i+PT_R3) * sizeof(unsigned long)),
2086 &tcp->u_arg[i]) < 0)
2089 # elif defined(SPARC) || defined(SPARC64)
2091 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2092 tcp->u_nargs = sysent[tcp->scno].nargs;
2094 tcp->u_nargs = MAX_ARGS;
2095 for (i = 0; i < tcp->u_nargs; i++)
2096 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2097 # elif defined(HPPA)
2099 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2100 tcp->u_nargs = sysent[tcp->scno].nargs;
2102 tcp->u_nargs = MAX_ARGS;
2103 for (i = 0; i < tcp->u_nargs; i++) {
2104 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2109 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2110 tcp->u_nargs = sysent[tcp->scno].nargs;
2112 tcp->u_nargs = MAX_ARGS;
2113 for (i = 0; i < tcp->u_nargs; i++)
2114 tcp->u_arg[i] = regs.uregs[i];
2115 # elif defined(AVR32)
2116 tcp->u_nargs = sysent[tcp->scno].nargs;
2117 tcp->u_arg[0] = regs.r12;
2118 tcp->u_arg[1] = regs.r11;
2119 tcp->u_arg[2] = regs.r10;
2120 tcp->u_arg[3] = regs.r9;
2121 tcp->u_arg[4] = regs.r5;
2122 tcp->u_arg[5] = regs.r3;
2123 # elif defined(BFIN)
2125 static const int argreg[] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 };
2127 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2128 tcp->u_nargs = sysent[tcp->scno].nargs;
2130 tcp->u_nargs = ARRAY_SIZE(argreg);
2132 for (i = 0; i < tcp->u_nargs; ++i)
2133 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2137 static const int syscall_regs[] = {
2138 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6), 4 * (REG_REG0+7),
2139 4 * (REG_REG0 ), 4 * (REG_REG0+1), 4 * (REG_REG0+2)
2142 tcp->u_nargs = sysent[tcp->scno].nargs;
2143 for (i = 0; i < tcp->u_nargs; i++) {
2144 if (upeek(tcp, syscall_regs[i], &tcp->u_arg[i]) < 0)
2147 # elif defined(SH64)
2149 /* Registers used by SH5 Linux system calls for parameters */
2150 static const int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2153 * TODO: should also check that the number of arguments encoded
2154 * in the trap number matches the number strace expects.
2157 assert(sysent[tcp->scno].nargs < ARRAY_SIZE(syscall_regs));
2160 tcp->u_nargs = sysent[tcp->scno].nargs;
2161 for (i = 0; i < tcp->u_nargs; i++) {
2162 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2165 # elif defined(X86_64)
2167 static const int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2168 { 8 * RDI, 8 * RSI, 8 * RDX, 8 * R10, 8 * R8 , 8 * R9 }, /* x86-64 ABI */
2169 { 8 * RBX, 8 * RCX, 8 * RDX, 8 * RSI, 8 * RDI, 8 * RBP } /* i386 ABI */
2172 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2173 tcp->u_nargs = sysent[tcp->scno].nargs;
2175 tcp->u_nargs = MAX_ARGS;
2176 for (i = 0; i < tcp->u_nargs; i++) {
2177 if (upeek(tcp, argreg[current_personality][i], &tcp->u_arg[i]) < 0)
2180 # elif defined(MICROBLAZE)
2182 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2183 tcp->u_nargs = sysent[tcp->scno].nargs;
2186 for (i = 0; i < tcp->u_nargs; i++) {
2187 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
2190 # elif defined(CRISV10) || defined(CRISV32)
2192 static const int crisregs[] = {
2193 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2194 4*PT_R13 , 4*PT_MOF, 4*PT_SRP
2197 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2198 tcp->u_nargs = sysent[tcp->scno].nargs;
2201 for (i = 0; i < tcp->u_nargs; i++) {
2202 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2205 # elif defined(TILE)
2207 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2208 tcp->u_nargs = sysent[tcp->scno].nargs;
2210 tcp->u_nargs = MAX_ARGS;
2211 for (i = 0; i < tcp->u_nargs; ++i) {
2212 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2215 # elif defined(M68K)
2217 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2218 tcp->u_nargs = sysent[tcp->scno].nargs;
2220 tcp->u_nargs = MAX_ARGS;
2221 for (i = 0; i < tcp->u_nargs; i++) {
2222 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
2225 # else /* Other architecture (like i386) (32bits specific) */
2227 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2228 tcp->u_nargs = sysent[tcp->scno].nargs;
2230 tcp->u_nargs = MAX_ARGS;
2231 for (i = 0; i < tcp->u_nargs; i++) {
2232 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2239 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2240 tcp->u_nargs = sysent[tcp->scno].nargs;
2242 tcp->u_nargs = MAX_ARGS;
2243 for (i = 0; i < tcp->u_nargs; i++) {
2246 if (upeek(tcp, uoff(u_arg[0]) +
2247 (i * sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2254 * SGI is broken: even though it has pr_sysarg, it doesn't
2255 * set them on system call entry. Get a clue.
2257 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2258 tcp->u_nargs = sysent[tcp->scno].nargs;
2260 tcp->u_nargs = tcp->status.pr_nsysarg;
2261 if (tcp->u_nargs > 4) {
2262 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2263 4 * sizeof(tcp->u_arg[0]));
2264 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2265 (tcp->u_nargs - 4) * sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2268 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2269 tcp->u_nargs * sizeof(tcp->u_arg[0]));
2271 # elif UNIXWARE >= 2
2273 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2275 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2276 tcp->u_nargs = sysent[tcp->scno].nargs;
2278 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2279 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2280 tcp->u_nargs * sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2281 # elif defined(HAVE_PR_SYSCALL)
2283 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2284 tcp->u_nargs = sysent[tcp->scno].nargs;
2286 tcp->u_nargs = tcp->status.pr_nsysarg;
2287 for (i = 0; i < tcp->u_nargs; i++)
2288 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2289 # elif defined(I386)
2290 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2291 tcp->u_nargs = sysent[tcp->scno].nargs;
2294 if (tcp->u_nargs > 0)
2295 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2296 tcp->u_nargs * sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2298 I DONT KNOW WHAT TO DO
2302 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2303 sysent[tcp->scno].nargs > tcp->status.val)
2304 tcp->u_nargs = sysent[tcp->scno].nargs;
2306 tcp->u_nargs = tcp->status.val;
2307 if (tcp->u_nargs < 0)
2309 if (tcp->u_nargs > MAX_ARGS)
2310 tcp->u_nargs = MAX_ARGS;
2311 switch (regs.r_eax) {
2313 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2314 regs.r_esp + sizeof(int) + sizeof(quad_t));
2317 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2318 regs.r_esp + 2 * sizeof(int));
2321 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2322 regs.r_esp + sizeof(int));
2325 #endif /* FREEBSD */
2330 trace_syscall_exiting(struct tcb *tcp)
2337 /* Measure the exit time as early as possible to avoid errors. */
2339 gettimeofday(&tv, NULL);
2341 /* BTW, why we don't just memorize syscall no. on entry
2342 * in tcp->something?
2344 scno_good = res = get_scno(tcp);
2348 res = syscall_fixup(tcp);
2352 res = get_error(tcp);
2356 internal_syscall(tcp);
2358 if (res == 1 && filtered(tcp)) {
2359 tcp->flags &= ~TCB_INSYSCALL;
2363 if (tcp->flags & TCB_REPRINT) {
2368 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2369 tprintf("syscall_%lu", tcp->scno);
2371 tprintf("%s", sysent[tcp->scno].sys_name);
2372 tprintf(" resumed> ");
2376 struct timeval t = tv;
2377 int rc = count_syscall(tcp, &t);
2378 if (cflag == CFLAG_ONLY_STATS) {
2379 tcp->flags &= ~TCB_INSYSCALL;
2387 tprintf("= ? <unavailable>");
2389 tcp->flags &= ~TCB_INSYSCALL;
2393 if (tcp->scno >= nsyscalls || tcp->scno < 0
2394 || (qual_flags[tcp->scno] & QUAL_RAW))
2395 sys_res = printargs(tcp);
2397 if (not_failing_only && tcp->u_error)
2398 return 0; /* ignore failed syscalls */
2399 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2402 u_error = tcp->u_error;
2405 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2406 qual_flags[tcp->scno] & QUAL_RAW) {
2408 tprintf("= -1 (errno %ld)", u_error);
2410 tprintf("= %#lx", tcp->u_rval);
2412 else if (!(sys_res & RVAL_NONE) && u_error) {
2416 tprintf("= ? ERESTARTSYS (To be restarted)");
2418 case ERESTARTNOINTR:
2419 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2421 case ERESTARTNOHAND:
2422 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2424 case ERESTART_RESTARTBLOCK:
2425 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2431 tprintf("E??? (errno %ld)", u_error);
2432 else if (u_error < nerrnos)
2433 tprintf("%s (%s)", errnoent[u_error],
2436 tprintf("ERRNO_%ld (%s)", u_error,
2440 if ((sys_res & RVAL_STR) && tcp->auxstr)
2441 tprintf(" (%s)", tcp->auxstr);
2444 if (sys_res & RVAL_NONE)
2447 switch (sys_res & RVAL_MASK) {
2449 tprintf("= %#lx", tcp->u_rval);
2452 tprintf("= %#lo", tcp->u_rval);
2455 tprintf("= %lu", tcp->u_rval);
2458 tprintf("= %ld", tcp->u_rval);
2460 #ifdef HAVE_LONG_LONG
2462 tprintf("= %#llx", tcp->u_lrval);
2465 tprintf("= %#llo", tcp->u_lrval);
2467 case RVAL_LUDECIMAL:
2468 tprintf("= %llu", tcp->u_lrval);
2471 tprintf("= %lld", tcp->u_lrval);
2476 "invalid rval format\n");
2480 if ((sys_res & RVAL_STR) && tcp->auxstr)
2481 tprintf(" (%s)", tcp->auxstr);
2484 tv_sub(&tv, &tv, &tcp->etime);
2485 tprintf(" <%ld.%06ld>",
2486 (long) tv.tv_sec, (long) tv.tv_usec);
2491 if (fflush(tcp->outf) == EOF)
2493 tcp->flags &= ~TCB_INSYSCALL;
2498 trace_syscall_entering(struct tcb *tcp)
2503 scno_good = res = get_scno(tcp);
2507 res = syscall_fixup(tcp);
2511 res = syscall_enter(tcp);
2517 tcp->flags &= ~TCB_REPRINT;
2520 tprintf("????" /* anti-trigraph gap */ "(");
2521 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2522 tprintf("syscall_%lu(", tcp->scno);
2524 tprintf("%s(", sysent[tcp->scno].sys_name);
2526 * " <unavailable>" will be added later by the code which
2527 * detects ptrace errors.
2529 tcp->flags |= TCB_INSYSCALL;
2533 switch (known_scno(tcp)) {
2534 #ifdef SYS_socket_subcall
2535 case SYS_socketcall:
2536 decode_subcall(tcp, SYS_socket_subcall,
2537 SYS_socket_nsubcalls, deref_style);
2540 #ifdef SYS_ipc_subcall
2542 decode_subcall(tcp, SYS_ipc_subcall,
2543 SYS_ipc_nsubcalls, shift_style);
2547 #ifdef SYS_pgrpsys_subcall
2549 decode_subcall(tcp, SYS_pgrpsys_subcall,
2550 SYS_pgrpsys_nsubcalls, shift_style);
2552 #endif /* SYS_pgrpsys_subcall */
2553 #ifdef SYS_sigcall_subcall
2555 decode_subcall(tcp, SYS_sigcall_subcall,
2556 SYS_sigcall_nsubcalls, mask_style);
2558 #endif /* SYS_sigcall_subcall */
2560 decode_subcall(tcp, SYS_msgsys_subcall,
2561 SYS_msgsys_nsubcalls, shift_style);
2564 decode_subcall(tcp, SYS_shmsys_subcall,
2565 SYS_shmsys_nsubcalls, shift_style);
2568 decode_subcall(tcp, SYS_semsys_subcall,
2569 SYS_semsys_nsubcalls, shift_style);
2572 decode_subcall(tcp, SYS_sysfs_subcall,
2573 SYS_sysfs_nsubcalls, shift_style);
2576 decode_subcall(tcp, SYS_spcall_subcall,
2577 SYS_spcall_nsubcalls, shift_style);
2579 #ifdef SYS_context_subcall
2581 decode_subcall(tcp, SYS_context_subcall,
2582 SYS_context_nsubcalls, shift_style);
2584 #endif /* SYS_context_subcall */
2585 #ifdef SYS_door_subcall
2587 decode_subcall(tcp, SYS_door_subcall,
2588 SYS_door_nsubcalls, door_style);
2590 #endif /* SYS_door_subcall */
2591 #ifdef SYS_kaio_subcall
2593 decode_subcall(tcp, SYS_kaio_subcall,
2594 SYS_kaio_nsubcalls, shift_style);
2602 decode_subcall(tcp, 0, 0, table_style);
2607 decode_subcall(tcp, SYS_semsys_subcall,
2608 SYS_semsys_nsubcalls, shift_style);
2611 decode_subcall(tcp, SYS_msgsys_subcall,
2612 SYS_msgsys_nsubcalls, shift_style);
2615 decode_subcall(tcp, SYS_shmsys_subcall,
2616 SYS_shmsys_nsubcalls, shift_style);
2621 internal_syscall(tcp);
2623 if ((tcp->scno >= 0 && tcp->scno < nsyscalls &&
2624 !(qual_flags[tcp->scno] & QUAL_TRACE)) ||
2625 (tracing_paths && !pathtrace_match(tcp))) {
2626 tcp->flags |= TCB_INSYSCALL | TCB_FILTERED;
2630 tcp->flags &= ~TCB_FILTERED;
2632 if (cflag == CFLAG_ONLY_STATS) {
2633 tcp->flags |= TCB_INSYSCALL;
2634 gettimeofday(&tcp->etime, NULL);
2639 tcp->flags &= ~TCB_REPRINT;
2641 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2642 tprintf("syscall_%lu(", tcp->scno);
2644 tprintf("%s(", sysent[tcp->scno].sys_name);
2645 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2646 ((qual_flags[tcp->scno] & QUAL_RAW) &&
2647 sysent[tcp->scno].sys_func != sys_exit))
2648 sys_res = printargs(tcp);
2650 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2651 if (fflush(tcp->outf) == EOF)
2653 tcp->flags |= TCB_INSYSCALL;
2654 /* Measure the entrance time as late as possible to avoid errors. */
2656 gettimeofday(&tcp->etime, NULL);
2661 trace_syscall(struct tcb *tcp)
2663 return exiting(tcp) ?
2664 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2668 printargs(struct tcb *tcp)
2670 if (entering(tcp)) {
2673 for (i = 0; i < tcp->u_nargs; i++)
2674 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2680 getrval2(struct tcb *tcp)
2685 #if defined (SPARC) || defined (SPARC64)
2686 struct pt_regs regs;
2687 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
2689 val = regs.u_regs[U_REG_O1];
2691 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2694 if (upeek(tcp, PT_R9, &val) < 0)
2700 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2706 val = tcp->status.PR_REG[R_O1];
2709 val = tcp->status.PR_REG[EDX];
2712 val = tcp->status.PR_REG[RDX];
2715 val = tcp->status.PR_REG[CTX_V1];
2721 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2729 * Apparently, indirect system calls have already be converted by ptrace(2),
2730 * so if you see "indir" this program has gone astray.
2733 sys_indir(struct tcb *tcp)
2737 if (entering(tcp)) {
2738 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2739 fprintf(stderr, "Bogus syscall: %u\n", scno);
2742 nargs = sysent[scno].nargs;
2743 tprintf("%s", sysent[scno].sys_name);
2744 for (i = 0; i < nargs; i++)
2745 tprintf(", %#lx", tcp->u_arg[i+1]);
2752 is_restart_error(struct tcb *tcp)
2757 switch (tcp->u_error) {
2759 case ERESTARTNOINTR:
2760 case ERESTARTNOHAND:
2761 case ERESTART_RESTARTBLOCK: