2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/syscall.h>
43 #include <sys/param.h>
47 #ifndef PTRACE_PEEKUSR
48 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
50 #elif defined(HAVE_LINUX_PTRACE_H)
52 # ifdef HAVE_STRUCT_IA64_FPREG
53 # define ia64_fpreg XXX_ia64_fpreg
55 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
56 # define pt_all_user_regs XXX_pt_all_user_regs
58 #include <linux/ptrace.h>
60 # undef pt_all_user_regs
63 #if defined (LINUX) && defined (SPARC64)
64 # undef PTRACE_GETREGS
65 # define PTRACE_GETREGS PTRACE_GETREGS64
66 # undef PTRACE_SETREGS
67 # define PTRACE_SETREGS PTRACE_SETREGS64
68 #endif /* LINUX && SPARC64 */
70 #if defined(LINUX) && defined(IA64)
71 # include <asm/ptrace_offsets.h>
75 #define NR_SYSCALL_BASE 0
78 #define ERESTARTSYS 512
80 #ifndef ERESTARTNOINTR
81 #define ERESTARTNOINTR 513
83 #ifndef ERESTARTNOHAND
84 #define ERESTARTNOHAND 514 /* restart if no handler.. */
87 #define ENOIOCTLCMD 515 /* No ioctl command */
89 #ifndef ERESTART_RESTARTBLOCK
90 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
98 #undef NR_SYSCALL_BASE
99 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
105 /* Define these shorthand notations to simplify the syscallent files. */
106 #define TD TRACE_DESC
107 #define TF TRACE_FILE
109 #define TN TRACE_NETWORK
110 #define TP TRACE_PROCESS
111 #define TS TRACE_SIGNAL
113 static const struct sysent sysent0[] = {
114 #include "syscallent.h"
116 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
117 int qual_flags0[MAX_QUALS];
119 #if SUPPORTED_PERSONALITIES >= 2
120 static const struct sysent sysent1[] = {
121 #include "syscallent1.h"
123 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
124 int qual_flags1[MAX_QUALS];
125 #endif /* SUPPORTED_PERSONALITIES >= 2 */
127 #if SUPPORTED_PERSONALITIES >= 3
128 static const struct sysent sysent2[] = {
129 #include "syscallent2.h"
131 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
132 int qual_flags2[MAX_QUALS];
133 #endif /* SUPPORTED_PERSONALITIES >= 3 */
135 const struct sysent *sysent;
139 /* Now undef them since short defines cause wicked namespace pollution. */
147 static const char *const errnoent0[] = {
148 #include "errnoent.h"
150 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
152 #if SUPPORTED_PERSONALITIES >= 2
153 static const char *const errnoent1[] = {
154 #include "errnoent1.h"
156 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
157 #endif /* SUPPORTED_PERSONALITIES >= 2 */
159 #if SUPPORTED_PERSONALITIES >= 3
160 static const char *const errnoent2[] = {
161 #include "errnoent2.h"
163 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
164 #endif /* SUPPORTED_PERSONALITIES >= 3 */
166 const char *const *errnoent;
169 int current_personality;
171 #ifndef PERSONALITY0_WORDSIZE
172 # define PERSONALITY0_WORDSIZE sizeof(long)
174 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
175 PERSONALITY0_WORDSIZE,
176 #if SUPPORTED_PERSONALITIES > 1
177 PERSONALITY1_WORDSIZE,
179 #if SUPPORTED_PERSONALITIES > 2
180 PERSONALITY2_WORDSIZE,
185 set_personality(int personality)
187 switch (personality) {
189 errnoent = errnoent0;
192 nsyscalls = nsyscalls0;
193 ioctlent = ioctlent0;
194 nioctlents = nioctlents0;
195 signalent = signalent0;
196 nsignals = nsignals0;
197 qual_flags = qual_flags0;
200 #if SUPPORTED_PERSONALITIES >= 2
202 errnoent = errnoent1;
205 nsyscalls = nsyscalls1;
206 ioctlent = ioctlent1;
207 nioctlents = nioctlents1;
208 signalent = signalent1;
209 nsignals = nsignals1;
210 qual_flags = qual_flags1;
212 #endif /* SUPPORTED_PERSONALITIES >= 2 */
214 #if SUPPORTED_PERSONALITIES >= 3
216 errnoent = errnoent2;
219 nsyscalls = nsyscalls2;
220 ioctlent = ioctlent2;
221 nioctlents = nioctlents2;
222 signalent = signalent2;
223 nsignals = nsignals2;
224 qual_flags = qual_flags2;
226 #endif /* SUPPORTED_PERSONALITIES >= 3 */
232 current_personality = personality;
237 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
239 static const struct qual_options {
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);
475 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
477 switch (known_scno(tcp)) {
482 #if defined SYS_pread && SYS_pread64 != SYS_pread
487 #elif defined SYS_sub_recv
492 #elif defined SYS_sub_recvfrom
493 case SYS_sub_recvfrom:
495 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
496 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
502 #if defined SYS_pwrite && SYS_pwrite64 != SYS_pwrite
507 #elif defined SYS_sub_send
512 #elif defined SYS_sub_sendto
515 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
516 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
520 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
521 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
526 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
527 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
534 enum subcall_style { shift_style, deref_style, mask_style, door_style };
536 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
544 static const struct subcall subcalls_table[] = {
545 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
547 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
549 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
551 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
555 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
558 decode_subcall(tcp, subcall, nsubcalls, style)
562 enum subcall_style style;
564 unsigned long addr, mask;
566 int size = personality_wordsize[current_personality];
570 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
572 tcp->scno = subcall + tcp->u_arg[0];
573 if (sysent[tcp->scno].nargs != -1)
574 tcp->u_nargs = sysent[tcp->scno].nargs;
577 for (i = 0; i < tcp->u_nargs; i++)
578 tcp->u_arg[i] = tcp->u_arg[i + 1];
581 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
583 tcp->scno = subcall + tcp->u_arg[0];
584 addr = tcp->u_arg[1];
585 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
586 if (size == sizeof(int)) {
588 if (umove(tcp, addr, &arg) < 0)
592 else if (size == sizeof(long)) {
594 if (umove(tcp, addr, &arg) < 0)
602 tcp->u_nargs = sysent[tcp->scno].nargs;
605 mask = (tcp->u_arg[0] >> 8) & 0xff;
606 for (i = 0; mask; i++)
610 tcp->u_arg[0] &= 0xff;
611 tcp->scno = subcall + i;
612 if (sysent[tcp->scno].nargs != -1)
613 tcp->u_nargs = sysent[tcp->scno].nargs;
617 * Oh, yuck. The call code is the *sixth* argument.
618 * (don't you mean the *last* argument? - JH)
620 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
622 tcp->scno = subcall + tcp->u_arg[5];
623 if (sysent[tcp->scno].nargs != -1)
624 tcp->u_nargs = sysent[tcp->scno].nargs;
630 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
631 if (subcalls_table[i].call == tcp->scno) break;
632 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
633 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
634 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
635 for (i = 0; i < tcp->u_nargs; i++)
636 tcp->u_arg[i] = tcp->u_arg[i + 1];
644 struct tcb *tcp_last = NULL;
647 internal_syscall(struct tcb *tcp)
650 * We must always trace a few critical system calls in order to
651 * correctly support following forks in the presence of tracing
656 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
659 func = sysent[tcp->scno].sys_func;
661 if (sys_exit == func)
662 return internal_exit(tcp);
664 if ( sys_fork == func
665 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
675 return internal_fork(tcp);
677 if ( sys_execve == func
678 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
682 || sys_rexecve == func
685 return internal_exec(tcp);
687 if ( sys_waitpid == func
689 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
693 || sys_osf_wait4 == func
696 return internal_wait(tcp, 2);
698 #if defined(LINUX) || defined(SVR4)
699 if (sys_waitid == func)
700 return internal_wait(tcp, 3);
713 #elif defined (POWERPC)
714 static long result,flags;
720 static struct pt_regs regs;
721 #elif defined (ALPHA)
725 static struct pt_regs regs;
726 #elif defined (SPARC) || defined (SPARC64)
727 static struct pt_regs regs;
728 static unsigned long trap;
729 #elif defined(LINUX_MIPSN32)
735 #elif defined(S390) || defined(S390X)
738 static long syscall_mode;
745 #elif defined(X86_64)
747 #elif defined(CRISV10) || defined(CRISV32)
749 #elif defined(MICROBLAZE)
758 get_scno(struct tcb *tcp)
763 # if defined(S390) || defined(S390X)
764 if (tcp->flags & TCB_WAITEXECVE) {
766 * When the execve system call completes successfully, the
767 * new process still has -ENOSYS (old style) or __NR_execve
768 * (new style) in gpr2. We cannot recover the scno again
769 * by disassembly, because the image that executed the
770 * syscall is gone now. Fortunately, we don't want it. We
771 * leave the flag set so that syscall_fixup can fake the
774 if (tcp->flags & TCB_INSYSCALL)
777 * This is the SIGTRAP after execve. We cannot try to read
778 * the system call here either.
780 tcp->flags &= ~TCB_WAITEXECVE;
784 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
787 if (syscall_mode != -ENOSYS) {
789 * Since kernel version 2.5.44 the scno gets passed in gpr2.
794 * Old style of "passing" the scno via the SVC instruction.
797 long opcode, offset_reg, tmp;
799 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
800 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
801 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
802 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
804 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
807 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
809 perror("peektext(pc-oneword)");
814 * We have to check if the SVC got executed directly or via an
815 * EXECUTE instruction. In case of EXECUTE it is necessary to do
816 * instruction decoding to derive the system call number.
817 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
818 * so that this doesn't work if a SVC opcode is part of an EXECUTE
819 * opcode. Since there is no way to find out the opcode size this
820 * is the best we can do...
823 if ((opcode & 0xff00) == 0x0a00) {
825 scno = opcode & 0xff;
828 /* SVC got executed by EXECUTE instruction */
831 * Do instruction decoding of EXECUTE. If you really want to
832 * understand this, read the Principles of Operations.
834 svc_addr = (void *) (opcode & 0xfff);
837 offset_reg = (opcode & 0x000f0000) >> 16;
838 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
843 offset_reg = (opcode & 0x0000f000) >> 12;
844 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
848 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
857 offset_reg = (opcode & 0x00f00000) >> 20;
858 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
861 scno = (scno | tmp) & 0xff;
864 # elif defined (POWERPC)
865 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
867 if (!(tcp->flags & TCB_INSYSCALL)) {
868 /* Check if we return from execve. */
869 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
870 tcp->flags &= ~TCB_WAITEXECVE;
876 if (!(tcp->flags & TCB_INSYSCALL)) {
877 static int currpers = -1;
881 /* Check for 64/32 bit mode. */
882 if (upeek(tcp, sizeof (unsigned long)*PT_MSR, &val) < 0)
884 /* SF is bit 0 of MSR */
889 if (currpers != current_personality) {
890 static const char *const names[] = {"64 bit", "32 bit"};
891 set_personality(currpers);
892 printf("[ Process PID=%d runs in %s mode. ]\n",
893 pid, names[current_personality]);
897 # elif defined(AVR32)
899 * Read complete register set in one go.
901 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
905 * We only need to grab the syscall number on syscall entry.
907 if (!(tcp->flags & TCB_INSYSCALL)) {
910 /* Check if we return from execve. */
911 if (tcp->flags & TCB_WAITEXECVE) {
912 tcp->flags &= ~TCB_WAITEXECVE;
917 if (upeek(tcp, PT_ORIG_P0, &scno))
919 # elif defined (I386)
920 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
922 # elif defined (X86_64)
923 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
926 if (!(tcp->flags & TCB_INSYSCALL)) {
927 static int currpers = -1;
931 /* Check CS register value. On x86-64 linux it is:
932 * 0x33 for long mode (64 bit)
933 * 0x23 for compatibility mode (32 bit)
934 * It takes only one ptrace and thus doesn't need
937 if (upeek(tcp, 8*CS, &val) < 0)
940 case 0x23: currpers = 1; break;
941 case 0x33: currpers = 0; break;
943 fprintf(stderr, "Unknown value CS=0x%02X while "
944 "detecting personality of process "
945 "PID=%d\n", (int)val, pid);
946 currpers = current_personality;
950 /* This version analyzes the opcode of a syscall instruction.
951 * (int 0x80 on i386 vs. syscall on x86-64)
952 * It works, but is too complicated.
954 unsigned long val, rip, i;
956 if (upeek(tcp, 8*RIP, &rip) < 0)
957 perror("upeek(RIP)");
959 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
963 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
965 printf("ptrace_peektext failed: %s\n",
967 switch (call & 0xffff) {
968 /* x86-64: syscall = 0x0f 0x05 */
969 case 0x050f: currpers = 0; break;
970 /* i386: int 0x80 = 0xcd 0x80 */
971 case 0x80cd: currpers = 1; break;
973 currpers = current_personality;
975 "Unknown syscall opcode (0x%04X) while "
976 "detecting personality of process "
977 "PID=%d\n", (int)call, pid);
981 if (currpers != current_personality) {
982 static const char *const names[] = {"64 bit", "32 bit"};
983 set_personality(currpers);
984 printf("[ Process PID=%d runs in %s mode. ]\n",
985 pid, names[current_personality]);
989 # define IA64_PSR_IS ((long)1 << 34)
990 if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
991 ia32 = (psr & IA64_PSR_IS) != 0;
992 if (!(tcp->flags & TCB_INSYSCALL)) {
994 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
997 if (upeek (tcp, PT_R15, &scno) < 0)
1000 /* Check if we return from execve. */
1001 if (tcp->flags & TCB_WAITEXECVE) {
1002 tcp->flags &= ~TCB_WAITEXECVE;
1006 /* syscall in progress */
1007 if (upeek (tcp, PT_R8, &r8) < 0)
1009 if (upeek (tcp, PT_R10, &r10) < 0)
1012 # elif defined (ARM)
1014 * Read complete register set in one go.
1016 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
1020 * We only need to grab the syscall number on syscall entry.
1022 if (regs.ARM_ip == 0) {
1023 if (!(tcp->flags & TCB_INSYSCALL)) {
1024 /* Check if we return from execve. */
1025 if (tcp->flags & TCB_WAITEXECVE) {
1026 tcp->flags &= ~TCB_WAITEXECVE;
1032 * Note: we only deal with only 32-bit CPUs here.
1034 if (regs.ARM_cpsr & 0x20) {
1036 * Get the Thumb-mode system call number
1041 * Get the ARM-mode system call number
1044 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1048 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1049 tcp->flags &= ~TCB_WAITEXECVE;
1053 /* Handle the EABI syscall convention. We do not
1054 bother converting structures between the two
1055 ABIs, but basic functionality should work even
1056 if strace and the traced program have different
1058 if (scno == 0xef000000) {
1061 if ((scno & 0x0ff00000) != 0x0f900000) {
1062 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1068 * Fixup the syscall number
1073 if (scno & 0x0f0000) {
1075 * Handle ARM specific syscall
1082 if (tcp->flags & TCB_INSYSCALL) {
1083 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1084 tcp->flags &= ~TCB_INSYSCALL;
1087 if (!(tcp->flags & TCB_INSYSCALL)) {
1088 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1089 tcp->flags |= TCB_INSYSCALL;
1092 # elif defined (M68K)
1093 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1095 # elif defined (LINUX_MIPSN32)
1096 unsigned long long regs[38];
1098 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1103 if(!(tcp->flags & TCB_INSYSCALL)) {
1106 /* Check if we return from execve. */
1107 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1108 tcp->flags &= ~TCB_WAITEXECVE;
1112 if (scno < 0 || scno > nsyscalls) {
1113 if(a3 == 0 || a3 == -1) {
1115 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1120 # elif defined (MIPS)
1121 if (upeek(tcp, REG_A3, &a3) < 0)
1123 if(!(tcp->flags & TCB_INSYSCALL)) {
1124 if (upeek(tcp, REG_V0, &scno) < 0)
1127 /* Check if we return from execve. */
1128 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1129 tcp->flags &= ~TCB_WAITEXECVE;
1133 if (scno < 0 || scno > nsyscalls) {
1134 if(a3 == 0 || a3 == -1) {
1136 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1141 if (upeek(tcp, REG_V0, &r2) < 0)
1144 # elif defined (ALPHA)
1145 if (upeek(tcp, REG_A3, &a3) < 0)
1148 if (!(tcp->flags & TCB_INSYSCALL)) {
1149 if (upeek(tcp, REG_R0, &scno) < 0)
1152 /* Check if we return from execve. */
1153 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1154 tcp->flags &= ~TCB_WAITEXECVE;
1159 * Do some sanity checks to figure out if it's
1160 * really a syscall entry
1162 if (scno < 0 || scno > nsyscalls) {
1163 if (a3 == 0 || a3 == -1) {
1165 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1171 if (upeek(tcp, REG_R0, &r0) < 0)
1174 # elif defined (SPARC) || defined (SPARC64)
1175 /* Everything we need is in the current register set. */
1176 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1179 /* If we are entering, then disassemble the syscall trap. */
1180 if (!(tcp->flags & TCB_INSYSCALL)) {
1181 /* Retrieve the syscall trap instruction. */
1183 # if defined(SPARC64)
1184 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1187 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1192 /* Disassemble the trap to see what personality to use. */
1195 /* Linux/SPARC syscall trap. */
1199 /* Linux/SPARC64 syscall trap. */
1203 /* SunOS syscall trap. (pers 1) */
1204 fprintf(stderr,"syscall: SunOS no support\n");
1207 /* Solaris 2.x syscall trap. (per 2) */
1211 /* NetBSD/FreeBSD syscall trap. */
1212 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1215 /* Solaris 2.x gettimeofday */
1219 /* Unknown syscall trap. */
1220 if(tcp->flags & TCB_WAITEXECVE) {
1221 tcp->flags &= ~TCB_WAITEXECVE;
1224 # if defined (SPARC64)
1225 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1227 fprintf(stderr,"syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1232 /* Extract the system call number from the registers. */
1233 if (trap == 0x91d02027)
1236 scno = regs.u_regs[U_REG_G1];
1238 scno = regs.u_regs[U_REG_O0];
1239 memmove (®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1242 # elif defined(HPPA)
1243 if (upeek(tcp, PT_GR20, &scno) < 0)
1245 if (!(tcp->flags & TCB_INSYSCALL)) {
1246 /* Check if we return from execve. */
1247 if ((tcp->flags & TCB_WAITEXECVE)) {
1248 tcp->flags &= ~TCB_WAITEXECVE;
1254 * In the new syscall ABI, the system call number is in R3.
1256 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1260 /* Odd as it may seem, a glibc bug has been known to cause
1261 glibc to issue bogus negative syscall numbers. So for
1262 our purposes, make strace print what it *should* have been */
1263 long correct_scno = (scno & 0xff);
1266 "Detected glibc bug: bogus system call"
1267 " number = %ld, correcting to %ld\n",
1270 scno = correct_scno;
1273 if (!(tcp->flags & TCB_INSYSCALL)) {
1274 /* Check if we return from execve. */
1275 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1276 tcp->flags &= ~TCB_WAITEXECVE;
1280 # elif defined(SH64)
1281 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1285 if (!(tcp->flags & TCB_INSYSCALL)) {
1286 /* Check if we return from execve. */
1287 if (tcp->flags & TCB_WAITEXECVE) {
1288 tcp->flags &= ~TCB_WAITEXECVE;
1292 # elif defined(CRISV10) || defined(CRISV32)
1293 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1295 # elif defined(TILE)
1296 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1299 if (!(tcp->flags & TCB_INSYSCALL)) {
1300 /* Check if we return from execve. */
1301 if (tcp->flags & TCB_WAITEXECVE) {
1302 tcp->flags &= ~TCB_WAITEXECVE;
1306 # elif defined(MICROBLAZE)
1307 if (upeek(tcp, 0, &scno) < 0)
1313 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1316 /* new syscall ABI returns result in R0 */
1317 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1320 /* ABI defines result returned in r9 */
1321 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1326 # ifdef HAVE_PR_SYSCALL
1327 scno = tcp->status.PR_SYSCALL;
1330 scno = tcp->status.PR_WHAT;
1332 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1336 switch (regs.r_eax) {
1339 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1345 # endif /* FREEBSD */
1346 # endif /* !HAVE_PR_SYSCALL */
1347 #endif /* USE_PROCFS */
1349 if (!(tcp->flags & TCB_INSYSCALL))
1359 long scno = tcp->scno;
1360 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1361 scno = sysent[scno].native_scno;
1363 scno += NR_SYSCALL_BASE;
1367 /* Called in trace_syscall() at each syscall entry and exit.
1369 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1370 * 1: ok, continue in trace_syscall().
1371 * other: error, trace_syscall() should print error indicator
1372 * ("????" etc) and bail out.
1375 syscall_fixup(struct tcb *tcp)
1378 int scno = known_scno(tcp);
1380 if (!(tcp->flags & TCB_INSYSCALL)) {
1381 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1385 || scno == SYS_vfork
1386 #endif /* SYS_vfork */
1388 || scno == SYS_fork1
1389 #endif /* SYS_fork1 */
1391 || scno == SYS_forkall
1392 #endif /* SYS_forkall */
1394 || scno == SYS_rfork1
1395 #endif /* SYS_fork1 */
1397 || scno == SYS_rforkall
1398 #endif /* SYS_rforkall */
1400 /* We are returning in the child, fake it. */
1401 tcp->status.PR_WHY = PR_SYSENTRY;
1403 tcp->status.PR_WHY = PR_SYSEXIT;
1406 fprintf(stderr, "syscall: missing entry\n");
1407 tcp->flags |= TCB_INSYSCALL;
1412 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1413 fprintf(stderr, "syscall: missing exit\n");
1414 tcp->flags &= ~TCB_INSYSCALL;
1417 #endif /* USE_PROCFS */
1419 if (!(tcp->flags & TCB_INSYSCALL)) {
1421 fprintf(stderr, "syscall: missing entry\n");
1422 tcp->flags |= TCB_INSYSCALL;
1429 * This happens when a signal handler
1430 * for a signal which interrupted a
1431 * a system call makes another system call.
1433 fprintf(stderr, "syscall: missing exit\n");
1435 tcp->flags &= ~TCB_INSYSCALL;
1441 if (upeek(tcp, 4*EAX, &eax) < 0)
1443 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1445 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1448 #elif defined (X86_64)
1449 if (upeek(tcp, 8*RAX, &rax) < 0)
1451 if (current_personality == 1)
1452 rax = (long int)(int)rax; /* sign extend from 32 bits */
1453 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1455 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1458 #elif defined (S390) || defined (S390X)
1459 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1461 if (syscall_mode != -ENOSYS)
1462 syscall_mode = tcp->scno;
1463 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1465 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1468 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1469 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1470 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1472 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1473 * flag set for the post-execve SIGTRAP to see and reset.
1477 #elif defined (POWERPC)
1478 # define SO_MASK 0x10000000
1479 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1481 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1483 if (flags & SO_MASK)
1485 #elif defined (M68K)
1486 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1488 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1490 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1498 if (upeek(tcp, PT_R0, &r0) < 0)
1500 #elif defined (HPPA)
1501 if (upeek(tcp, PT_GR28, &r28) < 0)
1504 if (upeek(tcp, PT_R10, &r10) < 0)
1506 if (upeek(tcp, PT_R8, &r8) < 0)
1508 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1510 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1513 #elif defined(CRISV10) || defined(CRISV32)
1514 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1516 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1518 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1521 #elif defined(MICROBLAZE)
1522 if (upeek(tcp, 3 * 4, &r3) < 0)
1524 if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1526 fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
1536 * Check the syscall return value register value for whether it is
1537 * a negated errno code indicating an error, or a success return value.
1540 is_negated_errno(unsigned long int val)
1542 unsigned long int max = -(long int) nerrnos;
1543 if (personality_wordsize[current_personality] < sizeof(val)) {
1544 val = (unsigned int) val;
1545 max = (unsigned int) max;
1552 get_error(struct tcb *tcp)
1556 # if defined(S390) || defined(S390X)
1557 if (is_negated_errno(gpr2)) {
1565 # elif defined(I386)
1566 if (is_negated_errno(eax)) {
1574 # elif defined(X86_64)
1575 if (is_negated_errno(rax)) {
1583 # elif defined(IA64)
1588 if (is_negated_errno(err)) {
1605 # elif defined(MIPS)
1613 # elif defined(POWERPC)
1614 if (is_negated_errno(result)) {
1619 tcp->u_rval = result;
1622 # elif defined(M68K)
1623 if (is_negated_errno(d0)) {
1632 if (is_negated_errno(regs.ARM_r0)) {
1634 u_error = -regs.ARM_r0;
1637 tcp->u_rval = regs.ARM_r0;
1640 # elif defined(AVR32)
1641 if (regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1643 u_error = -regs.r12;
1646 tcp->u_rval = regs.r12;
1649 # elif defined(BFIN)
1650 if (is_negated_errno(r0)) {
1657 # elif defined(ALPHA)
1666 # elif defined(SPARC)
1667 if (regs.psr & PSR_C) {
1669 u_error = regs.u_regs[U_REG_O0];
1672 tcp->u_rval = regs.u_regs[U_REG_O0];
1675 # elif defined(SPARC64)
1676 if (regs.tstate & 0x1100000000UL) {
1678 u_error = regs.u_regs[U_REG_O0];
1681 tcp->u_rval = regs.u_regs[U_REG_O0];
1684 # elif defined(HPPA)
1685 if (is_negated_errno(r28)) {
1694 /* interpret R0 as return value or error number */
1695 if (is_negated_errno(r0)) {
1703 # elif defined(SH64)
1704 /* interpret result as return value or error number */
1705 if (is_negated_errno(r9)) {
1713 # elif defined(CRISV10) || defined(CRISV32)
1714 if (r10 && (unsigned) -r10 < nerrnos) {
1722 # elif defined(TILE)
1724 /* interpret result as return value or error number */
1725 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1727 if (rval < 0 && rval > -nerrnos) {
1735 # elif defined(MICROBLAZE)
1736 /* interpret result as return value or error number */
1737 if (is_negated_errno(r3)) {
1748 /* get error code from user struct */
1749 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1751 u_error >>= 24; /* u_error is a char */
1753 /* get system call return value */
1754 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1759 /* Judicious guessing goes a long way. */
1760 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1762 u_error = tcp->status.pr_reg[R_O0];
1765 tcp->u_rval = tcp->status.pr_reg[R_O0];
1770 /* Wanna know how to kill an hour single-stepping? */
1771 if (tcp->status.PR_REG[EFL] & 0x1) {
1773 u_error = tcp->status.PR_REG[EAX];
1776 tcp->u_rval = tcp->status.PR_REG[EAX];
1777 #ifdef HAVE_LONG_LONG
1779 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1780 tcp->status.PR_REG[EAX];
1786 /* Wanna know how to kill an hour single-stepping? */
1787 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1789 u_error = tcp->status.PR_REG[RAX];
1792 tcp->u_rval = tcp->status.PR_REG[RAX];
1797 if (tcp->status.pr_reg[CTX_A3]) {
1799 u_error = tcp->status.pr_reg[CTX_V0];
1802 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1808 if (regs.r_eflags & PSL_C) {
1810 u_error = regs.r_eax;
1812 tcp->u_rval = regs.r_eax;
1814 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1817 #endif /* FREEBSD */
1818 tcp->u_error = u_error;
1823 force_result(tcp, error, rval)
1829 # if defined(S390) || defined(S390X)
1830 gpr2 = error ? -error : rval;
1831 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1833 # elif defined(I386)
1834 eax = error ? -error : rval;
1835 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1837 # elif defined(X86_64)
1838 rax = error ? -error : rval;
1839 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1841 # elif defined(IA64)
1843 r8 = error ? -error : rval;
1844 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1856 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1857 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1860 # elif defined(BFIN)
1861 r0 = error ? -error : rval;
1862 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1864 # elif defined(MIPS)
1873 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1874 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1875 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1877 # elif defined(POWERPC)
1878 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1888 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1889 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1891 # elif defined(M68K)
1892 d0 = error ? -error : rval;
1893 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1896 regs.ARM_r0 = error ? -error : rval;
1897 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1899 # elif defined(AVR32)
1900 regs.r12 = error ? -error : rval;
1901 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1903 # elif defined(ALPHA)
1912 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1913 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1915 # elif defined(SPARC)
1916 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1920 regs.u_regs[U_REG_O0] = error;
1924 regs.u_regs[U_REG_O0] = rval;
1926 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1928 # elif defined(SPARC64)
1929 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1932 regs.tstate |= 0x1100000000UL;
1933 regs.u_regs[U_REG_O0] = error;
1936 regs.tstate &= ~0x1100000000UL;
1937 regs.u_regs[U_REG_O0] = rval;
1939 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1941 # elif defined(HPPA)
1942 r28 = error ? -error : rval;
1943 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1946 r0 = error ? -error : rval;
1947 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1949 # elif defined(SH64)
1950 r9 = error ? -error : rval;
1951 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1957 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1959 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1969 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1974 regs.r_eflags |= PSL_C;
1978 regs.r_eflags &= ~PSL_C;
1981 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1985 #endif /* FREEBSD */
1987 /* All branches reach here on success (only). */
1988 tcp->u_error = error;
1994 syscall_enter(struct tcb *tcp)
1997 #if defined(S390) || defined(S390X)
2000 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2001 tcp->u_nargs = sysent[tcp->scno].nargs;
2003 tcp->u_nargs = MAX_ARGS;
2004 for (i = 0; i < tcp->u_nargs; i++) {
2005 if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
2009 #elif defined (ALPHA)
2012 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2013 tcp->u_nargs = sysent[tcp->scno].nargs;
2015 tcp->u_nargs = MAX_ARGS;
2016 for (i = 0; i < tcp->u_nargs; i++) {
2017 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
2018 * for scno somewhere above here!
2020 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
2024 #elif defined (IA64)
2027 unsigned long *out0, cfm, sof, sol, i;
2029 /* be backwards compatible with kernel < 2.4.4... */
2031 # define PT_RBS_END PT_AR_BSP
2034 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
2036 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2039 sof = (cfm >> 0) & 0x7f;
2040 sol = (cfm >> 7) & 0x7f;
2041 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2043 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2044 && sysent[tcp->scno].nargs != -1)
2045 tcp->u_nargs = sysent[tcp->scno].nargs;
2047 tcp->u_nargs = MAX_ARGS;
2048 for (i = 0; i < tcp->u_nargs; ++i) {
2049 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2050 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2056 if (/* EBX = out0 */
2057 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2059 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2061 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2063 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2065 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2067 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2070 for (i = 0; i < 6; ++i)
2071 /* truncate away IVE sign-extension */
2072 tcp->u_arg[i] &= 0xffffffff;
2074 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2075 && sysent[tcp->scno].nargs != -1)
2076 tcp->u_nargs = sysent[tcp->scno].nargs;
2081 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2082 /* N32 and N64 both use up to six registers. */
2084 unsigned long long regs[38];
2087 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2088 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2090 nargs = tcp->u_nargs = MAX_ARGS;
2092 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2095 for(i = 0; i < nargs; i++) {
2096 tcp->u_arg[i] = regs[REG_A0 + i];
2097 # if defined (LINUX_MIPSN32)
2098 tcp->ext_arg[i] = regs[REG_A0 + i];
2102 #elif defined (MIPS)
2107 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2108 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2110 nargs = tcp->u_nargs = MAX_ARGS;
2112 if(upeek(tcp, REG_SP, &sp) < 0)
2114 for(i = 0; i < 4; i++) {
2115 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2118 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2119 (char *)(tcp->u_arg + 4));
2121 for(i = 0; i < nargs; i++) {
2122 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2127 #elif defined (POWERPC)
2129 # define PT_ORIG_R3 34
2133 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2134 tcp->u_nargs = sysent[tcp->scno].nargs;
2136 tcp->u_nargs = MAX_ARGS;
2137 for (i = 0; i < tcp->u_nargs; i++) {
2138 if (upeek(tcp, (i==0) ?
2139 (sizeof(unsigned long)*PT_ORIG_R3) :
2140 ((i+PT_R3)*sizeof(unsigned long)),
2141 &tcp->u_arg[i]) < 0)
2145 #elif defined (SPARC) || defined (SPARC64)
2149 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2150 tcp->u_nargs = sysent[tcp->scno].nargs;
2152 tcp->u_nargs = MAX_ARGS;
2153 for (i = 0; i < tcp->u_nargs; i++)
2154 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2156 #elif defined (HPPA)
2160 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2161 tcp->u_nargs = sysent[tcp->scno].nargs;
2163 tcp->u_nargs = MAX_ARGS;
2164 for (i = 0; i < tcp->u_nargs; i++) {
2165 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2173 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2174 tcp->u_nargs = sysent[tcp->scno].nargs;
2176 tcp->u_nargs = MAX_ARGS;
2177 for (i = 0; i < tcp->u_nargs; i++)
2178 tcp->u_arg[i] = regs.uregs[i];
2180 #elif defined(AVR32)
2181 tcp->u_nargs = sysent[tcp->scno].nargs;
2182 tcp->u_arg[0] = regs.r12;
2183 tcp->u_arg[1] = regs.r11;
2184 tcp->u_arg[2] = regs.r10;
2185 tcp->u_arg[3] = regs.r9;
2186 tcp->u_arg[4] = regs.r5;
2187 tcp->u_arg[5] = regs.r3;
2191 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2193 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2194 tcp->u_nargs = sysent[tcp->scno].nargs;
2196 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2198 for (i = 0; i < tcp->u_nargs; ++i)
2199 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2205 static int syscall_regs[] = {
2206 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2207 REG_REG0, REG_REG0+1, REG_REG0+2
2210 tcp->u_nargs = sysent[tcp->scno].nargs;
2211 for (i = 0; i < tcp->u_nargs; i++) {
2212 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2219 /* Registers used by SH5 Linux system calls for parameters */
2220 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2223 * TODO: should also check that the number of arguments encoded
2224 * in the trap number matches the number strace expects.
2227 assert(sysent[tcp->scno].nargs <
2228 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2231 tcp->u_nargs = sysent[tcp->scno].nargs;
2232 for (i = 0; i < tcp->u_nargs; i++) {
2233 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2238 #elif defined(X86_64)
2241 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2242 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2243 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2246 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2247 tcp->u_nargs = sysent[tcp->scno].nargs;
2249 tcp->u_nargs = MAX_ARGS;
2250 for (i = 0; i < tcp->u_nargs; i++) {
2251 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2255 #elif defined(MICROBLAZE)
2258 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2259 tcp->u_nargs = sysent[tcp->scno].nargs;
2262 for (i = 0; i < tcp->u_nargs; i++) {
2263 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
2267 #elif defined(CRISV10) || defined(CRISV32)
2270 static const int crisregs[] = {
2271 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2272 4*PT_R13, 4*PT_MOF, 4*PT_SRP
2275 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2276 tcp->u_nargs = sysent[tcp->scno].nargs;
2279 for (i = 0; i < tcp->u_nargs; i++) {
2280 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2287 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2288 tcp->u_nargs = sysent[tcp->scno].nargs;
2290 tcp->u_nargs = MAX_ARGS;
2291 for (i = 0; i < tcp->u_nargs; ++i) {
2292 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2296 #elif defined (M68K)
2299 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2300 tcp->u_nargs = sysent[tcp->scno].nargs;
2302 tcp->u_nargs = MAX_ARGS;
2303 for (i = 0; i < tcp->u_nargs; i++) {
2304 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
2308 #else /* Other architecture (like i386) (32bits specific) */
2311 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2312 tcp->u_nargs = sysent[tcp->scno].nargs;
2314 tcp->u_nargs = MAX_ARGS;
2315 for (i = 0; i < tcp->u_nargs; i++) {
2316 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2325 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2326 tcp->u_nargs = sysent[tcp->scno].nargs;
2328 tcp->u_nargs = MAX_ARGS;
2329 for (i = 0; i < tcp->u_nargs; i++) {
2332 if (upeek(tcp, uoff(u_arg[0]) +
2333 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2341 * SGI is broken: even though it has pr_sysarg, it doesn't
2342 * set them on system call entry. Get a clue.
2344 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2345 tcp->u_nargs = sysent[tcp->scno].nargs;
2347 tcp->u_nargs = tcp->status.pr_nsysarg;
2348 if (tcp->u_nargs > 4) {
2349 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2350 4*sizeof(tcp->u_arg[0]));
2351 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2352 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2355 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2356 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2360 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2362 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2363 tcp->u_nargs = sysent[tcp->scno].nargs;
2365 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2366 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2367 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2368 #elif defined (HAVE_PR_SYSCALL)
2369 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2370 tcp->u_nargs = sysent[tcp->scno].nargs;
2372 tcp->u_nargs = tcp->status.pr_nsysarg;
2375 for (i = 0; i < tcp->u_nargs; i++)
2376 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2378 #elif defined (I386)
2379 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2380 tcp->u_nargs = sysent[tcp->scno].nargs;
2383 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2384 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2386 I DONT KNOW WHAT TO DO
2387 #endif /* !HAVE_PR_SYSCALL */
2390 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2391 sysent[tcp->scno].nargs > tcp->status.val)
2392 tcp->u_nargs = sysent[tcp->scno].nargs;
2394 tcp->u_nargs = tcp->status.val;
2395 if (tcp->u_nargs < 0)
2397 if (tcp->u_nargs > MAX_ARGS)
2398 tcp->u_nargs = MAX_ARGS;
2399 switch(regs.r_eax) {
2401 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2402 regs.r_esp + sizeof(int) + sizeof(quad_t));
2405 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2406 regs.r_esp + 2 * sizeof(int));
2409 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2410 regs.r_esp + sizeof(int));
2413 #endif /* FREEBSD */
2418 trace_syscall_exiting(struct tcb *tcp)
2425 /* Measure the exit time as early as possible to avoid errors. */
2427 gettimeofday(&tv, NULL);
2429 /* BTW, why we don't just memorize syscall no. on entry
2430 * in tcp->something?
2432 scno_good = res = get_scno(tcp);
2436 res = syscall_fixup(tcp);
2440 res = get_error(tcp);
2444 internal_syscall(tcp);
2446 if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2447 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2448 tcp->flags &= ~TCB_INSYSCALL;
2452 if (tcp->flags & TCB_REPRINT) {
2457 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2458 tprintf("syscall_%lu", tcp->scno);
2460 tprintf("%s", sysent[tcp->scno].sys_name);
2461 tprintf(" resumed> ");
2465 struct timeval t = tv;
2466 int rc = count_syscall(tcp, &t);
2467 if (cflag == CFLAG_ONLY_STATS)
2469 tcp->flags &= ~TCB_INSYSCALL;
2477 tprintf("= ? <unavailable>");
2479 tcp->flags &= ~TCB_INSYSCALL;
2483 if (tcp->scno >= nsyscalls || tcp->scno < 0
2484 || (qual_flags[tcp->scno] & QUAL_RAW))
2485 sys_res = printargs(tcp);
2487 if (not_failing_only && tcp->u_error)
2488 return 0; /* ignore failed syscalls */
2489 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2492 u_error = tcp->u_error;
2495 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2496 qual_flags[tcp->scno] & QUAL_RAW) {
2498 tprintf("= -1 (errno %ld)", u_error);
2500 tprintf("= %#lx", tcp->u_rval);
2502 else if (!(sys_res & RVAL_NONE) && u_error) {
2506 tprintf("= ? ERESTARTSYS (To be restarted)");
2508 case ERESTARTNOINTR:
2509 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2511 case ERESTARTNOHAND:
2512 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2514 case ERESTART_RESTARTBLOCK:
2515 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2521 tprintf("E??? (errno %ld)", u_error);
2522 else if (u_error < nerrnos)
2523 tprintf("%s (%s)", errnoent[u_error],
2526 tprintf("ERRNO_%ld (%s)", u_error,
2530 if ((sys_res & RVAL_STR) && tcp->auxstr)
2531 tprintf(" (%s)", tcp->auxstr);
2534 if (sys_res & RVAL_NONE)
2537 switch (sys_res & RVAL_MASK) {
2539 tprintf("= %#lx", tcp->u_rval);
2542 tprintf("= %#lo", tcp->u_rval);
2545 tprintf("= %lu", tcp->u_rval);
2548 tprintf("= %ld", tcp->u_rval);
2550 #ifdef HAVE_LONG_LONG
2552 tprintf("= %#llx", tcp->u_lrval);
2555 tprintf("= %#llo", tcp->u_lrval);
2557 case RVAL_LUDECIMAL:
2558 tprintf("= %llu", tcp->u_lrval);
2561 tprintf("= %lld", tcp->u_lrval);
2566 "invalid rval format\n");
2570 if ((sys_res & RVAL_STR) && tcp->auxstr)
2571 tprintf(" (%s)", tcp->auxstr);
2574 tv_sub(&tv, &tv, &tcp->etime);
2575 tprintf(" <%ld.%06ld>",
2576 (long) tv.tv_sec, (long) tv.tv_usec);
2581 if (fflush(tcp->outf) == EOF)
2583 tcp->flags &= ~TCB_INSYSCALL;
2588 trace_syscall_entering(struct tcb *tcp)
2593 scno_good = res = get_scno(tcp);
2597 res = syscall_fixup(tcp);
2601 res = syscall_enter(tcp);
2607 tcp->flags &= ~TCB_REPRINT;
2610 tprintf("????" /* anti-trigraph gap */ "(");
2611 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2612 tprintf("syscall_%lu(", tcp->scno);
2614 tprintf("%s(", sysent[tcp->scno].sys_name);
2616 * " <unavailable>" will be added later by the code which
2617 * detects ptrace errors.
2619 tcp->flags |= TCB_INSYSCALL;
2623 switch (known_scno(tcp)) {
2624 #ifdef SYS_socket_subcall
2625 case SYS_socketcall:
2626 decode_subcall(tcp, SYS_socket_subcall,
2627 SYS_socket_nsubcalls, deref_style);
2630 #ifdef SYS_ipc_subcall
2632 decode_subcall(tcp, SYS_ipc_subcall,
2633 SYS_ipc_nsubcalls, shift_style);
2637 #ifdef SYS_pgrpsys_subcall
2639 decode_subcall(tcp, SYS_pgrpsys_subcall,
2640 SYS_pgrpsys_nsubcalls, shift_style);
2642 #endif /* SYS_pgrpsys_subcall */
2643 #ifdef SYS_sigcall_subcall
2645 decode_subcall(tcp, SYS_sigcall_subcall,
2646 SYS_sigcall_nsubcalls, mask_style);
2648 #endif /* SYS_sigcall_subcall */
2650 decode_subcall(tcp, SYS_msgsys_subcall,
2651 SYS_msgsys_nsubcalls, shift_style);
2654 decode_subcall(tcp, SYS_shmsys_subcall,
2655 SYS_shmsys_nsubcalls, shift_style);
2658 decode_subcall(tcp, SYS_semsys_subcall,
2659 SYS_semsys_nsubcalls, shift_style);
2662 decode_subcall(tcp, SYS_sysfs_subcall,
2663 SYS_sysfs_nsubcalls, shift_style);
2666 decode_subcall(tcp, SYS_spcall_subcall,
2667 SYS_spcall_nsubcalls, shift_style);
2669 #ifdef SYS_context_subcall
2671 decode_subcall(tcp, SYS_context_subcall,
2672 SYS_context_nsubcalls, shift_style);
2674 #endif /* SYS_context_subcall */
2675 #ifdef SYS_door_subcall
2677 decode_subcall(tcp, SYS_door_subcall,
2678 SYS_door_nsubcalls, door_style);
2680 #endif /* SYS_door_subcall */
2681 #ifdef SYS_kaio_subcall
2683 decode_subcall(tcp, SYS_kaio_subcall,
2684 SYS_kaio_nsubcalls, shift_style);
2692 decode_subcall(tcp, 0, 0, table_style);
2697 decode_subcall(tcp, SYS_semsys_subcall,
2698 SYS_semsys_nsubcalls, shift_style);
2701 decode_subcall(tcp, SYS_msgsys_subcall,
2702 SYS_msgsys_nsubcalls, shift_style);
2705 decode_subcall(tcp, SYS_shmsys_subcall,
2706 SYS_shmsys_nsubcalls, shift_style);
2711 internal_syscall(tcp);
2712 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2713 tcp->flags |= TCB_INSYSCALL;
2717 if (cflag == CFLAG_ONLY_STATS) {
2718 tcp->flags |= TCB_INSYSCALL;
2719 gettimeofday(&tcp->etime, NULL);
2724 tcp->flags &= ~TCB_REPRINT;
2726 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2727 tprintf("syscall_%lu(", tcp->scno);
2729 tprintf("%s(", sysent[tcp->scno].sys_name);
2730 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2731 ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2732 sys_res = printargs(tcp);
2734 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2735 if (fflush(tcp->outf) == EOF)
2737 tcp->flags |= TCB_INSYSCALL;
2738 /* Measure the entrance time as late as possible to avoid errors. */
2740 gettimeofday(&tcp->etime, NULL);
2745 trace_syscall(struct tcb *tcp)
2747 return exiting(tcp) ?
2748 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2755 if (entering(tcp)) {
2758 for (i = 0; i < tcp->u_nargs; i++)
2759 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2771 #if defined (SPARC) || defined (SPARC64)
2772 struct pt_regs regs;
2773 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2775 val = regs.u_regs[U_REG_O1];
2777 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2780 if (upeek(tcp, PT_R9, &val) < 0)
2786 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2792 val = tcp->status.PR_REG[R_O1];
2795 val = tcp->status.PR_REG[EDX];
2798 val = tcp->status.PR_REG[RDX];
2801 val = tcp->status.PR_REG[CTX_V1];
2807 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2815 * Apparently, indirect system calls have already be converted by ptrace(2),
2816 * so if you see "indir" this program has gone astray.
2824 if (entering(tcp)) {
2825 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2826 fprintf(stderr, "Bogus syscall: %u\n", scno);
2829 nargs = sysent[scno].nargs;
2830 tprintf("%s", sysent[scno].sys_name);
2831 for (i = 0; i < nargs; i++)
2832 tprintf(", %#lx", tcp->u_arg[i+1]);
2839 is_restart_error(struct tcb *tcp)
2844 switch (tcp->u_error) {
2846 case ERESTARTNOINTR:
2847 case ERESTARTNOHAND:
2848 case ERESTART_RESTARTBLOCK: