2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/syscall.h>
43 #include <sys/param.h>
47 #ifndef PTRACE_PEEKUSR
48 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
50 #elif defined(HAVE_LINUX_PTRACE_H)
52 # ifdef HAVE_STRUCT_IA64_FPREG
53 # define ia64_fpreg XXX_ia64_fpreg
55 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
56 # define pt_all_user_regs XXX_pt_all_user_regs
58 #include <linux/ptrace.h>
60 # undef pt_all_user_regs
63 #if defined (LINUX) && defined (SPARC64)
64 # undef PTRACE_GETREGS
65 # define PTRACE_GETREGS PTRACE_GETREGS64
66 # undef PTRACE_SETREGS
67 # define PTRACE_SETREGS PTRACE_SETREGS64
68 #endif /* LINUX && SPARC64 */
70 #if defined(LINUX) && defined(IA64)
71 # include <asm/ptrace_offsets.h>
75 #define NR_SYSCALL_BASE 0
78 #define ERESTARTSYS 512
80 #ifndef ERESTARTNOINTR
81 #define ERESTARTNOINTR 513
83 #ifndef ERESTARTNOHAND
84 #define ERESTARTNOHAND 514 /* restart if no handler.. */
87 #define ENOIOCTLCMD 515 /* No ioctl command */
89 #ifndef ERESTART_RESTARTBLOCK
90 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
98 #undef NR_SYSCALL_BASE
99 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
105 /* Define these shorthand notations to simplify the syscallent files. */
106 #define TD TRACE_DESC
107 #define TF TRACE_FILE
109 #define TN TRACE_NETWORK
110 #define TP TRACE_PROCESS
111 #define TS TRACE_SIGNAL
113 static const struct sysent sysent0[] = {
114 #include "syscallent.h"
116 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
117 int qual_flags0[MAX_QUALS];
119 #if SUPPORTED_PERSONALITIES >= 2
120 static const struct sysent sysent1[] = {
121 #include "syscallent1.h"
123 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
124 int qual_flags1[MAX_QUALS];
125 #endif /* SUPPORTED_PERSONALITIES >= 2 */
127 #if SUPPORTED_PERSONALITIES >= 3
128 static const struct sysent sysent2[] = {
129 #include "syscallent2.h"
131 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
132 int qual_flags2[MAX_QUALS];
133 #endif /* SUPPORTED_PERSONALITIES >= 3 */
135 const struct sysent *sysent;
139 /* Now undef them since short defines cause wicked namespace pollution. */
147 static const char *const errnoent0[] = {
148 #include "errnoent.h"
150 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
152 #if SUPPORTED_PERSONALITIES >= 2
153 static const char *const errnoent1[] = {
154 #include "errnoent1.h"
156 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
157 #endif /* SUPPORTED_PERSONALITIES >= 2 */
159 #if SUPPORTED_PERSONALITIES >= 3
160 static const char *const errnoent2[] = {
161 #include "errnoent2.h"
163 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
164 #endif /* SUPPORTED_PERSONALITIES >= 3 */
166 const char *const *errnoent;
169 int current_personality;
171 #ifndef PERSONALITY0_WORDSIZE
172 # define PERSONALITY0_WORDSIZE sizeof(long)
174 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
175 PERSONALITY0_WORDSIZE,
176 #if SUPPORTED_PERSONALITIES > 1
177 PERSONALITY1_WORDSIZE,
179 #if SUPPORTED_PERSONALITIES > 2
180 PERSONALITY2_WORDSIZE,
185 set_personality(int personality)
187 switch (personality) {
189 errnoent = errnoent0;
192 nsyscalls = nsyscalls0;
193 ioctlent = ioctlent0;
194 nioctlents = nioctlents0;
195 signalent = signalent0;
196 nsignals = nsignals0;
197 qual_flags = qual_flags0;
200 #if SUPPORTED_PERSONALITIES >= 2
202 errnoent = errnoent1;
205 nsyscalls = nsyscalls1;
206 ioctlent = ioctlent1;
207 nioctlents = nioctlents1;
208 signalent = signalent1;
209 nsignals = nsignals1;
210 qual_flags = qual_flags1;
212 #endif /* SUPPORTED_PERSONALITIES >= 2 */
214 #if SUPPORTED_PERSONALITIES >= 3
216 errnoent = errnoent2;
219 nsyscalls = nsyscalls2;
220 ioctlent = ioctlent2;
221 nioctlents = nioctlents2;
222 signalent = signalent2;
223 nsignals = nsignals2;
224 qual_flags = qual_flags2;
226 #endif /* SUPPORTED_PERSONALITIES >= 3 */
232 current_personality = personality;
237 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
239 static const struct qual_options {
245 { QUAL_TRACE, "trace", qual_syscall, "system call" },
246 { QUAL_TRACE, "t", qual_syscall, "system call" },
247 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
248 { QUAL_ABBREV, "a", qual_syscall, "system call" },
249 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
250 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
251 { QUAL_RAW, "raw", qual_syscall, "system call" },
252 { QUAL_RAW, "x", qual_syscall, "system call" },
253 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
254 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
255 { QUAL_SIGNAL, "s", qual_signal, "signal" },
256 { QUAL_FAULT, "fault", qual_fault, "fault" },
257 { QUAL_FAULT, "faults", qual_fault, "fault" },
258 { QUAL_FAULT, "m", qual_fault, "fault" },
259 { QUAL_READ, "read", qual_desc, "descriptor" },
260 { QUAL_READ, "reads", qual_desc, "descriptor" },
261 { QUAL_READ, "r", qual_desc, "descriptor" },
262 { QUAL_WRITE, "write", qual_desc, "descriptor" },
263 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
264 { QUAL_WRITE, "w", qual_desc, "descriptor" },
265 { 0, NULL, NULL, NULL },
269 qualify_one(n, opt, not, pers)
271 const struct qual_options *opt;
275 if (pers == 0 || pers < 0) {
277 qual_flags0[n] &= ~opt->bitflag;
279 qual_flags0[n] |= opt->bitflag;
282 #if SUPPORTED_PERSONALITIES >= 2
283 if (pers == 1 || pers < 0) {
285 qual_flags1[n] &= ~opt->bitflag;
287 qual_flags1[n] |= opt->bitflag;
289 #endif /* SUPPORTED_PERSONALITIES >= 2 */
291 #if SUPPORTED_PERSONALITIES >= 3
292 if (pers == 2 || pers < 0) {
294 qual_flags2[n] &= ~opt->bitflag;
296 qual_flags2[n] |= opt->bitflag;
298 #endif /* SUPPORTED_PERSONALITIES >= 3 */
302 qual_syscall(s, opt, not)
304 const struct qual_options *opt;
310 if (isdigit((unsigned char)*s)) {
312 if (i < 0 || i >= MAX_QUALS)
314 qualify_one(i, opt, not, -1);
317 for (i = 0; i < nsyscalls0; i++)
318 if (strcmp(s, sysent0[i].sys_name) == 0) {
319 qualify_one(i, opt, not, 0);
323 #if SUPPORTED_PERSONALITIES >= 2
324 for (i = 0; i < nsyscalls1; i++)
325 if (strcmp(s, sysent1[i].sys_name) == 0) {
326 qualify_one(i, opt, not, 1);
329 #endif /* SUPPORTED_PERSONALITIES >= 2 */
331 #if SUPPORTED_PERSONALITIES >= 3
332 for (i = 0; i < nsyscalls2; i++)
333 if (strcmp(s, sysent2[i].sys_name) == 0) {
334 qualify_one(i, opt, not, 2);
337 #endif /* SUPPORTED_PERSONALITIES >= 3 */
343 qual_signal(s, opt, not)
345 const struct qual_options *opt;
351 if (isdigit((unsigned char)*s)) {
353 if (signo < 0 || signo >= MAX_QUALS)
355 qualify_one(signo, opt, not, -1);
358 if (strlen(s) >= sizeof buf)
362 for (i = 0; s[i]; i++)
363 s[i] = toupper((unsigned char)(s[i]));
364 if (strncmp(s, "SIG", 3) == 0)
366 for (i = 0; i <= NSIG; i++)
367 if (strcmp(s, signame(i) + 3) == 0) {
368 qualify_one(i, opt, not, -1);
375 qual_fault(s, opt, not)
377 const struct qual_options *opt;
384 qual_desc(s, opt, not)
386 const struct qual_options *opt;
389 if (isdigit((unsigned char)*s)) {
391 if (desc < 0 || desc >= MAX_QUALS)
393 qualify_one(desc, opt, not, -1);
403 if (strcmp(s, "file") == 0)
405 if (strcmp(s, "ipc") == 0)
407 if (strcmp(s, "network") == 0)
408 return TRACE_NETWORK;
409 if (strcmp(s, "process") == 0)
410 return TRACE_PROCESS;
411 if (strcmp(s, "signal") == 0)
413 if (strcmp(s, "desc") == 0)
422 const struct qual_options *opt;
427 opt = &qual_options[0];
428 for (i = 0; (p = qual_options[i].option_name); i++) {
430 if (strncmp(s, p, n) == 0 && s[n] == '=') {
431 opt = &qual_options[i];
441 if (strcmp(s, "none") == 0) {
445 if (strcmp(s, "all") == 0) {
446 for (i = 0; i < MAX_QUALS; i++) {
447 qualify_one(i, opt, not, -1);
451 for (i = 0; i < MAX_QUALS; i++) {
452 qualify_one(i, opt, !not, -1);
454 for (p = strtok(s, ","); p; p = strtok(NULL, ",")) {
455 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
456 for (i = 0; i < nsyscalls0; i++)
457 if (sysent0[i].sys_flags & n)
458 qualify_one(i, opt, not, 0);
460 #if SUPPORTED_PERSONALITIES >= 2
461 for (i = 0; i < nsyscalls1; i++)
462 if (sysent1[i].sys_flags & n)
463 qualify_one(i, opt, not, 1);
464 #endif /* SUPPORTED_PERSONALITIES >= 2 */
466 #if SUPPORTED_PERSONALITIES >= 3
467 for (i = 0; i < nsyscalls2; i++)
468 if (sysent2[i].sys_flags & n)
469 qualify_one(i, opt, not, 2);
470 #endif /* SUPPORTED_PERSONALITIES >= 3 */
474 if (opt->qualify(p, opt, not)) {
475 fprintf(stderr, "strace: invalid %s `%s'\n",
476 opt->argument_name, p);
489 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
491 switch (known_scno(tcp)) {
496 #if defined SYS_pread && SYS_pread64 != SYS_pread
501 #elif defined SYS_sub_recv
506 #elif defined SYS_sub_recvfrom
507 case SYS_sub_recvfrom:
509 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
510 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
516 #if defined SYS_pwrite && SYS_pwrite64 != SYS_pwrite
521 #elif defined SYS_sub_send
526 #elif defined SYS_sub_sendto
529 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
530 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
534 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
535 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
540 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
541 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
548 enum subcall_style { shift_style, deref_style, mask_style, door_style };
550 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
558 static const struct subcall subcalls_table[] = {
559 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
561 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
563 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
565 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
569 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
572 decode_subcall(tcp, subcall, nsubcalls, style)
576 enum subcall_style style;
578 unsigned long addr, mask;
580 int size = personality_wordsize[current_personality];
584 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
586 tcp->scno = subcall + tcp->u_arg[0];
587 if (sysent[tcp->scno].nargs != -1)
588 tcp->u_nargs = sysent[tcp->scno].nargs;
591 for (i = 0; i < tcp->u_nargs; i++)
592 tcp->u_arg[i] = tcp->u_arg[i + 1];
595 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
597 tcp->scno = subcall + tcp->u_arg[0];
598 addr = tcp->u_arg[1];
599 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
600 if (size == sizeof(int)) {
602 if (umove(tcp, addr, &arg) < 0)
606 else if (size == sizeof(long)) {
608 if (umove(tcp, addr, &arg) < 0)
616 tcp->u_nargs = sysent[tcp->scno].nargs;
619 mask = (tcp->u_arg[0] >> 8) & 0xff;
620 for (i = 0; mask; i++)
624 tcp->u_arg[0] &= 0xff;
625 tcp->scno = subcall + i;
626 if (sysent[tcp->scno].nargs != -1)
627 tcp->u_nargs = sysent[tcp->scno].nargs;
631 * Oh, yuck. The call code is the *sixth* argument.
632 * (don't you mean the *last* argument? - JH)
634 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
636 tcp->scno = subcall + tcp->u_arg[5];
637 if (sysent[tcp->scno].nargs != -1)
638 tcp->u_nargs = sysent[tcp->scno].nargs;
644 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
645 if (subcalls_table[i].call == tcp->scno) break;
646 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
647 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
648 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
649 for (i = 0; i < tcp->u_nargs; i++)
650 tcp->u_arg[i] = tcp->u_arg[i + 1];
658 struct tcb *tcp_last = NULL;
661 internal_syscall(struct tcb *tcp)
664 * We must always trace a few critical system calls in order to
665 * correctly support following forks in the presence of tracing
670 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
673 func = sysent[tcp->scno].sys_func;
675 if (sys_exit == func)
676 return internal_exit(tcp);
678 if ( sys_fork == func
679 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
686 return internal_fork(tcp);
688 #if defined(LINUX) && (defined SYS_clone || defined SYS_clone2)
689 if (sys_clone == func)
690 return internal_clone(tcp);
693 if ( sys_execve == func
694 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
698 || sys_rexecve == func
701 return internal_exec(tcp);
703 if ( sys_waitpid == func
705 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
709 || sys_osf_wait4 == func
712 return internal_wait(tcp, 2);
714 #if defined(LINUX) || defined(SVR4)
715 if (sys_waitid == func)
716 return internal_wait(tcp, 3);
729 #elif defined (POWERPC)
730 static long result,flags;
736 static struct pt_regs regs;
737 #elif defined (ALPHA)
741 static struct pt_regs regs;
742 #elif defined (SPARC) || defined (SPARC64)
743 static struct pt_regs regs;
744 static unsigned long trap;
745 #elif defined(LINUX_MIPSN32)
751 #elif defined(S390) || defined(S390X)
754 static long syscall_mode;
761 #elif defined(X86_64)
763 #elif defined(CRISV10) || defined(CRISV32)
772 get_scno(struct tcb *tcp)
777 # if defined(S390) || defined(S390X)
778 if (tcp->flags & TCB_WAITEXECVE) {
780 * When the execve system call completes successfully, the
781 * new process still has -ENOSYS (old style) or __NR_execve
782 * (new style) in gpr2. We cannot recover the scno again
783 * by disassembly, because the image that executed the
784 * syscall is gone now. Fortunately, we don't want it. We
785 * leave the flag set so that syscall_fixup can fake the
788 if (tcp->flags & TCB_INSYSCALL)
791 * This is the SIGTRAP after execve. We cannot try to read
792 * the system call here either.
794 tcp->flags &= ~TCB_WAITEXECVE;
798 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
801 if (syscall_mode != -ENOSYS) {
803 * Since kernel version 2.5.44 the scno gets passed in gpr2.
808 * Old style of "passing" the scno via the SVC instruction.
811 long opcode, offset_reg, tmp;
813 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
814 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
815 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
816 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
818 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
821 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
823 perror("peektext(pc-oneword)");
828 * We have to check if the SVC got executed directly or via an
829 * EXECUTE instruction. In case of EXECUTE it is necessary to do
830 * instruction decoding to derive the system call number.
831 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
832 * so that this doesn't work if a SVC opcode is part of an EXECUTE
833 * opcode. Since there is no way to find out the opcode size this
834 * is the best we can do...
837 if ((opcode & 0xff00) == 0x0a00) {
839 scno = opcode & 0xff;
842 /* SVC got executed by EXECUTE instruction */
845 * Do instruction decoding of EXECUTE. If you really want to
846 * understand this, read the Principles of Operations.
848 svc_addr = (void *) (opcode & 0xfff);
851 offset_reg = (opcode & 0x000f0000) >> 16;
852 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
857 offset_reg = (opcode & 0x0000f000) >> 12;
858 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
862 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
871 offset_reg = (opcode & 0x00f00000) >> 20;
872 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
875 scno = (scno | tmp) & 0xff;
878 # elif defined (POWERPC)
879 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
881 if (!(tcp->flags & TCB_INSYSCALL)) {
882 /* Check if we return from execve. */
883 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
884 tcp->flags &= ~TCB_WAITEXECVE;
888 # elif defined(AVR32)
890 * Read complete register set in one go.
892 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
896 * We only need to grab the syscall number on syscall entry.
898 if (!(tcp->flags & TCB_INSYSCALL)) {
901 /* Check if we return from execve. */
902 if (tcp->flags & TCB_WAITEXECVE) {
903 tcp->flags &= ~TCB_WAITEXECVE;
908 if (upeek(tcp, PT_ORIG_P0, &scno))
910 # elif defined (I386)
911 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
913 # elif defined (X86_64)
914 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
917 if (!(tcp->flags & TCB_INSYSCALL)) {
918 static int currpers = -1;
922 /* Check CS register value. On x86-64 linux it is:
923 * 0x33 for long mode (64 bit)
924 * 0x23 for compatibility mode (32 bit)
925 * It takes only one ptrace and thus doesn't need
928 if (upeek(tcp, 8*CS, &val) < 0)
931 case 0x23: currpers = 1; break;
932 case 0x33: currpers = 0; break;
934 fprintf(stderr, "Unknown value CS=0x%02X while "
935 "detecting personality of process "
936 "PID=%d\n", (int)val, pid);
937 currpers = current_personality;
941 /* This version analyzes the opcode of a syscall instruction.
942 * (int 0x80 on i386 vs. syscall on x86-64)
943 * It works, but is too complicated.
945 unsigned long val, rip, i;
947 if (upeek(tcp, 8*RIP, &rip) < 0)
948 perror("upeek(RIP)");
950 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
954 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
956 printf("ptrace_peektext failed: %s\n",
958 switch (call & 0xffff) {
959 /* x86-64: syscall = 0x0f 0x05 */
960 case 0x050f: currpers = 0; break;
961 /* i386: int 0x80 = 0xcd 0x80 */
962 case 0x80cd: currpers = 1; break;
964 currpers = current_personality;
966 "Unknown syscall opcode (0x%04X) while "
967 "detecting personality of process "
968 "PID=%d\n", (int)call, pid);
972 if (currpers != current_personality) {
973 static const char *const names[] = {"64 bit", "32 bit"};
974 set_personality(currpers);
975 printf("[ Process PID=%d runs in %s mode. ]\n",
976 pid, names[current_personality]);
980 # define IA64_PSR_IS ((long)1 << 34)
981 if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
982 ia32 = (psr & IA64_PSR_IS) != 0;
983 if (!(tcp->flags & TCB_INSYSCALL)) {
985 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
988 if (upeek (tcp, PT_R15, &scno) < 0)
991 /* Check if we return from execve. */
992 if (tcp->flags & TCB_WAITEXECVE) {
993 tcp->flags &= ~TCB_WAITEXECVE;
997 /* syscall in progress */
998 if (upeek (tcp, PT_R8, &r8) < 0)
1000 if (upeek (tcp, PT_R10, &r10) < 0)
1003 # elif defined (ARM)
1005 * Read complete register set in one go.
1007 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
1011 * We only need to grab the syscall number on syscall entry.
1013 if (regs.ARM_ip == 0) {
1014 if (!(tcp->flags & TCB_INSYSCALL)) {
1015 /* Check if we return from execve. */
1016 if (tcp->flags & TCB_WAITEXECVE) {
1017 tcp->flags &= ~TCB_WAITEXECVE;
1023 * Note: we only deal with only 32-bit CPUs here.
1025 if (regs.ARM_cpsr & 0x20) {
1027 * Get the Thumb-mode system call number
1032 * Get the ARM-mode system call number
1035 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1039 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1040 tcp->flags &= ~TCB_WAITEXECVE;
1044 /* Handle the EABI syscall convention. We do not
1045 bother converting structures between the two
1046 ABIs, but basic functionality should work even
1047 if strace and the traced program have different
1049 if (scno == 0xef000000) {
1052 if ((scno & 0x0ff00000) != 0x0f900000) {
1053 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1059 * Fixup the syscall number
1064 if (scno & 0x0f0000) {
1066 * Handle ARM specific syscall
1073 if (tcp->flags & TCB_INSYSCALL) {
1074 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1075 tcp->flags &= ~TCB_INSYSCALL;
1078 if (!(tcp->flags & TCB_INSYSCALL)) {
1079 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1080 tcp->flags |= TCB_INSYSCALL;
1083 # elif defined (M68K)
1084 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1086 # elif defined (LINUX_MIPSN32)
1087 unsigned long long regs[38];
1089 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1094 if(!(tcp->flags & TCB_INSYSCALL)) {
1097 /* Check if we return from execve. */
1098 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1099 tcp->flags &= ~TCB_WAITEXECVE;
1103 if (scno < 0 || scno > nsyscalls) {
1104 if(a3 == 0 || a3 == -1) {
1106 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1111 # elif defined (MIPS)
1112 if (upeek(tcp, REG_A3, &a3) < 0)
1114 if(!(tcp->flags & TCB_INSYSCALL)) {
1115 if (upeek(tcp, REG_V0, &scno) < 0)
1118 /* Check if we return from execve. */
1119 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1120 tcp->flags &= ~TCB_WAITEXECVE;
1124 if (scno < 0 || scno > nsyscalls) {
1125 if(a3 == 0 || a3 == -1) {
1127 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1132 if (upeek(tcp, REG_V0, &r2) < 0)
1135 # elif defined (ALPHA)
1136 if (upeek(tcp, REG_A3, &a3) < 0)
1139 if (!(tcp->flags & TCB_INSYSCALL)) {
1140 if (upeek(tcp, REG_R0, &scno) < 0)
1143 /* Check if we return from execve. */
1144 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1145 tcp->flags &= ~TCB_WAITEXECVE;
1150 * Do some sanity checks to figure out if it's
1151 * really a syscall entry
1153 if (scno < 0 || scno > nsyscalls) {
1154 if (a3 == 0 || a3 == -1) {
1156 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1162 if (upeek(tcp, REG_R0, &r0) < 0)
1165 # elif defined (SPARC) || defined (SPARC64)
1166 /* Everything we need is in the current register set. */
1167 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1170 /* If we are entering, then disassemble the syscall trap. */
1171 if (!(tcp->flags & TCB_INSYSCALL)) {
1172 /* Retrieve the syscall trap instruction. */
1174 # if defined(SPARC64)
1175 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1178 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1183 /* Disassemble the trap to see what personality to use. */
1186 /* Linux/SPARC syscall trap. */
1190 /* Linux/SPARC64 syscall trap. */
1194 /* SunOS syscall trap. (pers 1) */
1195 fprintf(stderr,"syscall: SunOS no support\n");
1198 /* Solaris 2.x syscall trap. (per 2) */
1202 /* NetBSD/FreeBSD syscall trap. */
1203 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1206 /* Solaris 2.x gettimeofday */
1210 /* Unknown syscall trap. */
1211 if(tcp->flags & TCB_WAITEXECVE) {
1212 tcp->flags &= ~TCB_WAITEXECVE;
1215 # if defined (SPARC64)
1216 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1218 fprintf(stderr,"syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1223 /* Extract the system call number from the registers. */
1224 if (trap == 0x91d02027)
1227 scno = regs.u_regs[U_REG_G1];
1229 scno = regs.u_regs[U_REG_O0];
1230 memmove (®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1233 # elif defined(HPPA)
1234 if (upeek(tcp, PT_GR20, &scno) < 0)
1236 if (!(tcp->flags & TCB_INSYSCALL)) {
1237 /* Check if we return from execve. */
1238 if ((tcp->flags & TCB_WAITEXECVE)) {
1239 tcp->flags &= ~TCB_WAITEXECVE;
1245 * In the new syscall ABI, the system call number is in R3.
1247 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1251 /* Odd as it may seem, a glibc bug has been known to cause
1252 glibc to issue bogus negative syscall numbers. So for
1253 our purposes, make strace print what it *should* have been */
1254 long correct_scno = (scno & 0xff);
1257 "Detected glibc bug: bogus system call"
1258 " number = %ld, correcting to %ld\n",
1261 scno = correct_scno;
1264 if (!(tcp->flags & TCB_INSYSCALL)) {
1265 /* Check if we return from execve. */
1266 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1267 tcp->flags &= ~TCB_WAITEXECVE;
1271 # elif defined(SH64)
1272 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1276 if (!(tcp->flags & TCB_INSYSCALL)) {
1277 /* Check if we return from execve. */
1278 if (tcp->flags & TCB_WAITEXECVE) {
1279 tcp->flags &= ~TCB_WAITEXECVE;
1283 # elif defined(CRISV10) || defined(CRISV32)
1284 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1290 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1293 /* new syscall ABI returns result in R0 */
1294 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1297 /* ABI defines result returned in r9 */
1298 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1303 # ifdef HAVE_PR_SYSCALL
1304 scno = tcp->status.PR_SYSCALL;
1307 scno = tcp->status.PR_WHAT;
1309 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1313 switch (regs.r_eax) {
1316 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1322 # endif /* FREEBSD */
1323 # endif /* !HAVE_PR_SYSCALL */
1324 #endif /* USE_PROCFS */
1326 if (!(tcp->flags & TCB_INSYSCALL))
1336 long scno = tcp->scno;
1337 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1338 scno = sysent[scno].native_scno;
1340 scno += NR_SYSCALL_BASE;
1344 /* Called in trace_syscall() at each syscall entry and exit.
1346 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1347 * 1: ok, continue in trace_syscall().
1348 * other: error, trace_syscall() should print error indicator
1349 * ("????" etc) and bail out.
1352 syscall_fixup(struct tcb *tcp)
1355 int scno = known_scno(tcp);
1357 if (!(tcp->flags & TCB_INSYSCALL)) {
1358 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1362 || scno == SYS_vfork
1363 #endif /* SYS_vfork */
1365 || scno == SYS_fork1
1366 #endif /* SYS_fork1 */
1368 || scno == SYS_forkall
1369 #endif /* SYS_forkall */
1371 || scno == SYS_rfork1
1372 #endif /* SYS_fork1 */
1374 || scno == SYS_rforkall
1375 #endif /* SYS_rforkall */
1377 /* We are returning in the child, fake it. */
1378 tcp->status.PR_WHY = PR_SYSENTRY;
1380 tcp->status.PR_WHY = PR_SYSEXIT;
1383 fprintf(stderr, "syscall: missing entry\n");
1384 tcp->flags |= TCB_INSYSCALL;
1389 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1390 fprintf(stderr, "syscall: missing exit\n");
1391 tcp->flags &= ~TCB_INSYSCALL;
1394 #endif /* USE_PROCFS */
1396 if (!(tcp->flags & TCB_INSYSCALL)) {
1398 fprintf(stderr, "syscall: missing entry\n");
1399 tcp->flags |= TCB_INSYSCALL;
1406 * This happens when a signal handler
1407 * for a signal which interrupted a
1408 * a system call makes another system call.
1410 fprintf(stderr, "syscall: missing exit\n");
1412 tcp->flags &= ~TCB_INSYSCALL;
1418 if (upeek(tcp, 4*EAX, &eax) < 0)
1420 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1422 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1425 #elif defined (X86_64)
1426 if (upeek(tcp, 8*RAX, &rax) < 0)
1428 if (current_personality == 1)
1429 rax = (long int)(int)rax; /* sign extend from 32 bits */
1430 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1432 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1435 #elif defined (S390) || defined (S390X)
1436 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1438 if (syscall_mode != -ENOSYS)
1439 syscall_mode = tcp->scno;
1440 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1442 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1445 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1446 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1447 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1449 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1450 * flag set for the post-execve SIGTRAP to see and reset.
1454 #elif defined (POWERPC)
1455 # define SO_MASK 0x10000000
1456 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1458 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1460 if (flags & SO_MASK)
1462 #elif defined (M68K)
1463 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1465 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1467 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1475 if (upeek(tcp, PT_R0, &r0) < 0)
1477 #elif defined (HPPA)
1478 if (upeek(tcp, PT_GR28, &r28) < 0)
1481 if (upeek(tcp, PT_R10, &r10) < 0)
1483 if (upeek(tcp, PT_R8, &r8) < 0)
1485 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1487 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1490 #elif defined(CRISV10) || defined(CRISV32)
1491 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1493 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1495 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1505 * Check the syscall return value register value for whether it is
1506 * a negated errno code indicating an error, or a success return value.
1509 is_negated_errno(unsigned long int val)
1511 unsigned long int max = -(long int) nerrnos;
1512 if (personality_wordsize[current_personality] < sizeof(val)) {
1513 val = (unsigned int) val;
1514 max = (unsigned int) max;
1521 get_error(struct tcb *tcp)
1525 # if defined(S390) || defined(S390X)
1526 if (is_negated_errno(gpr2)) {
1534 # elif defined(I386)
1535 if (is_negated_errno(eax)) {
1543 # elif defined(X86_64)
1544 if (is_negated_errno(rax)) {
1552 # elif defined(IA64)
1557 if (is_negated_errno(err)) {
1574 # elif defined(MIPS)
1582 # elif defined(POWERPC)
1583 if (is_negated_errno(result)) {
1588 tcp->u_rval = result;
1591 # elif defined(M68K)
1592 if (is_negated_errno(d0)) {
1601 if (is_negated_errno(regs.ARM_r0)) {
1603 u_error = -regs.ARM_r0;
1606 tcp->u_rval = regs.ARM_r0;
1609 # elif defined(AVR32)
1610 if (regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1612 u_error = -regs.r12;
1615 tcp->u_rval = regs.r12;
1618 # elif defined(BFIN)
1619 if (is_negated_errno(r0)) {
1626 # elif defined(ALPHA)
1635 # elif defined(SPARC)
1636 if (regs.psr & PSR_C) {
1638 u_error = regs.u_regs[U_REG_O0];
1641 tcp->u_rval = regs.u_regs[U_REG_O0];
1644 # elif defined(SPARC64)
1645 if (regs.tstate & 0x1100000000UL) {
1647 u_error = regs.u_regs[U_REG_O0];
1650 tcp->u_rval = regs.u_regs[U_REG_O0];
1653 # elif defined(HPPA)
1654 if (is_negated_errno(r28)) {
1663 /* interpret R0 as return value or error number */
1664 if (is_negated_errno(r0)) {
1672 # elif defined(SH64)
1673 /* interpret result as return value or error number */
1674 if (is_negated_errno(r9)) {
1682 # elif defined(CRISV10) || defined(CRISV32)
1683 if (r10 && (unsigned) -r10 < nerrnos) {
1694 /* get error code from user struct */
1695 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1697 u_error >>= 24; /* u_error is a char */
1699 /* get system call return value */
1700 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1705 /* Judicious guessing goes a long way. */
1706 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1708 u_error = tcp->status.pr_reg[R_O0];
1711 tcp->u_rval = tcp->status.pr_reg[R_O0];
1716 /* Wanna know how to kill an hour single-stepping? */
1717 if (tcp->status.PR_REG[EFL] & 0x1) {
1719 u_error = tcp->status.PR_REG[EAX];
1722 tcp->u_rval = tcp->status.PR_REG[EAX];
1723 #ifdef HAVE_LONG_LONG
1725 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1726 tcp->status.PR_REG[EAX];
1732 /* Wanna know how to kill an hour single-stepping? */
1733 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1735 u_error = tcp->status.PR_REG[RAX];
1738 tcp->u_rval = tcp->status.PR_REG[RAX];
1743 if (tcp->status.pr_reg[CTX_A3]) {
1745 u_error = tcp->status.pr_reg[CTX_V0];
1748 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1754 if (regs.r_eflags & PSL_C) {
1756 u_error = regs.r_eax;
1758 tcp->u_rval = regs.r_eax;
1760 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1763 #endif /* FREEBSD */
1764 tcp->u_error = u_error;
1769 force_result(tcp, error, rval)
1775 # if defined(S390) || defined(S390X)
1776 gpr2 = error ? -error : rval;
1777 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1779 # elif defined(I386)
1780 eax = error ? -error : rval;
1781 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1783 # elif defined(X86_64)
1784 rax = error ? -error : rval;
1785 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1787 # elif defined(IA64)
1789 r8 = error ? -error : rval;
1790 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1802 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1803 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1806 # elif defined(BFIN)
1807 r0 = error ? -error : rval;
1808 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1810 # elif defined(MIPS)
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)
1823 # elif defined(POWERPC)
1824 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1834 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1835 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1837 # elif defined(M68K)
1838 d0 = error ? -error : rval;
1839 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1842 regs.ARM_r0 = error ? -error : rval;
1843 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1845 # elif defined(AVR32)
1846 regs.r12 = error ? -error : rval;
1847 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1849 # elif defined(ALPHA)
1858 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1859 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1861 # elif defined(SPARC)
1862 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1866 regs.u_regs[U_REG_O0] = error;
1870 regs.u_regs[U_REG_O0] = rval;
1872 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1874 # elif defined(SPARC64)
1875 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1878 regs.tstate |= 0x1100000000UL;
1879 regs.u_regs[U_REG_O0] = error;
1882 regs.tstate &= ~0x1100000000UL;
1883 regs.u_regs[U_REG_O0] = rval;
1885 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1887 # elif defined(HPPA)
1888 r28 = error ? -error : rval;
1889 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1892 r0 = error ? -error : rval;
1893 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1895 # elif defined(SH64)
1896 r9 = error ? -error : rval;
1897 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1903 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1905 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1915 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1920 regs.r_eflags |= PSL_C;
1924 regs.r_eflags &= ~PSL_C;
1927 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1931 #endif /* FREEBSD */
1933 /* All branches reach here on success (only). */
1934 tcp->u_error = error;
1940 syscall_enter(struct tcb *tcp)
1943 #if defined(S390) || defined(S390X)
1946 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1947 tcp->u_nargs = sysent[tcp->scno].nargs;
1949 tcp->u_nargs = MAX_ARGS;
1950 for (i = 0; i < tcp->u_nargs; i++) {
1951 if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1955 #elif defined (ALPHA)
1958 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1959 tcp->u_nargs = sysent[tcp->scno].nargs;
1961 tcp->u_nargs = MAX_ARGS;
1962 for (i = 0; i < tcp->u_nargs; i++) {
1963 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1964 * for scno somewhere above here!
1966 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1970 #elif defined (IA64)
1973 unsigned long *out0, cfm, sof, sol, i;
1975 /* be backwards compatible with kernel < 2.4.4... */
1977 # define PT_RBS_END PT_AR_BSP
1980 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
1982 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
1985 sof = (cfm >> 0) & 0x7f;
1986 sol = (cfm >> 7) & 0x7f;
1987 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
1989 if (tcp->scno >= 0 && tcp->scno < nsyscalls
1990 && sysent[tcp->scno].nargs != -1)
1991 tcp->u_nargs = sysent[tcp->scno].nargs;
1993 tcp->u_nargs = MAX_ARGS;
1994 for (i = 0; i < tcp->u_nargs; ++i) {
1995 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
1996 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2002 if (/* EBX = out0 */
2003 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2005 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2007 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2009 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2011 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2013 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2016 for (i = 0; i < 6; ++i)
2017 /* truncate away IVE sign-extension */
2018 tcp->u_arg[i] &= 0xffffffff;
2020 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2021 && sysent[tcp->scno].nargs != -1)
2022 tcp->u_nargs = sysent[tcp->scno].nargs;
2027 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2028 /* N32 and N64 both use up to six registers. */
2030 unsigned long long regs[38];
2033 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2034 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2036 nargs = tcp->u_nargs = MAX_ARGS;
2038 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2041 for(i = 0; i < nargs; i++) {
2042 tcp->u_arg[i] = regs[REG_A0 + i];
2043 # if defined (LINUX_MIPSN32)
2044 tcp->ext_arg[i] = regs[REG_A0 + i];
2048 #elif defined (MIPS)
2053 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2054 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2056 nargs = tcp->u_nargs = MAX_ARGS;
2058 if(upeek(tcp, REG_SP, &sp) < 0)
2060 for(i = 0; i < 4; i++) {
2061 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2064 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2065 (char *)(tcp->u_arg + 4));
2067 for(i = 0; i < nargs; i++) {
2068 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2073 #elif defined (POWERPC)
2075 # define PT_ORIG_R3 34
2079 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2080 tcp->u_nargs = sysent[tcp->scno].nargs;
2082 tcp->u_nargs = MAX_ARGS;
2083 for (i = 0; i < tcp->u_nargs; i++) {
2084 if (upeek(tcp, (i==0) ?
2085 (sizeof(unsigned long)*PT_ORIG_R3) :
2086 ((i+PT_R3)*sizeof(unsigned long)),
2087 &tcp->u_arg[i]) < 0)
2091 #elif defined (SPARC) || defined (SPARC64)
2095 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2096 tcp->u_nargs = sysent[tcp->scno].nargs;
2098 tcp->u_nargs = MAX_ARGS;
2099 for (i = 0; i < tcp->u_nargs; i++)
2100 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2102 #elif defined (HPPA)
2106 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2107 tcp->u_nargs = sysent[tcp->scno].nargs;
2109 tcp->u_nargs = MAX_ARGS;
2110 for (i = 0; i < tcp->u_nargs; i++) {
2111 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2119 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2120 tcp->u_nargs = sysent[tcp->scno].nargs;
2122 tcp->u_nargs = MAX_ARGS;
2123 for (i = 0; i < tcp->u_nargs; i++)
2124 tcp->u_arg[i] = regs.uregs[i];
2126 #elif defined(AVR32)
2127 tcp->u_nargs = sysent[tcp->scno].nargs;
2128 tcp->u_arg[0] = regs.r12;
2129 tcp->u_arg[1] = regs.r11;
2130 tcp->u_arg[2] = regs.r10;
2131 tcp->u_arg[3] = regs.r9;
2132 tcp->u_arg[4] = regs.r5;
2133 tcp->u_arg[5] = regs.r3;
2137 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2139 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2140 tcp->u_nargs = sysent[tcp->scno].nargs;
2142 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2144 for (i = 0; i < tcp->u_nargs; ++i)
2145 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2151 static int syscall_regs[] = {
2152 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2153 REG_REG0, REG_REG0+1, REG_REG0+2
2156 tcp->u_nargs = sysent[tcp->scno].nargs;
2157 for (i = 0; i < tcp->u_nargs; i++) {
2158 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2165 /* Registers used by SH5 Linux system calls for parameters */
2166 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2169 * TODO: should also check that the number of arguments encoded
2170 * in the trap number matches the number strace expects.
2173 assert(sysent[tcp->scno].nargs <
2174 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2177 tcp->u_nargs = sysent[tcp->scno].nargs;
2178 for (i = 0; i < tcp->u_nargs; i++) {
2179 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2184 #elif defined(X86_64)
2187 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2188 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2189 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2192 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2193 tcp->u_nargs = sysent[tcp->scno].nargs;
2195 tcp->u_nargs = MAX_ARGS;
2196 for (i = 0; i < tcp->u_nargs; i++) {
2197 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2201 #elif defined(CRISV10) || defined(CRISV32)
2204 static const int crisregs[] = {
2205 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2206 4*PT_R13, 4*PT_MOF, 4*PT_SRP
2209 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2210 tcp->u_nargs = sysent[tcp->scno].nargs;
2213 for (i = 0; i < tcp->u_nargs; i++) {
2214 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2218 #else /* Other architecture (like i386) (32bits specific) */
2221 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2222 tcp->u_nargs = sysent[tcp->scno].nargs;
2224 tcp->u_nargs = MAX_ARGS;
2225 for (i = 0; i < tcp->u_nargs; i++) {
2226 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2235 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2236 tcp->u_nargs = sysent[tcp->scno].nargs;
2238 tcp->u_nargs = MAX_ARGS;
2239 for (i = 0; i < tcp->u_nargs; i++) {
2242 if (upeek(tcp, uoff(u_arg[0]) +
2243 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2251 * SGI is broken: even though it has pr_sysarg, it doesn't
2252 * set them on system call entry. Get a clue.
2254 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2255 tcp->u_nargs = sysent[tcp->scno].nargs;
2257 tcp->u_nargs = tcp->status.pr_nsysarg;
2258 if (tcp->u_nargs > 4) {
2259 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2260 4*sizeof(tcp->u_arg[0]));
2261 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2262 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2265 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2266 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2270 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2272 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2273 tcp->u_nargs = sysent[tcp->scno].nargs;
2275 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2276 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2277 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2278 #elif defined (HAVE_PR_SYSCALL)
2279 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2280 tcp->u_nargs = sysent[tcp->scno].nargs;
2282 tcp->u_nargs = tcp->status.pr_nsysarg;
2285 for (i = 0; i < tcp->u_nargs; i++)
2286 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2288 #elif defined (I386)
2289 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2290 tcp->u_nargs = sysent[tcp->scno].nargs;
2293 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2294 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2296 I DONT KNOW WHAT TO DO
2297 #endif /* !HAVE_PR_SYSCALL */
2300 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2301 sysent[tcp->scno].nargs > tcp->status.val)
2302 tcp->u_nargs = sysent[tcp->scno].nargs;
2304 tcp->u_nargs = tcp->status.val;
2305 if (tcp->u_nargs < 0)
2307 if (tcp->u_nargs > MAX_ARGS)
2308 tcp->u_nargs = MAX_ARGS;
2309 switch(regs.r_eax) {
2311 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2312 regs.r_esp + sizeof(int) + sizeof(quad_t));
2315 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2316 regs.r_esp + 2 * sizeof(int));
2319 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2320 regs.r_esp + sizeof(int));
2323 #endif /* FREEBSD */
2328 trace_syscall(struct tcb *tcp)
2334 if (tcp->flags & TCB_INSYSCALL) {
2337 /* Measure the exit time as early as possible to avoid errors. */
2339 gettimeofday(&tv, NULL);
2341 /* BTW, why we don't just memorize syscall no. on entry
2342 * in tcp->something?
2344 scno_good = res = get_scno(tcp);
2348 res = syscall_fixup(tcp);
2352 res = get_error(tcp);
2356 internal_syscall(tcp);
2358 if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2359 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2360 tcp->flags &= ~TCB_INSYSCALL;
2364 if (tcp->flags & TCB_REPRINT) {
2369 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2370 tprintf("syscall_%lu", tcp->scno);
2372 tprintf("%s", sysent[tcp->scno].sys_name);
2373 tprintf(" resumed> ");
2377 return count_syscall(tcp, &tv);
2382 tprintf("= ? <unavailable>");
2384 tcp->flags &= ~TCB_INSYSCALL;
2388 if (tcp->scno >= nsyscalls || tcp->scno < 0
2389 || (qual_flags[tcp->scno] & QUAL_RAW))
2390 sys_res = printargs(tcp);
2392 if (not_failing_only && tcp->u_error)
2393 return 0; /* ignore failed syscalls */
2394 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2396 u_error = tcp->u_error;
2399 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2400 qual_flags[tcp->scno] & QUAL_RAW) {
2402 tprintf("= -1 (errno %ld)", u_error);
2404 tprintf("= %#lx", tcp->u_rval);
2406 else if (!(sys_res & RVAL_NONE) && u_error) {
2410 tprintf("= ? ERESTARTSYS (To be restarted)");
2412 case ERESTARTNOINTR:
2413 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2415 case ERESTARTNOHAND:
2416 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2418 case ERESTART_RESTARTBLOCK:
2419 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2425 tprintf("E??? (errno %ld)", u_error);
2426 else if (u_error < nerrnos)
2427 tprintf("%s (%s)", errnoent[u_error],
2430 tprintf("ERRNO_%ld (%s)", u_error,
2434 if ((sys_res & RVAL_STR) && tcp->auxstr)
2435 tprintf(" (%s)", tcp->auxstr);
2438 if (sys_res & RVAL_NONE)
2441 switch (sys_res & RVAL_MASK) {
2443 tprintf("= %#lx", tcp->u_rval);
2446 tprintf("= %#lo", tcp->u_rval);
2449 tprintf("= %lu", tcp->u_rval);
2452 tprintf("= %ld", tcp->u_rval);
2454 #ifdef HAVE_LONG_LONG
2456 tprintf("= %#llx", tcp->u_lrval);
2459 tprintf("= %#llo", tcp->u_lrval);
2461 case RVAL_LUDECIMAL:
2462 tprintf("= %llu", tcp->u_lrval);
2465 tprintf("= %lld", tcp->u_lrval);
2470 "invalid rval format\n");
2474 if ((sys_res & RVAL_STR) && tcp->auxstr)
2475 tprintf(" (%s)", tcp->auxstr);
2478 tv_sub(&tv, &tv, &tcp->etime);
2479 tprintf(" <%ld.%06ld>",
2480 (long) tv.tv_sec, (long) tv.tv_usec);
2485 if (fflush(tcp->outf) == EOF)
2487 tcp->flags &= ~TCB_INSYSCALL;
2491 /* Entering system call */
2492 scno_good = res = get_scno(tcp);
2496 res = syscall_fixup(tcp);
2500 res = syscall_enter(tcp);
2506 tcp->flags &= ~TCB_REPRINT;
2509 tprintf("????" /* anti-trigraph gap */ "(");
2510 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2511 tprintf("syscall_%lu(", tcp->scno);
2513 tprintf("%s(", sysent[tcp->scno].sys_name);
2515 * " <unavailable>" will be added later by the code which
2516 * detects ptrace errors.
2518 tcp->flags |= TCB_INSYSCALL;
2522 switch (known_scno(tcp)) {
2523 #ifdef SYS_socket_subcall
2524 case SYS_socketcall:
2525 decode_subcall(tcp, SYS_socket_subcall,
2526 SYS_socket_nsubcalls, deref_style);
2529 #ifdef SYS_ipc_subcall
2531 decode_subcall(tcp, SYS_ipc_subcall,
2532 SYS_ipc_nsubcalls, shift_style);
2536 #ifdef SYS_pgrpsys_subcall
2538 decode_subcall(tcp, SYS_pgrpsys_subcall,
2539 SYS_pgrpsys_nsubcalls, shift_style);
2541 #endif /* SYS_pgrpsys_subcall */
2542 #ifdef SYS_sigcall_subcall
2544 decode_subcall(tcp, SYS_sigcall_subcall,
2545 SYS_sigcall_nsubcalls, mask_style);
2547 #endif /* SYS_sigcall_subcall */
2549 decode_subcall(tcp, SYS_msgsys_subcall,
2550 SYS_msgsys_nsubcalls, shift_style);
2553 decode_subcall(tcp, SYS_shmsys_subcall,
2554 SYS_shmsys_nsubcalls, shift_style);
2557 decode_subcall(tcp, SYS_semsys_subcall,
2558 SYS_semsys_nsubcalls, shift_style);
2562 decode_subcall(tcp, SYS_utssys_subcall,
2563 SYS_utssys_nsubcalls, shift_style);
2567 decode_subcall(tcp, SYS_sysfs_subcall,
2568 SYS_sysfs_nsubcalls, shift_style);
2571 decode_subcall(tcp, SYS_spcall_subcall,
2572 SYS_spcall_nsubcalls, shift_style);
2574 #ifdef SYS_context_subcall
2576 decode_subcall(tcp, SYS_context_subcall,
2577 SYS_context_nsubcalls, shift_style);
2579 #endif /* SYS_context_subcall */
2580 #ifdef SYS_door_subcall
2582 decode_subcall(tcp, SYS_door_subcall,
2583 SYS_door_nsubcalls, door_style);
2585 #endif /* SYS_door_subcall */
2586 #ifdef SYS_kaio_subcall
2588 decode_subcall(tcp, SYS_kaio_subcall,
2589 SYS_kaio_nsubcalls, shift_style);
2597 decode_subcall(tcp, 0, 0, table_style);
2602 decode_subcall(tcp, SYS_semsys_subcall,
2603 SYS_semsys_nsubcalls, shift_style);
2606 decode_subcall(tcp, SYS_msgsys_subcall,
2607 SYS_msgsys_nsubcalls, shift_style);
2610 decode_subcall(tcp, SYS_shmsys_subcall,
2611 SYS_shmsys_nsubcalls, shift_style);
2616 internal_syscall(tcp);
2617 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2618 tcp->flags |= TCB_INSYSCALL;
2623 gettimeofday(&tcp->etime, NULL);
2624 tcp->flags |= TCB_INSYSCALL;
2629 tcp->flags &= ~TCB_REPRINT;
2631 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2632 tprintf("syscall_%lu(", tcp->scno);
2634 tprintf("%s(", sysent[tcp->scno].sys_name);
2635 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2636 ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2637 sys_res = printargs(tcp);
2639 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2640 if (fflush(tcp->outf) == EOF)
2642 tcp->flags |= TCB_INSYSCALL;
2643 /* Measure the entrance time as late as possible to avoid errors. */
2645 gettimeofday(&tcp->etime, NULL);
2653 if (entering(tcp)) {
2656 for (i = 0; i < tcp->u_nargs; i++)
2657 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2669 #if defined (SPARC) || defined (SPARC64)
2670 struct pt_regs regs;
2671 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2673 val = regs.u_regs[U_REG_O1];
2675 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2678 if (upeek(tcp, PT_R9, &val) < 0)
2684 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2690 val = tcp->status.PR_REG[R_O1];
2693 val = tcp->status.PR_REG[EDX];
2696 val = tcp->status.PR_REG[RDX];
2699 val = tcp->status.PR_REG[CTX_V1];
2705 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2713 * Apparently, indirect system calls have already be converted by ptrace(2),
2714 * so if you see "indir" this program has gone astray.
2722 if (entering(tcp)) {
2723 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2724 fprintf(stderr, "Bogus syscall: %u\n", scno);
2727 nargs = sysent[scno].nargs;
2728 tprintf("%s", sysent[scno].sys_name);
2729 for (i = 0; i < nargs; i++)
2730 tprintf(", %#lx", tcp->u_arg[i+1]);
2737 is_restart_error(struct tcb *tcp)
2742 switch (tcp->u_error) {
2744 case ERESTARTNOINTR:
2745 case ERESTARTNOHAND:
2746 case ERESTART_RESTARTBLOCK: