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