tizen beta release
[external/strace.git] / syscall.c
1 /*
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>
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
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.
21  *
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.
32  *
33  *      $Id$
34  */
35
36 #include "defs.h"
37
38 #include <signal.h>
39 #include <time.h>
40 #include <errno.h>
41 #include <sys/user.h>
42 #include <sys/syscall.h>
43 #include <sys/param.h>
44
45 #ifdef HAVE_SYS_REG_H
46 #include <sys/reg.h>
47 #ifndef PTRACE_PEEKUSR
48 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
49 #endif
50 #elif defined(HAVE_LINUX_PTRACE_H)
51 #undef PTRACE_SYSCALL
52 # ifdef HAVE_STRUCT_IA64_FPREG
53 #  define ia64_fpreg XXX_ia64_fpreg
54 # endif
55 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
56 #  define pt_all_user_regs XXX_pt_all_user_regs
57 # endif
58 #include <linux/ptrace.h>
59 # undef ia64_fpreg
60 # undef pt_all_user_regs
61 #endif
62
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 */
69
70 #if defined(LINUX) && defined(IA64)
71 # include <asm/ptrace_offsets.h>
72 # include <asm/rse.h>
73 #endif
74
75 #define NR_SYSCALL_BASE 0
76 #ifdef LINUX
77 #ifndef ERESTARTSYS
78 #define ERESTARTSYS     512
79 #endif
80 #ifndef ERESTARTNOINTR
81 #define ERESTARTNOINTR  513
82 #endif
83 #ifndef ERESTARTNOHAND
84 #define ERESTARTNOHAND  514     /* restart if no handler.. */
85 #endif
86 #ifndef ENOIOCTLCMD
87 #define ENOIOCTLCMD     515     /* No ioctl command */
88 #endif
89 #ifndef ERESTART_RESTARTBLOCK
90 #define ERESTART_RESTARTBLOCK 516       /* restart by calling sys_restart_syscall */
91 #endif
92 #ifndef NSIG
93 #define NSIG 32
94 #endif
95 #ifdef ARM
96 #undef NSIG
97 #define NSIG 32
98 #undef NR_SYSCALL_BASE
99 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
100 #endif
101 #endif /* LINUX */
102
103 #include "syscall.h"
104
105 /* Define these shorthand notations to simplify the syscallent files. */
106 #define TD TRACE_DESC
107 #define TF TRACE_FILE
108 #define TI TRACE_IPC
109 #define TN TRACE_NETWORK
110 #define TP TRACE_PROCESS
111 #define TS TRACE_SIGNAL
112
113 static const struct sysent sysent0[] = {
114 #include "syscallent.h"
115 };
116 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
117 int qual_flags0[MAX_QUALS];
118
119 #if SUPPORTED_PERSONALITIES >= 2
120 static const struct sysent sysent1[] = {
121 #include "syscallent1.h"
122 };
123 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
124 int qual_flags1[MAX_QUALS];
125 #endif /* SUPPORTED_PERSONALITIES >= 2 */
126
127 #if SUPPORTED_PERSONALITIES >= 3
128 static const struct sysent sysent2[] = {
129 #include "syscallent2.h"
130 };
131 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
132 int qual_flags2[MAX_QUALS];
133 #endif /* SUPPORTED_PERSONALITIES >= 3 */
134
135 const struct sysent *sysent;
136 int *qual_flags;
137 int nsyscalls;
138
139 /* Now undef them since short defines cause wicked namespace pollution. */
140 #undef TD
141 #undef TF
142 #undef TI
143 #undef TN
144 #undef TP
145 #undef TS
146
147 static const char *const errnoent0[] = {
148 #include "errnoent.h"
149 };
150 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
151
152 #if SUPPORTED_PERSONALITIES >= 2
153 static const char *const errnoent1[] = {
154 #include "errnoent1.h"
155 };
156 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
157 #endif /* SUPPORTED_PERSONALITIES >= 2 */
158
159 #if SUPPORTED_PERSONALITIES >= 3
160 static const char *const errnoent2[] = {
161 #include "errnoent2.h"
162 };
163 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
164 #endif /* SUPPORTED_PERSONALITIES >= 3 */
165
166 const char *const *errnoent;
167 int nerrnos;
168
169 int current_personality;
170
171 #ifndef PERSONALITY0_WORDSIZE
172 # define PERSONALITY0_WORDSIZE sizeof(long)
173 #endif
174 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
175         PERSONALITY0_WORDSIZE,
176 #if SUPPORTED_PERSONALITIES > 1
177         PERSONALITY1_WORDSIZE,
178 #endif
179 #if SUPPORTED_PERSONALITIES > 2
180         PERSONALITY2_WORDSIZE,
181 #endif
182 };;
183
184 int
185 set_personality(int personality)
186 {
187         switch (personality) {
188         case 0:
189                 errnoent = errnoent0;
190                 nerrnos = nerrnos0;
191                 sysent = sysent0;
192                 nsyscalls = nsyscalls0;
193                 ioctlent = ioctlent0;
194                 nioctlents = nioctlents0;
195                 signalent = signalent0;
196                 nsignals = nsignals0;
197                 qual_flags = qual_flags0;
198                 break;
199
200 #if SUPPORTED_PERSONALITIES >= 2
201         case 1:
202                 errnoent = errnoent1;
203                 nerrnos = nerrnos1;
204                 sysent = sysent1;
205                 nsyscalls = nsyscalls1;
206                 ioctlent = ioctlent1;
207                 nioctlents = nioctlents1;
208                 signalent = signalent1;
209                 nsignals = nsignals1;
210                 qual_flags = qual_flags1;
211                 break;
212 #endif /* SUPPORTED_PERSONALITIES >= 2 */
213
214 #if SUPPORTED_PERSONALITIES >= 3
215         case 2:
216                 errnoent = errnoent2;
217                 nerrnos = nerrnos2;
218                 sysent = sysent2;
219                 nsyscalls = nsyscalls2;
220                 ioctlent = ioctlent2;
221                 nioctlents = nioctlents2;
222                 signalent = signalent2;
223                 nsignals = nsignals2;
224                 qual_flags = qual_flags2;
225                 break;
226 #endif /* SUPPORTED_PERSONALITIES >= 3 */
227
228         default:
229                 return -1;
230         }
231
232         current_personality = personality;
233         return 0;
234 }
235
236
237 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
238
239 static const struct qual_options {
240         int bitflag;
241         char *option_name;
242         int (*qualify)();
243         char *argument_name;
244 } qual_options[] = {
245         { QUAL_TRACE,   "trace",        qual_syscall,   "system call"   },
246         { QUAL_TRACE,   "t",            qual_syscall,   "system call"   },
247         { QUAL_ABBREV,  "abbrev",       qual_syscall,   "system call"   },
248         { QUAL_ABBREV,  "a",            qual_syscall,   "system call"   },
249         { QUAL_VERBOSE, "verbose",      qual_syscall,   "system call"   },
250         { QUAL_VERBOSE, "v",            qual_syscall,   "system call"   },
251         { QUAL_RAW,     "raw",          qual_syscall,   "system call"   },
252         { QUAL_RAW,     "x",            qual_syscall,   "system call"   },
253         { QUAL_SIGNAL,  "signal",       qual_signal,    "signal"        },
254         { QUAL_SIGNAL,  "signals",      qual_signal,    "signal"        },
255         { QUAL_SIGNAL,  "s",            qual_signal,    "signal"        },
256         { QUAL_FAULT,   "fault",        qual_fault,     "fault"         },
257         { QUAL_FAULT,   "faults",       qual_fault,     "fault"         },
258         { QUAL_FAULT,   "m",            qual_fault,     "fault"         },
259         { QUAL_READ,    "read",         qual_desc,      "descriptor"    },
260         { QUAL_READ,    "reads",        qual_desc,      "descriptor"    },
261         { QUAL_READ,    "r",            qual_desc,      "descriptor"    },
262         { QUAL_WRITE,   "write",        qual_desc,      "descriptor"    },
263         { QUAL_WRITE,   "writes",       qual_desc,      "descriptor"    },
264         { QUAL_WRITE,   "w",            qual_desc,      "descriptor"    },
265         { 0,            NULL,           NULL,           NULL            },
266 };
267
268 static void
269 qualify_one(n, opt, not, pers)
270         int n;
271         const struct qual_options *opt;
272         int not;
273         int pers;
274 {
275         if (pers == 0 || pers < 0) {
276                 if (not)
277                         qual_flags0[n] &= ~opt->bitflag;
278                 else
279                         qual_flags0[n] |= opt->bitflag;
280         }
281
282 #if SUPPORTED_PERSONALITIES >= 2
283         if (pers == 1 || pers < 0) {
284                 if (not)
285                         qual_flags1[n] &= ~opt->bitflag;
286                 else
287                         qual_flags1[n] |= opt->bitflag;
288         }
289 #endif /* SUPPORTED_PERSONALITIES >= 2 */
290
291 #if SUPPORTED_PERSONALITIES >= 3
292         if (pers == 2 || pers < 0) {
293                 if (not)
294                         qual_flags2[n] &= ~opt->bitflag;
295                 else
296                         qual_flags2[n] |= opt->bitflag;
297         }
298 #endif /* SUPPORTED_PERSONALITIES >= 3 */
299 }
300
301 static int
302 qual_syscall(s, opt, not)
303         char *s;
304         const struct qual_options *opt;
305         int not;
306 {
307         int i;
308         int rc = -1;
309
310         if (isdigit((unsigned char)*s)) {
311                 int i = atoi(s);
312                 if (i < 0 || i >= MAX_QUALS)
313                         return -1;
314                 qualify_one(i, opt, not, -1);
315                 return 0;
316         }
317         for (i = 0; i < nsyscalls0; i++)
318                 if (strcmp(s, sysent0[i].sys_name) == 0) {
319                         qualify_one(i, opt, not, 0);
320                         rc = 0;
321                 }
322
323 #if SUPPORTED_PERSONALITIES >= 2
324         for (i = 0; i < nsyscalls1; i++)
325                 if (strcmp(s, sysent1[i].sys_name) == 0) {
326                         qualify_one(i, opt, not, 1);
327                         rc = 0;
328                 }
329 #endif /* SUPPORTED_PERSONALITIES >= 2 */
330
331 #if SUPPORTED_PERSONALITIES >= 3
332         for (i = 0; i < nsyscalls2; i++)
333                 if (strcmp(s, sysent2[i].sys_name) == 0) {
334                         qualify_one(i, opt, not, 2);
335                         rc = 0;
336                 }
337 #endif /* SUPPORTED_PERSONALITIES >= 3 */
338
339         return rc;
340 }
341
342 static int
343 qual_signal(s, opt, not)
344         char *s;
345         const struct qual_options *opt;
346         int not;
347 {
348         int i;
349         char buf[32];
350
351         if (isdigit((unsigned char)*s)) {
352                 int signo = atoi(s);
353                 if (signo < 0 || signo >= MAX_QUALS)
354                         return -1;
355                 qualify_one(signo, opt, not, -1);
356                 return 0;
357         }
358         if (strlen(s) >= sizeof buf)
359                 return -1;
360         strcpy(buf, s);
361         s = buf;
362         for (i = 0; s[i]; i++)
363                 s[i] = toupper((unsigned char)(s[i]));
364         if (strncmp(s, "SIG", 3) == 0)
365                 s += 3;
366         for (i = 0; i <= NSIG; i++)
367                 if (strcmp(s, signame(i) + 3) == 0) {
368                         qualify_one(i, opt, not, -1);
369                         return 0;
370                 }
371         return -1;
372 }
373
374 static int
375 qual_fault(s, opt, not)
376         char *s;
377         const struct qual_options *opt;
378         int not;
379 {
380         return -1;
381 }
382
383 static int
384 qual_desc(s, opt, not)
385         char *s;
386         const struct qual_options *opt;
387         int not;
388 {
389         if (isdigit((unsigned char)*s)) {
390                 int desc = atoi(s);
391                 if (desc < 0 || desc >= MAX_QUALS)
392                         return -1;
393                 qualify_one(desc, opt, not, -1);
394                 return 0;
395         }
396         return -1;
397 }
398
399 static int
400 lookup_class(s)
401         char *s;
402 {
403         if (strcmp(s, "file") == 0)
404                 return TRACE_FILE;
405         if (strcmp(s, "ipc") == 0)
406                 return TRACE_IPC;
407         if (strcmp(s, "network") == 0)
408                 return TRACE_NETWORK;
409         if (strcmp(s, "process") == 0)
410                 return TRACE_PROCESS;
411         if (strcmp(s, "signal") == 0)
412                 return TRACE_SIGNAL;
413         if (strcmp(s, "desc") == 0)
414                 return TRACE_DESC;
415         return -1;
416 }
417
418 void
419 qualify(s)
420 char *s;
421 {
422         const struct qual_options *opt;
423         int not;
424         char *p;
425         int i, n;
426
427         opt = &qual_options[0];
428         for (i = 0; (p = qual_options[i].option_name); i++) {
429                 n = strlen(p);
430                 if (strncmp(s, p, n) == 0 && s[n] == '=') {
431                         opt = &qual_options[i];
432                         s += n + 1;
433                         break;
434                 }
435         }
436         not = 0;
437         if (*s == '!') {
438                 not = 1;
439                 s++;
440         }
441         if (strcmp(s, "none") == 0) {
442                 not = 1 - not;
443                 s = "all";
444         }
445         if (strcmp(s, "all") == 0) {
446                 for (i = 0; i < MAX_QUALS; i++) {
447                         qualify_one(i, opt, not, -1);
448                 }
449                 return;
450         }
451         for (i = 0; i < MAX_QUALS; i++) {
452                 qualify_one(i, opt, !not, -1);
453         }
454         for (p = strtok(s, ","); p; p = strtok(NULL, ",")) {
455                 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
456                         for (i = 0; i < nsyscalls0; i++)
457                                 if (sysent0[i].sys_flags & n)
458                                         qualify_one(i, opt, not, 0);
459
460 #if SUPPORTED_PERSONALITIES >= 2
461                         for (i = 0; i < nsyscalls1; i++)
462                                 if (sysent1[i].sys_flags & n)
463                                         qualify_one(i, opt, not, 1);
464 #endif /* SUPPORTED_PERSONALITIES >= 2 */
465
466 #if SUPPORTED_PERSONALITIES >= 3
467                         for (i = 0; i < nsyscalls2; i++)
468                                 if (sysent2[i].sys_flags & n)
469                                         qualify_one(i, opt, not, 2);
470 #endif /* SUPPORTED_PERSONALITIES >= 3 */
471
472                         continue;
473                 }
474                 if (opt->qualify(p, opt, not)) {
475                         fprintf(stderr, "strace: invalid %s `%s'\n",
476                                 opt->argument_name, p);
477                         exit(1);
478                 }
479         }
480         return;
481 }
482
483 static void
484 dumpio(tcp)
485 struct tcb *tcp;
486 {
487         if (syserror(tcp))
488                 return;
489         if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
490                 return;
491         switch (known_scno(tcp)) {
492         case SYS_read:
493 #ifdef SYS_pread64
494         case SYS_pread64:
495 #endif
496 #if defined SYS_pread && SYS_pread64 != SYS_pread
497         case SYS_pread:
498 #endif
499 #ifdef SYS_recv
500         case SYS_recv:
501 #elif defined SYS_sub_recv
502         case SYS_sub_recv:
503 #endif
504 #ifdef SYS_recvfrom
505         case SYS_recvfrom:
506 #elif defined SYS_sub_recvfrom
507         case SYS_sub_recvfrom:
508 #endif
509                 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
510                         dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
511                 break;
512         case SYS_write:
513 #ifdef SYS_pwrite64
514         case SYS_pwrite64:
515 #endif
516 #if defined SYS_pwrite && SYS_pwrite64 != SYS_pwrite
517         case SYS_pwrite:
518 #endif
519 #ifdef SYS_send
520         case SYS_send:
521 #elif defined SYS_sub_send
522         case SYS_sub_send:
523 #endif
524 #ifdef SYS_sendto
525         case SYS_sendto:
526 #elif defined SYS_sub_sendto
527         case SYS_sub_sendto:
528 #endif
529                 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
530                         dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
531                 break;
532 #ifdef SYS_readv
533         case SYS_readv:
534                 if (qual_flags[tcp->u_arg[0]] & QUAL_READ)
535                         dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
536                 break;
537 #endif
538 #ifdef SYS_writev
539         case SYS_writev:
540                 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE)
541                         dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
542                 break;
543 #endif
544         }
545 }
546
547 #ifndef FREEBSD
548 enum subcall_style { shift_style, deref_style, mask_style, door_style };
549 #else /* FREEBSD */
550 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
551
552 struct subcall {
553   int call;
554   int nsubcalls;
555   int subcalls[5];
556 };
557
558 static const struct subcall subcalls_table[] = {
559   { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
560 #ifdef SYS_semconfig
561   { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
562 #else
563   { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
564 #endif
565   { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
566 };
567 #endif /* FREEBSD */
568
569 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
570
571 static void
572 decode_subcall(tcp, subcall, nsubcalls, style)
573 struct tcb *tcp;
574 int subcall;
575 int nsubcalls;
576 enum subcall_style style;
577 {
578         unsigned long addr, mask;
579         int i;
580         int size = personality_wordsize[current_personality];
581
582         switch (style) {
583         case shift_style:
584                 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
585                         return;
586                 tcp->scno = subcall + tcp->u_arg[0];
587                 if (sysent[tcp->scno].nargs != -1)
588                         tcp->u_nargs = sysent[tcp->scno].nargs;
589                 else
590                         tcp->u_nargs--;
591                 for (i = 0; i < tcp->u_nargs; i++)
592                         tcp->u_arg[i] = tcp->u_arg[i + 1];
593                 break;
594         case deref_style:
595                 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
596                         return;
597                 tcp->scno = subcall + tcp->u_arg[0];
598                 addr = tcp->u_arg[1];
599                 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
600                         if (size == sizeof(int)) {
601                                 unsigned int arg;
602                                 if (umove(tcp, addr, &arg) < 0)
603                                         arg = 0;
604                                 tcp->u_arg[i] = arg;
605                         }
606                         else if (size == sizeof(long)) {
607                                 unsigned long arg;
608                                 if (umove(tcp, addr, &arg) < 0)
609                                         arg = 0;
610                                 tcp->u_arg[i] = arg;
611                         }
612                         else
613                                 abort();
614                         addr += size;
615                 }
616                 tcp->u_nargs = sysent[tcp->scno].nargs;
617                 break;
618         case mask_style:
619                 mask = (tcp->u_arg[0] >> 8) & 0xff;
620                 for (i = 0; mask; i++)
621                         mask >>= 1;
622                 if (i >= nsubcalls)
623                         return;
624                 tcp->u_arg[0] &= 0xff;
625                 tcp->scno = subcall + i;
626                 if (sysent[tcp->scno].nargs != -1)
627                         tcp->u_nargs = sysent[tcp->scno].nargs;
628                 break;
629         case door_style:
630                 /*
631                  * Oh, yuck.  The call code is the *sixth* argument.
632                  * (don't you mean the *last* argument? - JH)
633                  */
634                 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
635                         return;
636                 tcp->scno = subcall + tcp->u_arg[5];
637                 if (sysent[tcp->scno].nargs != -1)
638                         tcp->u_nargs = sysent[tcp->scno].nargs;
639                 else
640                         tcp->u_nargs--;
641                 break;
642 #ifdef FREEBSD
643         case table_style:
644                 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
645                         if (subcalls_table[i].call == tcp->scno) break;
646                 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
647                     tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
648                         tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
649                         for (i = 0; i < tcp->u_nargs; i++)
650                                 tcp->u_arg[i] = tcp->u_arg[i + 1];
651                 }
652                 break;
653 #endif /* FREEBSD */
654         }
655 }
656 #endif
657
658 struct tcb *tcp_last = NULL;
659
660 static int
661 internal_syscall(struct tcb *tcp)
662 {
663         /*
664          * We must always trace a few critical system calls in order to
665          * correctly support following forks in the presence of tracing
666          * qualifiers.
667          */
668         int     (*func)();
669
670         if (tcp->scno < 0 || tcp->scno >= nsyscalls)
671                 return 0;
672
673         func = sysent[tcp->scno].sys_func;
674
675         if (sys_exit == func)
676                 return internal_exit(tcp);
677
678         if (   sys_fork == func
679 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
680             || sys_vfork == func
681 #endif
682 #ifdef LINUX
683             || sys_clone == func
684 #endif
685 #if UNIXWARE > 2
686             || sys_rfork == func
687 #endif
688            )
689                 return internal_fork(tcp);
690
691         if (   sys_execve == func
692 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
693             || sys_execv == func
694 #endif
695 #if UNIXWARE > 2
696             || sys_rexecve == func
697 #endif
698            )
699                 return internal_exec(tcp);
700
701         if (   sys_waitpid == func
702             || sys_wait4 == func
703 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
704             || sys_wait == func
705 #endif
706 #ifdef ALPHA
707             || sys_osf_wait4 == func
708 #endif
709            )
710                 return internal_wait(tcp, 2);
711
712 #if defined(LINUX) || defined(SVR4)
713         if (sys_waitid == func)
714                 return internal_wait(tcp, 3);
715 #endif
716
717         return 0;
718 }
719
720
721 #ifdef LINUX
722 #if defined (I386)
723         static long eax;
724 #elif defined (IA64)
725         long r8, r10, psr;
726         long ia32 = 0;
727 #elif defined (POWERPC)
728         static long result,flags;
729 #elif defined (M68K)
730         static int d0;
731 #elif defined(BFIN)
732         static long r0;
733 #elif defined (ARM)
734         static struct pt_regs regs;
735 #elif defined (ALPHA)
736         static long r0;
737         static long a3;
738 #elif defined(AVR32)
739         static struct pt_regs regs;
740 #elif defined (SPARC) || defined (SPARC64)
741         static struct pt_regs regs;
742         static unsigned long trap;
743 #elif defined(LINUX_MIPSN32)
744         static long long a3;
745         static long long r2;
746 #elif defined(MIPS)
747         static long a3;
748         static long r2;
749 #elif defined(S390) || defined(S390X)
750         static long gpr2;
751         static long pc;
752         static long syscall_mode;
753 #elif defined(HPPA)
754         static long r28;
755 #elif defined(SH)
756         static long r0;
757 #elif defined(SH64)
758         static long r9;
759 #elif defined(X86_64)
760         static long rax;
761 #elif defined(CRISV10) || defined(CRISV32)
762         static long r10;
763 #endif
764 #endif /* LINUX */
765 #ifdef FREEBSD
766         struct reg regs;
767 #endif /* FREEBSD */
768
769 int
770 get_scno(struct tcb *tcp)
771 {
772         long scno = 0;
773
774 #ifdef LINUX
775 # if defined(S390) || defined(S390X)
776         if (tcp->flags & TCB_WAITEXECVE) {
777                 /*
778                  * When the execve system call completes successfully, the
779                  * new process still has -ENOSYS (old style) or __NR_execve
780                  * (new style) in gpr2.  We cannot recover the scno again
781                  * by disassembly, because the image that executed the
782                  * syscall is gone now.  Fortunately, we don't want it.  We
783                  * leave the flag set so that syscall_fixup can fake the
784                  * result.
785                  */
786                 if (tcp->flags & TCB_INSYSCALL)
787                         return 1;
788                 /*
789                  * This is the SIGTRAP after execve.  We cannot try to read
790                  * the system call here either.
791                  */
792                 tcp->flags &= ~TCB_WAITEXECVE;
793                 return 0;
794         }
795
796         if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
797                         return -1;
798
799         if (syscall_mode != -ENOSYS) {
800                 /*
801                  * Since kernel version 2.5.44 the scno gets passed in gpr2.
802                  */
803                 scno = syscall_mode;
804         } else {
805                 /*
806                  * Old style of "passing" the scno via the SVC instruction.
807                  */
808
809                 long opcode, offset_reg, tmp;
810                 void * svc_addr;
811                 int gpr_offset[16] = {PT_GPR0,  PT_GPR1,  PT_ORIGGPR2, PT_GPR3,
812                                       PT_GPR4,  PT_GPR5,  PT_GPR6,     PT_GPR7,
813                                       PT_GPR8,  PT_GPR9,  PT_GPR10,    PT_GPR11,
814                                       PT_GPR12, PT_GPR13, PT_GPR14,    PT_GPR15};
815
816                 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
817                         return -1;
818                 errno = 0;
819                 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
820                 if (errno) {
821                         perror("peektext(pc-oneword)");
822                         return -1;
823                 }
824
825                 /*
826                  *  We have to check if the SVC got executed directly or via an
827                  *  EXECUTE instruction. In case of EXECUTE it is necessary to do
828                  *  instruction decoding to derive the system call number.
829                  *  Unfortunately the opcode sizes of EXECUTE and SVC are differently,
830                  *  so that this doesn't work if a SVC opcode is part of an EXECUTE
831                  *  opcode. Since there is no way to find out the opcode size this
832                  *  is the best we can do...
833                  */
834
835                 if ((opcode & 0xff00) == 0x0a00) {
836                         /* SVC opcode */
837                         scno = opcode & 0xff;
838                 }
839                 else {
840                         /* SVC got executed by EXECUTE instruction */
841
842                         /*
843                          *  Do instruction decoding of EXECUTE. If you really want to
844                          *  understand this, read the Principles of Operations.
845                          */
846                         svc_addr = (void *) (opcode & 0xfff);
847
848                         tmp = 0;
849                         offset_reg = (opcode & 0x000f0000) >> 16;
850                         if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
851                                 return -1;
852                         svc_addr += tmp;
853
854                         tmp = 0;
855                         offset_reg = (opcode & 0x0000f000) >> 12;
856                         if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
857                                 return -1;
858                         svc_addr += tmp;
859
860                         scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
861                         if (errno)
862                                 return -1;
863 #  if defined(S390X)
864                         scno >>= 48;
865 #  else
866                         scno >>= 16;
867 #  endif
868                         tmp = 0;
869                         offset_reg = (opcode & 0x00f00000) >> 20;
870                         if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
871                                 return -1;
872
873                         scno = (scno | tmp) & 0xff;
874                 }
875         }
876 # elif defined (POWERPC)
877         if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
878                 return -1;
879         if (!(tcp->flags & TCB_INSYSCALL)) {
880                 /* Check if we return from execve. */
881                 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
882                         tcp->flags &= ~TCB_WAITEXECVE;
883                         return 0;
884                 }
885         }
886 # elif defined(AVR32)
887         /*
888          * Read complete register set in one go.
889          */
890         if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, &regs) < 0)
891                 return -1;
892
893         /*
894          * We only need to grab the syscall number on syscall entry.
895          */
896         if (!(tcp->flags & TCB_INSYSCALL)) {
897                 scno = regs.r8;
898
899                 /* Check if we return from execve. */
900                 if (tcp->flags & TCB_WAITEXECVE) {
901                         tcp->flags &= ~TCB_WAITEXECVE;
902                         return 0;
903                 }
904         }
905 # elif defined(BFIN)
906         if (upeek(tcp, PT_ORIG_P0, &scno))
907                 return -1;
908 # elif defined (I386)
909         if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
910                 return -1;
911 # elif defined (X86_64)
912         if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
913                 return -1;
914
915         if (!(tcp->flags & TCB_INSYSCALL)) {
916                 static int currpers = -1;
917                 long val;
918                 int pid = tcp->pid;
919
920                 /* Check CS register value. On x86-64 linux it is:
921                  *      0x33    for long mode (64 bit)
922                  *      0x23    for compatibility mode (32 bit)
923                  * It takes only one ptrace and thus doesn't need
924                  * to be cached.
925                  */
926                 if (upeek(tcp, 8*CS, &val) < 0)
927                         return -1;
928                 switch (val) {
929                         case 0x23: currpers = 1; break;
930                         case 0x33: currpers = 0; break;
931                         default:
932                                 fprintf(stderr, "Unknown value CS=0x%02X while "
933                                          "detecting personality of process "
934                                          "PID=%d\n", (int)val, pid);
935                                 currpers = current_personality;
936                                 break;
937                 }
938 #  if 0
939                 /* This version analyzes the opcode of a syscall instruction.
940                  * (int 0x80 on i386 vs. syscall on x86-64)
941                  * It works, but is too complicated.
942                  */
943                 unsigned long val, rip, i;
944
945                 if (upeek(tcp, 8*RIP, &rip) < 0)
946                         perror("upeek(RIP)");
947
948                 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
949                 rip -= 2;
950                 errno = 0;
951
952                 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
953                 if (errno)
954                         printf("ptrace_peektext failed: %s\n",
955                                         strerror(errno));
956                 switch (call & 0xffff) {
957                         /* x86-64: syscall = 0x0f 0x05 */
958                         case 0x050f: currpers = 0; break;
959                         /* i386: int 0x80 = 0xcd 0x80 */
960                         case 0x80cd: currpers = 1; break;
961                         default:
962                                 currpers = current_personality;
963                                 fprintf(stderr,
964                                         "Unknown syscall opcode (0x%04X) while "
965                                         "detecting personality of process "
966                                         "PID=%d\n", (int)call, pid);
967                                 break;
968                 }
969 #  endif
970                 if (currpers != current_personality) {
971                         static const char *const names[] = {"64 bit", "32 bit"};
972                         set_personality(currpers);
973                         printf("[ Process PID=%d runs in %s mode. ]\n",
974                                         pid, names[current_personality]);
975                 }
976         }
977 # elif defined(IA64)
978 #       define IA64_PSR_IS      ((long)1 << 34)
979         if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
980                 ia32 = (psr & IA64_PSR_IS) != 0;
981         if (!(tcp->flags & TCB_INSYSCALL)) {
982                 if (ia32) {
983                         if (upeek(tcp, PT_R1, &scno) < 0)       /* orig eax */
984                                 return -1;
985                 } else {
986                         if (upeek (tcp, PT_R15, &scno) < 0)
987                                 return -1;
988                 }
989                 /* Check if we return from execve. */
990                 if (tcp->flags & TCB_WAITEXECVE) {
991                         tcp->flags &= ~TCB_WAITEXECVE;
992                         return 0;
993                 }
994         } else {
995                 /* syscall in progress */
996                 if (upeek (tcp, PT_R8, &r8) < 0)
997                         return -1;
998                 if (upeek (tcp, PT_R10, &r10) < 0)
999                         return -1;
1000         }
1001 # elif defined (ARM)
1002         /*
1003          * Read complete register set in one go.
1004          */
1005         if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)&regs) == -1)
1006                 return -1;
1007
1008         /*
1009          * We only need to grab the syscall number on syscall entry.
1010          */
1011         if (regs.ARM_ip == 0) {
1012                 if (!(tcp->flags & TCB_INSYSCALL)) {
1013                         /* Check if we return from execve. */
1014                         if (tcp->flags & TCB_WAITEXECVE) {
1015                                 tcp->flags &= ~TCB_WAITEXECVE;
1016                                 return 0;
1017                         }
1018                 }
1019
1020                 /*
1021                  * Note: we only deal with only 32-bit CPUs here.
1022                  */
1023                 if (regs.ARM_cpsr & 0x20) {
1024                         /*
1025                          * Get the Thumb-mode system call number
1026                          */
1027                         scno = regs.ARM_r7;
1028                 } else {
1029                         /*
1030                          * Get the ARM-mode system call number
1031                          */
1032                         errno = 0;
1033                         scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1034                         if (errno)
1035                                 return -1;
1036
1037                         if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1038                                 tcp->flags &= ~TCB_WAITEXECVE;
1039                                 return 0;
1040                         }
1041
1042                         /* Handle the EABI syscall convention.  We do not
1043                            bother converting structures between the two
1044                            ABIs, but basic functionality should work even
1045                            if strace and the traced program have different
1046                            ABIs.  */
1047                         if (scno == 0xef000000) {
1048                                 scno = regs.ARM_r7;
1049                         } else {
1050                                 if ((scno & 0x0ff00000) != 0x0f900000) {
1051                                         fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1052                                                 scno);
1053                                         return -1;
1054                                 }
1055
1056                                 /*
1057                                  * Fixup the syscall number
1058                                  */
1059                                 scno &= 0x000fffff;
1060                         }
1061                 }
1062                 if (scno & 0x0f0000) {
1063                         /*
1064                          * Handle ARM specific syscall
1065                          */
1066                         set_personality(1);
1067                         scno &= 0x0000ffff;
1068                 } else
1069                         set_personality(0);
1070
1071                 if (tcp->flags & TCB_INSYSCALL) {
1072                         fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1073                         tcp->flags &= ~TCB_INSYSCALL;
1074                 }
1075         } else {
1076                 if (!(tcp->flags & TCB_INSYSCALL)) {
1077                         fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1078                         tcp->flags |= TCB_INSYSCALL;
1079                 }
1080         }
1081 # elif defined (M68K)
1082         if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1083                 return -1;
1084 # elif defined (LINUX_MIPSN32)
1085         unsigned long long regs[38];
1086
1087         if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) &regs) < 0)
1088                 return -1;
1089         a3 = regs[REG_A3];
1090         r2 = regs[REG_V0];
1091
1092         if(!(tcp->flags & TCB_INSYSCALL)) {
1093                 scno = r2;
1094
1095                 /* Check if we return from execve. */
1096                 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1097                         tcp->flags &= ~TCB_WAITEXECVE;
1098                         return 0;
1099                 }
1100
1101                 if (scno < 0 || scno > nsyscalls) {
1102                         if(a3 == 0 || a3 == -1) {
1103                                 if(debug)
1104                                         fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1105                                 return 0;
1106                         }
1107                 }
1108         }
1109 # elif defined (MIPS)
1110         if (upeek(tcp, REG_A3, &a3) < 0)
1111                 return -1;
1112         if(!(tcp->flags & TCB_INSYSCALL)) {
1113                 if (upeek(tcp, REG_V0, &scno) < 0)
1114                         return -1;
1115
1116                 /* Check if we return from execve. */
1117                 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1118                         tcp->flags &= ~TCB_WAITEXECVE;
1119                         return 0;
1120                 }
1121
1122                 if (scno < 0 || scno > nsyscalls) {
1123                         if(a3 == 0 || a3 == -1) {
1124                                 if(debug)
1125                                         fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1126                                 return 0;
1127                         }
1128                 }
1129         } else {
1130                 if (upeek(tcp, REG_V0, &r2) < 0)
1131                         return -1;
1132         }
1133 # elif defined (ALPHA)
1134         if (upeek(tcp, REG_A3, &a3) < 0)
1135                 return -1;
1136
1137         if (!(tcp->flags & TCB_INSYSCALL)) {
1138                 if (upeek(tcp, REG_R0, &scno) < 0)
1139                         return -1;
1140
1141                 /* Check if we return from execve. */
1142                 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1143                         tcp->flags &= ~TCB_WAITEXECVE;
1144                         return 0;
1145                 }
1146
1147                 /*
1148                  * Do some sanity checks to figure out if it's
1149                  * really a syscall entry
1150                  */
1151                 if (scno < 0 || scno > nsyscalls) {
1152                         if (a3 == 0 || a3 == -1) {
1153                                 if (debug)
1154                                         fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1155                                 return 0;
1156                         }
1157                 }
1158         }
1159         else {
1160                 if (upeek(tcp, REG_R0, &r0) < 0)
1161                         return -1;
1162         }
1163 # elif defined (SPARC) || defined (SPARC64)
1164         /* Everything we need is in the current register set. */
1165         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
1166                 return -1;
1167
1168         /* If we are entering, then disassemble the syscall trap. */
1169         if (!(tcp->flags & TCB_INSYSCALL)) {
1170                 /* Retrieve the syscall trap instruction. */
1171                 errno = 0;
1172 #  if defined(SPARC64)
1173                 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1174                 trap >>= 32;
1175 #  else
1176                 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1177 #  endif
1178                 if (errno)
1179                         return -1;
1180
1181                 /* Disassemble the trap to see what personality to use. */
1182                 switch (trap) {
1183                 case 0x91d02010:
1184                         /* Linux/SPARC syscall trap. */
1185                         set_personality(0);
1186                         break;
1187                 case 0x91d0206d:
1188                         /* Linux/SPARC64 syscall trap. */
1189                         set_personality(2);
1190                         break;
1191                 case 0x91d02000:
1192                         /* SunOS syscall trap. (pers 1) */
1193                         fprintf(stderr,"syscall: SunOS no support\n");
1194                         return -1;
1195                 case 0x91d02008:
1196                         /* Solaris 2.x syscall trap. (per 2) */
1197                         set_personality(1);
1198                         break;
1199                 case 0x91d02009:
1200                         /* NetBSD/FreeBSD syscall trap. */
1201                         fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1202                         return -1;
1203                 case 0x91d02027:
1204                         /* Solaris 2.x gettimeofday */
1205                         set_personality(1);
1206                         break;
1207                 default:
1208                         /* Unknown syscall trap. */
1209                         if(tcp->flags & TCB_WAITEXECVE) {
1210                                 tcp->flags &= ~TCB_WAITEXECVE;
1211                                 return 0;
1212                         }
1213 #  if defined (SPARC64)
1214                         fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1215 #  else
1216                         fprintf(stderr,"syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1217 #  endif
1218                         return -1;
1219                 }
1220
1221                 /* Extract the system call number from the registers. */
1222                 if (trap == 0x91d02027)
1223                         scno = 156;
1224                 else
1225                         scno = regs.u_regs[U_REG_G1];
1226                 if (scno == 0) {
1227                         scno = regs.u_regs[U_REG_O0];
1228                         memmove (&regs.u_regs[U_REG_O0], &regs.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1229                 }
1230         }
1231 # elif defined(HPPA)
1232         if (upeek(tcp, PT_GR20, &scno) < 0)
1233                 return -1;
1234         if (!(tcp->flags & TCB_INSYSCALL)) {
1235                 /* Check if we return from execve. */
1236                 if ((tcp->flags & TCB_WAITEXECVE)) {
1237                         tcp->flags &= ~TCB_WAITEXECVE;
1238                         return 0;
1239                 }
1240         }
1241 # elif defined(SH)
1242         /*
1243          * In the new syscall ABI, the system call number is in R3.
1244          */
1245         if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1246                 return -1;
1247
1248         if (scno < 0) {
1249                 /* Odd as it may seem, a glibc bug has been known to cause
1250                    glibc to issue bogus negative syscall numbers.  So for
1251                    our purposes, make strace print what it *should* have been */
1252                 long correct_scno = (scno & 0xff);
1253                 if (debug)
1254                         fprintf(stderr,
1255                                 "Detected glibc bug: bogus system call"
1256                                 " number = %ld, correcting to %ld\n",
1257                                 scno,
1258                                 correct_scno);
1259                 scno = correct_scno;
1260         }
1261
1262         if (!(tcp->flags & TCB_INSYSCALL)) {
1263                 /* Check if we return from execve. */
1264                 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1265                         tcp->flags &= ~TCB_WAITEXECVE;
1266                         return 0;
1267                 }
1268         }
1269 # elif defined(SH64)
1270         if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1271                 return -1;
1272         scno &= 0xFFFF;
1273
1274         if (!(tcp->flags & TCB_INSYSCALL)) {
1275                 /* Check if we return from execve. */
1276                 if (tcp->flags & TCB_WAITEXECVE) {
1277                         tcp->flags &= ~TCB_WAITEXECVE;
1278                         return 0;
1279                 }
1280         }
1281 # elif defined(CRISV10) || defined(CRISV32)
1282         if (upeek(tcp, 4*PT_R9, &scno) < 0)
1283                 return -1;
1284 # elif defined(TILE)
1285         if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1286                 return -1;
1287
1288         if (!(tcp->flags & TCB_INSYSCALL)) {
1289                 /* Check if we return from execve. */
1290                 if (tcp->flags & TCB_WAITEXECVE) {
1291                         tcp->flags &= ~TCB_WAITEXECVE;
1292                         return 0;
1293                 }
1294         }
1295 # endif
1296 #endif /* LINUX */
1297
1298 #ifdef SUNOS4
1299         if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1300                 return -1;
1301 #elif defined(SH)
1302         /* new syscall ABI returns result in R0 */
1303         if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1304                 return -1;
1305 #elif defined(SH64)
1306         /* ABI defines result returned in r9 */
1307         if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1308                 return -1;
1309 #endif
1310
1311 #ifdef USE_PROCFS
1312 # ifdef HAVE_PR_SYSCALL
1313         scno = tcp->status.PR_SYSCALL;
1314 # else
1315 #  ifndef FREEBSD
1316         scno = tcp->status.PR_WHAT;
1317 #  else
1318         if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
1319                 perror("pread");
1320                 return -1;
1321         }
1322         switch (regs.r_eax) {
1323         case SYS_syscall:
1324         case SYS___syscall:
1325                 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1326                 break;
1327         default:
1328                 scno = regs.r_eax;
1329                 break;
1330         }
1331 #  endif /* FREEBSD */
1332 # endif /* !HAVE_PR_SYSCALL */
1333 #endif /* USE_PROCFS */
1334
1335         if (!(tcp->flags & TCB_INSYSCALL))
1336                 tcp->scno = scno;
1337         return 1;
1338 }
1339
1340
1341 long
1342 known_scno(tcp)
1343 struct tcb *tcp;
1344 {
1345         long scno = tcp->scno;
1346         if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1347                 scno = sysent[scno].native_scno;
1348         else
1349                 scno += NR_SYSCALL_BASE;
1350         return scno;
1351 }
1352
1353 /* Called in trace_syscall() at each syscall entry and exit.
1354  * Returns:
1355  * 0: "ignore this syscall", bail out of trace_syscall() silently.
1356  * 1: ok, continue in trace_syscall().
1357  * other: error, trace_syscall() should print error indicator
1358  *    ("????" etc) and bail out.
1359  */
1360 static int
1361 syscall_fixup(struct tcb *tcp)
1362 {
1363 #ifdef USE_PROCFS
1364         int scno = known_scno(tcp);
1365
1366         if (!(tcp->flags & TCB_INSYSCALL)) {
1367                 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1368                         if (
1369                             scno == SYS_fork
1370 #ifdef SYS_vfork
1371                             || scno == SYS_vfork
1372 #endif /* SYS_vfork */
1373 #ifdef SYS_fork1
1374                             || scno == SYS_fork1
1375 #endif /* SYS_fork1 */
1376 #ifdef SYS_forkall
1377                             || scno == SYS_forkall
1378 #endif /* SYS_forkall */
1379 #ifdef SYS_rfork1
1380                             || scno == SYS_rfork1
1381 #endif /* SYS_fork1 */
1382 #ifdef SYS_rforkall
1383                             || scno == SYS_rforkall
1384 #endif /* SYS_rforkall */
1385                             ) {
1386                                 /* We are returning in the child, fake it. */
1387                                 tcp->status.PR_WHY = PR_SYSENTRY;
1388                                 trace_syscall(tcp);
1389                                 tcp->status.PR_WHY = PR_SYSEXIT;
1390                         }
1391                         else {
1392                                 fprintf(stderr, "syscall: missing entry\n");
1393                                 tcp->flags |= TCB_INSYSCALL;
1394                         }
1395                 }
1396         }
1397         else {
1398                 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1399                         fprintf(stderr, "syscall: missing exit\n");
1400                         tcp->flags &= ~TCB_INSYSCALL;
1401                 }
1402         }
1403 #endif /* USE_PROCFS */
1404 #ifdef SUNOS4
1405         if (!(tcp->flags & TCB_INSYSCALL)) {
1406                 if (scno == 0) {
1407                         fprintf(stderr, "syscall: missing entry\n");
1408                         tcp->flags |= TCB_INSYSCALL;
1409                 }
1410         }
1411         else {
1412                 if (scno != 0) {
1413                         if (debug) {
1414                                 /*
1415                                  * This happens when a signal handler
1416                                  * for a signal which interrupted a
1417                                  * a system call makes another system call.
1418                                  */
1419                                 fprintf(stderr, "syscall: missing exit\n");
1420                         }
1421                         tcp->flags &= ~TCB_INSYSCALL;
1422                 }
1423         }
1424 #endif /* SUNOS4 */
1425 #ifdef LINUX
1426 #if defined (I386)
1427         if (upeek(tcp, 4*EAX, &eax) < 0)
1428                 return -1;
1429         if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1430                 if (debug)
1431                         fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1432                 return 0;
1433         }
1434 #elif defined (X86_64)
1435         if (upeek(tcp, 8*RAX, &rax) < 0)
1436                 return -1;
1437         if (current_personality == 1)
1438                 rax = (long int)(int)rax; /* sign extend from 32 bits */
1439         if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1440                 if (debug)
1441                         fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1442                 return 0;
1443         }
1444 #elif defined (S390) || defined (S390X)
1445         if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1446                 return -1;
1447         if (syscall_mode != -ENOSYS)
1448                 syscall_mode = tcp->scno;
1449         if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1450                 if (debug)
1451                         fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1452                 return 0;
1453         }
1454         else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1455                   == (TCB_INSYSCALL|TCB_WAITEXECVE))
1456                  && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1457                 /*
1458                  * Fake a return value of zero.  We leave the TCB_WAITEXECVE
1459                  * flag set for the post-execve SIGTRAP to see and reset.
1460                  */
1461                 gpr2 = 0;
1462         }
1463 #elif defined (POWERPC)
1464 # define SO_MASK 0x10000000
1465         if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1466                 return -1;
1467         if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1468                 return -1;
1469         if (flags & SO_MASK)
1470                 result = -result;
1471 #elif defined (M68K)
1472         if (upeek(tcp, 4*PT_D0, &d0) < 0)
1473                 return -1;
1474         if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1475                 if (debug)
1476                         fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1477                 return 0;
1478         }
1479 #elif defined (ARM)
1480         /*
1481          * Nothing required
1482          */
1483 #elif defined(BFIN)
1484         if (upeek(tcp, PT_R0, &r0) < 0)
1485                 return -1;
1486 #elif defined (HPPA)
1487         if (upeek(tcp, PT_GR28, &r28) < 0)
1488                 return -1;
1489 #elif defined(IA64)
1490         if (upeek(tcp, PT_R10, &r10) < 0)
1491                 return -1;
1492         if (upeek(tcp, PT_R8, &r8) < 0)
1493                 return -1;
1494         if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1495                 if (debug)
1496                         fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1497                 return 0;
1498         }
1499 #elif defined(CRISV10) || defined(CRISV32)
1500         if (upeek(tcp, 4*PT_R10, &r10) < 0)
1501                 return -1;
1502         if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1503                 if (debug)
1504                         fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1505                 return 0;
1506         }
1507 #endif
1508 #endif /* LINUX */
1509         return 1;
1510 }
1511
1512 #ifdef LINUX
1513 /*
1514  * Check the syscall return value register value for whether it is
1515  * a negated errno code indicating an error, or a success return value.
1516  */
1517 static inline int
1518 is_negated_errno(unsigned long int val)
1519 {
1520         unsigned long int max = -(long int) nerrnos;
1521         if (personality_wordsize[current_personality] < sizeof(val)) {
1522                 val = (unsigned int) val;
1523                 max = (unsigned int) max;
1524         }
1525         return val > max;
1526 }
1527 #endif
1528
1529 static int
1530 get_error(struct tcb *tcp)
1531 {
1532         int u_error = 0;
1533 #ifdef LINUX
1534 # if defined(S390) || defined(S390X)
1535         if (is_negated_errno(gpr2)) {
1536                 tcp->u_rval = -1;
1537                 u_error = -gpr2;
1538         }
1539         else {
1540                 tcp->u_rval = gpr2;
1541                 u_error = 0;
1542         }
1543 # elif defined(I386)
1544         if (is_negated_errno(eax)) {
1545                 tcp->u_rval = -1;
1546                 u_error = -eax;
1547         }
1548         else {
1549                 tcp->u_rval = eax;
1550                 u_error = 0;
1551         }
1552 # elif defined(X86_64)
1553         if (is_negated_errno(rax)) {
1554                 tcp->u_rval = -1;
1555                 u_error = -rax;
1556         }
1557         else {
1558                 tcp->u_rval = rax;
1559                 u_error = 0;
1560         }
1561 # elif defined(IA64)
1562         if (ia32) {
1563                 int err;
1564
1565                 err = (int)r8;
1566                 if (is_negated_errno(err)) {
1567                         tcp->u_rval = -1;
1568                         u_error = -err;
1569                 }
1570                 else {
1571                         tcp->u_rval = err;
1572                         u_error = 0;
1573                 }
1574         } else {
1575                 if (r10) {
1576                         tcp->u_rval = -1;
1577                         u_error = r8;
1578                 } else {
1579                         tcp->u_rval = r8;
1580                         u_error = 0;
1581                 }
1582         }
1583 # elif defined(MIPS)
1584                 if (a3) {
1585                         tcp->u_rval = -1;
1586                         u_error = r2;
1587                 } else {
1588                         tcp->u_rval = r2;
1589                         u_error = 0;
1590                 }
1591 # elif defined(POWERPC)
1592                 if (is_negated_errno(result)) {
1593                         tcp->u_rval = -1;
1594                         u_error = -result;
1595                 }
1596                 else {
1597                         tcp->u_rval = result;
1598                         u_error = 0;
1599                 }
1600 # elif defined(M68K)
1601                 if (is_negated_errno(d0)) {
1602                         tcp->u_rval = -1;
1603                         u_error = -d0;
1604                 }
1605                 else {
1606                         tcp->u_rval = d0;
1607                         u_error = 0;
1608                 }
1609 # elif defined(ARM)
1610                 if (is_negated_errno(regs.ARM_r0)) {
1611                         tcp->u_rval = -1;
1612                         u_error = -regs.ARM_r0;
1613                 }
1614                 else {
1615                         tcp->u_rval = regs.ARM_r0;
1616                         u_error = 0;
1617                 }
1618 # elif defined(AVR32)
1619                 if (regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1620                         tcp->u_rval = -1;
1621                         u_error = -regs.r12;
1622                 }
1623                 else {
1624                         tcp->u_rval = regs.r12;
1625                         u_error = 0;
1626                 }
1627 # elif defined(BFIN)
1628                 if (is_negated_errno(r0)) {
1629                         tcp->u_rval = -1;
1630                         u_error = -r0;
1631                 } else {
1632                         tcp->u_rval = r0;
1633                         u_error = 0;
1634                 }
1635 # elif defined(ALPHA)
1636                 if (a3) {
1637                         tcp->u_rval = -1;
1638                         u_error = r0;
1639                 }
1640                 else {
1641                         tcp->u_rval = r0;
1642                         u_error = 0;
1643                 }
1644 # elif defined(SPARC)
1645                 if (regs.psr & PSR_C) {
1646                         tcp->u_rval = -1;
1647                         u_error = regs.u_regs[U_REG_O0];
1648                 }
1649                 else {
1650                         tcp->u_rval = regs.u_regs[U_REG_O0];
1651                         u_error = 0;
1652                 }
1653 # elif defined(SPARC64)
1654                 if (regs.tstate & 0x1100000000UL) {
1655                         tcp->u_rval = -1;
1656                         u_error = regs.u_regs[U_REG_O0];
1657                 }
1658                 else {
1659                         tcp->u_rval = regs.u_regs[U_REG_O0];
1660                         u_error = 0;
1661                 }
1662 # elif defined(HPPA)
1663                 if (is_negated_errno(r28)) {
1664                         tcp->u_rval = -1;
1665                         u_error = -r28;
1666                 }
1667                 else {
1668                         tcp->u_rval = r28;
1669                         u_error = 0;
1670                 }
1671 # elif defined(SH)
1672                 /* interpret R0 as return value or error number */
1673                 if (is_negated_errno(r0)) {
1674                         tcp->u_rval = -1;
1675                         u_error = -r0;
1676                 }
1677                 else {
1678                         tcp->u_rval = r0;
1679                         u_error = 0;
1680                 }
1681 # elif defined(SH64)
1682                 /* interpret result as return value or error number */
1683                 if (is_negated_errno(r9)) {
1684                         tcp->u_rval = -1;
1685                         u_error = -r9;
1686                 }
1687                 else {
1688                         tcp->u_rval = r9;
1689                         u_error = 0;
1690                 }
1691 # elif defined(CRISV10) || defined(CRISV32)
1692                 if (r10 && (unsigned) -r10 < nerrnos) {
1693                         tcp->u_rval = -1;
1694                         u_error = -r10;
1695                 }
1696                 else {
1697                         tcp->u_rval = r10;
1698                         u_error = 0;
1699                 }
1700 # elif defined(TILE)
1701                 long rval;
1702                 /* interpret result as return value or error number */
1703                 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1704                         return -1;
1705                 if (rval < 0 && rval > -nerrnos) {
1706                         tcp->u_rval = -1;
1707                         u_error = -rval;
1708                 }
1709                 else {
1710                         tcp->u_rval = rval;
1711                         u_error = 0;
1712                 }
1713 # endif
1714 #endif /* LINUX */
1715 #ifdef SUNOS4
1716                 /* get error code from user struct */
1717                 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1718                         return -1;
1719                 u_error >>= 24; /* u_error is a char */
1720
1721                 /* get system call return value */
1722                 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1723                         return -1;
1724 #endif /* SUNOS4 */
1725 #ifdef SVR4
1726 #ifdef SPARC
1727                 /* Judicious guessing goes a long way. */
1728                 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1729                         tcp->u_rval = -1;
1730                         u_error = tcp->status.pr_reg[R_O0];
1731                 }
1732                 else {
1733                         tcp->u_rval = tcp->status.pr_reg[R_O0];
1734                         u_error = 0;
1735                 }
1736 #endif /* SPARC */
1737 #ifdef I386
1738                 /* Wanna know how to kill an hour single-stepping? */
1739                 if (tcp->status.PR_REG[EFL] & 0x1) {
1740                         tcp->u_rval = -1;
1741                         u_error = tcp->status.PR_REG[EAX];
1742                 }
1743                 else {
1744                         tcp->u_rval = tcp->status.PR_REG[EAX];
1745 #ifdef HAVE_LONG_LONG
1746                         tcp->u_lrval =
1747                                 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1748                                 tcp->status.PR_REG[EAX];
1749 #endif
1750                         u_error = 0;
1751                 }
1752 #endif /* I386 */
1753 #ifdef X86_64
1754                 /* Wanna know how to kill an hour single-stepping? */
1755                 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1756                         tcp->u_rval = -1;
1757                         u_error = tcp->status.PR_REG[RAX];
1758                 }
1759                 else {
1760                         tcp->u_rval = tcp->status.PR_REG[RAX];
1761                         u_error = 0;
1762                 }
1763 #endif /* X86_64 */
1764 #ifdef MIPS
1765                 if (tcp->status.pr_reg[CTX_A3]) {
1766                         tcp->u_rval = -1;
1767                         u_error = tcp->status.pr_reg[CTX_V0];
1768                 }
1769                 else {
1770                         tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1771                         u_error = 0;
1772                 }
1773 #endif /* MIPS */
1774 #endif /* SVR4 */
1775 #ifdef FREEBSD
1776                 if (regs.r_eflags & PSL_C) {
1777                         tcp->u_rval = -1;
1778                         u_error = regs.r_eax;
1779                 } else {
1780                         tcp->u_rval = regs.r_eax;
1781                         tcp->u_lrval =
1782                           ((unsigned long long) regs.r_edx << 32) +  regs.r_eax;
1783                         u_error = 0;
1784                 }
1785 #endif /* FREEBSD */
1786         tcp->u_error = u_error;
1787         return 1;
1788 }
1789
1790 int
1791 force_result(tcp, error, rval)
1792         struct tcb *tcp;
1793         int error;
1794         long rval;
1795 {
1796 #ifdef LINUX
1797 # if defined(S390) || defined(S390X)
1798         gpr2 = error ? -error : rval;
1799         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1800                 return -1;
1801 # elif defined(I386)
1802         eax = error ? -error : rval;
1803         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1804                 return -1;
1805 # elif defined(X86_64)
1806         rax = error ? -error : rval;
1807         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1808                 return -1;
1809 # elif defined(IA64)
1810         if (ia32) {
1811                 r8 = error ? -error : rval;
1812                 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1813                         return -1;
1814         }
1815         else {
1816                 if (error) {
1817                         r8 = error;
1818                         r10 = -1;
1819                 }
1820                 else {
1821                         r8 = rval;
1822                         r10 = 0;
1823                 }
1824                 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1825                     ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1826                         return -1;
1827         }
1828 # elif defined(BFIN)
1829         r0 = error ? -error : rval;
1830         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1831                 return -1;
1832 # elif defined(MIPS)
1833         if (error) {
1834                 r2 = error;
1835                 a3 = -1;
1836         }
1837         else {
1838                 r2 = rval;
1839                 a3 = 0;
1840         }
1841         /* PTRACE_POKEUSER is OK even for n32 since rval is only a long.  */
1842         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1843             ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1844                 return -1;
1845 # elif defined(POWERPC)
1846         if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1847                 return -1;
1848         if (error) {
1849                 flags |= SO_MASK;
1850                 result = error;
1851         }
1852         else {
1853                 flags &= ~SO_MASK;
1854                 result = rval;
1855         }
1856         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1857             ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1858                 return -1;
1859 # elif defined(M68K)
1860         d0 = error ? -error : rval;
1861         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1862                 return -1;
1863 # elif defined(ARM)
1864         regs.ARM_r0 = error ? -error : rval;
1865         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1866                 return -1;
1867 # elif defined(AVR32)
1868         regs.r12 = error ? -error : rval;
1869         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1870                 return -1;
1871 # elif defined(ALPHA)
1872         if (error) {
1873                 a3 = -1;
1874                 r0 = error;
1875         }
1876         else {
1877                 a3 = 0;
1878                 r0 = rval;
1879         }
1880         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1881             ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1882                 return -1;
1883 # elif defined(SPARC)
1884         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
1885                 return -1;
1886         if (error) {
1887                 regs.psr |= PSR_C;
1888                 regs.u_regs[U_REG_O0] = error;
1889         }
1890         else {
1891                 regs.psr &= ~PSR_C;
1892                 regs.u_regs[U_REG_O0] = rval;
1893         }
1894         if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
1895                 return -1;
1896 # elif defined(SPARC64)
1897         if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
1898                 return -1;
1899         if (error) {
1900                 regs.tstate |= 0x1100000000UL;
1901                 regs.u_regs[U_REG_O0] = error;
1902         }
1903         else {
1904                 regs.tstate &= ~0x1100000000UL;
1905                 regs.u_regs[U_REG_O0] = rval;
1906         }
1907         if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
1908                 return -1;
1909 # elif defined(HPPA)
1910         r28 = error ? -error : rval;
1911         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1912                 return -1;
1913 # elif defined(SH)
1914         r0 = error ? -error : rval;
1915         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1916                 return -1;
1917 # elif defined(SH64)
1918         r9 = error ? -error : rval;
1919         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1920                 return -1;
1921 # endif
1922 #endif /* LINUX */
1923
1924 #ifdef SUNOS4
1925         if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1926                    error << 24) < 0 ||
1927             ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1928                 return -1;
1929 #endif /* SUNOS4 */
1930
1931 #ifdef SVR4
1932         /* XXX no clue */
1933         return -1;
1934 #endif /* SVR4 */
1935
1936 #ifdef FREEBSD
1937         if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
1938                 perror("pread");
1939                 return -1;
1940         }
1941         if (error) {
1942                 regs.r_eflags |= PSL_C;
1943                 regs.r_eax = error;
1944         }
1945         else {
1946                 regs.r_eflags &= ~PSL_C;
1947                 regs.r_eax = rval;
1948         }
1949         if (pwrite(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
1950                 perror("pwrite");
1951                 return -1;
1952         }
1953 #endif /* FREEBSD */
1954
1955         /* All branches reach here on success (only).  */
1956         tcp->u_error = error;
1957         tcp->u_rval = rval;
1958         return 0;
1959 }
1960
1961 static int
1962 syscall_enter(struct tcb *tcp)
1963 {
1964 #ifdef LINUX
1965 #if defined(S390) || defined(S390X)
1966         {
1967                 int i;
1968                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1969                         tcp->u_nargs = sysent[tcp->scno].nargs;
1970                 else
1971                         tcp->u_nargs = MAX_ARGS;
1972                 for (i = 0; i < tcp->u_nargs; i++) {
1973                         if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1974                                 return -1;
1975                 }
1976         }
1977 #elif defined (ALPHA)
1978         {
1979                 int i;
1980                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1981                         tcp->u_nargs = sysent[tcp->scno].nargs;
1982                 else
1983                         tcp->u_nargs = MAX_ARGS;
1984                 for (i = 0; i < tcp->u_nargs; i++) {
1985                         /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1986                          * for scno somewhere above here!
1987                          */
1988                         if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1989                                 return -1;
1990                 }
1991         }
1992 #elif defined (IA64)
1993         {
1994                 if (!ia32) {
1995                         unsigned long *out0, cfm, sof, sol, i;
1996                         long rbs_end;
1997                         /* be backwards compatible with kernel < 2.4.4... */
1998 #                       ifndef PT_RBS_END
1999 #                         define PT_RBS_END     PT_AR_BSP
2000 #                       endif
2001
2002                         if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
2003                                 return -1;
2004                         if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2005                                 return -1;
2006
2007                         sof = (cfm >> 0) & 0x7f;
2008                         sol = (cfm >> 7) & 0x7f;
2009                         out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2010
2011                         if (tcp->scno >= 0 && tcp->scno < nsyscalls
2012                             && sysent[tcp->scno].nargs != -1)
2013                                 tcp->u_nargs = sysent[tcp->scno].nargs;
2014                         else
2015                                 tcp->u_nargs = MAX_ARGS;
2016                         for (i = 0; i < tcp->u_nargs; ++i) {
2017                                 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2018                                            sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2019                                         return -1;
2020                         }
2021                 } else {
2022                         int i;
2023
2024                         if (/* EBX = out0 */
2025                             upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2026                             /* ECX = out1 */
2027                             || upeek(tcp, PT_R9,  (long *) &tcp->u_arg[1]) < 0
2028                             /* EDX = out2 */
2029                             || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2030                             /* ESI = out3 */
2031                             || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2032                             /* EDI = out4 */
2033                             || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2034                             /* EBP = out5 */
2035                             || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2036                                 return -1;
2037
2038                         for (i = 0; i < 6; ++i)
2039                                 /* truncate away IVE sign-extension */
2040                                 tcp->u_arg[i] &= 0xffffffff;
2041
2042                         if (tcp->scno >= 0 && tcp->scno < nsyscalls
2043                             && sysent[tcp->scno].nargs != -1)
2044                                 tcp->u_nargs = sysent[tcp->scno].nargs;
2045                         else
2046                                 tcp->u_nargs = 5;
2047                 }
2048         }
2049 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2050         /* N32 and N64 both use up to six registers.  */
2051         {
2052                 unsigned long long regs[38];
2053                 int i, nargs;
2054
2055                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2056                         nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2057                 else
2058                         nargs = tcp->u_nargs = MAX_ARGS;
2059
2060                 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) &regs) < 0)
2061                         return -1;
2062
2063                 for(i = 0; i < nargs; i++) {
2064                         tcp->u_arg[i] = regs[REG_A0 + i];
2065 # if defined (LINUX_MIPSN32)
2066                         tcp->ext_arg[i] = regs[REG_A0 + i];
2067 # endif
2068                 }
2069         }
2070 #elif defined (MIPS)
2071         {
2072                 long sp;
2073                 int i, nargs;
2074
2075                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2076                         nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2077                 else
2078                         nargs = tcp->u_nargs = MAX_ARGS;
2079                 if(nargs > 4) {
2080                         if(upeek(tcp, REG_SP, &sp) < 0)
2081                                 return -1;
2082                         for(i = 0; i < 4; i++) {
2083                                 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2084                                         return -1;
2085                         }
2086                         umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2087                                (char *)(tcp->u_arg + 4));
2088                 } else {
2089                         for(i = 0; i < nargs; i++) {
2090                                 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2091                                         return -1;
2092                         }
2093                 }
2094         }
2095 #elif defined (POWERPC)
2096 # ifndef PT_ORIG_R3
2097 #  define PT_ORIG_R3 34
2098 # endif
2099         {
2100                 int i;
2101                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2102                         tcp->u_nargs = sysent[tcp->scno].nargs;
2103                 else
2104                         tcp->u_nargs = MAX_ARGS;
2105                 for (i = 0; i < tcp->u_nargs; i++) {
2106                         if (upeek(tcp, (i==0) ?
2107                                 (sizeof(unsigned long)*PT_ORIG_R3) :
2108                                 ((i+PT_R3)*sizeof(unsigned long)),
2109                                         &tcp->u_arg[i]) < 0)
2110                                 return -1;
2111                 }
2112         }
2113 #elif defined (SPARC) || defined (SPARC64)
2114         {
2115                 int i;
2116
2117                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2118                         tcp->u_nargs = sysent[tcp->scno].nargs;
2119                 else
2120                         tcp->u_nargs = MAX_ARGS;
2121                 for (i = 0; i < tcp->u_nargs; i++)
2122                         tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2123         }
2124 #elif defined (HPPA)
2125         {
2126                 int i;
2127
2128                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2129                         tcp->u_nargs = sysent[tcp->scno].nargs;
2130                 else
2131                         tcp->u_nargs = MAX_ARGS;
2132                 for (i = 0; i < tcp->u_nargs; i++) {
2133                         if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2134                                 return -1;
2135                 }
2136         }
2137 #elif defined(ARM)
2138         {
2139                 int i;
2140
2141                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2142                         tcp->u_nargs = sysent[tcp->scno].nargs;
2143                 else
2144                         tcp->u_nargs = MAX_ARGS;
2145                 for (i = 0; i < tcp->u_nargs; i++)
2146                         tcp->u_arg[i] = regs.uregs[i];
2147         }
2148 #elif defined(AVR32)
2149         tcp->u_nargs = sysent[tcp->scno].nargs;
2150         tcp->u_arg[0] = regs.r12;
2151         tcp->u_arg[1] = regs.r11;
2152         tcp->u_arg[2] = regs.r10;
2153         tcp->u_arg[3] = regs.r9;
2154         tcp->u_arg[4] = regs.r5;
2155         tcp->u_arg[5] = regs.r3;
2156 #elif defined(BFIN)
2157         {
2158                 int i;
2159                 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2160
2161                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2162                         tcp->u_nargs = sysent[tcp->scno].nargs;
2163                 else
2164                         tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2165
2166                 for (i = 0; i < tcp->u_nargs; ++i)
2167                         if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2168                                 return -1;
2169         }
2170 #elif defined(SH)
2171         {
2172                 int i;
2173                 static int syscall_regs[] = {
2174                         REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2175                         REG_REG0, REG_REG0+1, REG_REG0+2
2176                 };
2177
2178                 tcp->u_nargs = sysent[tcp->scno].nargs;
2179                 for (i = 0; i < tcp->u_nargs; i++) {
2180                         if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2181                                 return -1;
2182                 }
2183         }
2184 #elif defined(SH64)
2185         {
2186                 int i;
2187                 /* Registers used by SH5 Linux system calls for parameters */
2188                 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2189
2190                 /*
2191                  * TODO: should also check that the number of arguments encoded
2192                  *       in the trap number matches the number strace expects.
2193                  */
2194                 /*
2195                 assert(sysent[tcp->scno].nargs <
2196                        sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2197                  */
2198
2199                 tcp->u_nargs = sysent[tcp->scno].nargs;
2200                 for (i = 0; i < tcp->u_nargs; i++) {
2201                         if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2202                                 return -1;
2203                 }
2204         }
2205
2206 #elif defined(X86_64)
2207         {
2208                 int i;
2209                 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2210                         {RDI,RSI,RDX,R10,R8,R9},        /* x86-64 ABI */
2211                         {RBX,RCX,RDX,RSI,RDI,RBP}       /* i386 ABI */
2212                 };
2213
2214                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2215                         tcp->u_nargs = sysent[tcp->scno].nargs;
2216                 else
2217                         tcp->u_nargs = MAX_ARGS;
2218                 for (i = 0; i < tcp->u_nargs; i++) {
2219                         if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2220                                 return -1;
2221                 }
2222         }
2223 #elif defined(CRISV10) || defined(CRISV32)
2224         {
2225                 int i;
2226                 static const int crisregs[] = {
2227                         4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2228                         4*PT_R13, 4*PT_MOF, 4*PT_SRP
2229                 };
2230
2231                 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2232                         tcp->u_nargs = sysent[tcp->scno].nargs;
2233                 else
2234                         tcp->u_nargs = 0;
2235                 for (i = 0; i < tcp->u_nargs; i++) {
2236                         if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2237                                 return -1;
2238                 }
2239         }
2240 #elif defined(TILE)
2241         {
2242                 int i;
2243                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2244                         tcp->u_nargs = sysent[tcp->scno].nargs;
2245                 else
2246                         tcp->u_nargs = MAX_ARGS;
2247                 for (i = 0; i < tcp->u_nargs; ++i) {
2248                         if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2249                                 return -1;
2250                 }
2251         }
2252 #else /* Other architecture (like i386) (32bits specific) */
2253         {
2254                 int i;
2255                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2256                         tcp->u_nargs = sysent[tcp->scno].nargs;
2257                 else
2258                         tcp->u_nargs = MAX_ARGS;
2259                 for (i = 0; i < tcp->u_nargs; i++) {
2260                         if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2261                                 return -1;
2262                 }
2263         }
2264 #endif
2265 #endif /* LINUX */
2266 #ifdef SUNOS4
2267         {
2268                 int i;
2269                 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2270                         tcp->u_nargs = sysent[tcp->scno].nargs;
2271                 else
2272                         tcp->u_nargs = MAX_ARGS;
2273                 for (i = 0; i < tcp->u_nargs; i++) {
2274                         struct user *u;
2275
2276                         if (upeek(tcp, uoff(u_arg[0]) +
2277                             (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2278                                 return -1;
2279                 }
2280         }
2281 #endif /* SUNOS4 */
2282 #ifdef SVR4
2283 #ifdef MIPS
2284         /*
2285          * SGI is broken: even though it has pr_sysarg, it doesn't
2286          * set them on system call entry.  Get a clue.
2287          */
2288         if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2289                 tcp->u_nargs = sysent[tcp->scno].nargs;
2290         else
2291                 tcp->u_nargs = tcp->status.pr_nsysarg;
2292         if (tcp->u_nargs > 4) {
2293                 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2294                         4*sizeof(tcp->u_arg[0]));
2295                 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2296                         (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2297         }
2298         else {
2299                 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2300                         tcp->u_nargs*sizeof(tcp->u_arg[0]));
2301         }
2302 #elif UNIXWARE >= 2
2303         /*
2304          * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2305          */
2306         if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2307                 tcp->u_nargs = sysent[tcp->scno].nargs;
2308         else
2309                 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2310         umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2311                 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2312 #elif defined (HAVE_PR_SYSCALL)
2313         if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2314                 tcp->u_nargs = sysent[tcp->scno].nargs;
2315         else
2316                 tcp->u_nargs = tcp->status.pr_nsysarg;
2317         {
2318                 int i;
2319                 for (i = 0; i < tcp->u_nargs; i++)
2320                         tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2321         }
2322 #elif defined (I386)
2323         if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2324                 tcp->u_nargs = sysent[tcp->scno].nargs;
2325         else
2326                 tcp->u_nargs = 5;
2327         umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2328                 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2329 #else
2330         I DONT KNOW WHAT TO DO
2331 #endif /* !HAVE_PR_SYSCALL */
2332 #endif /* SVR4 */
2333 #ifdef FREEBSD
2334         if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2335             sysent[tcp->scno].nargs > tcp->status.val)
2336                 tcp->u_nargs = sysent[tcp->scno].nargs;
2337         else
2338                 tcp->u_nargs = tcp->status.val;
2339         if (tcp->u_nargs < 0)
2340                 tcp->u_nargs = 0;
2341         if (tcp->u_nargs > MAX_ARGS)
2342                 tcp->u_nargs = MAX_ARGS;
2343         switch(regs.r_eax) {
2344         case SYS___syscall:
2345                 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2346                       regs.r_esp + sizeof(int) + sizeof(quad_t));
2347                 break;
2348         case SYS_syscall:
2349                 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2350                       regs.r_esp + 2 * sizeof(int));
2351                 break;
2352         default:
2353                 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2354                       regs.r_esp + sizeof(int));
2355                 break;
2356         }
2357 #endif /* FREEBSD */
2358         return 1;
2359 }
2360
2361 static int
2362 trace_syscall_exiting(struct tcb *tcp)
2363 {
2364         int sys_res;
2365         struct timeval tv;
2366         int res, scno_good;
2367         long u_error;
2368
2369         /* Measure the exit time as early as possible to avoid errors. */
2370         if (dtime || cflag)
2371                 gettimeofday(&tv, NULL);
2372
2373         /* BTW, why we don't just memorize syscall no. on entry
2374          * in tcp->something?
2375          */
2376         scno_good = res = get_scno(tcp);
2377         if (res == 0)
2378                 return res;
2379         if (res == 1)
2380                 res = syscall_fixup(tcp);
2381         if (res == 0)
2382                 return res;
2383         if (res == 1)
2384                 res = get_error(tcp);
2385         if (res == 0)
2386                 return res;
2387         if (res == 1)
2388                 internal_syscall(tcp);
2389
2390         if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2391             !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2392                 tcp->flags &= ~TCB_INSYSCALL;
2393                 return 0;
2394         }
2395
2396         if (tcp->flags & TCB_REPRINT) {
2397                 printleader(tcp);
2398                 tprintf("<... ");
2399                 if (scno_good != 1)
2400                         tprintf("????");
2401                 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2402                         tprintf("syscall_%lu", tcp->scno);
2403                 else
2404                         tprintf("%s", sysent[tcp->scno].sys_name);
2405                 tprintf(" resumed> ");
2406         }
2407
2408         if (cflag) {
2409                 struct timeval t = tv;
2410                 int rc = count_syscall(tcp, &t);
2411                 if (cflag == CFLAG_ONLY_STATS)
2412                 {
2413                         tcp->flags &= ~TCB_INSYSCALL;
2414                         return rc;
2415                 }
2416         }
2417
2418         if (res != 1) {
2419                 tprintf(") ");
2420                 tabto(acolumn);
2421                 tprintf("= ? <unavailable>");
2422                 printtrailer();
2423                 tcp->flags &= ~TCB_INSYSCALL;
2424                 return res;
2425         }
2426
2427         if (tcp->scno >= nsyscalls || tcp->scno < 0
2428             || (qual_flags[tcp->scno] & QUAL_RAW))
2429                 sys_res = printargs(tcp);
2430         else {
2431                 if (not_failing_only && tcp->u_error)
2432                         return 0;       /* ignore failed syscalls */
2433                 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2434         }
2435
2436         u_error = tcp->u_error;
2437         tprintf(") ");
2438         tabto(acolumn);
2439         if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2440             qual_flags[tcp->scno] & QUAL_RAW) {
2441                 if (u_error)
2442                         tprintf("= -1 (errno %ld)", u_error);
2443                 else
2444                         tprintf("= %#lx", tcp->u_rval);
2445         }
2446         else if (!(sys_res & RVAL_NONE) && u_error) {
2447                 switch (u_error) {
2448 #ifdef LINUX
2449                 case ERESTARTSYS:
2450                         tprintf("= ? ERESTARTSYS (To be restarted)");
2451                         break;
2452                 case ERESTARTNOINTR:
2453                         tprintf("= ? ERESTARTNOINTR (To be restarted)");
2454                         break;
2455                 case ERESTARTNOHAND:
2456                         tprintf("= ? ERESTARTNOHAND (To be restarted)");
2457                         break;
2458                 case ERESTART_RESTARTBLOCK:
2459                         tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2460                         break;
2461 #endif /* LINUX */
2462                 default:
2463                         tprintf("= -1 ");
2464                         if (u_error < 0)
2465                                 tprintf("E??? (errno %ld)", u_error);
2466                         else if (u_error < nerrnos)
2467                                 tprintf("%s (%s)", errnoent[u_error],
2468                                         strerror(u_error));
2469                         else
2470                                 tprintf("ERRNO_%ld (%s)", u_error,
2471                                         strerror(u_error));
2472                         break;
2473                 }
2474                 if ((sys_res & RVAL_STR) && tcp->auxstr)
2475                         tprintf(" (%s)", tcp->auxstr);
2476         }
2477         else {
2478                 if (sys_res & RVAL_NONE)
2479                         tprintf("= ?");
2480                 else {
2481                         switch (sys_res & RVAL_MASK) {
2482                         case RVAL_HEX:
2483                                 tprintf("= %#lx", tcp->u_rval);
2484                                 break;
2485                         case RVAL_OCTAL:
2486                                 tprintf("= %#lo", tcp->u_rval);
2487                                 break;
2488                         case RVAL_UDECIMAL:
2489                                 tprintf("= %lu", tcp->u_rval);
2490                                 break;
2491                         case RVAL_DECIMAL:
2492                                 tprintf("= %ld", tcp->u_rval);
2493                                 break;
2494 #ifdef HAVE_LONG_LONG
2495                         case RVAL_LHEX:
2496                                 tprintf("= %#llx", tcp->u_lrval);
2497                                 break;
2498                         case RVAL_LOCTAL:
2499                                 tprintf("= %#llo", tcp->u_lrval);
2500                                 break;
2501                         case RVAL_LUDECIMAL:
2502                                 tprintf("= %llu", tcp->u_lrval);
2503                                 break;
2504                         case RVAL_LDECIMAL:
2505                                 tprintf("= %lld", tcp->u_lrval);
2506                                 break;
2507 #endif
2508                         default:
2509                                 fprintf(stderr,
2510                                         "invalid rval format\n");
2511                                 break;
2512                         }
2513                 }
2514                 if ((sys_res & RVAL_STR) && tcp->auxstr)
2515                         tprintf(" (%s)", tcp->auxstr);
2516         }
2517         if (dtime) {
2518                 tv_sub(&tv, &tv, &tcp->etime);
2519                 tprintf(" <%ld.%06ld>",
2520                         (long) tv.tv_sec, (long) tv.tv_usec);
2521         }
2522         printtrailer();
2523
2524         dumpio(tcp);
2525         if (fflush(tcp->outf) == EOF)
2526                 return -1;
2527         tcp->flags &= ~TCB_INSYSCALL;
2528         return 0;
2529 }
2530
2531 static int
2532 trace_syscall_entering(struct tcb *tcp)
2533 {
2534         int sys_res;
2535         int res, scno_good;
2536
2537         scno_good = res = get_scno(tcp);
2538         if (res == 0)
2539                 return res;
2540         if (res == 1)
2541                 res = syscall_fixup(tcp);
2542         if (res == 0)
2543                 return res;
2544         if (res == 1)
2545                 res = syscall_enter(tcp);
2546         if (res == 0)
2547                 return res;
2548
2549         if (res != 1) {
2550                 printleader(tcp);
2551                 tcp->flags &= ~TCB_REPRINT;
2552                 tcp_last = tcp;
2553                 if (scno_good != 1)
2554                         tprintf("????" /* anti-trigraph gap */ "(");
2555                 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2556                         tprintf("syscall_%lu(", tcp->scno);
2557                 else
2558                         tprintf("%s(", sysent[tcp->scno].sys_name);
2559                 /*
2560                  * " <unavailable>" will be added later by the code which
2561                  * detects ptrace errors.
2562                  */
2563                 tcp->flags |= TCB_INSYSCALL;
2564                 return res;
2565         }
2566
2567         switch (known_scno(tcp)) {
2568 #ifdef SYS_socket_subcall
2569         case SYS_socketcall:
2570                 decode_subcall(tcp, SYS_socket_subcall,
2571                         SYS_socket_nsubcalls, deref_style);
2572                 break;
2573 #endif
2574 #ifdef SYS_ipc_subcall
2575         case SYS_ipc:
2576                 decode_subcall(tcp, SYS_ipc_subcall,
2577                         SYS_ipc_nsubcalls, shift_style);
2578                 break;
2579 #endif
2580 #ifdef SVR4
2581 #ifdef SYS_pgrpsys_subcall
2582         case SYS_pgrpsys:
2583                 decode_subcall(tcp, SYS_pgrpsys_subcall,
2584                         SYS_pgrpsys_nsubcalls, shift_style);
2585                 break;
2586 #endif /* SYS_pgrpsys_subcall */
2587 #ifdef SYS_sigcall_subcall
2588         case SYS_sigcall:
2589                 decode_subcall(tcp, SYS_sigcall_subcall,
2590                         SYS_sigcall_nsubcalls, mask_style);
2591                 break;
2592 #endif /* SYS_sigcall_subcall */
2593         case SYS_msgsys:
2594                 decode_subcall(tcp, SYS_msgsys_subcall,
2595                         SYS_msgsys_nsubcalls, shift_style);
2596                 break;
2597         case SYS_shmsys:
2598                 decode_subcall(tcp, SYS_shmsys_subcall,
2599                         SYS_shmsys_nsubcalls, shift_style);
2600                 break;
2601         case SYS_semsys:
2602                 decode_subcall(tcp, SYS_semsys_subcall,
2603                         SYS_semsys_nsubcalls, shift_style);
2604                 break;
2605         case SYS_sysfs:
2606                 decode_subcall(tcp, SYS_sysfs_subcall,
2607                         SYS_sysfs_nsubcalls, shift_style);
2608                 break;
2609         case SYS_spcall:
2610                 decode_subcall(tcp, SYS_spcall_subcall,
2611                         SYS_spcall_nsubcalls, shift_style);
2612                 break;
2613 #ifdef SYS_context_subcall
2614         case SYS_context:
2615                 decode_subcall(tcp, SYS_context_subcall,
2616                         SYS_context_nsubcalls, shift_style);
2617                 break;
2618 #endif /* SYS_context_subcall */
2619 #ifdef SYS_door_subcall
2620         case SYS_door:
2621                 decode_subcall(tcp, SYS_door_subcall,
2622                         SYS_door_nsubcalls, door_style);
2623                 break;
2624 #endif /* SYS_door_subcall */
2625 #ifdef SYS_kaio_subcall
2626         case SYS_kaio:
2627                 decode_subcall(tcp, SYS_kaio_subcall,
2628                         SYS_kaio_nsubcalls, shift_style);
2629                 break;
2630 #endif
2631 #endif /* SVR4 */
2632 #ifdef FREEBSD
2633         case SYS_msgsys:
2634         case SYS_shmsys:
2635         case SYS_semsys:
2636                 decode_subcall(tcp, 0, 0, table_style);
2637                 break;
2638 #endif
2639 #ifdef SUNOS4
2640         case SYS_semsys:
2641                 decode_subcall(tcp, SYS_semsys_subcall,
2642                         SYS_semsys_nsubcalls, shift_style);
2643                 break;
2644         case SYS_msgsys:
2645                 decode_subcall(tcp, SYS_msgsys_subcall,
2646                         SYS_msgsys_nsubcalls, shift_style);
2647                 break;
2648         case SYS_shmsys:
2649                 decode_subcall(tcp, SYS_shmsys_subcall,
2650                         SYS_shmsys_nsubcalls, shift_style);
2651                 break;
2652 #endif
2653         }
2654
2655         internal_syscall(tcp);
2656         if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2657                 tcp->flags |= TCB_INSYSCALL;
2658                 return 0;
2659         }
2660
2661         if (cflag == CFLAG_ONLY_STATS) {
2662                 tcp->flags |= TCB_INSYSCALL;
2663                 gettimeofday(&tcp->etime, NULL);
2664                 return 0;
2665         }
2666
2667         printleader(tcp);
2668         tcp->flags &= ~TCB_REPRINT;
2669         tcp_last = tcp;
2670         if (tcp->scno >= nsyscalls || tcp->scno < 0)
2671                 tprintf("syscall_%lu(", tcp->scno);
2672         else
2673                 tprintf("%s(", sysent[tcp->scno].sys_name);
2674         if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2675             ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2676                 sys_res = printargs(tcp);
2677         else
2678                 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2679         if (fflush(tcp->outf) == EOF)
2680                 return -1;
2681         tcp->flags |= TCB_INSYSCALL;
2682         /* Measure the entrance time as late as possible to avoid errors. */
2683         if (dtime || cflag)
2684                 gettimeofday(&tcp->etime, NULL);
2685         return sys_res;
2686 }
2687
2688 int
2689 trace_syscall(struct tcb *tcp)
2690 {
2691         return exiting(tcp) ?
2692                 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2693 }
2694
2695 int
2696 printargs(tcp)
2697 struct tcb *tcp;
2698 {
2699         if (entering(tcp)) {
2700                 int i;
2701
2702                 for (i = 0; i < tcp->u_nargs; i++)
2703                         tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2704         }
2705         return 0;
2706 }
2707
2708 long
2709 getrval2(tcp)
2710 struct tcb *tcp;
2711 {
2712         long val = -1;
2713
2714 #ifdef LINUX
2715 #if defined (SPARC) || defined (SPARC64)
2716         struct pt_regs regs;
2717         if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
2718                 return -1;
2719         val = regs.u_regs[U_REG_O1];
2720 #elif defined(SH)
2721         if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2722                 return -1;
2723 #elif defined(IA64)
2724         if (upeek(tcp, PT_R9, &val) < 0)
2725                 return -1;
2726 #endif
2727 #endif /* LINUX */
2728
2729 #ifdef SUNOS4
2730         if (upeek(tcp, uoff(u_rval2), &val) < 0)
2731                 return -1;
2732 #endif /* SUNOS4 */
2733
2734 #ifdef SVR4
2735 #ifdef SPARC
2736         val = tcp->status.PR_REG[R_O1];
2737 #endif /* SPARC */
2738 #ifdef I386
2739         val = tcp->status.PR_REG[EDX];
2740 #endif /* I386 */
2741 #ifdef X86_64
2742         val = tcp->status.PR_REG[RDX];
2743 #endif /* X86_64 */
2744 #ifdef MIPS
2745         val = tcp->status.PR_REG[CTX_V1];
2746 #endif /* MIPS */
2747 #endif /* SVR4 */
2748
2749 #ifdef FREEBSD
2750         struct reg regs;
2751         pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
2752         val = regs.r_edx;
2753 #endif
2754         return val;
2755 }
2756
2757 #ifdef SUNOS4
2758 /*
2759  * Apparently, indirect system calls have already be converted by ptrace(2),
2760  * so if you see "indir" this program has gone astray.
2761  */
2762 int
2763 sys_indir(tcp)
2764 struct tcb *tcp;
2765 {
2766         int i, scno, nargs;
2767
2768         if (entering(tcp)) {
2769                 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2770                         fprintf(stderr, "Bogus syscall: %u\n", scno);
2771                         return 0;
2772                 }
2773                 nargs = sysent[scno].nargs;
2774                 tprintf("%s", sysent[scno].sys_name);
2775                 for (i = 0; i < nargs; i++)
2776                         tprintf(", %#lx", tcp->u_arg[i+1]);
2777         }
2778         return 0;
2779 }
2780 #endif /* SUNOS4 */
2781
2782 int
2783 is_restart_error(struct tcb *tcp)
2784 {
2785 #ifdef LINUX
2786         if (!syserror(tcp))
2787                 return 0;
2788         switch (tcp->u_error) {
2789                 case ERESTARTSYS:
2790                 case ERESTARTNOINTR:
2791                 case ERESTARTNOHAND:
2792                 case ERESTART_RESTARTBLOCK:
2793                         return 1;
2794                 default:
2795                         break;
2796         }
2797 #endif /* LINUX */
2798         return 0;
2799 }