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