2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 #include <sys/syscall.h>
43 #include <sys/param.h>
47 #ifndef PTRACE_PEEKUSR
48 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
50 #elif defined(HAVE_LINUX_PTRACE_H)
52 # ifdef HAVE_STRUCT_IA64_FPREG
53 # define ia64_fpreg XXX_ia64_fpreg
55 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
56 # define pt_all_user_regs XXX_pt_all_user_regs
58 #include <linux/ptrace.h>
60 # undef pt_all_user_regs
63 #if defined (LINUX) && defined (SPARC64)
64 # undef PTRACE_GETREGS
65 # define PTRACE_GETREGS PTRACE_GETREGS64
66 # undef PTRACE_SETREGS
67 # define PTRACE_SETREGS PTRACE_SETREGS64
68 #endif /* LINUX && SPARC64 */
70 #if defined(LINUX) && defined(IA64)
71 # include <asm/ptrace_offsets.h>
75 #define NR_SYSCALL_BASE 0
78 #define ERESTARTSYS 512
80 #ifndef ERESTARTNOINTR
81 #define ERESTARTNOINTR 513
83 #ifndef ERESTARTNOHAND
84 #define ERESTARTNOHAND 514 /* restart if no handler.. */
87 #define ENOIOCTLCMD 515 /* No ioctl command */
89 #ifndef ERESTART_RESTARTBLOCK
90 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
98 #undef NR_SYSCALL_BASE
99 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
105 /* Define these shorthand notations to simplify the syscallent files. */
106 #define TD TRACE_DESC
107 #define TF TRACE_FILE
109 #define TN TRACE_NETWORK
110 #define TP TRACE_PROCESS
111 #define TS TRACE_SIGNAL
112 #define NF SYSCALL_NEVER_FAILS
114 static const struct sysent sysent0[] = {
115 #include "syscallent.h"
117 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
118 int qual_flags0[MAX_QUALS];
120 #if SUPPORTED_PERSONALITIES >= 2
121 static const struct sysent sysent1[] = {
122 #include "syscallent1.h"
124 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
125 int qual_flags1[MAX_QUALS];
126 #endif /* SUPPORTED_PERSONALITIES >= 2 */
128 #if SUPPORTED_PERSONALITIES >= 3
129 static const struct sysent sysent2[] = {
130 #include "syscallent2.h"
132 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
133 int qual_flags2[MAX_QUALS];
134 #endif /* SUPPORTED_PERSONALITIES >= 3 */
136 const struct sysent *sysent;
140 /* Now undef them since short defines cause wicked namespace pollution. */
149 static const char *const errnoent0[] = {
150 #include "errnoent.h"
152 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
154 #if SUPPORTED_PERSONALITIES >= 2
155 static const char *const errnoent1[] = {
156 #include "errnoent1.h"
158 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
159 #endif /* SUPPORTED_PERSONALITIES >= 2 */
161 #if SUPPORTED_PERSONALITIES >= 3
162 static const char *const errnoent2[] = {
163 #include "errnoent2.h"
165 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
166 #endif /* SUPPORTED_PERSONALITIES >= 3 */
168 const char *const *errnoent;
171 int current_personality;
173 #ifndef PERSONALITY0_WORDSIZE
174 # define PERSONALITY0_WORDSIZE sizeof(long)
176 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
177 PERSONALITY0_WORDSIZE,
178 #if SUPPORTED_PERSONALITIES > 1
179 PERSONALITY1_WORDSIZE,
181 #if SUPPORTED_PERSONALITIES > 2
182 PERSONALITY2_WORDSIZE,
187 set_personality(int personality)
189 switch (personality) {
191 errnoent = errnoent0;
194 nsyscalls = nsyscalls0;
195 ioctlent = ioctlent0;
196 nioctlents = nioctlents0;
197 signalent = signalent0;
198 nsignals = nsignals0;
199 qual_flags = qual_flags0;
202 #if SUPPORTED_PERSONALITIES >= 2
204 errnoent = errnoent1;
207 nsyscalls = nsyscalls1;
208 ioctlent = ioctlent1;
209 nioctlents = nioctlents1;
210 signalent = signalent1;
211 nsignals = nsignals1;
212 qual_flags = qual_flags1;
214 #endif /* SUPPORTED_PERSONALITIES >= 2 */
216 #if SUPPORTED_PERSONALITIES >= 3
218 errnoent = errnoent2;
221 nsyscalls = nsyscalls2;
222 ioctlent = ioctlent2;
223 nioctlents = nioctlents2;
224 signalent = signalent2;
225 nsignals = nsignals2;
226 qual_flags = qual_flags2;
228 #endif /* SUPPORTED_PERSONALITIES >= 3 */
234 current_personality = personality;
239 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
241 static const struct qual_options {
243 const char *option_name;
244 int (*qualify)(const char *, int, int);
245 const char *argument_name;
247 { QUAL_TRACE, "trace", qual_syscall, "system call" },
248 { QUAL_TRACE, "t", qual_syscall, "system call" },
249 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
250 { QUAL_ABBREV, "a", qual_syscall, "system call" },
251 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
252 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
253 { QUAL_RAW, "raw", qual_syscall, "system call" },
254 { QUAL_RAW, "x", qual_syscall, "system call" },
255 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
256 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
257 { QUAL_SIGNAL, "s", qual_signal, "signal" },
258 { QUAL_FAULT, "fault", qual_fault, "fault" },
259 { QUAL_FAULT, "faults", qual_fault, "fault" },
260 { QUAL_FAULT, "m", qual_fault, "fault" },
261 { QUAL_READ, "read", qual_desc, "descriptor" },
262 { QUAL_READ, "reads", qual_desc, "descriptor" },
263 { QUAL_READ, "r", qual_desc, "descriptor" },
264 { QUAL_WRITE, "write", qual_desc, "descriptor" },
265 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
266 { QUAL_WRITE, "w", qual_desc, "descriptor" },
267 { 0, NULL, NULL, NULL },
271 qualify_one(int n, int bitflag, int not, int pers)
273 if (pers == 0 || pers < 0) {
275 qual_flags0[n] &= ~bitflag;
277 qual_flags0[n] |= bitflag;
280 #if SUPPORTED_PERSONALITIES >= 2
281 if (pers == 1 || pers < 0) {
283 qual_flags1[n] &= ~bitflag;
285 qual_flags1[n] |= bitflag;
287 #endif /* SUPPORTED_PERSONALITIES >= 2 */
289 #if SUPPORTED_PERSONALITIES >= 3
290 if (pers == 2 || pers < 0) {
292 qual_flags2[n] &= ~bitflag;
294 qual_flags2[n] |= bitflag;
296 #endif /* SUPPORTED_PERSONALITIES >= 3 */
300 qual_syscall(const char *s, int bitflag, int not)
305 if (isdigit((unsigned char)*s)) {
307 if (i < 0 || i >= MAX_QUALS)
309 qualify_one(i, bitflag, not, -1);
312 for (i = 0; i < nsyscalls0; i++)
313 if (strcmp(s, sysent0[i].sys_name) == 0) {
314 qualify_one(i, bitflag, not, 0);
318 #if SUPPORTED_PERSONALITIES >= 2
319 for (i = 0; i < nsyscalls1; i++)
320 if (strcmp(s, sysent1[i].sys_name) == 0) {
321 qualify_one(i, bitflag, not, 1);
324 #endif /* SUPPORTED_PERSONALITIES >= 2 */
326 #if SUPPORTED_PERSONALITIES >= 3
327 for (i = 0; i < nsyscalls2; i++)
328 if (strcmp(s, sysent2[i].sys_name) == 0) {
329 qualify_one(i, bitflag, not, 2);
332 #endif /* SUPPORTED_PERSONALITIES >= 3 */
338 qual_signal(const char *s, int bitflag, int not)
343 if (isdigit((unsigned char)*s)) {
345 if (signo < 0 || signo >= MAX_QUALS)
347 qualify_one(signo, bitflag, not, -1);
350 if (strlen(s) >= sizeof buf)
354 if (strncasecmp(s, "SIG", 3) == 0)
356 for (i = 0; i <= NSIG; i++)
357 if (strcasecmp(s, signame(i) + 3) == 0) {
358 qualify_one(i, bitflag, not, -1);
365 qual_fault(const char *s, int bitflag, int not)
371 qual_desc(const char *s, int bitflag, int not)
373 if (isdigit((unsigned char)*s)) {
375 if (desc < 0 || desc >= MAX_QUALS)
377 qualify_one(desc, bitflag, not, -1);
384 lookup_class(const char *s)
386 if (strcmp(s, "file") == 0)
388 if (strcmp(s, "ipc") == 0)
390 if (strcmp(s, "network") == 0)
391 return TRACE_NETWORK;
392 if (strcmp(s, "process") == 0)
393 return TRACE_PROCESS;
394 if (strcmp(s, "signal") == 0)
396 if (strcmp(s, "desc") == 0)
402 qualify(const char *s)
404 const struct qual_options *opt;
410 opt = &qual_options[0];
411 for (i = 0; (p = qual_options[i].option_name); i++) {
413 if (strncmp(s, p, n) == 0 && s[n] == '=') {
414 opt = &qual_options[i];
424 if (strcmp(s, "none") == 0) {
428 if (strcmp(s, "all") == 0) {
429 for (i = 0; i < MAX_QUALS; i++) {
430 qualify_one(i, opt->bitflag, not, -1);
434 for (i = 0; i < MAX_QUALS; i++) {
435 qualify_one(i, opt->bitflag, !not, -1);
437 if (!(copy = strdup(s))) {
438 fprintf(stderr, "out of memory\n");
441 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
442 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
443 for (i = 0; i < nsyscalls0; i++)
444 if (sysent0[i].sys_flags & n)
445 qualify_one(i, opt->bitflag, not, 0);
447 #if SUPPORTED_PERSONALITIES >= 2
448 for (i = 0; i < nsyscalls1; i++)
449 if (sysent1[i].sys_flags & n)
450 qualify_one(i, opt->bitflag, not, 1);
451 #endif /* SUPPORTED_PERSONALITIES >= 2 */
453 #if SUPPORTED_PERSONALITIES >= 3
454 for (i = 0; i < nsyscalls2; i++)
455 if (sysent2[i].sys_flags & n)
456 qualify_one(i, opt->bitflag, not, 2);
457 #endif /* SUPPORTED_PERSONALITIES >= 3 */
461 if (opt->qualify(p, opt->bitflag, not)) {
462 fprintf(stderr, "strace: invalid %s `%s'\n",
463 opt->argument_name, p);
472 dumpio(struct tcb *tcp)
476 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
478 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
480 if (sysent[tcp->scno].sys_func == printargs)
482 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
483 if (sysent[tcp->scno].sys_func == sys_read ||
484 sysent[tcp->scno].sys_func == sys_pread ||
485 sysent[tcp->scno].sys_func == sys_pread64 ||
486 sysent[tcp->scno].sys_func == sys_recv ||
487 sysent[tcp->scno].sys_func == sys_recvfrom)
488 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
489 else if (sysent[tcp->scno].sys_func == sys_readv)
490 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
493 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
494 if (sysent[tcp->scno].sys_func == sys_write ||
495 sysent[tcp->scno].sys_func == sys_pwrite ||
496 sysent[tcp->scno].sys_func == sys_pwrite64 ||
497 sysent[tcp->scno].sys_func == sys_send ||
498 sysent[tcp->scno].sys_func == sys_sendto)
499 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
500 else if (sysent[tcp->scno].sys_func == sys_writev)
501 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
507 enum subcall_style { shift_style, deref_style, mask_style, door_style };
509 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
517 static const struct subcall subcalls_table[] = {
518 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
520 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
522 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
524 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
528 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
531 decode_subcall(tcp, subcall, nsubcalls, style)
535 enum subcall_style style;
537 unsigned long addr, mask;
539 int size = personality_wordsize[current_personality];
543 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
545 tcp->scno = subcall + tcp->u_arg[0];
546 if (sysent[tcp->scno].nargs != -1)
547 tcp->u_nargs = sysent[tcp->scno].nargs;
550 for (i = 0; i < tcp->u_nargs; i++)
551 tcp->u_arg[i] = tcp->u_arg[i + 1];
554 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
556 tcp->scno = subcall + tcp->u_arg[0];
557 addr = tcp->u_arg[1];
558 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
559 if (size == sizeof(int)) {
561 if (umove(tcp, addr, &arg) < 0)
565 else if (size == sizeof(long)) {
567 if (umove(tcp, addr, &arg) < 0)
575 tcp->u_nargs = sysent[tcp->scno].nargs;
578 mask = (tcp->u_arg[0] >> 8) & 0xff;
579 for (i = 0; mask; i++)
583 tcp->u_arg[0] &= 0xff;
584 tcp->scno = subcall + i;
585 if (sysent[tcp->scno].nargs != -1)
586 tcp->u_nargs = sysent[tcp->scno].nargs;
590 * Oh, yuck. The call code is the *sixth* argument.
591 * (don't you mean the *last* argument? - JH)
593 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
595 tcp->scno = subcall + tcp->u_arg[5];
596 if (sysent[tcp->scno].nargs != -1)
597 tcp->u_nargs = sysent[tcp->scno].nargs;
603 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
604 if (subcalls_table[i].call == tcp->scno) break;
605 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
606 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
607 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
608 for (i = 0; i < tcp->u_nargs; i++)
609 tcp->u_arg[i] = tcp->u_arg[i + 1];
617 struct tcb *tcp_last = NULL;
620 internal_syscall(struct tcb *tcp)
623 * We must always trace a few critical system calls in order to
624 * correctly support following forks in the presence of tracing
629 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
632 func = sysent[tcp->scno].sys_func;
634 if (sys_exit == func)
635 return internal_exit(tcp);
637 if ( sys_fork == func
638 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
648 return internal_fork(tcp);
650 if ( sys_execve == func
651 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
655 || sys_rexecve == func
658 return internal_exec(tcp);
660 if ( sys_waitpid == func
662 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
666 || sys_osf_wait4 == func
669 return internal_wait(tcp, 2);
671 #if defined(LINUX) || defined(SVR4)
672 if (sys_waitid == func)
673 return internal_wait(tcp, 3);
686 #elif defined (POWERPC)
687 static long result,flags;
693 static struct pt_regs regs;
694 #elif defined (ALPHA)
698 static struct pt_regs regs;
699 #elif defined (SPARC) || defined (SPARC64)
700 static struct pt_regs regs;
701 static unsigned long trap;
702 #elif defined(LINUX_MIPSN32)
708 #elif defined(S390) || defined(S390X)
711 static long syscall_mode;
718 #elif defined(X86_64)
720 #elif defined(CRISV10) || defined(CRISV32)
722 #elif defined(MICROBLAZE)
731 get_scno(struct tcb *tcp)
736 # if defined(S390) || defined(S390X)
737 if (tcp->flags & TCB_WAITEXECVE) {
739 * When the execve system call completes successfully, the
740 * new process still has -ENOSYS (old style) or __NR_execve
741 * (new style) in gpr2. We cannot recover the scno again
742 * by disassembly, because the image that executed the
743 * syscall is gone now. Fortunately, we don't want it. We
744 * leave the flag set so that syscall_fixup can fake the
747 if (tcp->flags & TCB_INSYSCALL)
750 * This is the SIGTRAP after execve. We cannot try to read
751 * the system call here either.
753 tcp->flags &= ~TCB_WAITEXECVE;
757 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
760 if (syscall_mode != -ENOSYS) {
762 * Since kernel version 2.5.44 the scno gets passed in gpr2.
767 * Old style of "passing" the scno via the SVC instruction.
770 long opcode, offset_reg, tmp;
772 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
773 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
774 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
775 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
777 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
780 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
782 perror("peektext(pc-oneword)");
787 * We have to check if the SVC got executed directly or via an
788 * EXECUTE instruction. In case of EXECUTE it is necessary to do
789 * instruction decoding to derive the system call number.
790 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
791 * so that this doesn't work if a SVC opcode is part of an EXECUTE
792 * opcode. Since there is no way to find out the opcode size this
793 * is the best we can do...
796 if ((opcode & 0xff00) == 0x0a00) {
798 scno = opcode & 0xff;
801 /* SVC got executed by EXECUTE instruction */
804 * Do instruction decoding of EXECUTE. If you really want to
805 * understand this, read the Principles of Operations.
807 svc_addr = (void *) (opcode & 0xfff);
810 offset_reg = (opcode & 0x000f0000) >> 16;
811 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
816 offset_reg = (opcode & 0x0000f000) >> 12;
817 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
821 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
830 offset_reg = (opcode & 0x00f00000) >> 20;
831 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
834 scno = (scno | tmp) & 0xff;
837 # elif defined (POWERPC)
838 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
840 if (!(tcp->flags & TCB_INSYSCALL)) {
841 /* Check if we return from execve. */
842 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
843 tcp->flags &= ~TCB_WAITEXECVE;
849 if (!(tcp->flags & TCB_INSYSCALL)) {
850 static int currpers = -1;
854 /* Check for 64/32 bit mode. */
855 if (upeek(tcp, sizeof (unsigned long)*PT_MSR, &val) < 0)
857 /* SF is bit 0 of MSR */
862 if (currpers != current_personality) {
863 static const char *const names[] = {"64 bit", "32 bit"};
864 set_personality(currpers);
865 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
866 pid, names[current_personality]);
870 # elif defined(AVR32)
872 * Read complete register set in one go.
874 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
878 * We only need to grab the syscall number on syscall entry.
880 if (!(tcp->flags & TCB_INSYSCALL)) {
883 /* Check if we return from execve. */
884 if (tcp->flags & TCB_WAITEXECVE) {
885 tcp->flags &= ~TCB_WAITEXECVE;
890 if (upeek(tcp, PT_ORIG_P0, &scno))
892 # elif defined (I386)
893 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
895 # elif defined (X86_64)
896 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
899 if (!(tcp->flags & TCB_INSYSCALL)) {
900 static int currpers = -1;
904 /* Check CS register value. On x86-64 linux it is:
905 * 0x33 for long mode (64 bit)
906 * 0x23 for compatibility mode (32 bit)
907 * It takes only one ptrace and thus doesn't need
910 if (upeek(tcp, 8*CS, &val) < 0)
913 case 0x23: currpers = 1; break;
914 case 0x33: currpers = 0; break;
916 fprintf(stderr, "Unknown value CS=0x%02X while "
917 "detecting personality of process "
918 "PID=%d\n", (int)val, pid);
919 currpers = current_personality;
923 /* This version analyzes the opcode of a syscall instruction.
924 * (int 0x80 on i386 vs. syscall on x86-64)
925 * It works, but is too complicated.
927 unsigned long val, rip, i;
929 if (upeek(tcp, 8*RIP, &rip) < 0)
930 perror("upeek(RIP)");
932 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
936 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
938 fprintf(stderr, "ptrace_peektext failed: %s\n",
940 switch (call & 0xffff) {
941 /* x86-64: syscall = 0x0f 0x05 */
942 case 0x050f: currpers = 0; break;
943 /* i386: int 0x80 = 0xcd 0x80 */
944 case 0x80cd: currpers = 1; break;
946 currpers = current_personality;
948 "Unknown syscall opcode (0x%04X) while "
949 "detecting personality of process "
950 "PID=%d\n", (int)call, pid);
954 if (currpers != current_personality) {
955 static const char *const names[] = {"64 bit", "32 bit"};
956 set_personality(currpers);
957 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
958 pid, names[current_personality]);
962 # define IA64_PSR_IS ((long)1 << 34)
963 if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
964 ia32 = (psr & IA64_PSR_IS) != 0;
965 if (!(tcp->flags & TCB_INSYSCALL)) {
967 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
970 if (upeek (tcp, PT_R15, &scno) < 0)
973 /* Check if we return from execve. */
974 if (tcp->flags & TCB_WAITEXECVE) {
975 tcp->flags &= ~TCB_WAITEXECVE;
979 /* syscall in progress */
980 if (upeek (tcp, PT_R8, &r8) < 0)
982 if (upeek (tcp, PT_R10, &r10) < 0)
987 * Read complete register set in one go.
989 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
993 * We only need to grab the syscall number on syscall entry.
995 if (regs.ARM_ip == 0) {
996 if (!(tcp->flags & TCB_INSYSCALL)) {
997 /* Check if we return from execve. */
998 if (tcp->flags & TCB_WAITEXECVE) {
999 tcp->flags &= ~TCB_WAITEXECVE;
1005 * Note: we only deal with only 32-bit CPUs here.
1007 if (regs.ARM_cpsr & 0x20) {
1009 * Get the Thumb-mode system call number
1014 * Get the ARM-mode system call number
1017 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1021 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1022 tcp->flags &= ~TCB_WAITEXECVE;
1026 /* Handle the EABI syscall convention. We do not
1027 bother converting structures between the two
1028 ABIs, but basic functionality should work even
1029 if strace and the traced program have different
1031 if (scno == 0xef000000) {
1034 if ((scno & 0x0ff00000) != 0x0f900000) {
1035 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1041 * Fixup the syscall number
1046 if (scno & 0x0f0000) {
1048 * Handle ARM specific syscall
1055 if (tcp->flags & TCB_INSYSCALL) {
1056 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1057 tcp->flags &= ~TCB_INSYSCALL;
1060 if (!(tcp->flags & TCB_INSYSCALL)) {
1061 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1062 tcp->flags |= TCB_INSYSCALL;
1065 # elif defined (M68K)
1066 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1068 # elif defined (LINUX_MIPSN32)
1069 unsigned long long regs[38];
1071 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1076 if(!(tcp->flags & TCB_INSYSCALL)) {
1079 /* Check if we return from execve. */
1080 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1081 tcp->flags &= ~TCB_WAITEXECVE;
1085 if (scno < 0 || scno > nsyscalls) {
1086 if(a3 == 0 || a3 == -1) {
1088 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1093 # elif defined (MIPS)
1094 if (upeek(tcp, REG_A3, &a3) < 0)
1096 if(!(tcp->flags & TCB_INSYSCALL)) {
1097 if (upeek(tcp, REG_V0, &scno) < 0)
1100 /* Check if we return from execve. */
1101 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1102 tcp->flags &= ~TCB_WAITEXECVE;
1106 if (scno < 0 || scno > nsyscalls) {
1107 if(a3 == 0 || a3 == -1) {
1109 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1114 if (upeek(tcp, REG_V0, &r2) < 0)
1117 # elif defined (ALPHA)
1118 if (upeek(tcp, REG_A3, &a3) < 0)
1121 if (!(tcp->flags & TCB_INSYSCALL)) {
1122 if (upeek(tcp, REG_R0, &scno) < 0)
1125 /* Check if we return from execve. */
1126 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1127 tcp->flags &= ~TCB_WAITEXECVE;
1132 * Do some sanity checks to figure out if it's
1133 * really a syscall entry
1135 if (scno < 0 || scno > nsyscalls) {
1136 if (a3 == 0 || a3 == -1) {
1138 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1144 if (upeek(tcp, REG_R0, &r0) < 0)
1147 # elif defined (SPARC) || defined (SPARC64)
1148 /* Everything we need is in the current register set. */
1149 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1152 /* If we are entering, then disassemble the syscall trap. */
1153 if (!(tcp->flags & TCB_INSYSCALL)) {
1154 /* Retrieve the syscall trap instruction. */
1156 # if defined(SPARC64)
1157 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1160 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1165 /* Disassemble the trap to see what personality to use. */
1168 /* Linux/SPARC syscall trap. */
1172 /* Linux/SPARC64 syscall trap. */
1176 /* SunOS syscall trap. (pers 1) */
1177 fprintf(stderr,"syscall: SunOS no support\n");
1180 /* Solaris 2.x syscall trap. (per 2) */
1184 /* NetBSD/FreeBSD syscall trap. */
1185 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1188 /* Solaris 2.x gettimeofday */
1192 /* Unknown syscall trap. */
1193 if(tcp->flags & TCB_WAITEXECVE) {
1194 tcp->flags &= ~TCB_WAITEXECVE;
1197 # if defined (SPARC64)
1198 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1200 fprintf(stderr,"syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1205 /* Extract the system call number from the registers. */
1206 if (trap == 0x91d02027)
1209 scno = regs.u_regs[U_REG_G1];
1211 scno = regs.u_regs[U_REG_O0];
1212 memmove (®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1215 # elif defined(HPPA)
1216 if (upeek(tcp, PT_GR20, &scno) < 0)
1218 if (!(tcp->flags & TCB_INSYSCALL)) {
1219 /* Check if we return from execve. */
1220 if ((tcp->flags & TCB_WAITEXECVE)) {
1221 tcp->flags &= ~TCB_WAITEXECVE;
1227 * In the new syscall ABI, the system call number is in R3.
1229 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1233 /* Odd as it may seem, a glibc bug has been known to cause
1234 glibc to issue bogus negative syscall numbers. So for
1235 our purposes, make strace print what it *should* have been */
1236 long correct_scno = (scno & 0xff);
1239 "Detected glibc bug: bogus system call"
1240 " number = %ld, correcting to %ld\n",
1243 scno = correct_scno;
1246 if (!(tcp->flags & TCB_INSYSCALL)) {
1247 /* Check if we return from execve. */
1248 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1249 tcp->flags &= ~TCB_WAITEXECVE;
1253 # elif defined(SH64)
1254 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1258 if (!(tcp->flags & TCB_INSYSCALL)) {
1259 /* Check if we return from execve. */
1260 if (tcp->flags & TCB_WAITEXECVE) {
1261 tcp->flags &= ~TCB_WAITEXECVE;
1265 # elif defined(CRISV10) || defined(CRISV32)
1266 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1268 # elif defined(TILE)
1269 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1272 if (!(tcp->flags & TCB_INSYSCALL)) {
1273 /* Check if we return from execve. */
1274 if (tcp->flags & TCB_WAITEXECVE) {
1275 tcp->flags &= ~TCB_WAITEXECVE;
1279 # elif defined(MICROBLAZE)
1280 if (upeek(tcp, 0, &scno) < 0)
1286 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1289 /* new syscall ABI returns result in R0 */
1290 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1293 /* ABI defines result returned in r9 */
1294 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1299 # ifdef HAVE_PR_SYSCALL
1300 scno = tcp->status.PR_SYSCALL;
1303 scno = tcp->status.PR_WHAT;
1305 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1309 switch (regs.r_eax) {
1312 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1318 # endif /* FREEBSD */
1319 # endif /* !HAVE_PR_SYSCALL */
1320 #endif /* USE_PROCFS */
1322 if (!(tcp->flags & TCB_INSYSCALL))
1329 known_scno(struct tcb *tcp)
1331 long scno = tcp->scno;
1332 #if SUPPORTED_PERSONALITIES > 1
1333 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1334 scno = sysent[scno].native_scno;
1337 scno += NR_SYSCALL_BASE;
1341 /* Called in trace_syscall() at each syscall entry and exit.
1343 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1344 * 1: ok, continue in trace_syscall().
1345 * other: error, trace_syscall() should print error indicator
1346 * ("????" etc) and bail out.
1349 syscall_fixup(struct tcb *tcp)
1352 int scno = known_scno(tcp);
1354 if (!(tcp->flags & TCB_INSYSCALL)) {
1355 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1359 || scno == SYS_vfork
1360 #endif /* SYS_vfork */
1362 || scno == SYS_fork1
1363 #endif /* SYS_fork1 */
1365 || scno == SYS_forkall
1366 #endif /* SYS_forkall */
1368 || scno == SYS_rfork1
1369 #endif /* SYS_fork1 */
1371 || scno == SYS_rforkall
1372 #endif /* SYS_rforkall */
1374 /* We are returning in the child, fake it. */
1375 tcp->status.PR_WHY = PR_SYSENTRY;
1377 tcp->status.PR_WHY = PR_SYSEXIT;
1380 fprintf(stderr, "syscall: missing entry\n");
1381 tcp->flags |= TCB_INSYSCALL;
1386 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1387 fprintf(stderr, "syscall: missing exit\n");
1388 tcp->flags &= ~TCB_INSYSCALL;
1391 #endif /* USE_PROCFS */
1393 if (!(tcp->flags & TCB_INSYSCALL)) {
1395 fprintf(stderr, "syscall: missing entry\n");
1396 tcp->flags |= TCB_INSYSCALL;
1403 * This happens when a signal handler
1404 * for a signal which interrupted a
1405 * a system call makes another system call.
1407 fprintf(stderr, "syscall: missing exit\n");
1409 tcp->flags &= ~TCB_INSYSCALL;
1415 if (upeek(tcp, 4*EAX, &eax) < 0)
1417 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1419 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1422 #elif defined (X86_64)
1423 if (upeek(tcp, 8*RAX, &rax) < 0)
1425 if (current_personality == 1)
1426 rax = (long int)(int)rax; /* sign extend from 32 bits */
1427 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1429 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1432 #elif defined (S390) || defined (S390X)
1433 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1435 if (syscall_mode != -ENOSYS)
1436 syscall_mode = tcp->scno;
1437 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1439 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1442 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1443 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1444 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1446 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1447 * flag set for the post-execve SIGTRAP to see and reset.
1451 #elif defined (POWERPC)
1452 # define SO_MASK 0x10000000
1453 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1455 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1457 if (flags & SO_MASK)
1459 #elif defined (M68K)
1460 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1462 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1464 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1472 if (upeek(tcp, PT_R0, &r0) < 0)
1474 #elif defined (HPPA)
1475 if (upeek(tcp, PT_GR28, &r28) < 0)
1478 if (upeek(tcp, PT_R10, &r10) < 0)
1480 if (upeek(tcp, PT_R8, &r8) < 0)
1482 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1484 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1487 #elif defined(CRISV10) || defined(CRISV32)
1488 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1490 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1492 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1495 #elif defined(MICROBLAZE)
1496 if (upeek(tcp, 3 * 4, &r3) < 0)
1498 if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1500 fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
1510 * Check the syscall return value register value for whether it is
1511 * a negated errno code indicating an error, or a success return value.
1514 is_negated_errno(unsigned long int val)
1516 unsigned long int max = -(long int) nerrnos;
1517 if (personality_wordsize[current_personality] < sizeof(val)) {
1518 val = (unsigned int) val;
1519 max = (unsigned int) max;
1526 get_error(struct tcb *tcp)
1530 int check_errno = 1;
1531 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
1532 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) {
1535 # if defined(S390) || defined(S390X)
1536 if (check_errno && is_negated_errno(gpr2)) {
1544 # elif defined(I386)
1545 if (check_errno && is_negated_errno(eax)) {
1553 # elif defined(X86_64)
1554 if (check_errno && is_negated_errno(rax)) {
1562 # elif defined(IA64)
1567 if (check_errno && is_negated_errno(err)) {
1576 if (check_errno && r10) {
1584 # elif defined(MIPS)
1585 if (check_errno && a3) {
1592 # elif defined(POWERPC)
1593 if (check_errno && is_negated_errno(result)) {
1598 tcp->u_rval = result;
1601 # elif defined(M68K)
1602 if (check_errno && is_negated_errno(d0)) {
1611 if (check_errno && is_negated_errno(regs.ARM_r0)) {
1613 u_error = -regs.ARM_r0;
1616 tcp->u_rval = regs.ARM_r0;
1619 # elif defined(AVR32)
1620 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1622 u_error = -regs.r12;
1625 tcp->u_rval = regs.r12;
1628 # elif defined(BFIN)
1629 if (check_errno && is_negated_errno(r0)) {
1636 # elif defined(ALPHA)
1637 if (check_errno && a3) {
1645 # elif defined(SPARC)
1646 if (check_errno && regs.psr & PSR_C) {
1648 u_error = regs.u_regs[U_REG_O0];
1651 tcp->u_rval = regs.u_regs[U_REG_O0];
1654 # elif defined(SPARC64)
1655 if (check_errno && regs.tstate & 0x1100000000UL) {
1657 u_error = regs.u_regs[U_REG_O0];
1660 tcp->u_rval = regs.u_regs[U_REG_O0];
1663 # elif defined(HPPA)
1664 if (check_errno && is_negated_errno(r28)) {
1673 /* interpret R0 as return value or error number */
1674 if (check_errno && is_negated_errno(r0)) {
1682 # elif defined(SH64)
1683 /* interpret result as return value or error number */
1684 if (check_errno && is_negated_errno(r9)) {
1692 # elif defined(CRISV10) || defined(CRISV32)
1693 if (check_errno && r10 && (unsigned) -r10 < nerrnos) {
1701 # elif defined(TILE)
1703 /* interpret result as return value or error number */
1704 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1706 if (check_errno && rval < 0 && rval > -nerrnos) {
1714 # elif defined(MICROBLAZE)
1715 /* interpret result as return value or error number */
1716 if (check_errno && is_negated_errno(r3)) {
1727 /* get error code from user struct */
1728 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1730 u_error >>= 24; /* u_error is a char */
1732 /* get system call return value */
1733 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1738 /* Judicious guessing goes a long way. */
1739 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1741 u_error = tcp->status.pr_reg[R_O0];
1744 tcp->u_rval = tcp->status.pr_reg[R_O0];
1749 /* Wanna know how to kill an hour single-stepping? */
1750 if (tcp->status.PR_REG[EFL] & 0x1) {
1752 u_error = tcp->status.PR_REG[EAX];
1755 tcp->u_rval = tcp->status.PR_REG[EAX];
1756 #ifdef HAVE_LONG_LONG
1758 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1759 tcp->status.PR_REG[EAX];
1765 /* Wanna know how to kill an hour single-stepping? */
1766 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1768 u_error = tcp->status.PR_REG[RAX];
1771 tcp->u_rval = tcp->status.PR_REG[RAX];
1776 if (tcp->status.pr_reg[CTX_A3]) {
1778 u_error = tcp->status.pr_reg[CTX_V0];
1781 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1787 if (regs.r_eflags & PSL_C) {
1789 u_error = regs.r_eax;
1791 tcp->u_rval = regs.r_eax;
1793 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1796 #endif /* FREEBSD */
1797 tcp->u_error = u_error;
1802 force_result(tcp, error, rval)
1808 # if defined(S390) || defined(S390X)
1809 gpr2 = error ? -error : rval;
1810 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1812 # elif defined(I386)
1813 eax = error ? -error : rval;
1814 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1816 # elif defined(X86_64)
1817 rax = error ? -error : rval;
1818 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1820 # elif defined(IA64)
1822 r8 = error ? -error : rval;
1823 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1835 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1836 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1839 # elif defined(BFIN)
1840 r0 = error ? -error : rval;
1841 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1843 # elif defined(MIPS)
1852 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1853 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1854 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1856 # elif defined(POWERPC)
1857 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1867 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1868 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1870 # elif defined(M68K)
1871 d0 = error ? -error : rval;
1872 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1875 regs.ARM_r0 = error ? -error : rval;
1876 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1878 # elif defined(AVR32)
1879 regs.r12 = error ? -error : rval;
1880 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1882 # elif defined(ALPHA)
1891 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1892 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1894 # elif defined(SPARC)
1895 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1899 regs.u_regs[U_REG_O0] = error;
1903 regs.u_regs[U_REG_O0] = rval;
1905 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1907 # elif defined(SPARC64)
1908 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1911 regs.tstate |= 0x1100000000UL;
1912 regs.u_regs[U_REG_O0] = error;
1915 regs.tstate &= ~0x1100000000UL;
1916 regs.u_regs[U_REG_O0] = rval;
1918 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1920 # elif defined(HPPA)
1921 r28 = error ? -error : rval;
1922 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1925 r0 = error ? -error : rval;
1926 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1928 # elif defined(SH64)
1929 r9 = error ? -error : rval;
1930 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1936 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1938 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1948 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1953 regs.r_eflags |= PSL_C;
1957 regs.r_eflags &= ~PSL_C;
1960 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1964 #endif /* FREEBSD */
1966 /* All branches reach here on success (only). */
1967 tcp->u_error = error;
1973 syscall_enter(struct tcb *tcp)
1976 #if defined(S390) || defined(S390X)
1979 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1980 tcp->u_nargs = sysent[tcp->scno].nargs;
1982 tcp->u_nargs = MAX_ARGS;
1983 for (i = 0; i < tcp->u_nargs; i++) {
1984 if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1988 #elif defined (ALPHA)
1991 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1992 tcp->u_nargs = sysent[tcp->scno].nargs;
1994 tcp->u_nargs = MAX_ARGS;
1995 for (i = 0; i < tcp->u_nargs; i++) {
1996 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1997 * for scno somewhere above here!
1999 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
2003 #elif defined (IA64)
2006 unsigned long *out0, cfm, sof, sol, i;
2008 /* be backwards compatible with kernel < 2.4.4... */
2010 # define PT_RBS_END PT_AR_BSP
2013 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
2015 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2018 sof = (cfm >> 0) & 0x7f;
2019 sol = (cfm >> 7) & 0x7f;
2020 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2022 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2023 && sysent[tcp->scno].nargs != -1)
2024 tcp->u_nargs = sysent[tcp->scno].nargs;
2026 tcp->u_nargs = MAX_ARGS;
2027 for (i = 0; i < tcp->u_nargs; ++i) {
2028 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2029 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2035 if (/* EBX = out0 */
2036 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2038 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2040 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2042 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2044 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2046 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2049 for (i = 0; i < 6; ++i)
2050 /* truncate away IVE sign-extension */
2051 tcp->u_arg[i] &= 0xffffffff;
2053 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2054 && sysent[tcp->scno].nargs != -1)
2055 tcp->u_nargs = sysent[tcp->scno].nargs;
2060 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2061 /* N32 and N64 both use up to six registers. */
2063 unsigned long long regs[38];
2066 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2067 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2069 nargs = tcp->u_nargs = MAX_ARGS;
2071 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2074 for(i = 0; i < nargs; i++) {
2075 tcp->u_arg[i] = regs[REG_A0 + i];
2076 # if defined (LINUX_MIPSN32)
2077 tcp->ext_arg[i] = regs[REG_A0 + i];
2081 #elif defined (MIPS)
2086 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2087 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2089 nargs = tcp->u_nargs = MAX_ARGS;
2091 if(upeek(tcp, REG_SP, &sp) < 0)
2093 for(i = 0; i < 4; i++) {
2094 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2097 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2098 (char *)(tcp->u_arg + 4));
2100 for(i = 0; i < nargs; i++) {
2101 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2106 #elif defined (POWERPC)
2108 # define PT_ORIG_R3 34
2112 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2113 tcp->u_nargs = sysent[tcp->scno].nargs;
2115 tcp->u_nargs = MAX_ARGS;
2116 for (i = 0; i < tcp->u_nargs; i++) {
2117 if (upeek(tcp, (i==0) ?
2118 (sizeof(unsigned long)*PT_ORIG_R3) :
2119 ((i+PT_R3)*sizeof(unsigned long)),
2120 &tcp->u_arg[i]) < 0)
2124 #elif defined (SPARC) || defined (SPARC64)
2128 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2129 tcp->u_nargs = sysent[tcp->scno].nargs;
2131 tcp->u_nargs = MAX_ARGS;
2132 for (i = 0; i < tcp->u_nargs; i++)
2133 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2135 #elif defined (HPPA)
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 = MAX_ARGS;
2143 for (i = 0; i < tcp->u_nargs; i++) {
2144 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2152 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2153 tcp->u_nargs = sysent[tcp->scno].nargs;
2155 tcp->u_nargs = MAX_ARGS;
2156 for (i = 0; i < tcp->u_nargs; i++)
2157 tcp->u_arg[i] = regs.uregs[i];
2159 #elif defined(AVR32)
2160 tcp->u_nargs = sysent[tcp->scno].nargs;
2161 tcp->u_arg[0] = regs.r12;
2162 tcp->u_arg[1] = regs.r11;
2163 tcp->u_arg[2] = regs.r10;
2164 tcp->u_arg[3] = regs.r9;
2165 tcp->u_arg[4] = regs.r5;
2166 tcp->u_arg[5] = regs.r3;
2170 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2172 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2173 tcp->u_nargs = sysent[tcp->scno].nargs;
2175 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2177 for (i = 0; i < tcp->u_nargs; ++i)
2178 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2184 static int syscall_regs[] = {
2185 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2186 REG_REG0, REG_REG0+1, REG_REG0+2
2189 tcp->u_nargs = sysent[tcp->scno].nargs;
2190 for (i = 0; i < tcp->u_nargs; i++) {
2191 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2198 /* Registers used by SH5 Linux system calls for parameters */
2199 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2202 * TODO: should also check that the number of arguments encoded
2203 * in the trap number matches the number strace expects.
2206 assert(sysent[tcp->scno].nargs <
2207 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2210 tcp->u_nargs = sysent[tcp->scno].nargs;
2211 for (i = 0; i < tcp->u_nargs; i++) {
2212 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2217 #elif defined(X86_64)
2220 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2221 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2222 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2225 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2226 tcp->u_nargs = sysent[tcp->scno].nargs;
2228 tcp->u_nargs = MAX_ARGS;
2229 for (i = 0; i < tcp->u_nargs; i++) {
2230 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2234 #elif defined(MICROBLAZE)
2237 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2238 tcp->u_nargs = sysent[tcp->scno].nargs;
2241 for (i = 0; i < tcp->u_nargs; i++) {
2242 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
2246 #elif defined(CRISV10) || defined(CRISV32)
2249 static const int crisregs[] = {
2250 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2251 4*PT_R13, 4*PT_MOF, 4*PT_SRP
2254 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2255 tcp->u_nargs = sysent[tcp->scno].nargs;
2258 for (i = 0; i < tcp->u_nargs; i++) {
2259 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2266 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2267 tcp->u_nargs = sysent[tcp->scno].nargs;
2269 tcp->u_nargs = MAX_ARGS;
2270 for (i = 0; i < tcp->u_nargs; ++i) {
2271 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2275 #elif defined (M68K)
2278 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2279 tcp->u_nargs = sysent[tcp->scno].nargs;
2281 tcp->u_nargs = MAX_ARGS;
2282 for (i = 0; i < tcp->u_nargs; i++) {
2283 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
2287 #else /* Other architecture (like i386) (32bits specific) */
2290 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2291 tcp->u_nargs = sysent[tcp->scno].nargs;
2293 tcp->u_nargs = MAX_ARGS;
2294 for (i = 0; i < tcp->u_nargs; i++) {
2295 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2304 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2305 tcp->u_nargs = sysent[tcp->scno].nargs;
2307 tcp->u_nargs = MAX_ARGS;
2308 for (i = 0; i < tcp->u_nargs; i++) {
2311 if (upeek(tcp, uoff(u_arg[0]) +
2312 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2320 * SGI is broken: even though it has pr_sysarg, it doesn't
2321 * set them on system call entry. Get a clue.
2323 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2324 tcp->u_nargs = sysent[tcp->scno].nargs;
2326 tcp->u_nargs = tcp->status.pr_nsysarg;
2327 if (tcp->u_nargs > 4) {
2328 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2329 4*sizeof(tcp->u_arg[0]));
2330 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2331 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2334 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2335 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2339 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2341 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2342 tcp->u_nargs = sysent[tcp->scno].nargs;
2344 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2345 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2346 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2347 #elif defined (HAVE_PR_SYSCALL)
2348 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2349 tcp->u_nargs = sysent[tcp->scno].nargs;
2351 tcp->u_nargs = tcp->status.pr_nsysarg;
2354 for (i = 0; i < tcp->u_nargs; i++)
2355 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2357 #elif defined (I386)
2358 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2359 tcp->u_nargs = sysent[tcp->scno].nargs;
2362 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2363 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2365 I DONT KNOW WHAT TO DO
2366 #endif /* !HAVE_PR_SYSCALL */
2369 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2370 sysent[tcp->scno].nargs > tcp->status.val)
2371 tcp->u_nargs = sysent[tcp->scno].nargs;
2373 tcp->u_nargs = tcp->status.val;
2374 if (tcp->u_nargs < 0)
2376 if (tcp->u_nargs > MAX_ARGS)
2377 tcp->u_nargs = MAX_ARGS;
2378 switch(regs.r_eax) {
2380 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2381 regs.r_esp + sizeof(int) + sizeof(quad_t));
2384 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2385 regs.r_esp + 2 * sizeof(int));
2388 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2389 regs.r_esp + sizeof(int));
2392 #endif /* FREEBSD */
2397 trace_syscall_exiting(struct tcb *tcp)
2404 /* Measure the exit time as early as possible to avoid errors. */
2406 gettimeofday(&tv, NULL);
2408 /* BTW, why we don't just memorize syscall no. on entry
2409 * in tcp->something?
2411 scno_good = res = get_scno(tcp);
2415 res = syscall_fixup(tcp);
2419 res = get_error(tcp);
2423 internal_syscall(tcp);
2425 if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2426 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2427 tcp->flags &= ~TCB_INSYSCALL;
2431 if (tcp->flags & TCB_REPRINT) {
2436 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2437 tprintf("syscall_%lu", tcp->scno);
2439 tprintf("%s", sysent[tcp->scno].sys_name);
2440 tprintf(" resumed> ");
2444 struct timeval t = tv;
2445 int rc = count_syscall(tcp, &t);
2446 if (cflag == CFLAG_ONLY_STATS)
2448 tcp->flags &= ~TCB_INSYSCALL;
2456 tprintf("= ? <unavailable>");
2458 tcp->flags &= ~TCB_INSYSCALL;
2462 if (tcp->scno >= nsyscalls || tcp->scno < 0
2463 || (qual_flags[tcp->scno] & QUAL_RAW))
2464 sys_res = printargs(tcp);
2466 if (not_failing_only && tcp->u_error)
2467 return 0; /* ignore failed syscalls */
2468 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2471 u_error = tcp->u_error;
2474 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2475 qual_flags[tcp->scno] & QUAL_RAW) {
2477 tprintf("= -1 (errno %ld)", u_error);
2479 tprintf("= %#lx", tcp->u_rval);
2481 else if (!(sys_res & RVAL_NONE) && u_error) {
2485 tprintf("= ? ERESTARTSYS (To be restarted)");
2487 case ERESTARTNOINTR:
2488 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2490 case ERESTARTNOHAND:
2491 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2493 case ERESTART_RESTARTBLOCK:
2494 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2500 tprintf("E??? (errno %ld)", u_error);
2501 else if (u_error < nerrnos)
2502 tprintf("%s (%s)", errnoent[u_error],
2505 tprintf("ERRNO_%ld (%s)", u_error,
2509 if ((sys_res & RVAL_STR) && tcp->auxstr)
2510 tprintf(" (%s)", tcp->auxstr);
2513 if (sys_res & RVAL_NONE)
2516 switch (sys_res & RVAL_MASK) {
2518 tprintf("= %#lx", tcp->u_rval);
2521 tprintf("= %#lo", tcp->u_rval);
2524 tprintf("= %lu", tcp->u_rval);
2527 tprintf("= %ld", tcp->u_rval);
2529 #ifdef HAVE_LONG_LONG
2531 tprintf("= %#llx", tcp->u_lrval);
2534 tprintf("= %#llo", tcp->u_lrval);
2536 case RVAL_LUDECIMAL:
2537 tprintf("= %llu", tcp->u_lrval);
2540 tprintf("= %lld", tcp->u_lrval);
2545 "invalid rval format\n");
2549 if ((sys_res & RVAL_STR) && tcp->auxstr)
2550 tprintf(" (%s)", tcp->auxstr);
2553 tv_sub(&tv, &tv, &tcp->etime);
2554 tprintf(" <%ld.%06ld>",
2555 (long) tv.tv_sec, (long) tv.tv_usec);
2560 if (fflush(tcp->outf) == EOF)
2562 tcp->flags &= ~TCB_INSYSCALL;
2567 trace_syscall_entering(struct tcb *tcp)
2572 scno_good = res = get_scno(tcp);
2576 res = syscall_fixup(tcp);
2580 res = syscall_enter(tcp);
2586 tcp->flags &= ~TCB_REPRINT;
2589 tprintf("????" /* anti-trigraph gap */ "(");
2590 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2591 tprintf("syscall_%lu(", tcp->scno);
2593 tprintf("%s(", sysent[tcp->scno].sys_name);
2595 * " <unavailable>" will be added later by the code which
2596 * detects ptrace errors.
2598 tcp->flags |= TCB_INSYSCALL;
2602 switch (known_scno(tcp)) {
2603 #ifdef SYS_socket_subcall
2604 case SYS_socketcall:
2605 decode_subcall(tcp, SYS_socket_subcall,
2606 SYS_socket_nsubcalls, deref_style);
2609 #ifdef SYS_ipc_subcall
2611 decode_subcall(tcp, SYS_ipc_subcall,
2612 SYS_ipc_nsubcalls, shift_style);
2616 #ifdef SYS_pgrpsys_subcall
2618 decode_subcall(tcp, SYS_pgrpsys_subcall,
2619 SYS_pgrpsys_nsubcalls, shift_style);
2621 #endif /* SYS_pgrpsys_subcall */
2622 #ifdef SYS_sigcall_subcall
2624 decode_subcall(tcp, SYS_sigcall_subcall,
2625 SYS_sigcall_nsubcalls, mask_style);
2627 #endif /* SYS_sigcall_subcall */
2629 decode_subcall(tcp, SYS_msgsys_subcall,
2630 SYS_msgsys_nsubcalls, shift_style);
2633 decode_subcall(tcp, SYS_shmsys_subcall,
2634 SYS_shmsys_nsubcalls, shift_style);
2637 decode_subcall(tcp, SYS_semsys_subcall,
2638 SYS_semsys_nsubcalls, shift_style);
2641 decode_subcall(tcp, SYS_sysfs_subcall,
2642 SYS_sysfs_nsubcalls, shift_style);
2645 decode_subcall(tcp, SYS_spcall_subcall,
2646 SYS_spcall_nsubcalls, shift_style);
2648 #ifdef SYS_context_subcall
2650 decode_subcall(tcp, SYS_context_subcall,
2651 SYS_context_nsubcalls, shift_style);
2653 #endif /* SYS_context_subcall */
2654 #ifdef SYS_door_subcall
2656 decode_subcall(tcp, SYS_door_subcall,
2657 SYS_door_nsubcalls, door_style);
2659 #endif /* SYS_door_subcall */
2660 #ifdef SYS_kaio_subcall
2662 decode_subcall(tcp, SYS_kaio_subcall,
2663 SYS_kaio_nsubcalls, shift_style);
2671 decode_subcall(tcp, 0, 0, table_style);
2676 decode_subcall(tcp, SYS_semsys_subcall,
2677 SYS_semsys_nsubcalls, shift_style);
2680 decode_subcall(tcp, SYS_msgsys_subcall,
2681 SYS_msgsys_nsubcalls, shift_style);
2684 decode_subcall(tcp, SYS_shmsys_subcall,
2685 SYS_shmsys_nsubcalls, shift_style);
2690 internal_syscall(tcp);
2691 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2692 tcp->flags |= TCB_INSYSCALL;
2696 if (cflag == CFLAG_ONLY_STATS) {
2697 tcp->flags |= TCB_INSYSCALL;
2698 gettimeofday(&tcp->etime, NULL);
2703 tcp->flags &= ~TCB_REPRINT;
2705 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2706 tprintf("syscall_%lu(", tcp->scno);
2708 tprintf("%s(", sysent[tcp->scno].sys_name);
2709 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2710 ((qual_flags[tcp->scno] & QUAL_RAW) &&
2711 sysent[tcp->scno].sys_func != sys_exit))
2712 sys_res = printargs(tcp);
2714 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2715 if (fflush(tcp->outf) == EOF)
2717 tcp->flags |= TCB_INSYSCALL;
2718 /* Measure the entrance time as late as possible to avoid errors. */
2720 gettimeofday(&tcp->etime, NULL);
2725 trace_syscall(struct tcb *tcp)
2727 return exiting(tcp) ?
2728 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2735 if (entering(tcp)) {
2738 for (i = 0; i < tcp->u_nargs; i++)
2739 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2751 #if defined (SPARC) || defined (SPARC64)
2752 struct pt_regs regs;
2753 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2755 val = regs.u_regs[U_REG_O1];
2757 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2760 if (upeek(tcp, PT_R9, &val) < 0)
2766 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2772 val = tcp->status.PR_REG[R_O1];
2775 val = tcp->status.PR_REG[EDX];
2778 val = tcp->status.PR_REG[RDX];
2781 val = tcp->status.PR_REG[CTX_V1];
2787 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2795 * Apparently, indirect system calls have already be converted by ptrace(2),
2796 * so if you see "indir" this program has gone astray.
2804 if (entering(tcp)) {
2805 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2806 fprintf(stderr, "Bogus syscall: %u\n", scno);
2809 nargs = sysent[scno].nargs;
2810 tprintf("%s", sysent[scno].sys_name);
2811 for (i = 0; i < nargs; i++)
2812 tprintf(", %#lx", tcp->u_arg[i+1]);
2819 is_restart_error(struct tcb *tcp)
2824 switch (tcp->u_error) {
2826 case ERESTARTNOINTR:
2827 case ERESTARTNOHAND:
2828 case ERESTART_RESTARTBLOCK: