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>
46 #if defined (SPARC) || defined (SPARC64)
47 # define fpq kernel_fpq
49 # define fpu kernel_fpu
52 #if defined (SPARC) || defined (SPARC64)
61 #ifndef PTRACE_PEEKUSR
62 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
64 #elif defined(HAVE_LINUX_PTRACE_H)
66 # ifdef HAVE_STRUCT_IA64_FPREG
67 # define ia64_fpreg XXX_ia64_fpreg
69 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
70 # define pt_all_user_regs XXX_pt_all_user_regs
72 #include <linux/ptrace.h>
74 # undef pt_all_user_regs
77 #if defined (LINUX) && defined (SPARC64)
79 # undef PTRACE_GETREGS
80 # define PTRACE_GETREGS PTRACE_GETREGS64
81 # undef PTRACE_SETREGS
82 # define PTRACE_SETREGS PTRACE_SETREGS64
83 #endif /* LINUX && SPARC64 */
85 #if defined(LINUX) && defined(IA64)
86 # include <asm/ptrace_offsets.h>
90 #define NR_SYSCALL_BASE 0
93 #define ERESTARTSYS 512
95 #ifndef ERESTARTNOINTR
96 #define ERESTARTNOINTR 513
98 #ifndef ERESTARTNOHAND
99 #define ERESTARTNOHAND 514 /* restart if no handler.. */
102 #define ENOIOCTLCMD 515 /* No ioctl command */
104 #ifndef ERESTART_RESTARTBLOCK
105 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
113 #undef NR_SYSCALL_BASE
114 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
120 /* Define these shorthand notations to simplify the syscallent files. */
121 #define TD TRACE_DESC
122 #define TF TRACE_FILE
124 #define TN TRACE_NETWORK
125 #define TP TRACE_PROCESS
126 #define TS TRACE_SIGNAL
128 static const struct sysent sysent0[] = {
129 #include "syscallent.h"
131 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
132 int qual_flags0[MAX_QUALS];
134 #if SUPPORTED_PERSONALITIES >= 2
135 static const struct sysent sysent1[] = {
136 #include "syscallent1.h"
138 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
139 int qual_flags1[MAX_QUALS];
140 #endif /* SUPPORTED_PERSONALITIES >= 2 */
142 #if SUPPORTED_PERSONALITIES >= 3
143 static const struct sysent sysent2[] = {
144 #include "syscallent2.h"
146 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
147 int qual_flags2[MAX_QUALS];
148 #endif /* SUPPORTED_PERSONALITIES >= 3 */
150 const struct sysent *sysent;
154 /* Now undef them since short defines cause wicked namespace pollution. */
162 static const char *const errnoent0[] = {
163 #include "errnoent.h"
165 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
167 #if SUPPORTED_PERSONALITIES >= 2
168 static const char *const errnoent1[] = {
169 #include "errnoent1.h"
171 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
172 #endif /* SUPPORTED_PERSONALITIES >= 2 */
174 #if SUPPORTED_PERSONALITIES >= 3
175 static const char *const errnoent2[] = {
176 #include "errnoent2.h"
178 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
179 #endif /* SUPPORTED_PERSONALITIES >= 3 */
181 const char *const *errnoent;
184 int current_personality;
186 #ifndef PERSONALITY0_WORDSIZE
187 # define PERSONALITY0_WORDSIZE sizeof(long)
189 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
190 PERSONALITY0_WORDSIZE,
191 #if SUPPORTED_PERSONALITIES > 1
192 PERSONALITY1_WORDSIZE,
194 #if SUPPORTED_PERSONALITIES > 2
195 PERSONALITY2_WORDSIZE,
200 set_personality(int personality)
202 switch (personality) {
204 errnoent = errnoent0;
207 nsyscalls = nsyscalls0;
208 ioctlent = ioctlent0;
209 nioctlents = nioctlents0;
210 signalent = signalent0;
211 nsignals = nsignals0;
212 qual_flags = qual_flags0;
215 #if SUPPORTED_PERSONALITIES >= 2
217 errnoent = errnoent1;
220 nsyscalls = nsyscalls1;
221 ioctlent = ioctlent1;
222 nioctlents = nioctlents1;
223 signalent = signalent1;
224 nsignals = nsignals1;
225 qual_flags = qual_flags1;
227 #endif /* SUPPORTED_PERSONALITIES >= 2 */
229 #if SUPPORTED_PERSONALITIES >= 3
231 errnoent = errnoent2;
234 nsyscalls = nsyscalls2;
235 ioctlent = ioctlent2;
236 nioctlents = nioctlents2;
237 signalent = signalent2;
238 nsignals = nsignals2;
239 qual_flags = qual_flags2;
241 #endif /* SUPPORTED_PERSONALITIES >= 3 */
247 current_personality = personality;
252 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
254 static const struct qual_options {
260 { QUAL_TRACE, "trace", qual_syscall, "system call" },
261 { QUAL_TRACE, "t", qual_syscall, "system call" },
262 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
263 { QUAL_ABBREV, "a", qual_syscall, "system call" },
264 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
265 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
266 { QUAL_RAW, "raw", qual_syscall, "system call" },
267 { QUAL_RAW, "x", qual_syscall, "system call" },
268 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
269 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
270 { QUAL_SIGNAL, "s", qual_signal, "signal" },
271 { QUAL_FAULT, "fault", qual_fault, "fault" },
272 { QUAL_FAULT, "faults", qual_fault, "fault" },
273 { QUAL_FAULT, "m", qual_fault, "fault" },
274 { QUAL_READ, "read", qual_desc, "descriptor" },
275 { QUAL_READ, "reads", qual_desc, "descriptor" },
276 { QUAL_READ, "r", qual_desc, "descriptor" },
277 { QUAL_WRITE, "write", qual_desc, "descriptor" },
278 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
279 { QUAL_WRITE, "w", qual_desc, "descriptor" },
280 { 0, NULL, NULL, NULL },
284 qualify_one(n, opt, not, pers)
286 const struct qual_options *opt;
290 if (pers == 0 || pers < 0) {
292 qual_flags0[n] &= ~opt->bitflag;
294 qual_flags0[n] |= opt->bitflag;
297 #if SUPPORTED_PERSONALITIES >= 2
298 if (pers == 1 || pers < 0) {
300 qual_flags1[n] &= ~opt->bitflag;
302 qual_flags1[n] |= opt->bitflag;
304 #endif /* SUPPORTED_PERSONALITIES >= 2 */
306 #if SUPPORTED_PERSONALITIES >= 3
307 if (pers == 2 || pers < 0) {
309 qual_flags2[n] &= ~opt->bitflag;
311 qual_flags2[n] |= opt->bitflag;
313 #endif /* SUPPORTED_PERSONALITIES >= 3 */
317 qual_syscall(s, opt, not)
319 const struct qual_options *opt;
325 if (isdigit((unsigned char)*s)) {
327 if (i < 0 || i >= MAX_QUALS)
329 qualify_one(i, opt, not, -1);
332 for (i = 0; i < nsyscalls0; i++)
333 if (strcmp(s, sysent0[i].sys_name) == 0) {
334 qualify_one(i, opt, not, 0);
338 #if SUPPORTED_PERSONALITIES >= 2
339 for (i = 0; i < nsyscalls1; i++)
340 if (strcmp(s, sysent1[i].sys_name) == 0) {
341 qualify_one(i, opt, not, 1);
344 #endif /* SUPPORTED_PERSONALITIES >= 2 */
346 #if SUPPORTED_PERSONALITIES >= 3
347 for (i = 0; i < nsyscalls2; i++)
348 if (strcmp(s, sysent2[i].sys_name) == 0) {
349 qualify_one(i, opt, not, 2);
352 #endif /* SUPPORTED_PERSONALITIES >= 3 */
358 qual_signal(s, opt, not)
360 const struct qual_options *opt;
366 if (isdigit((unsigned char)*s)) {
368 if (signo < 0 || signo >= MAX_QUALS)
370 qualify_one(signo, opt, not, -1);
373 if (strlen(s) >= sizeof buf)
377 for (i = 0; s[i]; i++)
378 s[i] = toupper((unsigned char)(s[i]));
379 if (strncmp(s, "SIG", 3) == 0)
381 for (i = 0; i <= NSIG; i++)
382 if (strcmp(s, signame(i) + 3) == 0) {
383 qualify_one(i, opt, not, -1);
390 qual_fault(s, opt, not)
392 const struct qual_options *opt;
399 qual_desc(s, opt, not)
401 const struct qual_options *opt;
404 if (isdigit((unsigned char)*s)) {
406 if (desc < 0 || desc >= MAX_QUALS)
408 qualify_one(desc, opt, not, -1);
418 if (strcmp(s, "file") == 0)
420 if (strcmp(s, "ipc") == 0)
422 if (strcmp(s, "network") == 0)
423 return TRACE_NETWORK;
424 if (strcmp(s, "process") == 0)
425 return TRACE_PROCESS;
426 if (strcmp(s, "signal") == 0)
428 if (strcmp(s, "desc") == 0)
437 const struct qual_options *opt;
442 opt = &qual_options[0];
443 for (i = 0; (p = qual_options[i].option_name); i++) {
445 if (strncmp(s, p, n) == 0 && s[n] == '=') {
446 opt = &qual_options[i];
456 if (strcmp(s, "none") == 0) {
460 if (strcmp(s, "all") == 0) {
461 for (i = 0; i < MAX_QUALS; i++) {
462 qualify_one(i, opt, not, -1);
466 for (i = 0; i < MAX_QUALS; i++) {
467 qualify_one(i, opt, !not, -1);
469 for (p = strtok(s, ","); p; p = strtok(NULL, ",")) {
470 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
471 for (i = 0; i < nsyscalls0; i++)
472 if (sysent0[i].sys_flags & n)
473 qualify_one(i, opt, not, 0);
475 #if SUPPORTED_PERSONALITIES >= 2
476 for (i = 0; i < nsyscalls1; i++)
477 if (sysent1[i].sys_flags & n)
478 qualify_one(i, opt, not, 1);
479 #endif /* SUPPORTED_PERSONALITIES >= 2 */
481 #if SUPPORTED_PERSONALITIES >= 3
482 for (i = 0; i < nsyscalls2; i++)
483 if (sysent2[i].sys_flags & n)
484 qualify_one(i, opt, not, 2);
485 #endif /* SUPPORTED_PERSONALITIES >= 3 */
489 if (opt->qualify(p, opt, not)) {
490 fprintf(stderr, "strace: invalid %s `%s'\n",
491 opt->argument_name, p);
504 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
506 switch (known_scno(tcp)) {
511 #if defined SYS_pread && SYS_pread64 != SYS_pread
516 #elif defined SYS_sub_recv
521 #elif defined SYS_sub_recvfrom
522 case SYS_sub_recvfrom:
524 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
525 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
531 #if defined SYS_pwrite && SYS_pwrite64 != SYS_pwrite
536 #elif defined SYS_sub_send
541 #elif defined SYS_sub_sendto
544 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
545 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
549 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
550 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
555 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
556 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
563 enum subcall_style { shift_style, deref_style, mask_style, door_style };
565 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
573 static const struct subcall subcalls_table[] = {
574 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
576 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
578 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
580 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
584 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
587 decode_subcall(tcp, subcall, nsubcalls, style)
591 enum subcall_style style;
593 unsigned long addr, mask;
595 int size = personality_wordsize[current_personality];
599 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
601 tcp->scno = subcall + tcp->u_arg[0];
602 if (sysent[tcp->scno].nargs != -1)
603 tcp->u_nargs = sysent[tcp->scno].nargs;
606 for (i = 0; i < tcp->u_nargs; i++)
607 tcp->u_arg[i] = tcp->u_arg[i + 1];
610 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
612 tcp->scno = subcall + tcp->u_arg[0];
613 addr = tcp->u_arg[1];
614 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
615 if (size == sizeof(int)) {
617 if (umove(tcp, addr, &arg) < 0)
621 else if (size == sizeof(long)) {
623 if (umove(tcp, addr, &arg) < 0)
631 tcp->u_nargs = sysent[tcp->scno].nargs;
634 mask = (tcp->u_arg[0] >> 8) & 0xff;
635 for (i = 0; mask; i++)
639 tcp->u_arg[0] &= 0xff;
640 tcp->scno = subcall + i;
641 if (sysent[tcp->scno].nargs != -1)
642 tcp->u_nargs = sysent[tcp->scno].nargs;
646 * Oh, yuck. The call code is the *sixth* argument.
647 * (don't you mean the *last* argument? - JH)
649 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
651 tcp->scno = subcall + tcp->u_arg[5];
652 if (sysent[tcp->scno].nargs != -1)
653 tcp->u_nargs = sysent[tcp->scno].nargs;
659 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
660 if (subcalls_table[i].call == tcp->scno) break;
661 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
662 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
663 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
664 for (i = 0; i < tcp->u_nargs; i++)
665 tcp->u_arg[i] = tcp->u_arg[i + 1];
673 struct tcb *tcp_last = NULL;
676 internal_syscall(struct tcb *tcp)
679 * We must always trace a few critical system calls in order to
680 * correctly support following forks in the presence of tracing
685 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
688 func = sysent[tcp->scno].sys_func;
690 if (sys_exit == func)
691 return internal_exit(tcp);
693 if ( sys_fork == func
694 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
701 return internal_fork(tcp);
703 #if defined(LINUX) && (defined SYS_clone || defined SYS_clone2)
704 if (sys_clone == func)
705 return internal_clone(tcp);
708 if ( sys_execve == func
709 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
713 || sys_rexecve == func
716 return internal_exec(tcp);
718 if ( sys_waitpid == func
720 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
724 || sys_osf_wait4 == func
727 return internal_wait(tcp, 2);
729 #if defined(LINUX) || defined(SVR4)
730 if (sys_waitid == func)
731 return internal_wait(tcp, 3);
744 #elif defined (POWERPC)
745 static long result,flags;
751 static struct pt_regs regs;
752 #elif defined (ALPHA)
755 #elif defined (SPARC) || defined (SPARC64)
756 static struct regs regs;
757 static unsigned long trap;
758 #elif defined(LINUX_MIPSN32)
764 #elif defined(S390) || defined(S390X)
767 static long syscall_mode;
774 #elif defined(X86_64)
792 #if defined(S390) || defined(S390X)
793 if (tcp->flags & TCB_WAITEXECVE) {
795 * When the execve system call completes successfully, the
796 * new process still has -ENOSYS (old style) or __NR_execve
797 * (new style) in gpr2. We cannot recover the scno again
798 * by disassembly, because the image that executed the
799 * syscall is gone now. Fortunately, we don't want it. We
800 * leave the flag set so that syscall_fixup can fake the
803 if (tcp->flags & TCB_INSYSCALL)
806 * This is the SIGTRAP after execve. We cannot try to read
807 * the system call here either.
809 tcp->flags &= ~TCB_WAITEXECVE;
813 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
816 if (syscall_mode != -ENOSYS) {
818 * Since kernel version 2.5.44 the scno gets passed in gpr2.
823 * Old style of "passing" the scno via the SVC instruction.
826 long opcode, offset_reg, tmp;
828 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
829 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
830 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
831 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
833 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
836 opcode = ptrace(PTRACE_PEEKTEXT, pid, (char *)(pc-sizeof(long)), 0);
838 perror("peektext(pc-oneword)");
843 * We have to check if the SVC got executed directly or via an
844 * EXECUTE instruction. In case of EXECUTE it is necessary to do
845 * instruction decoding to derive the system call number.
846 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
847 * so that this doesn't work if a SVC opcode is part of an EXECUTE
848 * opcode. Since there is no way to find out the opcode size this
849 * is the best we can do...
852 if ((opcode & 0xff00) == 0x0a00) {
854 scno = opcode & 0xff;
857 /* SVC got executed by EXECUTE instruction */
860 * Do instruction decoding of EXECUTE. If you really want to
861 * understand this, read the Principles of Operations.
863 svc_addr = (void *) (opcode & 0xfff);
866 offset_reg = (opcode & 0x000f0000) >> 16;
867 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
872 offset_reg = (opcode & 0x0000f000) >> 12;
873 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
877 scno = ptrace(PTRACE_PEEKTEXT, pid, svc_addr, 0);
886 offset_reg = (opcode & 0x00f00000) >> 20;
887 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
890 scno = (scno | tmp) & 0xff;
893 #elif defined (POWERPC)
894 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
896 if (!(tcp->flags & TCB_INSYSCALL)) {
897 /* Check if we return from execve. */
898 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
899 tcp->flags &= ~TCB_WAITEXECVE;
904 if (upeek(tcp, PT_ORIG_P0, &scno))
906 /* Check if we return from execve. */
907 if (tcp->flags & TCB_WAITEXECVE && tcp->flags & TCB_INSYSCALL)
908 tcp->flags &= ~(TCB_INSYSCALL | TCB_WAITEXECVE);
910 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
912 #elif defined (X86_64)
913 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
916 if (!(tcp->flags & TCB_INSYSCALL)) {
917 static int currpers = -1;
920 /* Check CS register value. On x86-64 linux it is:
921 * 0x33 for long mode (64 bit)
922 * 0x23 for compatibility mode (32 bit)
923 * It takes only one ptrace and thus doesn't need
926 if (upeek(tcp, 8*CS, &val) < 0)
929 case 0x23: currpers = 1; break;
930 case 0x33: currpers = 0; break;
932 fprintf(stderr, "Unknown value CS=0x%02X while "
933 "detecting personality of process "
934 "PID=%d\n", (int)val, pid);
935 currpers = current_personality;
939 /* This version analyzes the opcode of a syscall instruction.
940 * (int 0x80 on i386 vs. syscall on x86-64)
941 * It works, but is too complicated.
943 unsigned long val, rip, i;
945 if (upeek(tcp, 8*RIP, &rip) < 0)
946 perror("upeek(RIP)");
948 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
952 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
954 printf("ptrace_peektext failed: %s\n",
956 switch (call & 0xffff) {
957 /* x86-64: syscall = 0x0f 0x05 */
958 case 0x050f: currpers = 0; break;
959 /* i386: int 0x80 = 0xcd 0x80 */
960 case 0x80cd: currpers = 1; break;
962 currpers = current_personality;
964 "Unknown syscall opcode (0x%04X) while "
965 "detecting personality of process "
966 "PID=%d\n", (int)call, pid);
970 if (currpers != current_personality) {
971 static const char *const names[] = {"64 bit", "32 bit"};
972 set_personality(currpers);
973 printf("[ Process PID=%d runs in %s mode. ]\n",
974 pid, names[current_personality]);
978 # define IA64_PSR_IS ((long)1 << 34)
979 if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
980 ia32 = (psr & IA64_PSR_IS) != 0;
981 if (!(tcp->flags & TCB_INSYSCALL)) {
983 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
986 if (upeek (tcp, PT_R15, &scno) < 0)
989 /* Check if we return from execve. */
990 if (tcp->flags & TCB_WAITEXECVE) {
991 tcp->flags &= ~TCB_WAITEXECVE;
995 /* syscall in progress */
996 if (upeek (tcp, PT_R8, &r8) < 0)
998 if (upeek (tcp, PT_R10, &r10) < 0)
1003 * Read complete register set in one go.
1005 if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)®s) == -1)
1009 * We only need to grab the syscall number on syscall entry.
1011 if (regs.ARM_ip == 0) {
1012 if (!(tcp->flags & TCB_INSYSCALL)) {
1013 /* Check if we return from execve. */
1014 if (tcp->flags & TCB_WAITEXECVE) {
1015 tcp->flags &= ~TCB_WAITEXECVE;
1021 * Note: we only deal with only 32-bit CPUs here.
1023 if (regs.ARM_cpsr & 0x20) {
1025 * Get the Thumb-mode system call number
1030 * Get the ARM-mode system call number
1033 scno = ptrace(PTRACE_PEEKTEXT, pid, (void *)(regs.ARM_pc - 4), NULL);
1037 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1038 tcp->flags &= ~TCB_WAITEXECVE;
1042 /* Handle the EABI syscall convention. We do not
1043 bother converting structures between the two
1044 ABIs, but basic functionality should work even
1045 if strace and the traced program have different
1047 if (scno == 0xef000000) {
1050 if ((scno & 0x0ff00000) != 0x0f900000) {
1051 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1057 * Fixup the syscall number
1062 if (scno & 0x0f0000) {
1064 * Handle ARM specific syscall
1071 if (tcp->flags & TCB_INSYSCALL) {
1072 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1073 tcp->flags &= ~TCB_INSYSCALL;
1076 if (!(tcp->flags & TCB_INSYSCALL)) {
1077 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1078 tcp->flags |= TCB_INSYSCALL;
1081 #elif defined (M68K)
1082 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1084 #elif defined (LINUX_MIPSN32)
1085 unsigned long long regs[38];
1087 if (ptrace (PTRACE_GETREGS, pid, NULL, (long) ®s) < 0)
1092 if(!(tcp->flags & TCB_INSYSCALL)) {
1095 /* Check if we return from execve. */
1096 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1097 tcp->flags &= ~TCB_WAITEXECVE;
1101 if (scno < 0 || scno > nsyscalls) {
1102 if(a3 == 0 || a3 == -1) {
1104 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1109 #elif defined (MIPS)
1110 if (upeek(tcp, REG_A3, &a3) < 0)
1112 if(!(tcp->flags & TCB_INSYSCALL)) {
1113 if (upeek(tcp, REG_V0, &scno) < 0)
1116 /* Check if we return from execve. */
1117 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1118 tcp->flags &= ~TCB_WAITEXECVE;
1122 if (scno < 0 || scno > nsyscalls) {
1123 if(a3 == 0 || a3 == -1) {
1125 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1130 if (upeek(tcp, REG_V0, &r2) < 0)
1133 #elif defined (ALPHA)
1134 if (upeek(tcp, REG_A3, &a3) < 0)
1137 if (!(tcp->flags & TCB_INSYSCALL)) {
1138 if (upeek(tcp, REG_R0, &scno) < 0)
1141 /* Check if we return from execve. */
1142 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1143 tcp->flags &= ~TCB_WAITEXECVE;
1148 * Do some sanity checks to figure out if it's
1149 * really a syscall entry
1151 if (scno < 0 || scno > nsyscalls) {
1152 if (a3 == 0 || a3 == -1) {
1154 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1160 if (upeek(tcp, REG_R0, &r0) < 0)
1163 #elif defined (SPARC) || defined (SPARC64)
1164 /* Everything we need is in the current register set. */
1165 if (ptrace(PTRACE_GETREGS,pid,(char *)®s,0) < 0)
1168 /* If we are entering, then disassemble the syscall trap. */
1169 if (!(tcp->flags & TCB_INSYSCALL)) {
1170 /* Retrieve the syscall trap instruction. */
1172 trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
1173 #if defined(SPARC64)
1179 /* Disassemble the trap to see what personality to use. */
1182 /* Linux/SPARC syscall trap. */
1186 /* Linux/SPARC64 syscall trap. */
1190 /* SunOS syscall trap. (pers 1) */
1191 fprintf(stderr,"syscall: SunOS no support\n");
1194 /* Solaris 2.x syscall trap. (per 2) */
1198 /* NetBSD/FreeBSD syscall trap. */
1199 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1202 /* Solaris 2.x gettimeofday */
1206 /* Unknown syscall trap. */
1207 if(tcp->flags & TCB_WAITEXECVE) {
1208 tcp->flags &= ~TCB_WAITEXECVE;
1211 #if defined (SPARC64)
1212 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.r_tpc);
1214 fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
1219 /* Extract the system call number from the registers. */
1220 if (trap == 0x91d02027)
1226 memmove (®s.r_o0, ®s.r_o1, 7*sizeof(regs.r_o0));
1230 if (upeek(tcp, PT_GR20, &scno) < 0)
1232 if (!(tcp->flags & TCB_INSYSCALL)) {
1233 /* Check if we return from execve. */
1234 if ((tcp->flags & TCB_WAITEXECVE)) {
1235 tcp->flags &= ~TCB_WAITEXECVE;
1241 * In the new syscall ABI, the system call number is in R3.
1243 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1247 /* Odd as it may seem, a glibc bug has been known to cause
1248 glibc to issue bogus negative syscall numbers. So for
1249 our purposes, make strace print what it *should* have been */
1250 long correct_scno = (scno & 0xff);
1253 "Detected glibc bug: bogus system call"
1254 " number = %ld, correcting to %ld\n",
1257 scno = correct_scno;
1260 if (!(tcp->flags & TCB_INSYSCALL)) {
1261 /* Check if we return from execve. */
1262 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1263 tcp->flags &= ~TCB_WAITEXECVE;
1268 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1272 if (!(tcp->flags & TCB_INSYSCALL)) {
1273 /* Check if we return from execve. */
1274 if (tcp->flags & TCB_WAITEXECVE) {
1275 tcp->flags &= ~TCB_WAITEXECVE;
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;
1297 #else /* !HAVE_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 */
1317 if (!(tcp->flags & TCB_INSYSCALL))
1327 long scno = tcp->scno;
1328 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1329 scno = sysent[scno].native_scno;
1331 scno += NR_SYSCALL_BASE;
1335 /* Called in trace_syscall() at each syscall entry and exit.
1337 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1338 * 1: ok, continue in trace_syscall().
1339 * other: error, trace_syscall() should print error indicator
1340 * ("????" etc) and bail out.
1347 int scno = known_scno(tcp);
1349 if (!(tcp->flags & TCB_INSYSCALL)) {
1350 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1354 || scno == SYS_vfork
1355 #endif /* SYS_vfork */
1357 || scno == SYS_fork1
1358 #endif /* SYS_fork1 */
1360 || scno == SYS_forkall
1361 #endif /* SYS_forkall */
1363 || scno == SYS_rfork1
1364 #endif /* SYS_fork1 */
1366 || scno == SYS_rforkall
1367 #endif /* SYS_rforkall */
1369 /* We are returning in the child, fake it. */
1370 tcp->status.PR_WHY = PR_SYSENTRY;
1372 tcp->status.PR_WHY = PR_SYSEXIT;
1375 fprintf(stderr, "syscall: missing entry\n");
1376 tcp->flags |= TCB_INSYSCALL;
1381 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1382 fprintf(stderr, "syscall: missing exit\n");
1383 tcp->flags &= ~TCB_INSYSCALL;
1386 #endif /* USE_PROCFS */
1388 if (!(tcp->flags & TCB_INSYSCALL)) {
1390 fprintf(stderr, "syscall: missing entry\n");
1391 tcp->flags |= TCB_INSYSCALL;
1398 * This happens when a signal handler
1399 * for a signal which interrupted a
1400 * a system call makes another system call.
1402 fprintf(stderr, "syscall: missing exit\n");
1404 tcp->flags &= ~TCB_INSYSCALL;
1410 if (upeek(tcp, 4*EAX, &eax) < 0)
1412 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1414 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1417 #elif defined (X86_64)
1418 if (upeek(tcp, 8*RAX, &rax) < 0)
1420 if (current_personality == 1)
1421 rax = (long int)(int)rax; /* sign extend from 32 bits */
1422 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1424 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1427 #elif defined (S390) || defined (S390X)
1428 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1430 if (syscall_mode != -ENOSYS)
1431 syscall_mode = tcp->scno;
1432 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1434 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1437 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1438 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1439 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1441 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1442 * flag set for the post-execve SIGTRAP to see and reset.
1446 #elif defined (POWERPC)
1447 # define SO_MASK 0x10000000
1448 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1450 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1452 if (flags & SO_MASK)
1454 #elif defined (M68K)
1455 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1457 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1459 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1467 if (upeek(tcp, PT_R0, &r0) < 0)
1469 #elif defined (HPPA)
1470 if (upeek(tcp, PT_GR28, &r28) < 0)
1473 if (upeek(tcp, PT_R10, &r10) < 0)
1475 if (upeek(tcp, PT_R8, &r8) < 0)
1477 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1479 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1489 * Check the syscall return value register value for whether it is
1490 * a negated errno code indicating an error, or a success return value.
1493 is_negated_errno(unsigned long int val)
1495 unsigned long int max = -(long int) nerrnos;
1496 if (personality_wordsize[current_personality] < sizeof(val)) {
1497 val = (unsigned int) val;
1498 max = (unsigned int) max;
1510 #if defined(S390) || defined(S390X)
1511 if (is_negated_errno(gpr2)) {
1519 #else /* !S390 && !S390X */
1521 if (is_negated_errno(eax)) {
1531 if (is_negated_errno(rax)) {
1545 if (is_negated_errno(err)) {
1573 if (is_negated_errno(result)) {
1578 tcp->u_rval = result;
1581 #else /* !POWERPC */
1583 if (is_negated_errno(d0)) {
1593 if (is_negated_errno(regs.ARM_r0)) {
1595 u_error = -regs.ARM_r0;
1598 tcp->u_rval = regs.ARM_r0;
1603 if (is_negated_errno(r0)) {
1622 if (regs.r_psr & PSR_C) {
1624 u_error = regs.r_o0;
1627 tcp->u_rval = regs.r_o0;
1632 if (regs.r_tstate & 0x1100000000UL) {
1634 u_error = regs.r_o0;
1637 tcp->u_rval = regs.r_o0;
1640 #else /* !SPARC64 */
1642 if (is_negated_errno(r28)) {
1652 /* interpret R0 as return value or error number */
1653 if (is_negated_errno(r0)) {
1663 /* interpret result as return value or error number */
1664 if (is_negated_errno(r9)) {
1676 #endif /* SPARC64 */
1681 #endif /* POWERPC */
1686 #endif /* S390 || S390X */
1689 /* get error code from user struct */
1690 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1692 u_error >>= 24; /* u_error is a char */
1694 /* get system call return value */
1695 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1700 /* Judicious guessing goes a long way. */
1701 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1703 u_error = tcp->status.pr_reg[R_O0];
1706 tcp->u_rval = tcp->status.pr_reg[R_O0];
1711 /* Wanna know how to kill an hour single-stepping? */
1712 if (tcp->status.PR_REG[EFL] & 0x1) {
1714 u_error = tcp->status.PR_REG[EAX];
1717 tcp->u_rval = tcp->status.PR_REG[EAX];
1718 #ifdef HAVE_LONG_LONG
1720 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1721 tcp->status.PR_REG[EAX];
1727 /* Wanna know how to kill an hour single-stepping? */
1728 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1730 u_error = tcp->status.PR_REG[RAX];
1733 tcp->u_rval = tcp->status.PR_REG[RAX];
1738 if (tcp->status.pr_reg[CTX_A3]) {
1740 u_error = tcp->status.pr_reg[CTX_V0];
1743 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1749 if (regs.r_eflags & PSL_C) {
1751 u_error = regs.r_eax;
1753 tcp->u_rval = regs.r_eax;
1755 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1758 #endif /* FREEBSD */
1759 tcp->u_error = u_error;
1764 force_result(tcp, error, rval)
1770 #if defined(S390) || defined(S390X)
1771 gpr2 = error ? -error : rval;
1772 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1774 #else /* !S390 && !S390X */
1776 eax = error ? -error : rval;
1777 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1781 rax = error ? -error : rval;
1782 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1787 r8 = error ? -error : rval;
1788 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1800 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1801 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1806 r0 = error ? -error : rval;
1807 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1819 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1820 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1821 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1825 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1835 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1836 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1838 #else /* !POWERPC */
1840 d0 = error ? -error : rval;
1841 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1845 regs.ARM_r0 = error ? -error : rval;
1846 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1858 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1859 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1863 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1866 regs.r_psr |= PSR_C;
1870 regs.r_psr &= ~PSR_C;
1873 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1877 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1880 regs.r_tstate |= 0x1100000000UL;
1884 regs.r_tstate &= ~0x1100000000UL;
1887 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1889 #else /* !SPARC64 */
1891 r28 = error ? -error : rval;
1892 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1896 r0 = error ? -error : rval;
1897 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1901 r9 = error ? -error : rval;
1902 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1908 #endif /* SPARC64 */
1912 #endif /* POWERPC */
1918 #endif /* S390 || S390X */
1921 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1923 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1931 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1936 regs.r_eflags |= PSL_C;
1940 regs.r_eflags &= ~PSL_C;
1943 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1947 #endif /* FREEBSD */
1949 /* All branches reach here on success (only). */
1950 tcp->u_error = error;
1960 #if defined(S390) || defined(S390X)
1963 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1964 tcp->u_nargs = sysent[tcp->scno].nargs;
1966 tcp->u_nargs = MAX_ARGS;
1967 for (i = 0; i < tcp->u_nargs; i++) {
1968 if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1972 #elif defined (ALPHA)
1975 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1976 tcp->u_nargs = sysent[tcp->scno].nargs;
1978 tcp->u_nargs = MAX_ARGS;
1979 for (i = 0; i < tcp->u_nargs; i++) {
1980 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1981 * for scno somewhere above here!
1983 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1987 #elif defined (IA64)
1990 unsigned long *out0, cfm, sof, sol, i;
1992 /* be backwards compatible with kernel < 2.4.4... */
1994 # define PT_RBS_END PT_AR_BSP
1997 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
1999 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2002 sof = (cfm >> 0) & 0x7f;
2003 sol = (cfm >> 7) & 0x7f;
2004 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2006 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2007 && sysent[tcp->scno].nargs != -1)
2008 tcp->u_nargs = sysent[tcp->scno].nargs;
2010 tcp->u_nargs = MAX_ARGS;
2011 for (i = 0; i < tcp->u_nargs; ++i) {
2012 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2013 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2019 if (/* EBX = out0 */
2020 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2022 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2024 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2026 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2028 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2030 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2033 for (i = 0; i < 6; ++i)
2034 /* truncate away IVE sign-extension */
2035 tcp->u_arg[i] &= 0xffffffff;
2037 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2038 && sysent[tcp->scno].nargs != -1)
2039 tcp->u_nargs = sysent[tcp->scno].nargs;
2044 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2045 /* N32 and N64 both use up to six registers. */
2047 unsigned long long regs[38];
2050 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2051 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2053 nargs = tcp->u_nargs = MAX_ARGS;
2055 if (ptrace (PTRACE_GETREGS, pid, NULL, (long) ®s) < 0)
2058 for(i = 0; i < nargs; i++) {
2059 tcp->u_arg[i] = regs[REG_A0 + i];
2060 # if defined (LINUX_MIPSN32)
2061 tcp->ext_arg[i] = regs[REG_A0 + i];
2065 #elif defined (MIPS)
2070 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2071 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2073 nargs = tcp->u_nargs = MAX_ARGS;
2075 if(upeek(tcp, REG_SP, &sp) < 0)
2077 for(i = 0; i < 4; i++) {
2078 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2081 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2082 (char *)(tcp->u_arg + 4));
2084 for(i = 0; i < nargs; i++) {
2085 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2090 #elif defined (POWERPC)
2092 #define PT_ORIG_R3 34
2096 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2097 tcp->u_nargs = sysent[tcp->scno].nargs;
2099 tcp->u_nargs = MAX_ARGS;
2100 for (i = 0; i < tcp->u_nargs; i++) {
2101 if (upeek(tcp, (i==0) ?
2102 (sizeof(unsigned long)*PT_ORIG_R3) :
2103 ((i+PT_R3)*sizeof(unsigned long)),
2104 &tcp->u_arg[i]) < 0)
2108 #elif defined (SPARC) || defined (SPARC64)
2112 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2113 tcp->u_nargs = sysent[tcp->scno].nargs;
2115 tcp->u_nargs = MAX_ARGS;
2116 for (i = 0; i < tcp->u_nargs; i++)
2117 tcp->u_arg[i] = *((®s.r_o0) + i);
2119 #elif defined (HPPA)
2123 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2124 tcp->u_nargs = sysent[tcp->scno].nargs;
2126 tcp->u_nargs = MAX_ARGS;
2127 for (i = 0; i < tcp->u_nargs; i++) {
2128 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2136 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2137 tcp->u_nargs = sysent[tcp->scno].nargs;
2139 tcp->u_nargs = MAX_ARGS;
2140 for (i = 0; i < tcp->u_nargs; i++)
2141 tcp->u_arg[i] = regs.uregs[i];
2146 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2148 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2149 tcp->u_nargs = sysent[tcp->scno].nargs;
2151 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2153 for (i = 0; i < tcp->u_nargs; ++i)
2154 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2160 static int syscall_regs[] = {
2161 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2162 REG_REG0, REG_REG0+1, REG_REG0+2
2165 tcp->u_nargs = sysent[tcp->scno].nargs;
2166 for (i = 0; i < tcp->u_nargs; i++) {
2167 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2174 /* Registers used by SH5 Linux system calls for parameters */
2175 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2178 * TODO: should also check that the number of arguments encoded
2179 * in the trap number matches the number strace expects.
2182 assert(sysent[tcp->scno].nargs <
2183 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2186 tcp->u_nargs = sysent[tcp->scno].nargs;
2187 for (i = 0; i < tcp->u_nargs; i++) {
2188 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2193 #elif defined(X86_64)
2196 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2197 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2198 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2201 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2202 tcp->u_nargs = sysent[tcp->scno].nargs;
2204 tcp->u_nargs = MAX_ARGS;
2205 for (i = 0; i < tcp->u_nargs; i++) {
2206 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2210 #else /* Other architecture (like i386) (32bits specific) */
2213 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2214 tcp->u_nargs = sysent[tcp->scno].nargs;
2216 tcp->u_nargs = MAX_ARGS;
2217 for (i = 0; i < tcp->u_nargs; i++) {
2218 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2227 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2228 tcp->u_nargs = sysent[tcp->scno].nargs;
2230 tcp->u_nargs = MAX_ARGS;
2231 for (i = 0; i < tcp->u_nargs; i++) {
2234 if (upeek(tcp, uoff(u_arg[0]) +
2235 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2243 * SGI is broken: even though it has pr_sysarg, it doesn't
2244 * set them on system call entry. Get a clue.
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 = tcp->status.pr_nsysarg;
2250 if (tcp->u_nargs > 4) {
2251 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2252 4*sizeof(tcp->u_arg[0]));
2253 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2254 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2257 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2258 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2262 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2264 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2265 tcp->u_nargs = sysent[tcp->scno].nargs;
2267 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2268 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2269 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2270 #elif defined (HAVE_PR_SYSCALL)
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 = tcp->status.pr_nsysarg;
2277 for (i = 0; i < tcp->u_nargs; i++)
2278 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2280 #elif defined (I386)
2281 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2282 tcp->u_nargs = sysent[tcp->scno].nargs;
2285 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2286 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2288 I DONT KNOW WHAT TO DO
2289 #endif /* !HAVE_PR_SYSCALL */
2292 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2293 sysent[tcp->scno].nargs > tcp->status.val)
2294 tcp->u_nargs = sysent[tcp->scno].nargs;
2296 tcp->u_nargs = tcp->status.val;
2297 if (tcp->u_nargs < 0)
2299 if (tcp->u_nargs > MAX_ARGS)
2300 tcp->u_nargs = MAX_ARGS;
2301 switch(regs.r_eax) {
2303 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2304 regs.r_esp + sizeof(int) + sizeof(quad_t));
2307 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2308 regs.r_esp + 2 * sizeof(int));
2311 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2312 regs.r_esp + sizeof(int));
2315 #endif /* FREEBSD */
2320 trace_syscall(struct tcb *tcp)
2326 if (tcp->flags & TCB_INSYSCALL) {
2329 /* Measure the exit time as early as possible to avoid errors. */
2331 gettimeofday(&tv, NULL);
2333 scno_good = res = get_scno(tcp);
2337 res = syscall_fixup(tcp);
2341 res = get_error(tcp);
2345 internal_syscall(tcp);
2347 if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2348 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2349 tcp->flags &= ~TCB_INSYSCALL;
2353 if (tcp->flags & TCB_REPRINT) {
2358 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2359 tprintf("syscall_%lu", tcp->scno);
2361 tprintf("%s", sysent[tcp->scno].sys_name);
2362 tprintf(" resumed> ");
2366 return count_syscall(tcp, &tv);
2371 tcp->flags &= ~TCB_INSYSCALL;
2375 if (tcp->scno >= nsyscalls || tcp->scno < 0
2376 || (qual_flags[tcp->scno] & QUAL_RAW))
2377 sys_res = printargs(tcp);
2379 if (not_failing_only && tcp->u_error)
2380 return 0; /* ignore failed syscalls */
2381 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2383 u_error = tcp->u_error;
2386 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2387 qual_flags[tcp->scno] & QUAL_RAW) {
2389 tprintf("= -1 (errno %ld)", u_error);
2391 tprintf("= %#lx", tcp->u_rval);
2393 else if (!(sys_res & RVAL_NONE) && u_error) {
2397 tprintf("= ? ERESTARTSYS (To be restarted)");
2399 case ERESTARTNOINTR:
2400 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2402 case ERESTARTNOHAND:
2403 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2405 case ERESTART_RESTARTBLOCK:
2406 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2412 tprintf("E??? (errno %ld)", u_error);
2413 else if (u_error < nerrnos)
2414 tprintf("%s (%s)", errnoent[u_error],
2417 tprintf("ERRNO_%ld (%s)", u_error,
2421 if ((sys_res & RVAL_STR) && tcp->auxstr)
2422 tprintf(" (%s)", tcp->auxstr);
2425 if (sys_res & RVAL_NONE)
2428 switch (sys_res & RVAL_MASK) {
2430 tprintf("= %#lx", tcp->u_rval);
2433 tprintf("= %#lo", tcp->u_rval);
2436 tprintf("= %lu", tcp->u_rval);
2439 tprintf("= %ld", tcp->u_rval);
2441 #ifdef HAVE_LONG_LONG
2443 tprintf("= %#llx", tcp->u_lrval);
2446 tprintf("= %#llo", tcp->u_lrval);
2448 case RVAL_LUDECIMAL:
2449 tprintf("= %llu", tcp->u_lrval);
2452 tprintf("= %lld", tcp->u_lrval);
2457 "invalid rval format\n");
2461 if ((sys_res & RVAL_STR) && tcp->auxstr)
2462 tprintf(" (%s)", tcp->auxstr);
2465 tv_sub(&tv, &tv, &tcp->etime);
2466 tprintf(" <%ld.%06ld>",
2467 (long) tv.tv_sec, (long) tv.tv_usec);
2472 if (fflush(tcp->outf) == EOF)
2474 tcp->flags &= ~TCB_INSYSCALL;
2478 /* Entering system call */
2479 scno_good = res = get_scno(tcp);
2483 res = syscall_fixup(tcp);
2487 res = syscall_enter(tcp);
2493 tcp->flags &= ~TCB_REPRINT;
2496 tprintf("????" /* anti-trigraph gap */ "(");
2497 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2498 tprintf("syscall_%lu(", tcp->scno);
2500 tprintf("%s(", sysent[tcp->scno].sys_name);
2502 * " <unavailable>" will be added later by the code which
2503 * detects ptrace errors.
2505 tcp->flags |= TCB_INSYSCALL;
2509 switch (known_scno(tcp)) {
2510 #ifdef SYS_socket_subcall
2511 case SYS_socketcall:
2512 decode_subcall(tcp, SYS_socket_subcall,
2513 SYS_socket_nsubcalls, deref_style);
2516 #ifdef SYS_ipc_subcall
2518 decode_subcall(tcp, SYS_ipc_subcall,
2519 SYS_ipc_nsubcalls, shift_style);
2523 #ifdef SYS_pgrpsys_subcall
2525 decode_subcall(tcp, SYS_pgrpsys_subcall,
2526 SYS_pgrpsys_nsubcalls, shift_style);
2528 #endif /* SYS_pgrpsys_subcall */
2529 #ifdef SYS_sigcall_subcall
2531 decode_subcall(tcp, SYS_sigcall_subcall,
2532 SYS_sigcall_nsubcalls, mask_style);
2534 #endif /* SYS_sigcall_subcall */
2536 decode_subcall(tcp, SYS_msgsys_subcall,
2537 SYS_msgsys_nsubcalls, shift_style);
2540 decode_subcall(tcp, SYS_shmsys_subcall,
2541 SYS_shmsys_nsubcalls, shift_style);
2544 decode_subcall(tcp, SYS_semsys_subcall,
2545 SYS_semsys_nsubcalls, shift_style);
2549 decode_subcall(tcp, SYS_utssys_subcall,
2550 SYS_utssys_nsubcalls, shift_style);
2554 decode_subcall(tcp, SYS_sysfs_subcall,
2555 SYS_sysfs_nsubcalls, shift_style);
2558 decode_subcall(tcp, SYS_spcall_subcall,
2559 SYS_spcall_nsubcalls, shift_style);
2561 #ifdef SYS_context_subcall
2563 decode_subcall(tcp, SYS_context_subcall,
2564 SYS_context_nsubcalls, shift_style);
2566 #endif /* SYS_context_subcall */
2567 #ifdef SYS_door_subcall
2569 decode_subcall(tcp, SYS_door_subcall,
2570 SYS_door_nsubcalls, door_style);
2572 #endif /* SYS_door_subcall */
2573 #ifdef SYS_kaio_subcall
2575 decode_subcall(tcp, SYS_kaio_subcall,
2576 SYS_kaio_nsubcalls, shift_style);
2584 decode_subcall(tcp, 0, 0, table_style);
2589 decode_subcall(tcp, SYS_semsys_subcall,
2590 SYS_semsys_nsubcalls, shift_style);
2593 decode_subcall(tcp, SYS_msgsys_subcall,
2594 SYS_msgsys_nsubcalls, shift_style);
2597 decode_subcall(tcp, SYS_shmsys_subcall,
2598 SYS_shmsys_nsubcalls, shift_style);
2603 internal_syscall(tcp);
2604 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2605 tcp->flags |= TCB_INSYSCALL;
2610 gettimeofday(&tcp->etime, NULL);
2611 tcp->flags |= TCB_INSYSCALL;
2616 tcp->flags &= ~TCB_REPRINT;
2618 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2619 tprintf("syscall_%lu(", tcp->scno);
2621 tprintf("%s(", sysent[tcp->scno].sys_name);
2622 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2623 ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2624 sys_res = printargs(tcp);
2626 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2627 if (fflush(tcp->outf) == EOF)
2629 tcp->flags |= TCB_INSYSCALL;
2630 /* Measure the entrance time as late as possible to avoid errors. */
2632 gettimeofday(&tcp->etime, NULL);
2640 if (entering(tcp)) {
2643 for (i = 0; i < tcp->u_nargs; i++)
2644 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2656 #if defined (SPARC) || defined (SPARC64)
2658 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2662 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2665 if (upeek(tcp, PT_R9, &val) < 0)
2667 #endif /* SPARC || SPARC64 */
2671 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2677 val = tcp->status.PR_REG[R_O1];
2680 val = tcp->status.PR_REG[EDX];
2683 val = tcp->status.PR_REG[RDX];
2686 val = tcp->status.PR_REG[CTX_V1];
2691 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2699 * Apparently, indirect system calls have already be converted by ptrace(2),
2700 * so if you see "indir" this program has gone astray.
2708 if (entering(tcp)) {
2709 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2710 fprintf(stderr, "Bogus syscall: %u\n", scno);
2713 nargs = sysent[scno].nargs;
2714 tprintf("%s", sysent[scno].sys_name);
2715 for (i = 0; i < nargs; i++)
2716 tprintf(", %#lx", tcp->u_arg[i+1]);
2723 is_restart_error(struct tcb *tcp)
2728 switch (tcp->u_error) {
2730 case ERESTARTNOINTR:
2731 case ERESTARTNOHAND:
2732 case ERESTART_RESTARTBLOCK: