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
112 #define NF SYSCALL_NEVER_FAILS
114 static const struct sysent sysent0[] = {
115 #include "syscallent.h"
117 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
118 int qual_flags0[MAX_QUALS];
120 #if SUPPORTED_PERSONALITIES >= 2
121 static const struct sysent sysent1[] = {
122 #include "syscallent1.h"
124 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
125 int qual_flags1[MAX_QUALS];
126 #endif /* SUPPORTED_PERSONALITIES >= 2 */
128 #if SUPPORTED_PERSONALITIES >= 3
129 static const struct sysent sysent2[] = {
130 #include "syscallent2.h"
132 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
133 int qual_flags2[MAX_QUALS];
134 #endif /* SUPPORTED_PERSONALITIES >= 3 */
136 const struct sysent *sysent;
140 /* Now undef them since short defines cause wicked namespace pollution. */
149 static const char *const errnoent0[] = {
150 #include "errnoent.h"
152 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
154 #if SUPPORTED_PERSONALITIES >= 2
155 static const char *const errnoent1[] = {
156 #include "errnoent1.h"
158 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
159 #endif /* SUPPORTED_PERSONALITIES >= 2 */
161 #if SUPPORTED_PERSONALITIES >= 3
162 static const char *const errnoent2[] = {
163 #include "errnoent2.h"
165 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
166 #endif /* SUPPORTED_PERSONALITIES >= 3 */
168 const char *const *errnoent;
171 int current_personality;
173 #ifndef PERSONALITY0_WORDSIZE
174 # define PERSONALITY0_WORDSIZE sizeof(long)
176 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
177 PERSONALITY0_WORDSIZE,
178 #if SUPPORTED_PERSONALITIES > 1
179 PERSONALITY1_WORDSIZE,
181 #if SUPPORTED_PERSONALITIES > 2
182 PERSONALITY2_WORDSIZE,
187 set_personality(int personality)
189 switch (personality) {
191 errnoent = errnoent0;
194 nsyscalls = nsyscalls0;
195 ioctlent = ioctlent0;
196 nioctlents = nioctlents0;
197 signalent = signalent0;
198 nsignals = nsignals0;
199 qual_flags = qual_flags0;
202 #if SUPPORTED_PERSONALITIES >= 2
204 errnoent = errnoent1;
207 nsyscalls = nsyscalls1;
208 ioctlent = ioctlent1;
209 nioctlents = nioctlents1;
210 signalent = signalent1;
211 nsignals = nsignals1;
212 qual_flags = qual_flags1;
214 #endif /* SUPPORTED_PERSONALITIES >= 2 */
216 #if SUPPORTED_PERSONALITIES >= 3
218 errnoent = errnoent2;
221 nsyscalls = nsyscalls2;
222 ioctlent = ioctlent2;
223 nioctlents = nioctlents2;
224 signalent = signalent2;
225 nsignals = nsignals2;
226 qual_flags = qual_flags2;
228 #endif /* SUPPORTED_PERSONALITIES >= 3 */
234 current_personality = personality;
239 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
241 static const struct qual_options {
243 const char *option_name;
244 int (*qualify)(const char *, int, int);
245 const char *argument_name;
247 { QUAL_TRACE, "trace", qual_syscall, "system call" },
248 { QUAL_TRACE, "t", qual_syscall, "system call" },
249 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
250 { QUAL_ABBREV, "a", qual_syscall, "system call" },
251 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
252 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
253 { QUAL_RAW, "raw", qual_syscall, "system call" },
254 { QUAL_RAW, "x", qual_syscall, "system call" },
255 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
256 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
257 { QUAL_SIGNAL, "s", qual_signal, "signal" },
258 { QUAL_FAULT, "fault", qual_fault, "fault" },
259 { QUAL_FAULT, "faults", qual_fault, "fault" },
260 { QUAL_FAULT, "m", qual_fault, "fault" },
261 { QUAL_READ, "read", qual_desc, "descriptor" },
262 { QUAL_READ, "reads", qual_desc, "descriptor" },
263 { QUAL_READ, "r", qual_desc, "descriptor" },
264 { QUAL_WRITE, "write", qual_desc, "descriptor" },
265 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
266 { QUAL_WRITE, "w", qual_desc, "descriptor" },
267 { 0, NULL, NULL, NULL },
271 qualify_one(int n, int bitflag, int not, int pers)
273 if (pers == 0 || pers < 0) {
275 qual_flags0[n] &= ~bitflag;
277 qual_flags0[n] |= bitflag;
280 #if SUPPORTED_PERSONALITIES >= 2
281 if (pers == 1 || pers < 0) {
283 qual_flags1[n] &= ~bitflag;
285 qual_flags1[n] |= bitflag;
287 #endif /* SUPPORTED_PERSONALITIES >= 2 */
289 #if SUPPORTED_PERSONALITIES >= 3
290 if (pers == 2 || pers < 0) {
292 qual_flags2[n] &= ~bitflag;
294 qual_flags2[n] |= bitflag;
296 #endif /* SUPPORTED_PERSONALITIES >= 3 */
300 qual_syscall(const char *s, int bitflag, int not)
305 if (isdigit((unsigned char)*s)) {
307 if (i < 0 || i >= MAX_QUALS)
309 qualify_one(i, bitflag, not, -1);
312 for (i = 0; i < nsyscalls0; i++)
313 if (strcmp(s, sysent0[i].sys_name) == 0) {
314 qualify_one(i, bitflag, not, 0);
318 #if SUPPORTED_PERSONALITIES >= 2
319 for (i = 0; i < nsyscalls1; i++)
320 if (strcmp(s, sysent1[i].sys_name) == 0) {
321 qualify_one(i, bitflag, not, 1);
324 #endif /* SUPPORTED_PERSONALITIES >= 2 */
326 #if SUPPORTED_PERSONALITIES >= 3
327 for (i = 0; i < nsyscalls2; i++)
328 if (strcmp(s, sysent2[i].sys_name) == 0) {
329 qualify_one(i, bitflag, not, 2);
332 #endif /* SUPPORTED_PERSONALITIES >= 3 */
338 qual_signal(const char *s, int bitflag, int not)
343 if (isdigit((unsigned char)*s)) {
345 if (signo < 0 || signo >= MAX_QUALS)
347 qualify_one(signo, bitflag, not, -1);
350 if (strlen(s) >= sizeof buf)
354 if (strncasecmp(s, "SIG", 3) == 0)
356 for (i = 0; i <= NSIG; i++)
357 if (strcasecmp(s, signame(i) + 3) == 0) {
358 qualify_one(i, bitflag, not, -1);
365 qual_fault(const char *s, int bitflag, int not)
371 qual_desc(const char *s, int bitflag, int not)
373 if (isdigit((unsigned char)*s)) {
375 if (desc < 0 || desc >= MAX_QUALS)
377 qualify_one(desc, bitflag, not, -1);
384 lookup_class(const char *s)
386 if (strcmp(s, "file") == 0)
388 if (strcmp(s, "ipc") == 0)
390 if (strcmp(s, "network") == 0)
391 return TRACE_NETWORK;
392 if (strcmp(s, "process") == 0)
393 return TRACE_PROCESS;
394 if (strcmp(s, "signal") == 0)
396 if (strcmp(s, "desc") == 0)
402 qualify(const char *s)
404 const struct qual_options *opt;
410 opt = &qual_options[0];
411 for (i = 0; (p = qual_options[i].option_name); i++) {
413 if (strncmp(s, p, n) == 0 && s[n] == '=') {
414 opt = &qual_options[i];
424 if (strcmp(s, "none") == 0) {
428 if (strcmp(s, "all") == 0) {
429 for (i = 0; i < MAX_QUALS; i++) {
430 qualify_one(i, opt->bitflag, not, -1);
434 for (i = 0; i < MAX_QUALS; i++) {
435 qualify_one(i, opt->bitflag, !not, -1);
437 if (!(copy = strdup(s))) {
438 fprintf(stderr, "out of memory\n");
441 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
442 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
443 for (i = 0; i < nsyscalls0; i++)
444 if (sysent0[i].sys_flags & n)
445 qualify_one(i, opt->bitflag, not, 0);
447 #if SUPPORTED_PERSONALITIES >= 2
448 for (i = 0; i < nsyscalls1; i++)
449 if (sysent1[i].sys_flags & n)
450 qualify_one(i, opt->bitflag, not, 1);
451 #endif /* SUPPORTED_PERSONALITIES >= 2 */
453 #if SUPPORTED_PERSONALITIES >= 3
454 for (i = 0; i < nsyscalls2; i++)
455 if (sysent2[i].sys_flags & n)
456 qualify_one(i, opt->bitflag, not, 2);
457 #endif /* SUPPORTED_PERSONALITIES >= 3 */
461 if (opt->qualify(p, opt->bitflag, not)) {
462 fprintf(stderr, "strace: invalid %s `%s'\n",
463 opt->argument_name, p);
472 dumpio(struct tcb *tcp)
476 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
478 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
480 if (sysent[tcp->scno].sys_func == printargs)
482 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
483 if (sysent[tcp->scno].sys_func == sys_read ||
484 sysent[tcp->scno].sys_func == sys_pread ||
485 sysent[tcp->scno].sys_func == sys_pread64 ||
486 sysent[tcp->scno].sys_func == sys_recv ||
487 sysent[tcp->scno].sys_func == sys_recvfrom)
488 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
489 else if (sysent[tcp->scno].sys_func == sys_readv)
490 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
493 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
494 if (sysent[tcp->scno].sys_func == sys_write ||
495 sysent[tcp->scno].sys_func == sys_pwrite ||
496 sysent[tcp->scno].sys_func == sys_pwrite64 ||
497 sysent[tcp->scno].sys_func == sys_send ||
498 sysent[tcp->scno].sys_func == sys_sendto)
499 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
500 else if (sysent[tcp->scno].sys_func == sys_writev)
501 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
507 enum subcall_style { shift_style, deref_style, mask_style, door_style };
509 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
517 static const struct subcall subcalls_table[] = {
518 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
520 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
522 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
524 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
528 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
531 decode_subcall(struct tcb *tcp, int subcall, int nsubcalls, enum subcall_style style)
533 unsigned long addr, mask;
535 int size = personality_wordsize[current_personality];
539 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
541 tcp->scno = subcall + tcp->u_arg[0];
542 if (sysent[tcp->scno].nargs != -1)
543 tcp->u_nargs = sysent[tcp->scno].nargs;
546 for (i = 0; i < tcp->u_nargs; i++)
547 tcp->u_arg[i] = tcp->u_arg[i + 1];
550 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
552 tcp->scno = subcall + tcp->u_arg[0];
553 addr = tcp->u_arg[1];
554 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
555 if (size == sizeof(int)) {
557 if (umove(tcp, addr, &arg) < 0)
561 else if (size == sizeof(long)) {
563 if (umove(tcp, addr, &arg) < 0)
571 tcp->u_nargs = sysent[tcp->scno].nargs;
574 mask = (tcp->u_arg[0] >> 8) & 0xff;
575 for (i = 0; mask; i++)
579 tcp->u_arg[0] &= 0xff;
580 tcp->scno = subcall + i;
581 if (sysent[tcp->scno].nargs != -1)
582 tcp->u_nargs = sysent[tcp->scno].nargs;
586 * Oh, yuck. The call code is the *sixth* argument.
587 * (don't you mean the *last* argument? - JH)
589 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
591 tcp->scno = subcall + tcp->u_arg[5];
592 if (sysent[tcp->scno].nargs != -1)
593 tcp->u_nargs = sysent[tcp->scno].nargs;
599 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
600 if (subcalls_table[i].call == tcp->scno) break;
601 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
602 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
603 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
604 for (i = 0; i < tcp->u_nargs; i++)
605 tcp->u_arg[i] = tcp->u_arg[i + 1];
613 struct tcb *tcp_last = NULL;
616 internal_syscall(struct tcb *tcp)
619 * We must always trace a few critical system calls in order to
620 * correctly support following forks in the presence of tracing
625 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
628 func = sysent[tcp->scno].sys_func;
630 if (sys_exit == func)
631 return internal_exit(tcp);
633 if ( sys_fork == func
634 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
644 return internal_fork(tcp);
646 if ( sys_execve == func
647 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
651 || sys_rexecve == func
654 return internal_exec(tcp);
656 if ( sys_waitpid == func
658 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
662 || sys_osf_wait4 == func
665 return internal_wait(tcp, 2);
667 #if defined(LINUX) || defined(SVR4)
668 if (sys_waitid == func)
669 return internal_wait(tcp, 3);
679 # elif defined (IA64)
680 long r8, r10, psr; /* TODO: make static? */
681 long ia32 = 0; /* not static */
682 # elif defined (POWERPC)
683 static long result, flags;
684 # elif defined (M68K)
689 static struct pt_regs regs;
690 # elif defined (ALPHA)
693 # elif defined(AVR32)
694 static struct pt_regs regs;
695 # elif defined (SPARC) || defined (SPARC64)
696 static struct pt_regs regs;
697 static unsigned long trap;
698 # elif defined(LINUX_MIPSN32)
704 # elif defined(S390) || defined(S390X)
707 static long syscall_mode;
714 # elif defined(X86_64)
716 # elif defined(CRISV10) || defined(CRISV32)
718 # elif defined(MICROBLAZE)
723 struct reg regs; /* TODO: make static? */
727 get_scno(struct tcb *tcp)
732 # if defined(S390) || defined(S390X)
733 if (tcp->flags & TCB_WAITEXECVE) {
735 * When the execve system call completes successfully, the
736 * new process still has -ENOSYS (old style) or __NR_execve
737 * (new style) in gpr2. We cannot recover the scno again
738 * by disassembly, because the image that executed the
739 * syscall is gone now. Fortunately, we don't want it. We
740 * leave the flag set so that syscall_fixup can fake the
743 if (tcp->flags & TCB_INSYSCALL)
746 * This is the SIGTRAP after execve. We cannot try to read
747 * the system call here either.
749 tcp->flags &= ~TCB_WAITEXECVE;
753 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
756 if (syscall_mode != -ENOSYS) {
758 * Since kernel version 2.5.44 the scno gets passed in gpr2.
763 * Old style of "passing" the scno via the SVC instruction.
766 long opcode, offset_reg, tmp;
768 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
769 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
770 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
771 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
773 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
776 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
778 perror("peektext(pc-oneword)");
783 * We have to check if the SVC got executed directly or via an
784 * EXECUTE instruction. In case of EXECUTE it is necessary to do
785 * instruction decoding to derive the system call number.
786 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
787 * so that this doesn't work if a SVC opcode is part of an EXECUTE
788 * opcode. Since there is no way to find out the opcode size this
789 * is the best we can do...
792 if ((opcode & 0xff00) == 0x0a00) {
794 scno = opcode & 0xff;
797 /* SVC got executed by EXECUTE instruction */
800 * Do instruction decoding of EXECUTE. If you really want to
801 * understand this, read the Principles of Operations.
803 svc_addr = (void *) (opcode & 0xfff);
806 offset_reg = (opcode & 0x000f0000) >> 16;
807 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
812 offset_reg = (opcode & 0x0000f000) >> 12;
813 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
817 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
826 offset_reg = (opcode & 0x00f00000) >> 20;
827 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
830 scno = (scno | tmp) & 0xff;
833 # elif defined (POWERPC)
834 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
836 if (!(tcp->flags & TCB_INSYSCALL)) {
837 /* Check if we return from execve. */
838 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
839 tcp->flags &= ~TCB_WAITEXECVE;
845 if (!(tcp->flags & TCB_INSYSCALL)) {
846 static int currpers = -1;
850 /* Check for 64/32 bit mode. */
851 if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0)
853 /* SF is bit 0 of MSR */
858 if (currpers != current_personality) {
859 static const char *const names[] = {"64 bit", "32 bit"};
860 set_personality(currpers);
861 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
862 pid, names[current_personality]);
866 # elif defined(AVR32)
868 * Read complete register set in one go.
870 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
874 * We only need to grab the syscall number on syscall entry.
876 if (!(tcp->flags & TCB_INSYSCALL)) {
879 /* Check if we return from execve. */
880 if (tcp->flags & TCB_WAITEXECVE) {
881 tcp->flags &= ~TCB_WAITEXECVE;
886 if (upeek(tcp, PT_ORIG_P0, &scno))
888 # elif defined (I386)
889 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
891 # elif defined (X86_64)
892 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
895 if (!(tcp->flags & TCB_INSYSCALL)) {
896 static int currpers = -1;
900 /* Check CS register value. On x86-64 linux it is:
901 * 0x33 for long mode (64 bit)
902 * 0x23 for compatibility mode (32 bit)
903 * It takes only one ptrace and thus doesn't need
906 if (upeek(tcp, 8*CS, &val) < 0)
909 case 0x23: currpers = 1; break;
910 case 0x33: currpers = 0; break;
912 fprintf(stderr, "Unknown value CS=0x%02X while "
913 "detecting personality of process "
914 "PID=%d\n", (int)val, pid);
915 currpers = current_personality;
919 /* This version analyzes the opcode of a syscall instruction.
920 * (int 0x80 on i386 vs. syscall on x86-64)
921 * It works, but is too complicated.
923 unsigned long val, rip, i;
925 if (upeek(tcp, 8*RIP, &rip) < 0)
926 perror("upeek(RIP)");
928 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
932 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
934 fprintf(stderr, "ptrace_peektext failed: %s\n",
936 switch (call & 0xffff) {
937 /* x86-64: syscall = 0x0f 0x05 */
938 case 0x050f: currpers = 0; break;
939 /* i386: int 0x80 = 0xcd 0x80 */
940 case 0x80cd: currpers = 1; break;
942 currpers = current_personality;
944 "Unknown syscall opcode (0x%04X) while "
945 "detecting personality of process "
946 "PID=%d\n", (int)call, pid);
950 if (currpers != current_personality) {
951 static const char *const names[] = {"64 bit", "32 bit"};
952 set_personality(currpers);
953 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
954 pid, names[current_personality]);
958 # define IA64_PSR_IS ((long)1 << 34)
959 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0)
960 ia32 = (psr & IA64_PSR_IS) != 0;
961 if (!(tcp->flags & TCB_INSYSCALL)) {
963 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
966 if (upeek(tcp, PT_R15, &scno) < 0)
969 /* Check if we return from execve. */
970 if (tcp->flags & TCB_WAITEXECVE) {
971 tcp->flags &= ~TCB_WAITEXECVE;
975 /* syscall in progress */
976 if (upeek(tcp, PT_R8, &r8) < 0)
978 if (upeek(tcp, PT_R10, &r10) < 0)
983 * Read complete register set in one go.
985 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
989 * We only need to grab the syscall number on syscall entry.
991 if (regs.ARM_ip == 0) {
992 if (!(tcp->flags & TCB_INSYSCALL)) {
993 /* Check if we return from execve. */
994 if (tcp->flags & TCB_WAITEXECVE) {
995 tcp->flags &= ~TCB_WAITEXECVE;
1001 * Note: we only deal with only 32-bit CPUs here.
1003 if (regs.ARM_cpsr & 0x20) {
1005 * Get the Thumb-mode system call number
1010 * Get the ARM-mode system call number
1013 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1017 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1018 tcp->flags &= ~TCB_WAITEXECVE;
1022 /* Handle the EABI syscall convention. We do not
1023 bother converting structures between the two
1024 ABIs, but basic functionality should work even
1025 if strace and the traced program have different
1027 if (scno == 0xef000000) {
1030 if ((scno & 0x0ff00000) != 0x0f900000) {
1031 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1037 * Fixup the syscall number
1042 if (scno & 0x0f0000) {
1044 * Handle ARM specific syscall
1051 if (tcp->flags & TCB_INSYSCALL) {
1052 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1053 tcp->flags &= ~TCB_INSYSCALL;
1056 if (!(tcp->flags & TCB_INSYSCALL)) {
1057 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1058 tcp->flags |= TCB_INSYSCALL;
1061 # elif defined (M68K)
1062 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1064 # elif defined (LINUX_MIPSN32)
1065 unsigned long long regs[38];
1067 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1072 if (!(tcp->flags & TCB_INSYSCALL)) {
1075 /* Check if we return from execve. */
1076 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1077 tcp->flags &= ~TCB_WAITEXECVE;
1081 if (scno < 0 || scno > nsyscalls) {
1082 if (a3 == 0 || a3 == -1) {
1084 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
1089 # elif defined (MIPS)
1090 if (upeek(tcp, REG_A3, &a3) < 0)
1092 if (!(tcp->flags & TCB_INSYSCALL)) {
1093 if (upeek(tcp, REG_V0, &scno) < 0)
1096 /* Check if we return from execve. */
1097 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1098 tcp->flags &= ~TCB_WAITEXECVE;
1102 if (scno < 0 || scno > nsyscalls) {
1103 if (a3 == 0 || a3 == -1) {
1105 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
1110 if (upeek(tcp, REG_V0, &r2) < 0)
1113 # elif defined (ALPHA)
1114 if (upeek(tcp, REG_A3, &a3) < 0)
1117 if (!(tcp->flags & TCB_INSYSCALL)) {
1118 if (upeek(tcp, REG_R0, &scno) < 0)
1121 /* Check if we return from execve. */
1122 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1123 tcp->flags &= ~TCB_WAITEXECVE;
1128 * Do some sanity checks to figure out if it's
1129 * really a syscall entry
1131 if (scno < 0 || scno > nsyscalls) {
1132 if (a3 == 0 || a3 == -1) {
1134 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
1140 if (upeek(tcp, REG_R0, &r0) < 0)
1143 # elif defined (SPARC) || defined (SPARC64)
1144 /* Everything we need is in the current register set. */
1145 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1148 /* If we are entering, then disassemble the syscall trap. */
1149 if (!(tcp->flags & TCB_INSYSCALL)) {
1150 /* Retrieve the syscall trap instruction. */
1152 # if defined(SPARC64)
1153 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1156 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1161 /* Disassemble the trap to see what personality to use. */
1164 /* Linux/SPARC syscall trap. */
1168 /* Linux/SPARC64 syscall trap. */
1172 /* SunOS syscall trap. (pers 1) */
1173 fprintf(stderr, "syscall: SunOS no support\n");
1176 /* Solaris 2.x syscall trap. (per 2) */
1180 /* NetBSD/FreeBSD syscall trap. */
1181 fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n");
1184 /* Solaris 2.x gettimeofday */
1188 /* Unknown syscall trap. */
1189 if (tcp->flags & TCB_WAITEXECVE) {
1190 tcp->flags &= ~TCB_WAITEXECVE;
1193 # if defined (SPARC64)
1194 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1196 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1201 /* Extract the system call number from the registers. */
1202 if (trap == 0x91d02027)
1205 scno = regs.u_regs[U_REG_G1];
1207 scno = regs.u_regs[U_REG_O0];
1208 memmove(®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1211 # elif defined(HPPA)
1212 if (upeek(tcp, PT_GR20, &scno) < 0)
1214 if (!(tcp->flags & TCB_INSYSCALL)) {
1215 /* Check if we return from execve. */
1216 if ((tcp->flags & TCB_WAITEXECVE)) {
1217 tcp->flags &= ~TCB_WAITEXECVE;
1223 * In the new syscall ABI, the system call number is in R3.
1225 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1229 /* Odd as it may seem, a glibc bug has been known to cause
1230 glibc to issue bogus negative syscall numbers. So for
1231 our purposes, make strace print what it *should* have been */
1232 long correct_scno = (scno & 0xff);
1235 "Detected glibc bug: bogus system call"
1236 " number = %ld, correcting to %ld\n",
1239 scno = correct_scno;
1242 if (!(tcp->flags & TCB_INSYSCALL)) {
1243 /* Check if we return from execve. */
1244 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1245 tcp->flags &= ~TCB_WAITEXECVE;
1249 # elif defined(SH64)
1250 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1254 if (!(tcp->flags & TCB_INSYSCALL)) {
1255 /* Check if we return from execve. */
1256 if (tcp->flags & TCB_WAITEXECVE) {
1257 tcp->flags &= ~TCB_WAITEXECVE;
1261 # elif defined(CRISV10) || defined(CRISV32)
1262 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1264 # elif defined(TILE)
1265 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1268 if (!(tcp->flags & TCB_INSYSCALL)) {
1269 /* Check if we return from execve. */
1270 if (tcp->flags & TCB_WAITEXECVE) {
1271 tcp->flags &= ~TCB_WAITEXECVE;
1275 # elif defined(MICROBLAZE)
1276 if (upeek(tcp, 0, &scno) < 0)
1282 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1285 /* new syscall ABI returns result in R0 */
1286 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1289 /* ABI defines result returned in r9 */
1290 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1295 # ifdef HAVE_PR_SYSCALL
1296 scno = tcp->status.PR_SYSCALL;
1299 scno = tcp->status.PR_WHAT;
1301 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1305 switch (regs.r_eax) {
1308 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1314 # endif /* FREEBSD */
1315 # endif /* !HAVE_PR_SYSCALL */
1316 #endif /* USE_PROCFS */
1318 if (!(tcp->flags & TCB_INSYSCALL))
1325 known_scno(struct tcb *tcp)
1327 long scno = tcp->scno;
1328 #if SUPPORTED_PERSONALITIES > 1
1329 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1330 scno = sysent[scno].native_scno;
1333 scno += NR_SYSCALL_BASE;
1337 /* Called in trace_syscall() at each syscall entry and exit.
1339 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1340 * 1: ok, continue in trace_syscall().
1341 * other: error, trace_syscall() should print error indicator
1342 * ("????" etc) and bail out.
1345 syscall_fixup(struct tcb *tcp)
1348 int scno = known_scno(tcp);
1350 if (!(tcp->flags & TCB_INSYSCALL)) {
1351 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1355 || scno == SYS_vfork
1356 #endif /* SYS_vfork */
1358 || scno == SYS_fork1
1359 #endif /* SYS_fork1 */
1361 || scno == SYS_forkall
1362 #endif /* SYS_forkall */
1364 || scno == SYS_rfork1
1365 #endif /* SYS_fork1 */
1367 || scno == SYS_rforkall
1368 #endif /* SYS_rforkall */
1370 /* We are returning in the child, fake it. */
1371 tcp->status.PR_WHY = PR_SYSENTRY;
1373 tcp->status.PR_WHY = PR_SYSEXIT;
1376 fprintf(stderr, "syscall: missing entry\n");
1377 tcp->flags |= TCB_INSYSCALL;
1382 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1383 fprintf(stderr, "syscall: missing exit\n");
1384 tcp->flags &= ~TCB_INSYSCALL;
1387 #endif /* USE_PROCFS */
1389 if (!(tcp->flags & TCB_INSYSCALL)) {
1391 fprintf(stderr, "syscall: missing entry\n");
1392 tcp->flags |= TCB_INSYSCALL;
1399 * This happens when a signal handler
1400 * for a signal which interrupted a
1401 * a system call makes another system call.
1403 fprintf(stderr, "syscall: missing exit\n");
1405 tcp->flags &= ~TCB_INSYSCALL;
1411 if (upeek(tcp, 4*EAX, &eax) < 0)
1413 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1415 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1418 #elif defined (X86_64)
1419 if (upeek(tcp, 8*RAX, &rax) < 0)
1421 if (current_personality == 1)
1422 rax = (long int)(int)rax; /* sign extend from 32 bits */
1423 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1425 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1428 #elif defined (S390) || defined (S390X)
1429 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1431 if (syscall_mode != -ENOSYS)
1432 syscall_mode = tcp->scno;
1433 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1435 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1438 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1439 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1440 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1442 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1443 * flag set for the post-execve SIGTRAP to see and reset.
1447 #elif defined (POWERPC)
1448 # define SO_MASK 0x10000000
1449 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1451 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1453 if (flags & SO_MASK)
1455 #elif defined (M68K)
1456 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1458 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1460 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1468 if (upeek(tcp, PT_R0, &r0) < 0)
1470 #elif defined (HPPA)
1471 if (upeek(tcp, PT_GR28, &r28) < 0)
1474 if (upeek(tcp, PT_R10, &r10) < 0)
1476 if (upeek(tcp, PT_R8, &r8) < 0)
1478 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1480 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1483 #elif defined(CRISV10) || defined(CRISV32)
1484 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1486 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1488 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1491 #elif defined(MICROBLAZE)
1492 if (upeek(tcp, 3 * 4, &r3) < 0)
1494 if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1496 fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
1506 * Check the syscall return value register value for whether it is
1507 * a negated errno code indicating an error, or a success return value.
1510 is_negated_errno(unsigned long int val)
1512 unsigned long int max = -(long int) nerrnos;
1513 if (personality_wordsize[current_personality] < sizeof(val)) {
1514 val = (unsigned int) val;
1515 max = (unsigned int) max;
1522 get_error(struct tcb *tcp)
1526 int check_errno = 1;
1527 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
1528 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) {
1531 # if defined(S390) || defined(S390X)
1532 if (check_errno && is_negated_errno(gpr2)) {
1540 # elif defined(I386)
1541 if (check_errno && is_negated_errno(eax)) {
1549 # elif defined(X86_64)
1550 if (check_errno && is_negated_errno(rax)) {
1558 # elif defined(IA64)
1563 if (check_errno && is_negated_errno(err)) {
1572 if (check_errno && r10) {
1580 # elif defined(MIPS)
1581 if (check_errno && a3) {
1588 # elif defined(POWERPC)
1589 if (check_errno && is_negated_errno(result)) {
1594 tcp->u_rval = result;
1597 # elif defined(M68K)
1598 if (check_errno && is_negated_errno(d0)) {
1607 if (check_errno && is_negated_errno(regs.ARM_r0)) {
1609 u_error = -regs.ARM_r0;
1612 tcp->u_rval = regs.ARM_r0;
1615 # elif defined(AVR32)
1616 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1618 u_error = -regs.r12;
1621 tcp->u_rval = regs.r12;
1624 # elif defined(BFIN)
1625 if (check_errno && is_negated_errno(r0)) {
1632 # elif defined(ALPHA)
1633 if (check_errno && a3) {
1641 # elif defined(SPARC)
1642 if (check_errno && regs.psr & PSR_C) {
1644 u_error = regs.u_regs[U_REG_O0];
1647 tcp->u_rval = regs.u_regs[U_REG_O0];
1650 # elif defined(SPARC64)
1651 if (check_errno && regs.tstate & 0x1100000000UL) {
1653 u_error = regs.u_regs[U_REG_O0];
1656 tcp->u_rval = regs.u_regs[U_REG_O0];
1659 # elif defined(HPPA)
1660 if (check_errno && is_negated_errno(r28)) {
1669 /* interpret R0 as return value or error number */
1670 if (check_errno && is_negated_errno(r0)) {
1678 # elif defined(SH64)
1679 /* interpret result as return value or error number */
1680 if (check_errno && is_negated_errno(r9)) {
1688 # elif defined(CRISV10) || defined(CRISV32)
1689 if (check_errno && r10 && (unsigned) -r10 < nerrnos) {
1697 # elif defined(TILE)
1699 /* interpret result as return value or error number */
1700 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1702 if (check_errno && rval < 0 && rval > -nerrnos) {
1710 # elif defined(MICROBLAZE)
1711 /* interpret result as return value or error number */
1712 if (check_errno && is_negated_errno(r3)) {
1723 /* get error code from user struct */
1724 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1726 u_error >>= 24; /* u_error is a char */
1728 /* get system call return value */
1729 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1734 /* Judicious guessing goes a long way. */
1735 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1737 u_error = tcp->status.pr_reg[R_O0];
1740 tcp->u_rval = tcp->status.pr_reg[R_O0];
1745 /* Wanna know how to kill an hour single-stepping? */
1746 if (tcp->status.PR_REG[EFL] & 0x1) {
1748 u_error = tcp->status.PR_REG[EAX];
1751 tcp->u_rval = tcp->status.PR_REG[EAX];
1752 # ifdef HAVE_LONG_LONG
1754 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1755 tcp->status.PR_REG[EAX];
1761 /* Wanna know how to kill an hour single-stepping? */
1762 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1764 u_error = tcp->status.PR_REG[RAX];
1767 tcp->u_rval = tcp->status.PR_REG[RAX];
1770 # endif /* X86_64 */
1772 if (tcp->status.pr_reg[CTX_A3]) {
1774 u_error = tcp->status.pr_reg[CTX_V0];
1777 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1783 if (regs.r_eflags & PSL_C) {
1785 u_error = regs.r_eax;
1787 tcp->u_rval = regs.r_eax;
1789 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1792 #endif /* FREEBSD */
1793 tcp->u_error = u_error;
1798 force_result(struct tcb *tcp, int error, long rval)
1801 # if defined(S390) || defined(S390X)
1802 gpr2 = error ? -error : rval;
1803 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1805 # elif defined(I386)
1806 eax = error ? -error : rval;
1807 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1809 # elif defined(X86_64)
1810 rax = error ? -error : rval;
1811 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1813 # elif defined(IA64)
1815 r8 = error ? -error : rval;
1816 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1828 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1829 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1832 # elif defined(BFIN)
1833 r0 = error ? -error : rval;
1834 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1836 # elif defined(MIPS)
1845 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1846 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1847 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1849 # elif defined(POWERPC)
1850 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1860 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1861 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1863 # elif defined(M68K)
1864 d0 = error ? -error : rval;
1865 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1868 regs.ARM_r0 = error ? -error : rval;
1869 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1871 # elif defined(AVR32)
1872 regs.r12 = error ? -error : rval;
1873 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1875 # elif defined(ALPHA)
1884 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1885 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1887 # elif defined(SPARC)
1888 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1892 regs.u_regs[U_REG_O0] = error;
1896 regs.u_regs[U_REG_O0] = rval;
1898 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1900 # elif defined(SPARC64)
1901 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1904 regs.tstate |= 0x1100000000UL;
1905 regs.u_regs[U_REG_O0] = error;
1908 regs.tstate &= ~0x1100000000UL;
1909 regs.u_regs[U_REG_O0] = rval;
1911 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1913 # elif defined(HPPA)
1914 r28 = error ? -error : rval;
1915 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1918 r0 = error ? -error : rval;
1919 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1921 # elif defined(SH64)
1922 r9 = error ? -error : rval;
1923 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1929 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1931 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1941 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1946 regs.r_eflags |= PSL_C;
1950 regs.r_eflags &= ~PSL_C;
1953 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1957 #endif /* FREEBSD */
1959 /* All branches reach here on success (only). */
1960 tcp->u_error = error;
1966 syscall_enter(struct tcb *tcp)
1969 #if defined(S390) || defined(S390X)
1972 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1973 tcp->u_nargs = sysent[tcp->scno].nargs;
1975 tcp->u_nargs = MAX_ARGS;
1976 for (i = 0; i < tcp->u_nargs; i++) {
1977 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1981 #elif defined (ALPHA)
1984 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1985 tcp->u_nargs = sysent[tcp->scno].nargs;
1987 tcp->u_nargs = MAX_ARGS;
1988 for (i = 0; i < tcp->u_nargs; i++) {
1989 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1990 * for scno somewhere above here!
1992 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1996 #elif defined (IA64)
1999 unsigned long *out0, cfm, sof, sol, i;
2001 /* be backwards compatible with kernel < 2.4.4... */
2003 # define PT_RBS_END PT_AR_BSP
2006 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
2008 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2011 sof = (cfm >> 0) & 0x7f;
2012 sol = (cfm >> 7) & 0x7f;
2013 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2015 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2016 && sysent[tcp->scno].nargs != -1)
2017 tcp->u_nargs = sysent[tcp->scno].nargs;
2019 tcp->u_nargs = MAX_ARGS;
2020 for (i = 0; i < tcp->u_nargs; ++i) {
2021 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2022 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2028 if (/* EBX = out0 */
2029 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2031 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2033 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2035 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2037 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2039 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2042 for (i = 0; i < 6; ++i)
2043 /* truncate away IVE sign-extension */
2044 tcp->u_arg[i] &= 0xffffffff;
2046 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2047 && sysent[tcp->scno].nargs != -1)
2048 tcp->u_nargs = sysent[tcp->scno].nargs;
2053 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2054 /* N32 and N64 both use up to six registers. */
2056 unsigned long long regs[38];
2059 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2060 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2062 nargs = tcp->u_nargs = MAX_ARGS;
2064 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2067 for (i = 0; i < nargs; i++) {
2068 tcp->u_arg[i] = regs[REG_A0 + i];
2069 # if defined (LINUX_MIPSN32)
2070 tcp->ext_arg[i] = regs[REG_A0 + i];
2074 #elif defined (MIPS)
2079 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2080 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2082 nargs = tcp->u_nargs = MAX_ARGS;
2084 if (upeek(tcp, REG_SP, &sp) < 0)
2086 for (i = 0; i < 4; i++) {
2087 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2090 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2091 (char *)(tcp->u_arg + 4));
2093 for (i = 0; i < nargs; i++) {
2094 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2099 #elif defined (POWERPC)
2101 # define PT_ORIG_R3 34
2105 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2106 tcp->u_nargs = sysent[tcp->scno].nargs;
2108 tcp->u_nargs = MAX_ARGS;
2109 for (i = 0; i < tcp->u_nargs; i++) {
2110 if (upeek(tcp, (i==0) ?
2111 (sizeof(unsigned long)*PT_ORIG_R3) :
2112 ((i+PT_R3)*sizeof(unsigned long)),
2113 &tcp->u_arg[i]) < 0)
2117 #elif defined (SPARC) || defined (SPARC64)
2121 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2122 tcp->u_nargs = sysent[tcp->scno].nargs;
2124 tcp->u_nargs = MAX_ARGS;
2125 for (i = 0; i < tcp->u_nargs; i++)
2126 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2128 #elif defined (HPPA)
2132 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2133 tcp->u_nargs = sysent[tcp->scno].nargs;
2135 tcp->u_nargs = MAX_ARGS;
2136 for (i = 0; i < tcp->u_nargs; i++) {
2137 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2145 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2146 tcp->u_nargs = sysent[tcp->scno].nargs;
2148 tcp->u_nargs = MAX_ARGS;
2149 for (i = 0; i < tcp->u_nargs; i++)
2150 tcp->u_arg[i] = regs.uregs[i];
2152 #elif defined(AVR32)
2153 tcp->u_nargs = sysent[tcp->scno].nargs;
2154 tcp->u_arg[0] = regs.r12;
2155 tcp->u_arg[1] = regs.r11;
2156 tcp->u_arg[2] = regs.r10;
2157 tcp->u_arg[3] = regs.r9;
2158 tcp->u_arg[4] = regs.r5;
2159 tcp->u_arg[5] = regs.r3;
2163 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2165 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2166 tcp->u_nargs = sysent[tcp->scno].nargs;
2168 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2170 for (i = 0; i < tcp->u_nargs; ++i)
2171 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2177 static int syscall_regs[] = {
2178 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2179 REG_REG0, REG_REG0+1, REG_REG0+2
2182 tcp->u_nargs = sysent[tcp->scno].nargs;
2183 for (i = 0; i < tcp->u_nargs; i++) {
2184 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2191 /* Registers used by SH5 Linux system calls for parameters */
2192 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2195 * TODO: should also check that the number of arguments encoded
2196 * in the trap number matches the number strace expects.
2199 assert(sysent[tcp->scno].nargs <
2200 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2203 tcp->u_nargs = sysent[tcp->scno].nargs;
2204 for (i = 0; i < tcp->u_nargs; i++) {
2205 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2210 #elif defined(X86_64)
2213 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2214 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2215 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2218 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2219 tcp->u_nargs = sysent[tcp->scno].nargs;
2221 tcp->u_nargs = MAX_ARGS;
2222 for (i = 0; i < tcp->u_nargs; i++) {
2223 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2227 #elif defined(MICROBLAZE)
2230 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2231 tcp->u_nargs = sysent[tcp->scno].nargs;
2234 for (i = 0; i < tcp->u_nargs; i++) {
2235 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
2239 #elif defined(CRISV10) || defined(CRISV32)
2242 static const int crisregs[] = {
2243 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2244 4*PT_R13, 4*PT_MOF, 4*PT_SRP
2247 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2248 tcp->u_nargs = sysent[tcp->scno].nargs;
2251 for (i = 0; i < tcp->u_nargs; i++) {
2252 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2259 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2260 tcp->u_nargs = sysent[tcp->scno].nargs;
2262 tcp->u_nargs = MAX_ARGS;
2263 for (i = 0; i < tcp->u_nargs; ++i) {
2264 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2268 #elif defined (M68K)
2271 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2272 tcp->u_nargs = sysent[tcp->scno].nargs;
2274 tcp->u_nargs = MAX_ARGS;
2275 for (i = 0; i < tcp->u_nargs; i++) {
2276 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
2280 #else /* Other architecture (like i386) (32bits specific) */
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 = MAX_ARGS;
2287 for (i = 0; i < tcp->u_nargs; i++) {
2288 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2297 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2298 tcp->u_nargs = sysent[tcp->scno].nargs;
2300 tcp->u_nargs = MAX_ARGS;
2301 for (i = 0; i < tcp->u_nargs; i++) {
2304 if (upeek(tcp, uoff(u_arg[0]) +
2305 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2313 * SGI is broken: even though it has pr_sysarg, it doesn't
2314 * set them on system call entry. Get a clue.
2316 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2317 tcp->u_nargs = sysent[tcp->scno].nargs;
2319 tcp->u_nargs = tcp->status.pr_nsysarg;
2320 if (tcp->u_nargs > 4) {
2321 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2322 4*sizeof(tcp->u_arg[0]));
2323 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2324 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2327 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2328 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2332 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2334 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2335 tcp->u_nargs = sysent[tcp->scno].nargs;
2337 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2338 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2339 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2340 #elif defined (HAVE_PR_SYSCALL)
2341 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2342 tcp->u_nargs = sysent[tcp->scno].nargs;
2344 tcp->u_nargs = tcp->status.pr_nsysarg;
2347 for (i = 0; i < tcp->u_nargs; i++)
2348 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2350 #elif defined (I386)
2351 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2352 tcp->u_nargs = sysent[tcp->scno].nargs;
2355 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2356 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2358 I DONT KNOW WHAT TO DO
2359 #endif /* !HAVE_PR_SYSCALL */
2362 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2363 sysent[tcp->scno].nargs > tcp->status.val)
2364 tcp->u_nargs = sysent[tcp->scno].nargs;
2366 tcp->u_nargs = tcp->status.val;
2367 if (tcp->u_nargs < 0)
2369 if (tcp->u_nargs > MAX_ARGS)
2370 tcp->u_nargs = MAX_ARGS;
2371 switch (regs.r_eax) {
2373 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2374 regs.r_esp + sizeof(int) + sizeof(quad_t));
2377 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2378 regs.r_esp + 2 * sizeof(int));
2381 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2382 regs.r_esp + sizeof(int));
2385 #endif /* FREEBSD */
2390 trace_syscall_exiting(struct tcb *tcp)
2397 /* Measure the exit time as early as possible to avoid errors. */
2399 gettimeofday(&tv, NULL);
2401 /* BTW, why we don't just memorize syscall no. on entry
2402 * in tcp->something?
2404 scno_good = res = get_scno(tcp);
2408 res = syscall_fixup(tcp);
2412 res = get_error(tcp);
2416 internal_syscall(tcp);
2418 if (res == 1 && filtered(tcp)) {
2419 tcp->flags &= ~TCB_INSYSCALL;
2423 if (tcp->flags & TCB_REPRINT) {
2428 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2429 tprintf("syscall_%lu", tcp->scno);
2431 tprintf("%s", sysent[tcp->scno].sys_name);
2432 tprintf(" resumed> ");
2436 struct timeval t = tv;
2437 int rc = count_syscall(tcp, &t);
2438 if (cflag == CFLAG_ONLY_STATS)
2440 tcp->flags &= ~TCB_INSYSCALL;
2448 tprintf("= ? <unavailable>");
2450 tcp->flags &= ~TCB_INSYSCALL;
2454 if (tcp->scno >= nsyscalls || tcp->scno < 0
2455 || (qual_flags[tcp->scno] & QUAL_RAW))
2456 sys_res = printargs(tcp);
2458 if (not_failing_only && tcp->u_error)
2459 return 0; /* ignore failed syscalls */
2460 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2463 u_error = tcp->u_error;
2466 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2467 qual_flags[tcp->scno] & QUAL_RAW) {
2469 tprintf("= -1 (errno %ld)", u_error);
2471 tprintf("= %#lx", tcp->u_rval);
2473 else if (!(sys_res & RVAL_NONE) && u_error) {
2477 tprintf("= ? ERESTARTSYS (To be restarted)");
2479 case ERESTARTNOINTR:
2480 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2482 case ERESTARTNOHAND:
2483 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2485 case ERESTART_RESTARTBLOCK:
2486 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2492 tprintf("E??? (errno %ld)", u_error);
2493 else if (u_error < nerrnos)
2494 tprintf("%s (%s)", errnoent[u_error],
2497 tprintf("ERRNO_%ld (%s)", u_error,
2501 if ((sys_res & RVAL_STR) && tcp->auxstr)
2502 tprintf(" (%s)", tcp->auxstr);
2505 if (sys_res & RVAL_NONE)
2508 switch (sys_res & RVAL_MASK) {
2510 tprintf("= %#lx", tcp->u_rval);
2513 tprintf("= %#lo", tcp->u_rval);
2516 tprintf("= %lu", tcp->u_rval);
2519 tprintf("= %ld", tcp->u_rval);
2521 #ifdef HAVE_LONG_LONG
2523 tprintf("= %#llx", tcp->u_lrval);
2526 tprintf("= %#llo", tcp->u_lrval);
2528 case RVAL_LUDECIMAL:
2529 tprintf("= %llu", tcp->u_lrval);
2532 tprintf("= %lld", tcp->u_lrval);
2537 "invalid rval format\n");
2541 if ((sys_res & RVAL_STR) && tcp->auxstr)
2542 tprintf(" (%s)", tcp->auxstr);
2545 tv_sub(&tv, &tv, &tcp->etime);
2546 tprintf(" <%ld.%06ld>",
2547 (long) tv.tv_sec, (long) tv.tv_usec);
2552 if (fflush(tcp->outf) == EOF)
2554 tcp->flags &= ~TCB_INSYSCALL;
2559 trace_syscall_entering(struct tcb *tcp)
2564 scno_good = res = get_scno(tcp);
2568 res = syscall_fixup(tcp);
2572 res = syscall_enter(tcp);
2578 tcp->flags &= ~TCB_REPRINT;
2581 tprintf("????" /* anti-trigraph gap */ "(");
2582 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2583 tprintf("syscall_%lu(", tcp->scno);
2585 tprintf("%s(", sysent[tcp->scno].sys_name);
2587 * " <unavailable>" will be added later by the code which
2588 * detects ptrace errors.
2590 tcp->flags |= TCB_INSYSCALL;
2594 switch (known_scno(tcp)) {
2595 #ifdef SYS_socket_subcall
2596 case SYS_socketcall:
2597 decode_subcall(tcp, SYS_socket_subcall,
2598 SYS_socket_nsubcalls, deref_style);
2601 #ifdef SYS_ipc_subcall
2603 decode_subcall(tcp, SYS_ipc_subcall,
2604 SYS_ipc_nsubcalls, shift_style);
2608 #ifdef SYS_pgrpsys_subcall
2610 decode_subcall(tcp, SYS_pgrpsys_subcall,
2611 SYS_pgrpsys_nsubcalls, shift_style);
2613 #endif /* SYS_pgrpsys_subcall */
2614 #ifdef SYS_sigcall_subcall
2616 decode_subcall(tcp, SYS_sigcall_subcall,
2617 SYS_sigcall_nsubcalls, mask_style);
2619 #endif /* SYS_sigcall_subcall */
2621 decode_subcall(tcp, SYS_msgsys_subcall,
2622 SYS_msgsys_nsubcalls, shift_style);
2625 decode_subcall(tcp, SYS_shmsys_subcall,
2626 SYS_shmsys_nsubcalls, shift_style);
2629 decode_subcall(tcp, SYS_semsys_subcall,
2630 SYS_semsys_nsubcalls, shift_style);
2633 decode_subcall(tcp, SYS_sysfs_subcall,
2634 SYS_sysfs_nsubcalls, shift_style);
2637 decode_subcall(tcp, SYS_spcall_subcall,
2638 SYS_spcall_nsubcalls, shift_style);
2640 #ifdef SYS_context_subcall
2642 decode_subcall(tcp, SYS_context_subcall,
2643 SYS_context_nsubcalls, shift_style);
2645 #endif /* SYS_context_subcall */
2646 #ifdef SYS_door_subcall
2648 decode_subcall(tcp, SYS_door_subcall,
2649 SYS_door_nsubcalls, door_style);
2651 #endif /* SYS_door_subcall */
2652 #ifdef SYS_kaio_subcall
2654 decode_subcall(tcp, SYS_kaio_subcall,
2655 SYS_kaio_nsubcalls, shift_style);
2663 decode_subcall(tcp, 0, 0, table_style);
2668 decode_subcall(tcp, SYS_semsys_subcall,
2669 SYS_semsys_nsubcalls, shift_style);
2672 decode_subcall(tcp, SYS_msgsys_subcall,
2673 SYS_msgsys_nsubcalls, shift_style);
2676 decode_subcall(tcp, SYS_shmsys_subcall,
2677 SYS_shmsys_nsubcalls, shift_style);
2682 internal_syscall(tcp);
2684 if ((tcp->scno >= 0 && tcp->scno < nsyscalls &&
2685 !(qual_flags[tcp->scno] & QUAL_TRACE)) ||
2686 (tracing_paths && !pathtrace_match(tcp))) {
2687 tcp->flags |= TCB_INSYSCALL | TCB_FILTERED;
2691 tcp->flags &= ~TCB_FILTERED;
2693 if (cflag == CFLAG_ONLY_STATS) {
2694 tcp->flags |= TCB_INSYSCALL;
2695 gettimeofday(&tcp->etime, NULL);
2700 tcp->flags &= ~TCB_REPRINT;
2702 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2703 tprintf("syscall_%lu(", tcp->scno);
2705 tprintf("%s(", sysent[tcp->scno].sys_name);
2706 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2707 ((qual_flags[tcp->scno] & QUAL_RAW) &&
2708 sysent[tcp->scno].sys_func != sys_exit))
2709 sys_res = printargs(tcp);
2711 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2712 if (fflush(tcp->outf) == EOF)
2714 tcp->flags |= TCB_INSYSCALL;
2715 /* Measure the entrance time as late as possible to avoid errors. */
2717 gettimeofday(&tcp->etime, NULL);
2722 trace_syscall(struct tcb *tcp)
2724 return exiting(tcp) ?
2725 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2729 printargs(struct tcb *tcp)
2731 if (entering(tcp)) {
2734 for (i = 0; i < tcp->u_nargs; i++)
2735 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2741 getrval2(struct tcb *tcp)
2746 #if defined (SPARC) || defined (SPARC64)
2747 struct pt_regs regs;
2748 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
2750 val = regs.u_regs[U_REG_O1];
2752 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2755 if (upeek(tcp, PT_R9, &val) < 0)
2761 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2767 val = tcp->status.PR_REG[R_O1];
2770 val = tcp->status.PR_REG[EDX];
2773 val = tcp->status.PR_REG[RDX];
2776 val = tcp->status.PR_REG[CTX_V1];
2782 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2790 * Apparently, indirect system calls have already be converted by ptrace(2),
2791 * so if you see "indir" this program has gone astray.
2794 sys_indir(struct tcb *tcp)
2798 if (entering(tcp)) {
2799 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2800 fprintf(stderr, "Bogus syscall: %u\n", scno);
2803 nargs = sysent[scno].nargs;
2804 tprintf("%s", sysent[scno].sys_name);
2805 for (i = 0; i < nargs; i++)
2806 tprintf(", %#lx", tcp->u_arg[i+1]);
2813 is_restart_error(struct tcb *tcp)
2818 switch (tcp->u_error) {
2820 case ERESTARTNOINTR:
2821 case ERESTARTNOHAND:
2822 case ERESTART_RESTARTBLOCK: