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