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