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(personality)
203 switch (personality) {
205 errnoent = errnoent0;
208 nsyscalls = nsyscalls0;
209 ioctlent = ioctlent0;
210 nioctlents = nioctlents0;
211 signalent = signalent0;
212 nsignals = nsignals0;
213 qual_flags = qual_flags0;
216 #if SUPPORTED_PERSONALITIES >= 2
218 errnoent = errnoent1;
221 nsyscalls = nsyscalls1;
222 ioctlent = ioctlent1;
223 nioctlents = nioctlents1;
224 signalent = signalent1;
225 nsignals = nsignals1;
226 qual_flags = qual_flags1;
228 #endif /* SUPPORTED_PERSONALITIES >= 2 */
230 #if SUPPORTED_PERSONALITIES >= 3
232 errnoent = errnoent2;
235 nsyscalls = nsyscalls2;
236 ioctlent = ioctlent2;
237 nioctlents = nioctlents2;
238 signalent = signalent2;
239 nsignals = nsignals2;
240 qual_flags = qual_flags2;
242 #endif /* SUPPORTED_PERSONALITIES >= 3 */
248 current_personality = personality;
258 static struct call_counts *counts;
260 static struct timeval shortest = { 1000000, 0 };
262 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
264 static const struct qual_options {
270 { QUAL_TRACE, "trace", qual_syscall, "system call" },
271 { QUAL_TRACE, "t", qual_syscall, "system call" },
272 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
273 { QUAL_ABBREV, "a", qual_syscall, "system call" },
274 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
275 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
276 { QUAL_RAW, "raw", qual_syscall, "system call" },
277 { QUAL_RAW, "x", qual_syscall, "system call" },
278 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
279 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
280 { QUAL_SIGNAL, "s", qual_signal, "signal" },
281 { QUAL_FAULT, "fault", qual_fault, "fault" },
282 { QUAL_FAULT, "faults", qual_fault, "fault" },
283 { QUAL_FAULT, "m", qual_fault, "fault" },
284 { QUAL_READ, "read", qual_desc, "descriptor" },
285 { QUAL_READ, "reads", qual_desc, "descriptor" },
286 { QUAL_READ, "r", qual_desc, "descriptor" },
287 { QUAL_WRITE, "write", qual_desc, "descriptor" },
288 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
289 { QUAL_WRITE, "w", qual_desc, "descriptor" },
290 { 0, NULL, NULL, NULL },
294 qualify_one(n, opt, not, pers)
296 const struct qual_options *opt;
300 if (pers == 0 || pers < 0) {
302 qual_flags0[n] &= ~opt->bitflag;
304 qual_flags0[n] |= opt->bitflag;
307 #if SUPPORTED_PERSONALITIES >= 2
308 if (pers == 1 || pers < 0) {
310 qual_flags1[n] &= ~opt->bitflag;
312 qual_flags1[n] |= opt->bitflag;
314 #endif /* SUPPORTED_PERSONALITIES >= 2 */
316 #if SUPPORTED_PERSONALITIES >= 3
317 if (pers == 2 || pers < 0) {
319 qual_flags2[n] &= ~opt->bitflag;
321 qual_flags2[n] |= opt->bitflag;
323 #endif /* SUPPORTED_PERSONALITIES >= 3 */
327 qual_syscall(s, opt, not)
329 const struct qual_options *opt;
335 if (isdigit((unsigned char)*s)) {
337 if (i < 0 || i >= nsyscalls)
339 qualify_one(i, opt, not, -1);
342 for (i = 0; i < nsyscalls; i++) {
343 if (strcmp(s, sysent0[i].sys_name) == 0) {
344 qualify_one(i, opt, not, 0);
348 #if SUPPORTED_PERSONALITIES >= 2
349 if (strcmp(s, sysent1[i].sys_name) == 0) {
350 qualify_one(i, opt, not, 1);
353 #endif /* SUPPORTED_PERSONALITIES >= 2 */
355 #if SUPPORTED_PERSONALITIES >= 3
356 if (strcmp(s, sysent2[i].sys_name) == 0) {
357 qualify_one(i, opt, not, 2);
360 #endif /* SUPPORTED_PERSONALITIES >= 3 */
366 qual_signal(s, opt, not)
368 const struct qual_options *opt;
374 if (isdigit((unsigned char)*s)) {
376 if (signo < 0 || signo >= MAX_QUALS)
378 qualify_one(signo, opt, not, -1);
381 if (strlen(s) >= sizeof buf)
385 for (i = 0; s[i]; i++)
386 s[i] = toupper((unsigned char)(s[i]));
387 if (strncmp(s, "SIG", 3) == 0)
389 for (i = 0; i <= NSIG; i++)
390 if (strcmp(s, signame(i) + 3) == 0) {
391 qualify_one(i, opt, not, -1);
398 qual_fault(s, opt, not)
400 const struct qual_options *opt;
407 qual_desc(s, opt, not)
409 const struct qual_options *opt;
412 if (isdigit((unsigned char)*s)) {
414 if (desc < 0 || desc >= MAX_QUALS)
416 qualify_one(desc, opt, not, -1);
426 if (strcmp(s, "file") == 0)
428 if (strcmp(s, "ipc") == 0)
430 if (strcmp(s, "network") == 0)
431 return TRACE_NETWORK;
432 if (strcmp(s, "process") == 0)
433 return TRACE_PROCESS;
434 if (strcmp(s, "signal") == 0)
436 if (strcmp(s, "desc") == 0)
445 const struct qual_options *opt;
450 opt = &qual_options[0];
451 for (i = 0; (p = qual_options[i].option_name); i++) {
453 if (strncmp(s, p, n) == 0 && s[n] == '=') {
454 opt = &qual_options[i];
464 if (strcmp(s, "none") == 0) {
468 if (strcmp(s, "all") == 0) {
469 for (i = 0; i < MAX_QUALS; i++) {
470 qualify_one(i, opt, not, -1);
474 for (i = 0; i < MAX_QUALS; i++) {
475 qualify_one(i, opt, !not, -1);
477 for (p = strtok(s, ","); p; p = strtok(NULL, ",")) {
478 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
479 for (i = 0; i < MAX_QUALS; i++) {
480 if (sysent0[i].sys_flags & n)
481 qualify_one(i, opt, not, 0);
483 #if SUPPORTED_PERSONALITIES >= 2
484 if (sysent1[i].sys_flags & n)
485 qualify_one(i, opt, not, 1);
486 #endif /* SUPPORTED_PERSONALITIES >= 2 */
488 #if SUPPORTED_PERSONALITIES >= 3
489 if (sysent2[i].sys_flags & n)
490 qualify_one(i, opt, not, 2);
491 #endif /* SUPPORTED_PERSONALITIES >= 3 */
495 if (opt->qualify(p, opt, not)) {
496 fprintf(stderr, "strace: invalid %s `%s'\n",
497 opt->argument_name, p);
510 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
512 switch (known_scno(tcp)) {
517 #if defined SYS_pread && SYS_pread64 != SYS_pread
522 #elif defined SYS_sub_recv
527 #elif defined SYS_sub_recvfrom
528 case SYS_sub_recvfrom:
530 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
531 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
537 #if defined SYS_pwrite && SYS_pwrite64 != SYS_pwrite
542 #elif defined SYS_sub_send
547 #elif defined SYS_sub_sendto
550 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
551 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
555 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
556 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
562 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
563 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
570 enum subcall_style { shift_style, deref_style, mask_style, door_style };
572 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
580 static const struct subcall subcalls_table[] = {
581 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
583 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
585 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
587 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
591 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) ))
593 static const int socket_map [] = {
596 /* SYS_CONNECT */ 98,
597 /* SYS_LISTEN */ 106,
599 /* SYS_GETSOCKNAME */ 150,
600 /* SYS_GETPEERNAME */ 141,
601 /* SYS_SOCKETPAIR */ 135,
604 /* SYS_SENDTO */ 133,
605 /* SYS_RECVFROM */ 125,
606 /* SYS_SHUTDOWN */ 134,
607 /* SYS_SETSOCKOPT */ 105,
608 /* SYS_GETSOCKOPT */ 118,
609 /* SYS_SENDMSG */ 114,
610 /* SYS_RECVMSG */ 113
613 #if defined (SPARC) || defined (SPARC64)
615 sparc_socket_decode (tcp)
621 if (tcp->u_arg [0] < 1 || tcp->u_arg [0] > sizeof(socket_map)/sizeof(int)+1){
624 tcp->scno = socket_map [tcp->u_arg [0]-1];
625 n = tcp->u_nargs = sysent [tcp->scno].nargs;
626 addr = tcp->u_arg [1];
627 for (i = 0; i < n; i++){
629 if (umoven (tcp, addr, sizeof (arg), (void *) &arg) < 0)
631 tcp->u_arg [i] = arg;
632 addr += sizeof (arg);
638 decode_subcall(tcp, subcall, nsubcalls, style)
642 enum subcall_style style;
644 unsigned long addr, mask;
646 int size = personality_wordsize[current_personality];
650 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
652 tcp->scno = subcall + tcp->u_arg[0];
653 if (sysent[tcp->scno].nargs != -1)
654 tcp->u_nargs = sysent[tcp->scno].nargs;
657 for (i = 0; i < tcp->u_nargs; i++)
658 tcp->u_arg[i] = tcp->u_arg[i + 1];
661 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
663 tcp->scno = subcall + tcp->u_arg[0];
664 addr = tcp->u_arg[1];
665 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
666 if (size == sizeof(int)) {
668 if (umove(tcp, addr, &arg) < 0)
672 else if (size == sizeof(long)) {
674 if (umove(tcp, addr, &arg) < 0)
682 tcp->u_nargs = sysent[tcp->scno].nargs;
685 mask = (tcp->u_arg[0] >> 8) & 0xff;
686 for (i = 0; mask; i++)
690 tcp->u_arg[0] &= 0xff;
691 tcp->scno = subcall + i;
692 if (sysent[tcp->scno].nargs != -1)
693 tcp->u_nargs = sysent[tcp->scno].nargs;
697 * Oh, yuck. The call code is the *sixth* argument.
698 * (don't you mean the *last* argument? - JH)
700 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
702 tcp->scno = subcall + tcp->u_arg[5];
703 if (sysent[tcp->scno].nargs != -1)
704 tcp->u_nargs = sysent[tcp->scno].nargs;
710 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
711 if (subcalls_table[i].call == tcp->scno) break;
712 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
713 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
714 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
715 for (i = 0; i < tcp->u_nargs; i++)
716 tcp->u_arg[i] = tcp->u_arg[i + 1];
724 struct tcb *tcp_last = NULL;
727 internal_syscall(tcp)
731 * We must always trace a few critical system calls in order to
732 * correctly support following forks in the presence of tracing
735 switch (known_scno(tcp)) {
796 internal_wait(tcp, 2);
800 internal_wait(tcp, 3);
810 #ifdef __NR_exit_group
811 case __NR_exit_group:
814 case 252: /* IA-32 __NR_exit_group */
829 #elif defined (POWERPC)
830 static long result,flags;
834 static struct pt_regs regs;
835 #elif defined (ALPHA)
838 #elif defined (SPARC) || defined (SPARC64)
839 static struct regs regs;
840 static unsigned long trap;
844 #elif defined(S390) || defined(S390X)
847 static long syscall_mode;
854 #elif defined(X86_64)
872 #if defined(S390) || defined(S390X)
873 if (tcp->flags & TCB_WAITEXECVE) {
875 * When the execve system call completes successfully, the
876 * new process still has -ENOSYS (old style) or __NR_execve
877 * (new style) in gpr2. We cannot recover the scno again
878 * by disassembly, because the image that executed the
879 * syscall is gone now. Fortunately, we don't want it. We
880 * leave the flag set so that syscall_fixup can fake the
883 if (tcp->flags & TCB_INSYSCALL)
886 * This is the SIGTRAP after execve. We cannot try to read
887 * the system call here either.
889 tcp->flags &= ~TCB_WAITEXECVE;
893 if (upeek(pid, PT_GPR2, &syscall_mode) < 0)
896 if (syscall_mode != -ENOSYS) {
898 * Since kernel version 2.5.44 the scno gets passed in gpr2.
903 * Old style of "passing" the scno via the SVC instruction.
906 long opcode, offset_reg, tmp;
908 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
909 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
910 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
911 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
913 if (upeek(pid, PT_PSWADDR, &pc) < 0)
916 opcode = ptrace(PTRACE_PEEKTEXT, pid, (char *)(pc-sizeof(long)), 0);
918 perror("peektext(pc-oneword)");
923 * We have to check if the SVC got executed directly or via an
924 * EXECUTE instruction. In case of EXECUTE it is necessary to do
925 * instruction decoding to derive the system call number.
926 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
927 * so that this doesn't work if a SVC opcode is part of an EXECUTE
928 * opcode. Since there is no way to find out the opcode size this
929 * is the best we can do...
932 if ((opcode & 0xff00) == 0x0a00) {
934 scno = opcode & 0xff;
937 /* SVC got executed by EXECUTE instruction */
940 * Do instruction decoding of EXECUTE. If you really want to
941 * understand this, read the Principles of Operations.
943 svc_addr = (void *) (opcode & 0xfff);
946 offset_reg = (opcode & 0x000f0000) >> 16;
947 if (offset_reg && (upeek(pid, gpr_offset[offset_reg], &tmp) < 0))
952 offset_reg = (opcode & 0x0000f000) >> 12;
953 if (offset_reg && (upeek(pid, gpr_offset[offset_reg], &tmp) < 0))
957 scno = ptrace(PTRACE_PEEKTEXT, pid, svc_addr, 0);
966 offset_reg = (opcode & 0x00f00000) >> 20;
967 if (offset_reg && (upeek(pid, gpr_offset[offset_reg], &tmp) < 0))
970 scno = (scno | tmp) & 0xff;
973 #elif defined (POWERPC)
974 if (upeek(pid, sizeof(unsigned long)*PT_R0, &scno) < 0)
976 if (!(tcp->flags & TCB_INSYSCALL)) {
977 /* Check if we return from execve. */
978 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
979 tcp->flags &= ~TCB_WAITEXECVE;
984 if (upeek(pid, 4*ORIG_EAX, &scno) < 0)
986 #elif defined (X86_64)
987 if (upeek(pid, 8*ORIG_RAX, &scno) < 0)
990 if (!(tcp->flags & TCB_INSYSCALL)) {
991 static int currpers=-1;
994 /* Check CS register value. On x86-64 linux it is:
995 * 0x33 for long mode (64 bit)
996 * 0x23 for compatibility mode (32 bit)
997 * It takes only one ptrace and thus doesn't need
1000 if (upeek(pid, 8*CS, &val) < 0)
1004 case 0x23: currpers = 1; break;
1005 case 0x33: currpers = 0; break;
1007 fprintf(stderr, "Unknown value CS=0x%02X while "
1008 "detecting personality of process "
1009 "PID=%d\n", (int)val, pid);
1010 currpers = current_personality;
1014 /* This version analyzes the opcode of a syscall instruction.
1015 * (int 0x80 on i386 vs. syscall on x86-64)
1016 * It works, but is too complicated.
1018 unsigned long val, rip, i;
1020 if(upeek(pid, 8*RIP, &rip)<0)
1021 perror("upeek(RIP)");
1023 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
1027 call = ptrace(PTRACE_PEEKTEXT,pid,(char *)rip,0);
1029 printf("ptrace_peektext failed: %s\n",
1031 switch (call & 0xffff)
1033 /* x86-64: syscall = 0x0f 0x05 */
1034 case 0x050f: currpers = 0; break;
1035 /* i386: int 0x80 = 0xcd 0x80 */
1036 case 0x80cd: currpers = 1; break;
1038 currpers = current_personality;
1040 "Unknown syscall opcode (0x%04X) while "
1041 "detecting personality of process "
1042 "PID=%d\n", (int)call, pid);
1046 if(currpers != current_personality)
1048 char *names[]={"64 bit", "32 bit"};
1049 set_personality(currpers);
1050 printf("[ Process PID=%d runs in %s mode. ]\n",
1051 pid, names[current_personality]);
1055 # define IA64_PSR_IS ((long)1 << 34)
1056 if (upeek (pid, PT_CR_IPSR, &psr) >= 0)
1057 ia32 = (psr & IA64_PSR_IS) != 0;
1058 if (!(tcp->flags & TCB_INSYSCALL)) {
1060 if (upeek(pid, PT_R1, &scno) < 0) /* orig eax */
1063 if (upeek (pid, PT_R15, &scno) < 0)
1066 /* Check if we return from execve. */
1067 if (tcp->flags & TCB_WAITEXECVE) {
1068 tcp->flags &= ~TCB_WAITEXECVE;
1072 /* syscall in progress */
1073 if (upeek (pid, PT_R8, &r8) < 0)
1075 if (upeek (pid, PT_R10, &r10) < 0)
1080 * Read complete register set in one go.
1082 if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)®s) == -1)
1086 * We only need to grab the syscall number on syscall entry.
1088 if (regs.ARM_ip == 0) {
1090 * Note: we only deal with only 32-bit CPUs here.
1092 if (regs.ARM_cpsr & 0x20) {
1094 * Get the Thumb-mode system call number
1099 * Get the ARM-mode system call number
1102 scno = ptrace(PTRACE_PEEKTEXT, pid, (void *)(regs.ARM_pc - 4), NULL);
1106 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1107 tcp->flags &= ~TCB_WAITEXECVE;
1111 if ((scno & 0x0ff00000) != 0x0f900000) {
1112 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1118 * Fixup the syscall number
1123 if (tcp->flags & TCB_INSYSCALL) {
1124 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1125 tcp->flags &= ~TCB_INSYSCALL;
1128 if (!(tcp->flags & TCB_INSYSCALL)) {
1129 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1130 tcp->flags |= TCB_INSYSCALL;
1133 #elif defined (M68K)
1134 if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)
1136 #elif defined (MIPS)
1137 if (upeek(pid, REG_A3, &a3) < 0)
1140 if(!(tcp->flags & TCB_INSYSCALL)) {
1141 if (upeek(pid, REG_V0, &scno) < 0)
1144 if (scno < 0 || scno > nsyscalls) {
1145 if(a3 == 0 || a3 == -1) {
1147 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1152 if (upeek(pid, REG_V0, &r2) < 0)
1155 #elif defined (ALPHA)
1156 if (upeek(pid, REG_A3, &a3) < 0)
1159 if (!(tcp->flags & TCB_INSYSCALL)) {
1160 if (upeek(pid, REG_R0, &scno) < 0)
1163 /* Check if we return from execve. */
1164 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1165 tcp->flags &= ~TCB_WAITEXECVE;
1170 * Do some sanity checks to figure out if it's
1171 * really a syscall entry
1173 if (scno < 0 || scno > nsyscalls) {
1174 if (a3 == 0 || a3 == -1) {
1176 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1182 if (upeek(pid, REG_R0, &r0) < 0)
1185 #elif defined (SPARC) || defined (SPARC64)
1186 /* Everything we need is in the current register set. */
1187 if (ptrace(PTRACE_GETREGS,pid,(char *)®s,0) < 0)
1190 /* If we are entering, then disassemble the syscall trap. */
1191 if (!(tcp->flags & TCB_INSYSCALL)) {
1192 /* Retrieve the syscall trap instruction. */
1194 trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
1195 #if defined(SPARC64)
1201 /* Disassemble the trap to see what personality to use. */
1204 /* Linux/SPARC syscall trap. */
1208 /* Linux/SPARC64 syscall trap. */
1212 /* SunOS syscall trap. (pers 1) */
1213 fprintf(stderr,"syscall: SunOS no support\n");
1216 /* Solaris 2.x syscall trap. (per 2) */
1220 /* NetBSD/FreeBSD syscall trap. */
1221 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1224 /* Solaris 2.x gettimeofday */
1228 /* Unknown syscall trap. */
1229 if(tcp->flags & TCB_WAITEXECVE) {
1230 tcp->flags &= ~TCB_WAITEXECVE;
1233 #if defined (SPARC64)
1234 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.r_tpc);
1236 fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
1241 /* Extract the system call number from the registers. */
1242 if (trap == 0x91d02027)
1248 memmove (®s.r_o0, ®s.r_o1, 7*sizeof(regs.r_o0));
1252 if (upeek(pid, PT_GR20, &scno) < 0)
1254 if (!(tcp->flags & TCB_INSYSCALL)) {
1255 /* Check if we return from execve. */
1256 if ((tcp->flags & TCB_WAITEXECVE)) {
1257 tcp->flags &= ~TCB_WAITEXECVE;
1263 * In the new syscall ABI, the system call number is in R3.
1265 if (upeek(pid, 4*(REG_REG0+3), &scno) < 0)
1269 /* Odd as it may seem, a glibc bug has been known to cause
1270 glibc to issue bogus negative syscall numbers. So for
1271 our purposes, make strace print what it *should* have been */
1272 long correct_scno = (scno & 0xff);
1275 "Detected glibc bug: bogus system call number = %ld, "
1276 "correcting to %ld\n",
1279 scno = correct_scno;
1283 if (!(tcp->flags & TCB_INSYSCALL)) {
1284 /* Check if we return from execve. */
1285 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1286 tcp->flags &= ~TCB_WAITEXECVE;
1291 if (upeek(pid, REG_SYSCALL, &scno) < 0)
1295 if (!(tcp->flags & TCB_INSYSCALL)) {
1296 /* Check if we return from execve. */
1297 if (tcp->flags & TCB_WAITEXECVE) {
1298 tcp->flags &= ~TCB_WAITEXECVE;
1305 if (upeek(pid, uoff(u_arg[7]), &scno) < 0)
1308 /* new syscall ABI returns result in R0 */
1309 if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
1312 /* ABI defines result returned in r9 */
1313 if (upeek(pid, REG_GENERAL(9), (long *)&r9) < 0)
1318 #ifdef HAVE_PR_SYSCALL
1319 scno = tcp->status.PR_SYSCALL;
1320 #else /* !HAVE_PR_SYSCALL */
1322 scno = tcp->status.PR_WHAT;
1324 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1328 switch (regs.r_eax) {
1331 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1337 #endif /* FREEBSD */
1338 #endif /* !HAVE_PR_SYSCALL */
1339 #endif /* USE_PROCFS */
1340 if (!(tcp->flags & TCB_INSYSCALL))
1350 long scno = tcp->scno;
1351 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1352 scno = sysent[scno].native_scno;
1354 scno += NR_SYSCALL_BASE;
1364 #else /* USE_PROCFS */
1365 int scno = known_scno(tcp);
1367 if (!(tcp->flags & TCB_INSYSCALL)) {
1368 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1372 || scno == SYS_vfork
1373 #endif /* SYS_vfork */
1375 || scno == SYS_fork1
1376 #endif /* SYS_fork1 */
1378 || scno == SYS_forkall
1379 #endif /* SYS_forkall */
1381 || scno == SYS_rfork1
1382 #endif /* SYS_fork1 */
1384 || scno == SYS_rforkall
1385 #endif /* SYS_rforkall */
1387 /* We are returning in the child, fake it. */
1388 tcp->status.PR_WHY = PR_SYSENTRY;
1390 tcp->status.PR_WHY = PR_SYSEXIT;
1393 fprintf(stderr, "syscall: missing entry\n");
1394 tcp->flags |= TCB_INSYSCALL;
1399 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1400 fprintf(stderr, "syscall: missing exit\n");
1401 tcp->flags &= ~TCB_INSYSCALL;
1404 #endif /* USE_PROCFS */
1406 if (!(tcp->flags & TCB_INSYSCALL)) {
1408 fprintf(stderr, "syscall: missing entry\n");
1409 tcp->flags |= TCB_INSYSCALL;
1416 * This happens when a signal handler
1417 * for a signal which interrupted a
1418 * a system call makes another system call.
1420 fprintf(stderr, "syscall: missing exit\n");
1422 tcp->flags &= ~TCB_INSYSCALL;
1428 if (upeek(pid, 4*EAX, &eax) < 0)
1430 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1432 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1435 #elif defined (X86_64)
1436 if (upeek(pid, 8*RAX, &rax) < 0)
1438 if (current_personality == 1)
1439 rax = (long int)(int)rax; /* sign extend from 32 bits */
1440 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1442 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1445 #elif defined (S390) || defined (S390X)
1446 if (upeek(pid, PT_GPR2, &gpr2) < 0)
1448 if (syscall_mode != -ENOSYS)
1449 syscall_mode = tcp->scno;
1450 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1452 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1455 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1456 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1457 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1459 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1460 * flag set for the post-execve SIGTRAP to see and reset.
1464 #elif defined (POWERPC)
1465 # define SO_MASK 0x10000000
1466 if (upeek(pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1468 if (upeek(pid, sizeof(unsigned long)*PT_R3, &result) < 0)
1470 if (flags & SO_MASK)
1472 #elif defined (M68K)
1473 if (upeek(pid, 4*PT_D0, &d0) < 0)
1475 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1477 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1484 #elif defined (HPPA)
1485 if (upeek(pid, PT_GR28, &r28) < 0)
1488 if (upeek(pid, PT_R10, &r10) < 0)
1490 if (upeek(pid, PT_R8, &r8) < 0)
1492 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1494 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1508 #if defined(S390) || defined(S390X)
1509 if (gpr2 && (unsigned) -gpr2 < nerrnos) {
1517 #else /* !S390 && !S390X */
1519 if (eax < 0 && -eax < nerrnos) {
1529 if (rax < 0 && -rax < nerrnos) {
1543 if (err < 0 && -err < nerrnos) {
1571 if (result && (unsigned long) -result < nerrnos) {
1576 tcp->u_rval = result;
1579 #else /* !POWERPC */
1581 if (d0 && (unsigned) -d0 < nerrnos) {
1591 if (regs.ARM_r0 && (unsigned) -regs.ARM_r0 < nerrnos) {
1593 u_error = -regs.ARM_r0;
1596 tcp->u_rval = regs.ARM_r0;
1611 if (regs.r_psr & PSR_C) {
1613 u_error = regs.r_o0;
1616 tcp->u_rval = regs.r_o0;
1621 if (regs.r_tstate & 0x1100000000UL) {
1623 u_error = regs.r_o0;
1626 tcp->u_rval = regs.r_o0;
1629 #else /* !SPARC64 */
1631 if (r28 && (unsigned) -r28 < nerrnos) {
1641 /* interpret R0 as return value or error number */
1642 if (r0 && (unsigned) -r0 < nerrnos) {
1652 /* interpret result as return value or error number */
1653 if (r9 && (unsigned) -r9 < nerrnos) {
1665 #endif /* SPARC64 */
1669 #endif /* POWERPC */
1674 #endif /* S390 || S390X */
1677 /* get error code from user struct */
1678 if (upeek(pid, uoff(u_error), &u_error) < 0)
1680 u_error >>= 24; /* u_error is a char */
1682 /* get system call return value */
1683 if (upeek(pid, uoff(u_rval1), &tcp->u_rval) < 0)
1688 /* Judicious guessing goes a long way. */
1689 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1691 u_error = tcp->status.pr_reg[R_O0];
1694 tcp->u_rval = tcp->status.pr_reg[R_O0];
1699 /* Wanna know how to kill an hour single-stepping? */
1700 if (tcp->status.PR_REG[EFL] & 0x1) {
1702 u_error = tcp->status.PR_REG[EAX];
1705 tcp->u_rval = tcp->status.PR_REG[EAX];
1706 #ifdef HAVE_LONG_LONG
1708 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1709 tcp->status.PR_REG[EAX];
1715 /* Wanna know how to kill an hour single-stepping? */
1716 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1718 u_error = tcp->status.PR_REG[RAX];
1721 tcp->u_rval = tcp->status.PR_REG[RAX];
1726 if (tcp->status.pr_reg[CTX_A3]) {
1728 u_error = tcp->status.pr_reg[CTX_V0];
1731 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1737 if (regs.r_eflags & PSL_C) {
1739 u_error = regs.r_eax;
1741 tcp->u_rval = regs.r_eax;
1743 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1746 #endif /* FREEBSD */
1747 tcp->u_error = u_error;
1752 force_result(tcp, error, rval)
1758 #if defined(S390) || defined(S390X)
1759 gpr2 = error ? -error : rval;
1760 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1762 #else /* !S390 && !S390X */
1764 eax = error ? -error : rval;
1765 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1769 rax = error ? -error : rval;
1770 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1775 r8 = error ? -error : rval;
1776 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1788 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1789 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1802 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1803 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1807 if (upeek(tcp->pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1817 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1818 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1820 #else /* !POWERPC */
1822 d0 = error ? -error : rval;
1823 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1827 regs.ARM_r0 = error ? -error : rval;
1828 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1840 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1841 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1845 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1848 regs.r_psr |= PSR_C;
1852 regs.r_psr &= ~PSR_C;
1855 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1859 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1862 regs.r_tstate |= 0x1100000000UL;
1866 regs.r_tstate &= ~0x1100000000UL;
1869 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1871 #else /* !SPARC64 */
1873 r28 = error ? -error : rval;
1874 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1878 r0 = error ? -error : rval;
1879 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1883 r9 = error ? -error : rval;
1884 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1890 #endif /* SPARC64 */
1894 #endif /* POWERPC */
1899 #endif /* S390 || S390X */
1902 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1904 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1912 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1917 regs.r_eflags |= PSL_C;
1921 regs.r_eflags &= ~PSL_C;
1924 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1928 #endif /* FREEBSD */
1930 /* All branches reach here on success (only). */
1931 tcp->u_error = error;
1942 #endif /* !USE_PROCFS */
1944 #if defined(S390) || defined(S390X)
1947 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1948 tcp->u_nargs = sysent[tcp->scno].nargs;
1950 tcp->u_nargs = MAX_ARGS;
1951 for (i = 0; i < tcp->u_nargs; i++) {
1952 if (upeek(pid,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1956 #elif defined (ALPHA)
1959 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1960 tcp->u_nargs = sysent[tcp->scno].nargs;
1962 tcp->u_nargs = MAX_ARGS;
1963 for (i = 0; i < tcp->u_nargs; i++) {
1964 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1965 * for scno somewhere above here!
1967 if (upeek(pid, REG_A0+i, &tcp->u_arg[i]) < 0)
1971 #elif defined (IA64)
1974 unsigned long *out0, *rbs_end, cfm, sof, sol, i;
1975 /* be backwards compatible with kernel < 2.4.4... */
1977 # define PT_RBS_END PT_AR_BSP
1980 if (upeek(pid, PT_RBS_END, (long *) &rbs_end) < 0)
1982 if (upeek(pid, PT_CFM, (long *) &cfm) < 0)
1985 sof = (cfm >> 0) & 0x7f;
1986 sol = (cfm >> 7) & 0x7f;
1987 out0 = ia64_rse_skip_regs(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(pid, PT_R11, (long *) &tcp->u_arg[0]) < 0
2005 || upeek(pid, PT_R9, (long *) &tcp->u_arg[1]) < 0
2007 || upeek(pid, PT_R10, (long *) &tcp->u_arg[2]) < 0
2009 || upeek(pid, PT_R14, (long *) &tcp->u_arg[3]) < 0
2011 || upeek(pid, PT_R15, (long *) &tcp->u_arg[4]) < 0
2013 || upeek(pid, 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 (MIPS)
2032 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2033 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2035 nargs = tcp->u_nargs = MAX_ARGS;
2037 if(upeek(pid, REG_SP, &sp) < 0)
2039 for(i = 0; i < 4; i++) {
2040 if (upeek(pid, REG_A0 + i, &tcp->u_arg[i])<0)
2043 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2044 (char *)(tcp->u_arg + 4));
2046 for(i = 0; i < nargs; i++) {
2047 if (upeek(pid, REG_A0 + i, &tcp->u_arg[i]) < 0)
2052 #elif defined (POWERPC)
2054 #define PT_ORIG_R3 34
2058 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2059 tcp->u_nargs = sysent[tcp->scno].nargs;
2061 tcp->u_nargs = MAX_ARGS;
2062 for (i = 0; i < tcp->u_nargs; i++) {
2063 if (upeek(pid, (i==0) ?
2064 (sizeof(unsigned long)*PT_ORIG_R3) :
2065 ((i+PT_R3)*sizeof(unsigned long)),
2066 &tcp->u_arg[i]) < 0)
2070 #elif defined (SPARC) || defined (SPARC64)
2074 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2075 tcp->u_nargs = sysent[tcp->scno].nargs;
2077 tcp->u_nargs = MAX_ARGS;
2078 for (i = 0; i < tcp->u_nargs; i++)
2079 tcp->u_arg[i] = *((®s.r_o0) + i);
2081 #elif defined (HPPA)
2085 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2086 tcp->u_nargs = sysent[tcp->scno].nargs;
2088 tcp->u_nargs = MAX_ARGS;
2089 for (i = 0; i < tcp->u_nargs; i++) {
2090 if (upeek(pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2098 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2099 tcp->u_nargs = sysent[tcp->scno].nargs;
2101 tcp->u_nargs = MAX_ARGS;
2102 for (i = 0; i < tcp->u_nargs; i++)
2103 tcp->u_arg[i] = regs.uregs[i];
2108 static int syscall_regs[] = {
2109 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2110 REG_REG0, REG_REG0+1, REG_REG0+2
2113 tcp->u_nargs = sysent[tcp->scno].nargs;
2114 for (i = 0; i < tcp->u_nargs; i++) {
2115 if (upeek(pid, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2122 /* Registers used by SH5 Linux system calls for parameters */
2123 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2126 * TODO: should also check that the number of arguments encoded
2127 * in the trap number matches the number strace expects.
2130 assert(sysent[tcp->scno].nargs <
2131 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2134 tcp->u_nargs = sysent[tcp->scno].nargs;
2135 for (i = 0; i < tcp->u_nargs; i++) {
2136 if (upeek(pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2141 #elif defined(X86_64)
2144 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2145 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2146 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2149 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2150 tcp->u_nargs = sysent[tcp->scno].nargs;
2152 tcp->u_nargs = MAX_ARGS;
2153 for (i = 0; i < tcp->u_nargs; i++) {
2154 if (upeek(pid, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2158 #else /* Other architecture (like i386) (32bits specific) */
2161 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2162 tcp->u_nargs = sysent[tcp->scno].nargs;
2164 tcp->u_nargs = MAX_ARGS;
2165 for (i = 0; i < tcp->u_nargs; i++) {
2166 if (upeek(pid, i*4, &tcp->u_arg[i]) < 0)
2175 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2176 tcp->u_nargs = sysent[tcp->scno].nargs;
2178 tcp->u_nargs = MAX_ARGS;
2179 for (i = 0; i < tcp->u_nargs; i++) {
2182 if (upeek(pid, uoff(u_arg[0]) +
2183 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2191 * SGI is broken: even though it has pr_sysarg, it doesn't
2192 * set them on system call entry. Get a clue.
2194 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2195 tcp->u_nargs = sysent[tcp->scno].nargs;
2197 tcp->u_nargs = tcp->status.pr_nsysarg;
2198 if (tcp->u_nargs > 4) {
2199 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2200 4*sizeof(tcp->u_arg[0]));
2201 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2202 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2205 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2206 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2210 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2212 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2213 tcp->u_nargs = sysent[tcp->scno].nargs;
2215 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2216 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2217 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2218 #elif defined (HAVE_PR_SYSCALL)
2219 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2220 tcp->u_nargs = sysent[tcp->scno].nargs;
2222 tcp->u_nargs = tcp->status.pr_nsysarg;
2225 for (i = 0; i < tcp->u_nargs; i++)
2226 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2228 #elif defined (I386)
2229 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2230 tcp->u_nargs = sysent[tcp->scno].nargs;
2233 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2234 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2236 I DONT KNOW WHAT TO DO
2237 #endif /* !HAVE_PR_SYSCALL */
2240 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2241 sysent[tcp->scno].nargs > tcp->status.val)
2242 tcp->u_nargs = sysent[tcp->scno].nargs;
2244 tcp->u_nargs = tcp->status.val;
2245 if (tcp->u_nargs < 0)
2247 if (tcp->u_nargs > MAX_ARGS)
2248 tcp->u_nargs = MAX_ARGS;
2249 switch(regs.r_eax) {
2251 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2252 regs.r_esp + sizeof(int) + sizeof(quad_t));
2255 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2256 regs.r_esp + 2 * sizeof(int));
2259 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2260 regs.r_esp + sizeof(int));
2263 #endif /* FREEBSD */
2275 /* Measure the exit time as early as possible to avoid errors. */
2276 if (dtime && (tcp->flags & TCB_INSYSCALL))
2277 gettimeofday(&tv, NULL);
2279 res = get_scno(tcp);
2283 res = syscall_fixup(tcp);
2287 if (tcp->flags & TCB_INSYSCALL) {
2289 res = get_error(tcp);
2293 internal_syscall(tcp);
2294 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2295 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2296 tcp->flags &= ~TCB_INSYSCALL;
2300 if (tcp->flags & TCB_REPRINT) {
2303 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2304 tprintf("syscall_%lu", tcp->scno);
2306 tprintf("%s", sysent[tcp->scno].sys_name);
2307 tprintf(" resumed> ");
2310 if (cflag && tcp->scno < nsyscalls && tcp->scno >= 0) {
2311 if (counts == NULL) {
2312 counts = calloc(sizeof *counts, nsyscalls);
2313 if (counts == NULL) {
2315 strace: out of memory for call counts\n");
2320 counts[tcp->scno].calls++;
2322 counts[tcp->scno].errors++;
2323 tv_sub(&tv, &tv, &tcp->etime);
2325 if (tv_cmp(&tv, &tcp->dtime) > 0) {
2326 static struct timeval one_tick;
2327 if (one_tick.tv_usec == 0) {
2328 /* Initialize it. */
2329 struct itimerval it;
2330 memset(&it, 0, sizeof it);
2331 it.it_interval.tv_usec = 1;
2332 setitimer(ITIMER_REAL, &it, NULL);
2333 getitimer(ITIMER_REAL, &it);
2334 one_tick = it.it_interval;
2337 if (tv_nz(&tcp->dtime))
2339 else if (tv_cmp(&tv, &one_tick) > 0) {
2340 if (tv_cmp(&shortest, &one_tick) < 0)
2347 if (tv_cmp(&tv, &shortest) < 0)
2349 tv_add(&counts[tcp->scno].time,
2350 &counts[tcp->scno].time, &tv);
2351 tcp->flags &= ~TCB_INSYSCALL;
2355 if (tcp->scno >= nsyscalls || tcp->scno < 0
2356 || (qual_flags[tcp->scno] & QUAL_RAW))
2357 sys_res = printargs(tcp);
2359 if (not_failing_only && tcp->u_error)
2360 return 0; /* ignore failed syscalls */
2361 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2363 u_error = tcp->u_error;
2366 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2367 qual_flags[tcp->scno] & QUAL_RAW) {
2369 tprintf("= -1 (errno %ld)", u_error);
2371 tprintf("= %#lx", tcp->u_rval);
2373 else if (!(sys_res & RVAL_NONE) && u_error) {
2377 tprintf("= ? ERESTARTSYS (To be restarted)");
2379 case ERESTARTNOINTR:
2380 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2382 case ERESTARTNOHAND:
2383 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2385 case ERESTART_RESTARTBLOCK:
2386 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2392 tprintf("E??? (errno %ld)", u_error);
2393 else if (u_error < nerrnos)
2394 tprintf("%s (%s)", errnoent[u_error],
2397 tprintf("ERRNO_%ld (%s)", u_error,
2403 if (sys_res & RVAL_NONE)
2406 switch (sys_res & RVAL_MASK) {
2408 tprintf("= %#lx", tcp->u_rval);
2411 tprintf("= %#lo", tcp->u_rval);
2414 tprintf("= %lu", tcp->u_rval);
2417 tprintf("= %ld", tcp->u_rval);
2419 #ifdef HAVE_LONG_LONG
2421 tprintf("= %#llx", tcp->u_lrval);
2424 tprintf("= %#llo", tcp->u_lrval);
2426 case RVAL_LUDECIMAL:
2427 tprintf("= %llu", tcp->u_lrval);
2430 tprintf("= %lld", tcp->u_lrval);
2435 "invalid rval format\n");
2439 if ((sys_res & RVAL_STR) && tcp->auxstr)
2440 tprintf(" (%s)", tcp->auxstr);
2443 tv_sub(&tv, &tv, &tcp->etime);
2444 tprintf(" <%ld.%06ld>",
2445 (long) tv.tv_sec, (long) tv.tv_usec);
2450 if (fflush(tcp->outf) == EOF)
2452 tcp->flags &= ~TCB_INSYSCALL;
2456 /* Entering system call */
2457 res = syscall_enter(tcp);
2461 switch (known_scno(tcp)) {
2463 #if !defined (ALPHA) && !defined(SPARC) && !defined(SPARC64) && !defined(MIPS) && !defined(HPPA)
2464 case SYS_socketcall:
2465 decode_subcall(tcp, SYS_socket_subcall,
2466 SYS_socket_nsubcalls, deref_style);
2469 decode_subcall(tcp, SYS_ipc_subcall,
2470 SYS_ipc_nsubcalls, shift_style);
2472 #endif /* !ALPHA && !MIPS && !SPARC && !SPARC64 && !HPPA */
2473 #if defined (SPARC) || defined (SPARC64)
2474 case SYS_socketcall:
2475 sparc_socket_decode (tcp);
2480 #ifdef SYS_pgrpsys_subcall
2482 decode_subcall(tcp, SYS_pgrpsys_subcall,
2483 SYS_pgrpsys_nsubcalls, shift_style);
2485 #endif /* SYS_pgrpsys_subcall */
2486 #ifdef SYS_sigcall_subcall
2488 decode_subcall(tcp, SYS_sigcall_subcall,
2489 SYS_sigcall_nsubcalls, mask_style);
2491 #endif /* SYS_sigcall_subcall */
2493 decode_subcall(tcp, SYS_msgsys_subcall,
2494 SYS_msgsys_nsubcalls, shift_style);
2497 decode_subcall(tcp, SYS_shmsys_subcall,
2498 SYS_shmsys_nsubcalls, shift_style);
2501 decode_subcall(tcp, SYS_semsys_subcall,
2502 SYS_semsys_nsubcalls, shift_style);
2506 decode_subcall(tcp, SYS_utssys_subcall,
2507 SYS_utssys_nsubcalls, shift_style);
2511 decode_subcall(tcp, SYS_sysfs_subcall,
2512 SYS_sysfs_nsubcalls, shift_style);
2515 decode_subcall(tcp, SYS_spcall_subcall,
2516 SYS_spcall_nsubcalls, shift_style);
2518 #ifdef SYS_context_subcall
2520 decode_subcall(tcp, SYS_context_subcall,
2521 SYS_context_nsubcalls, shift_style);
2523 #endif /* SYS_context_subcall */
2524 #ifdef SYS_door_subcall
2526 decode_subcall(tcp, SYS_door_subcall,
2527 SYS_door_nsubcalls, door_style);
2529 #endif /* SYS_door_subcall */
2530 #ifdef SYS_kaio_subcall
2532 decode_subcall(tcp, SYS_kaio_subcall,
2533 SYS_kaio_nsubcalls, shift_style);
2541 decode_subcall(tcp, 0, 0, table_style);
2546 decode_subcall(tcp, SYS_semsys_subcall,
2547 SYS_semsys_nsubcalls, shift_style);
2550 decode_subcall(tcp, SYS_msgsys_subcall,
2551 SYS_msgsys_nsubcalls, shift_style);
2554 decode_subcall(tcp, SYS_shmsys_subcall,
2555 SYS_shmsys_nsubcalls, shift_style);
2560 internal_syscall(tcp);
2561 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2562 tcp->flags |= TCB_INSYSCALL;
2567 gettimeofday(&tcp->etime, NULL);
2568 tcp->flags |= TCB_INSYSCALL;
2573 tcp->flags &= ~TCB_REPRINT;
2575 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2576 tprintf("syscall_%lu(", tcp->scno);
2578 tprintf("%s(", sysent[tcp->scno].sys_name);
2579 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2580 ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2581 sys_res = printargs(tcp);
2583 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2584 if (fflush(tcp->outf) == EOF)
2586 tcp->flags |= TCB_INSYSCALL;
2587 /* Measure the entrance time as late as possible to avoid errors. */
2589 gettimeofday(&tcp->etime, NULL);
2597 if (entering(tcp)) {
2600 for (i = 0; i < tcp->u_nargs; i++)
2601 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2613 #if defined (SPARC) || defined (SPARC64)
2615 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2619 if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0)
2622 if (upeek(tcp->pid, PT_R9, &val) < 0)
2624 #endif /* SPARC || SPARC64 */
2628 if (upeek(tcp->pid, uoff(u_rval2), &val) < 0)
2634 val = tcp->status.PR_REG[R_O1];
2637 val = tcp->status.PR_REG[EDX];
2640 val = tcp->status.PR_REG[RDX];
2643 val = tcp->status.PR_REG[CTX_V1];
2648 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2655 * Apparently, indirect system calls have already be converted by ptrace(2),
2656 * so if you see "indir" this program has gone astray.
2664 if (entering(tcp)) {
2665 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2666 fprintf(stderr, "Bogus syscall: %u\n", scno);
2669 nargs = sysent[scno].nargs;
2670 tprintf("%s", sysent[scno].sys_name);
2671 for (i = 0; i < nargs; i++)
2672 tprintf(", %#lx", tcp->u_arg[i+1]);
2682 return -tv_cmp(&counts[*((int *) a)].time, &counts[*((int *) b)].time);
2690 return strcmp(sysent[*((int *) a)].sys_name,
2691 sysent[*((int *) b)].sys_name);
2699 int m = counts[*((int *) a)].calls, n = counts[*((int *) b)].calls;
2701 return (m < n) ? 1 : (m > n) ? -1 : 0;
2704 static int (*sortfun)();
2705 static struct timeval overhead = { -1, -1 };
2711 if (strcmp(sortby, "time") == 0)
2713 else if (strcmp(sortby, "calls") == 0)
2714 sortfun = count_cmp;
2715 else if (strcmp(sortby, "name") == 0)
2716 sortfun = syscall_cmp;
2717 else if (strcmp(sortby, "nothing") == 0)
2720 fprintf(stderr, "invalid sortby: `%s'\n", sortby);
2725 void set_overhead(n)
2728 overhead.tv_sec = n / 1000000;
2729 overhead.tv_usec = n % 1000000;
2737 int call_cum, error_cum;
2738 struct timeval tv_cum, dtv;
2740 char *dashes = "-------------------------";
2743 int *sorted_count = malloc(nsyscalls * sizeof(int));
2745 call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
2746 if (overhead.tv_sec == -1) {
2747 tv_mul(&overhead, &shortest, 8);
2748 tv_div(&overhead, &overhead, 10);
2750 for (i = 0; i < nsyscalls; i++) {
2751 sorted_count[i] = i;
2752 if (counts == NULL || counts[i].calls == 0)
2754 tv_mul(&dtv, &overhead, counts[i].calls);
2755 tv_sub(&counts[i].time, &counts[i].time, &dtv);
2756 call_cum += counts[i].calls;
2757 error_cum += counts[i].errors;
2758 tv_add(&tv_cum, &tv_cum, &counts[i].time);
2760 if (counts && sortfun)
2761 qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun);
2762 fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
2763 "% time", "seconds", "usecs/call",
2764 "calls", "errors", "syscall");
2765 fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
2766 dashes, dashes, dashes, dashes, dashes, dashes);
2768 for (i = 0; i < nsyscalls; i++) {
2769 j = sorted_count[i];
2770 if (counts[j].calls == 0)
2772 tv_div(&dtv, &counts[j].time, counts[j].calls);
2773 if (counts[j].errors)
2774 sprintf(error_str, "%d", counts[j].errors);
2776 error_str[0] = '\0';
2777 percent = (100.0 * tv_float(&counts[j].time)
2778 / tv_float(&tv_cum));
2779 fprintf(outf, "%6.2f %4ld.%06ld %11ld %9d %9.9s %s\n",
2780 percent, (long) counts[j].time.tv_sec,
2781 (long) counts[j].time.tv_usec,
2782 (long) 1000000 * dtv.tv_sec + dtv.tv_usec,
2784 error_str, sysent[j].sys_name);
2789 fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
2790 dashes, dashes, dashes, dashes, dashes, dashes);
2792 sprintf(error_str, "%d", error_cum);
2794 error_str[0] = '\0';
2795 fprintf(outf, "%6.6s %4ld.%06ld %11.11s %9d %9.9s %s\n",
2796 "100.00", (long) tv_cum.tv_sec, (long) tv_cum.tv_usec, "",
2797 call_cum, error_str, "total");