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