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