OSDN Git Service

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