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