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