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 		/*
   1017 		 * Note: we only deal with only 32-bit CPUs here.
   1018 		 */
   1019 		if (regs.ARM_cpsr & 0x20) {
   1020 			/*
   1021 			 * Get the Thumb-mode system call number
   1022 			 */
   1023 			scno = regs.ARM_r7;
   1024 		} else {
   1025 			/*
   1026 			 * Get the ARM-mode system call number
   1027 			 */
   1028 			errno = 0;
   1029 			scno = ptrace(PTRACE_PEEKTEXT, pid, (void *)(regs.ARM_pc - 4), NULL);
   1030 			if (errno)
   1031 				return -1;
   1032 
   1033 			if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
   1034 				tcp->flags &= ~TCB_WAITEXECVE;
   1035 				return 0;
   1036 			}
   1037 
   1038 			/* Handle the EABI syscall convention.  We do not
   1039 			   bother converting structures between the two
   1040 			   ABIs, but basic functionality should work even
   1041 			   if strace and the traced program have different
   1042 			   ABIs.  */
   1043 			if (scno == 0xef000000) {
   1044 				scno = regs.ARM_r7;
   1045 			} else {
   1046 				if ((scno & 0x0ff00000) != 0x0f900000) {
   1047 					fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
   1048 						scno);
   1049 					return -1;
   1050 				}
   1051 
   1052 				/*
   1053 				 * Fixup the syscall number
   1054 				 */
   1055 				scno &= 0x000fffff;
   1056 			}
   1057 		}
   1058 
   1059 		if (tcp->flags & TCB_INSYSCALL) {
   1060 			fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
   1061 			tcp->flags &= ~TCB_INSYSCALL;
   1062 		}
   1063 	} else {
   1064 		if (!(tcp->flags & TCB_INSYSCALL)) {
   1065 			fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
   1066 			tcp->flags |= TCB_INSYSCALL;
   1067 		}
   1068 	}
   1069 #elif defined (M68K)
   1070 	if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)
   1071 		return -1;
   1072 #elif defined (MIPS)
   1073 	if (upeek(pid, REG_A3, &a3) < 0)
   1074 	  	return -1;
   1075 
   1076 	if(!(tcp->flags & TCB_INSYSCALL)) {
   1077 	  	if (upeek(pid, REG_V0, &scno) < 0)
   1078 		  	return -1;
   1079 
   1080 		if (scno < 0 || scno > nsyscalls) {
   1081 			if(a3 == 0 || a3 == -1) {
   1082 				if(debug)
   1083 					fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
   1084 				return 0;
   1085 			}
   1086 		}
   1087 	} else {
   1088 	  	if (upeek(pid, REG_V0, &r2) < 0)
   1089 	    		return -1;
   1090 	}
   1091 #elif defined (ALPHA)
   1092 	if (upeek(pid, REG_A3, &a3) < 0)
   1093 		return -1;
   1094 
   1095 	if (!(tcp->flags & TCB_INSYSCALL)) {
   1096 		if (upeek(pid, REG_R0, &scno) < 0)
   1097 			return -1;
   1098 
   1099 		/* Check if we return from execve. */
   1100 		if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
   1101 			tcp->flags &= ~TCB_WAITEXECVE;
   1102 			return 0;
   1103 		}
   1104 
   1105 		/*
   1106 		 * Do some sanity checks to figure out if it's
   1107 		 * really a syscall entry
   1108 		 */
   1109 		if (scno < 0 || scno > nsyscalls) {
   1110 			if (a3 == 0 || a3 == -1) {
   1111 				if (debug)
   1112 					fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
   1113 				return 0;
   1114 			}
   1115 		}
   1116 	}
   1117 	else {
   1118 		if (upeek(pid, REG_R0, &r0) < 0)
   1119 			return -1;
   1120 	}
   1121 #elif defined (SPARC) || defined (SPARC64)
   1122 	/* Everything we need is in the current register set. */
   1123 	if (ptrace(PTRACE_GETREGS,pid,(char *)&regs,0) < 0)
   1124 		return -1;
   1125 
   1126         /* If we are entering, then disassemble the syscall trap. */
   1127 	if (!(tcp->flags & TCB_INSYSCALL)) {
   1128 		/* Retrieve the syscall trap instruction. */
   1129 		errno = 0;
   1130 		trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
   1131 #if defined(SPARC64)
   1132 		trap >>= 32;
   1133 #endif
   1134 		if (errno)
   1135 			return -1;
   1136 
   1137 		/* Disassemble the trap to see what personality to use. */
   1138 		switch (trap) {
   1139 		case 0x91d02010:
   1140 			/* Linux/SPARC syscall trap. */
   1141 			set_personality(0);
   1142 			break;
   1143 		case 0x91d0206d:
   1144 			/* Linux/SPARC64 syscall trap. */
   1145 			set_personality(2);
   1146 			break;
   1147 		case 0x91d02000:
   1148 			/* SunOS syscall trap. (pers 1) */
   1149 			fprintf(stderr,"syscall: SunOS no support\n");
   1150 			return -1;
   1151 		case 0x91d02008:
   1152 			/* Solaris 2.x syscall trap. (per 2) */
   1153 			set_personality(1);
   1154 			break;
   1155 		case 0x91d02009:
   1156 			/* NetBSD/FreeBSD syscall trap. */
   1157 			fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
   1158 			return -1;
   1159 		case 0x91d02027:
   1160 			/* Solaris 2.x gettimeofday */
   1161 			set_personality(1);
   1162 			break;
   1163 		default:
   1164 			/* Unknown syscall trap. */
   1165 			if(tcp->flags & TCB_WAITEXECVE) {
   1166 				tcp->flags &= ~TCB_WAITEXECVE;
   1167 				return 0;
   1168 			}
   1169 #if defined (SPARC64)
   1170 			fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.r_tpc);
   1171 #else
   1172 			fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
   1173 #endif
   1174 			return -1;
   1175 		}
   1176 
   1177 		/* Extract the system call number from the registers. */
   1178 		if (trap == 0x91d02027)
   1179 			scno = 156;
   1180 		else
   1181 			scno = regs.r_g1;
   1182 		if (scno == 0) {
   1183 			scno = regs.r_o0;
   1184 			memmove (&regs.r_o0, &regs.r_o1, 7*sizeof(regs.r_o0));
   1185 		}
   1186 	}
   1187 #elif defined(HPPA)
   1188 	if (upeek(pid, PT_GR20, &scno) < 0)
   1189 		return -1;
   1190 	if (!(tcp->flags & TCB_INSYSCALL)) {
   1191 		/* Check if we return from execve. */
   1192 		if ((tcp->flags & TCB_WAITEXECVE)) {
   1193 			tcp->flags &= ~TCB_WAITEXECVE;
   1194 			return 0;
   1195 		}
   1196 	}
   1197 #elif defined(SH)
   1198        /*
   1199         * In the new syscall ABI, the system call number is in R3.
   1200         */
   1201        if (upeek(pid, 4*(REG_REG0+3), &scno) < 0)
   1202                return -1;
   1203 
   1204        if (scno < 0) {
   1205            /* Odd as it may seem, a glibc bug has been known to cause
   1206               glibc to issue bogus negative syscall numbers.  So for
   1207               our purposes, make strace print what it *should* have been */
   1208            long correct_scno = (scno & 0xff);
   1209            if (debug)
   1210                fprintf(stderr,
   1211                    "Detected glibc bug: bogus system call number = %ld, "
   1212 		   "correcting to %ld\n",
   1213                    scno,
   1214                    correct_scno);
   1215            scno = correct_scno;
   1216        }
   1217 
   1218 
   1219        if (!(tcp->flags & TCB_INSYSCALL)) {
   1220                /* Check if we return from execve. */
   1221                if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
   1222                        tcp->flags &= ~TCB_WAITEXECVE;
   1223                        return 0;
   1224                }
   1225        }
   1226 #elif defined(SH64)
   1227 	if (upeek(pid, REG_SYSCALL, &scno) < 0)
   1228 		return -1;
   1229         scno &= 0xFFFF;
   1230 
   1231 	if (!(tcp->flags & TCB_INSYSCALL)) {
   1232 		/* Check if we return from execve. */
   1233 		if (tcp->flags & TCB_WAITEXECVE) {
   1234 			tcp->flags &= ~TCB_WAITEXECVE;
   1235 			return 0;
   1236 		}
   1237 	}
   1238 #endif /* SH64 */
   1239 #endif /* LINUX */
   1240 #ifdef SUNOS4
   1241 	if (upeek(pid, uoff(u_arg[7]), &scno) < 0)
   1242 		return -1;
   1243 #elif defined(SH)
   1244         /* new syscall ABI returns result in R0 */
   1245         if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
   1246                 return -1;
   1247 #elif defined(SH64)
   1248         /* ABI defines result returned in r9 */
   1249         if (upeek(pid, REG_GENERAL(9), (long *)&r9) < 0)
   1250                 return -1;
   1251 
   1252 #endif
   1253 #ifdef USE_PROCFS
   1254 #ifdef HAVE_PR_SYSCALL
   1255 	scno = tcp->status.PR_SYSCALL;
   1256 #else /* !HAVE_PR_SYSCALL */
   1257 #ifndef FREEBSD
   1258 	scno = tcp->status.PR_WHAT;
   1259 #else /* FREEBSD */
   1260 	if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
   1261 	        perror("pread");
   1262                 return -1;
   1263         }
   1264 	switch (regs.r_eax) {
   1265 	case SYS_syscall:
   1266 	case SYS___syscall:
   1267     	        pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
   1268 	        break;
   1269 	default:
   1270 	        scno = regs.r_eax;
   1271 	        break;
   1272 	}
   1273 #endif /* FREEBSD */
   1274 #endif /* !HAVE_PR_SYSCALL */
   1275 #endif /* USE_PROCFS */
   1276 	if (!(tcp->flags & TCB_INSYSCALL))
   1277 		tcp->scno = scno;
   1278 	return 1;
   1279 }
   1280 
   1281 
   1282 long
   1283 known_scno(tcp)
   1284 struct tcb *tcp;
   1285 {
   1286 	long scno = tcp->scno;
   1287 	if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
   1288 		scno = sysent[scno].native_scno;
   1289 	else
   1290 		scno += NR_SYSCALL_BASE;
   1291 	return scno;
   1292 }
   1293 
   1294 static int
   1295 syscall_fixup(tcp)
   1296 struct tcb *tcp;
   1297 {
   1298 #ifndef USE_PROCFS
   1299 	int pid = tcp->pid;
   1300 #else /* USE_PROCFS */
   1301 	int scno = known_scno(tcp);
   1302 
   1303 	if (!(tcp->flags & TCB_INSYSCALL)) {
   1304 		if (tcp->status.PR_WHY != PR_SYSENTRY) {
   1305 			if (
   1306 			    scno == SYS_fork
   1307 #ifdef SYS_vfork
   1308 			    || scno == SYS_vfork
   1309 #endif /* SYS_vfork */
   1310 #ifdef SYS_fork1
   1311 			    || scno == SYS_fork1
   1312 #endif /* SYS_fork1 */
   1313 #ifdef SYS_forkall
   1314 			    || scno == SYS_forkall
   1315 #endif /* SYS_forkall */
   1316 #ifdef SYS_rfork1
   1317 			    || scno == SYS_rfork1
   1318 #endif /* SYS_fork1 */
   1319 #ifdef SYS_rforkall
   1320 			    || scno == SYS_rforkall
   1321 #endif /* SYS_rforkall */
   1322 			    ) {
   1323 				/* We are returning in the child, fake it. */
   1324 				tcp->status.PR_WHY = PR_SYSENTRY;
   1325 				trace_syscall(tcp);
   1326 				tcp->status.PR_WHY = PR_SYSEXIT;
   1327 			}
   1328 			else {
   1329 				fprintf(stderr, "syscall: missing entry\n");
   1330 				tcp->flags |= TCB_INSYSCALL;
   1331 			}
   1332 		}
   1333 	}
   1334 	else {
   1335 		if (tcp->status.PR_WHY != PR_SYSEXIT) {
   1336 			fprintf(stderr, "syscall: missing exit\n");
   1337 			tcp->flags &= ~TCB_INSYSCALL;
   1338 		}
   1339 	}
   1340 #endif /* USE_PROCFS */
   1341 #ifdef SUNOS4
   1342 	if (!(tcp->flags & TCB_INSYSCALL)) {
   1343 		if (scno == 0) {
   1344 			fprintf(stderr, "syscall: missing entry\n");
   1345 			tcp->flags |= TCB_INSYSCALL;
   1346 		}
   1347 	}
   1348 	else {
   1349 		if (scno != 0) {
   1350 			if (debug) {
   1351 				/*
   1352 				 * This happens when a signal handler
   1353 				 * for a signal which interrupted a
   1354 				 * a system call makes another system call.
   1355 				 */
   1356 				fprintf(stderr, "syscall: missing exit\n");
   1357 			}
   1358 			tcp->flags &= ~TCB_INSYSCALL;
   1359 		}
   1360 	}
   1361 #endif /* SUNOS4 */
   1362 #ifdef LINUX
   1363 #if defined (I386)
   1364 	if (upeek(pid, 4*EAX, &eax) < 0)
   1365 		return -1;
   1366 	if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
   1367 		if (debug)
   1368 			fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
   1369 		return 0;
   1370 	}
   1371 #elif defined (X86_64)
   1372 	if (upeek(pid, 8*RAX, &rax) < 0)
   1373 		return -1;
   1374 	if (current_personality == 1)
   1375 		rax = (long int)(int)rax; /* sign extend from 32 bits */
   1376 	if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
   1377 		if (debug)
   1378 			fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
   1379 		return 0;
   1380 	}
   1381 #elif defined (S390) || defined (S390X)
   1382 	if (upeek(pid, PT_GPR2, &gpr2) < 0)
   1383 		return -1;
   1384 	if (syscall_mode != -ENOSYS)
   1385 		syscall_mode = tcp->scno;
   1386 	if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
   1387 		if (debug)
   1388 			fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
   1389 		return 0;
   1390 	}
   1391 	else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
   1392 		  == (TCB_INSYSCALL|TCB_WAITEXECVE))
   1393 		 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
   1394 		/*
   1395 		 * Fake a return value of zero.  We leave the TCB_WAITEXECVE
   1396 		 * flag set for the post-execve SIGTRAP to see and reset.
   1397 		 */
   1398 		gpr2 = 0;
   1399 	}
   1400 #elif defined (POWERPC)
   1401 # define SO_MASK 0x10000000
   1402 	if (upeek(pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
   1403 		return -1;
   1404 	if (upeek(pid, sizeof(unsigned long)*PT_R3, &result) < 0)
   1405 		return -1;
   1406 	if (flags & SO_MASK)
   1407 		result = -result;
   1408 #elif defined (M68K)
   1409 	if (upeek(pid, 4*PT_D0, &d0) < 0)
   1410 		return -1;
   1411 	if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
   1412 		if (debug)
   1413 			fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
   1414 		return 0;
   1415 	}
   1416 #elif defined (ARM)
   1417 	/*
   1418 	 * Nothing required
   1419 	 */
   1420 #elif defined (HPPA)
   1421 	if (upeek(pid, PT_GR28, &r28) < 0)
   1422 		return -1;
   1423 #elif defined(IA64)
   1424 	if (upeek(pid, PT_R10, &r10) < 0)
   1425 		return -1;
   1426 	if (upeek(pid, PT_R8, &r8) < 0)
   1427 		return -1;
   1428 	if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
   1429 		if (debug)
   1430 			fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
   1431 		return 0;
   1432 	}
   1433 #endif
   1434 #endif /* LINUX */
   1435 	return 1;
   1436 }
   1437 
   1438 static int
   1439 get_error(tcp)
   1440 struct tcb *tcp;
   1441 {
   1442 	int u_error = 0;
   1443 #ifdef LINUX
   1444 #if defined(S390) || defined(S390X)
   1445 		if (gpr2 && (unsigned) -gpr2 < nerrnos) {
   1446 			tcp->u_rval = -1;
   1447 			u_error = -gpr2;
   1448 		}
   1449 		else {
   1450 			tcp->u_rval = gpr2;
   1451 			u_error = 0;
   1452 		}
   1453 #else /* !S390 && !S390X */
   1454 #ifdef I386
   1455 		if (eax < 0 && -eax < nerrnos) {
   1456 			tcp->u_rval = -1;
   1457 			u_error = -eax;
   1458 		}
   1459 		else {
   1460 			tcp->u_rval = eax;
   1461 			u_error = 0;
   1462 		}
   1463 #else /* !I386 */
   1464 #ifdef X86_64
   1465 		if (rax < 0 && -rax < nerrnos) {
   1466 			tcp->u_rval = -1;
   1467 			u_error = -rax;
   1468 		}
   1469 		else {
   1470 			tcp->u_rval = rax;
   1471 			u_error = 0;
   1472 		}
   1473 #else
   1474 #ifdef IA64
   1475 		if (ia32) {
   1476 			int err;
   1477 
   1478 			err = (int)r8;
   1479 			if (err < 0 && -err < nerrnos) {
   1480 				tcp->u_rval = -1;
   1481 				u_error = -err;
   1482 			}
   1483 			else {
   1484 				tcp->u_rval = err;
   1485 				u_error = 0;
   1486 			}
   1487 		} else {
   1488 			if (r10) {
   1489 				tcp->u_rval = -1;
   1490 				u_error = r8;
   1491 			} else {
   1492 				tcp->u_rval = r8;
   1493 				u_error = 0;
   1494 			}
   1495 		}
   1496 #else /* !IA64 */
   1497 #ifdef MIPS
   1498 		if (a3) {
   1499 		  	tcp->u_rval = -1;
   1500 			u_error = r2;
   1501 		} else {
   1502 		  	tcp->u_rval = r2;
   1503 			u_error = 0;
   1504 		}
   1505 #else
   1506 #ifdef POWERPC
   1507 		if (result && (unsigned long) -result < nerrnos) {
   1508 			tcp->u_rval = -1;
   1509 			u_error = -result;
   1510 		}
   1511 		else {
   1512 			tcp->u_rval = result;
   1513 			u_error = 0;
   1514 		}
   1515 #else /* !POWERPC */
   1516 #ifdef M68K
   1517 		if (d0 && (unsigned) -d0 < nerrnos) {
   1518 			tcp->u_rval = -1;
   1519 			u_error = -d0;
   1520 		}
   1521 		else {
   1522 			tcp->u_rval = d0;
   1523 			u_error = 0;
   1524 		}
   1525 #else /* !M68K */
   1526 #ifdef ARM
   1527 		if (regs.ARM_r0 && (unsigned) -regs.ARM_r0 < nerrnos) {
   1528 			tcp->u_rval = -1;
   1529 			u_error = -regs.ARM_r0;
   1530 		}
   1531 		else {
   1532 			tcp->u_rval = regs.ARM_r0;
   1533 			u_error = 0;
   1534 		}
   1535 #else /* !ARM */
   1536 #ifdef ALPHA
   1537 		if (a3) {
   1538 			tcp->u_rval = -1;
   1539 			u_error = r0;
   1540 		}
   1541 		else {
   1542 			tcp->u_rval = r0;
   1543 			u_error = 0;
   1544 		}
   1545 #else /* !ALPHA */
   1546 #ifdef SPARC
   1547 		if (regs.r_psr & PSR_C) {
   1548 			tcp->u_rval = -1;
   1549 			u_error = regs.r_o0;
   1550 		}
   1551 		else {
   1552 			tcp->u_rval = regs.r_o0;
   1553 			u_error = 0;
   1554 		}
   1555 #else /* !SPARC */
   1556 #ifdef SPARC64
   1557 		if (regs.r_tstate & 0x1100000000UL) {
   1558 			tcp->u_rval = -1;
   1559 			u_error = regs.r_o0;
   1560 		}
   1561 		else {
   1562 			tcp->u_rval = regs.r_o0;
   1563 			u_error = 0;
   1564 		}
   1565 #else /* !SPARC64 */
   1566 #ifdef HPPA
   1567 		if (r28 && (unsigned) -r28 < nerrnos) {
   1568 			tcp->u_rval = -1;
   1569 			u_error = -r28;
   1570 		}
   1571 		else {
   1572 			tcp->u_rval = r28;
   1573 			u_error = 0;
   1574 		}
   1575 #else
   1576 #ifdef SH
   1577                /* interpret R0 as return value or error number */
   1578                if (r0 && (unsigned) -r0 < nerrnos) {
   1579                        tcp->u_rval = -1;
   1580                        u_error = -r0;
   1581                }
   1582                else {
   1583                        tcp->u_rval = r0;
   1584                        u_error = 0;
   1585                }
   1586 #else
   1587 #ifdef SH64
   1588                 /* interpret result as return value or error number */
   1589                 if (r9 && (unsigned) -r9 < nerrnos) {
   1590 	                tcp->u_rval = -1;
   1591 	                u_error = -r9;
   1592                 }
   1593                 else {
   1594                         tcp->u_rval = r9;
   1595 	                u_error = 0;
   1596                 }
   1597 #endif /* SH64 */
   1598 #endif /* SH */
   1599 #endif /* HPPA */
   1600 #endif /* SPARC */
   1601 #endif /* SPARC64 */
   1602 #endif /* ALPHA */
   1603 #endif /* ARM */
   1604 #endif /* M68K */
   1605 #endif /* POWERPC */
   1606 #endif /* MIPS */
   1607 #endif /* IA64 */
   1608 #endif /* X86_64 */
   1609 #endif /* I386 */
   1610 #endif /* S390 || S390X */
   1611 #endif /* LINUX */
   1612 #ifdef SUNOS4
   1613 		/* get error code from user struct */
   1614 		if (upeek(pid, uoff(u_error), &u_error) < 0)
   1615 			return -1;
   1616 		u_error >>= 24; /* u_error is a char */
   1617 
   1618 		/* get system call return value */
   1619 		if (upeek(pid, uoff(u_rval1), &tcp->u_rval) < 0)
   1620 			return -1;
   1621 #endif /* SUNOS4 */
   1622 #ifdef SVR4
   1623 #ifdef SPARC
   1624 		/* Judicious guessing goes a long way. */
   1625 		if (tcp->status.pr_reg[R_PSR] & 0x100000) {
   1626 			tcp->u_rval = -1;
   1627 			u_error = tcp->status.pr_reg[R_O0];
   1628 		}
   1629 		else {
   1630 			tcp->u_rval = tcp->status.pr_reg[R_O0];
   1631 			u_error = 0;
   1632 		}
   1633 #endif /* SPARC */
   1634 #ifdef I386
   1635 		/* Wanna know how to kill an hour single-stepping? */
   1636 		if (tcp->status.PR_REG[EFL] & 0x1) {
   1637 			tcp->u_rval = -1;
   1638 			u_error = tcp->status.PR_REG[EAX];
   1639 		}
   1640 		else {
   1641 			tcp->u_rval = tcp->status.PR_REG[EAX];
   1642 #ifdef HAVE_LONG_LONG
   1643 			tcp->u_lrval =
   1644 				((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
   1645 				tcp->status.PR_REG[EAX];
   1646 #endif
   1647 			u_error = 0;
   1648 		}
   1649 #endif /* I386 */
   1650 #ifdef X86_64
   1651 		/* Wanna know how to kill an hour single-stepping? */
   1652 		if (tcp->status.PR_REG[EFLAGS] & 0x1) {
   1653 			tcp->u_rval = -1;
   1654 			u_error = tcp->status.PR_REG[RAX];
   1655 		}
   1656 		else {
   1657 			tcp->u_rval = tcp->status.PR_REG[RAX];
   1658 			u_error = 0;
   1659 		}
   1660 #endif /* X86_64 */
   1661 #ifdef MIPS
   1662 		if (tcp->status.pr_reg[CTX_A3]) {
   1663 			tcp->u_rval = -1;
   1664 			u_error = tcp->status.pr_reg[CTX_V0];
   1665 		}
   1666 		else {
   1667 			tcp->u_rval = tcp->status.pr_reg[CTX_V0];
   1668 			u_error = 0;
   1669 		}
   1670 #endif /* MIPS */
   1671 #endif /* SVR4 */
   1672 #ifdef FREEBSD
   1673 		if (regs.r_eflags & PSL_C) {
   1674  		        tcp->u_rval = -1;
   1675 		        u_error = regs.r_eax;
   1676 		} else {
   1677 		        tcp->u_rval = regs.r_eax;
   1678 			tcp->u_lrval =
   1679 			  ((unsigned long long) regs.r_edx << 32) +  regs.r_eax;
   1680 		        u_error = 0;
   1681 		}
   1682 #endif /* FREEBSD */
   1683 	tcp->u_error = u_error;
   1684 	return 1;
   1685 }
   1686 
   1687 int
   1688 force_result(tcp, error, rval)
   1689 	struct tcb *tcp;
   1690 	int error;
   1691 	long rval;
   1692 {
   1693 #ifdef LINUX
   1694 #if defined(S390) || defined(S390X)
   1695 	gpr2 = error ? -error : rval;
   1696 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
   1697 		return -1;
   1698 #else /* !S390 && !S390X */
   1699 #ifdef I386
   1700 	eax = error ? -error : rval;
   1701 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
   1702 		return -1;
   1703 #else /* !I386 */
   1704 #ifdef X86_64
   1705 	rax = error ? -error : rval;
   1706 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
   1707 		return -1;
   1708 #else
   1709 #ifdef IA64
   1710 	if (ia32) {
   1711 		r8 = error ? -error : rval;
   1712 		if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
   1713 			return -1;
   1714 	}
   1715 	else {
   1716 		if (error) {
   1717 			r8 = error;
   1718 			r10 = -1;
   1719 		}
   1720 		else {
   1721 			r8 = rval;
   1722 			r10 = 0;
   1723 		}
   1724 		if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
   1725 		    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
   1726 			return -1;
   1727 	}
   1728 #else /* !IA64 */
   1729 #ifdef MIPS
   1730 	if (error) {
   1731 		r2 = error;
   1732 		a3 = -1;
   1733 	}
   1734 	else {
   1735 		r2 = rval;
   1736 		a3 = 0;
   1737 	}
   1738 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
   1739 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
   1740 	    	return -1;
   1741 #else
   1742 #ifdef POWERPC
   1743 	if (upeek(tcp->pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
   1744 		return -1;
   1745 	if (error) {
   1746 		flags |= SO_MASK;
   1747 		result = error;
   1748 	}
   1749 	else {
   1750 		flags &= ~SO_MASK;
   1751 		result = rval;
   1752 	}
   1753 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
   1754 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
   1755 		return -1;
   1756 #else /* !POWERPC */
   1757 #ifdef M68K
   1758 	d0 = error ? -error : rval;
   1759 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
   1760 		return -1;
   1761 #else /* !M68K */
   1762 #ifdef ARM
   1763        regs.ARM_r0 = error ? -error : rval;
   1764        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
   1765 		return -1;
   1766 #else /* !ARM */
   1767 #ifdef ALPHA
   1768 	if (error) {
   1769 		a3 = -1;
   1770 		r0 = error;
   1771 	}
   1772 	else {
   1773 		a3 = 0;
   1774 		r0 = rval;
   1775 	}
   1776 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
   1777 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
   1778 		return -1;
   1779 #else /* !ALPHA */
   1780 #ifdef SPARC
   1781 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
   1782 		return -1;
   1783 	if (error) {
   1784 		regs.r_psr |= PSR_C;
   1785 		regs.r_o0 = error;
   1786 	}
   1787 	else {
   1788 		regs.r_psr &= ~PSR_C;
   1789 		regs.r_o0 = rval;
   1790 	}
   1791 	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
   1792 		return -1;
   1793 #else /* !SPARC */
   1794 #ifdef SPARC64
   1795 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
   1796 		return -1;
   1797 	if (error) {
   1798 		regs.r_tstate |= 0x1100000000UL;
   1799 		regs.r_o0 = error;
   1800 	}
   1801 	else {
   1802 		regs.r_tstate &= ~0x1100000000UL;
   1803 		regs.r_o0 = rval;
   1804 	}
   1805 	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
   1806 		return -1;
   1807 #else /* !SPARC64 */
   1808 #ifdef HPPA
   1809 	r28 = error ? -error : rval;
   1810 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
   1811 		return -1;
   1812 #else
   1813 #ifdef SH
   1814 	r0 = error ? -error : rval;
   1815 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
   1816 		return -1;
   1817 #else
   1818 #ifdef SH64
   1819         r9 = error ? -error : rval;
   1820 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
   1821 		return -1;
   1822 #endif /* SH64 */
   1823 #endif /* SH */
   1824 #endif /* HPPA */
   1825 #endif /* SPARC */
   1826 #endif /* SPARC64 */
   1827 #endif /* ALPHA */
   1828 #endif /* ARM */
   1829 #endif /* M68K */
   1830 #endif /* POWERPC */
   1831 #endif /* MIPS */
   1832 #endif /* IA64 */
   1833 #endif /* X86_64 */
   1834 #endif /* I386 */
   1835 #endif /* S390 || S390X */
   1836 #endif /* LINUX */
   1837 #ifdef SUNOS4
   1838 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
   1839 		   error << 24) < 0 ||
   1840 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
   1841 		return -1;
   1842 #endif /* SUNOS4 */
   1843 #ifdef SVR4
   1844 	/* XXX no clue */
   1845 	return -1;
   1846 #endif /* SVR4 */
   1847 #ifdef FREEBSD
   1848 	if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
   1849 	        perror("pread");
   1850                 return -1;
   1851         }
   1852 	if (error) {
   1853 		regs.r_eflags |= PSL_C;
   1854 		regs.r_eax = error;
   1855 	}
   1856 	else {
   1857 		regs.r_eflags &= ~PSL_C;
   1858 		regs.r_eax = rval;
   1859 	}
   1860 	if (pwrite(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
   1861 	        perror("pwrite");
   1862                 return -1;
   1863         }
   1864 #endif /* FREEBSD */
   1865 
   1866 	/* All branches reach here on success (only).  */
   1867 	tcp->u_error = error;
   1868 	tcp->u_rval = rval;
   1869 	return 0;
   1870 }
   1871 
   1872 static int
   1873 syscall_enter(tcp)
   1874 struct tcb *tcp;
   1875 {
   1876 #ifndef USE_PROCFS
   1877 	int pid = tcp->pid;
   1878 #endif /* !USE_PROCFS */
   1879 #ifdef LINUX
   1880 #if defined(S390) || defined(S390X)
   1881 	{
   1882 		int i;
   1883 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   1884 			tcp->u_nargs = sysent[tcp->scno].nargs;
   1885 		else
   1886      	        	tcp->u_nargs = MAX_ARGS;
   1887 		for (i = 0; i < tcp->u_nargs; i++) {
   1888 			if (upeek(pid,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
   1889 				return -1;
   1890 		}
   1891 	}
   1892 #elif defined (ALPHA)
   1893 	{
   1894 		int i;
   1895 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   1896 			tcp->u_nargs = sysent[tcp->scno].nargs;
   1897 		else
   1898      	        	tcp->u_nargs = MAX_ARGS;
   1899 		for (i = 0; i < tcp->u_nargs; i++) {
   1900 			/* WTA: if scno is out-of-bounds this will bomb. Add range-check
   1901 			 * for scno somewhere above here!
   1902 			 */
   1903 			if (upeek(pid, REG_A0+i, &tcp->u_arg[i]) < 0)
   1904 				return -1;
   1905 		}
   1906 	}
   1907 #elif defined (IA64)
   1908 	{
   1909 		if (!ia32) {
   1910 			unsigned long *out0, *rbs_end, cfm, sof, sol, i;
   1911 			/* be backwards compatible with kernel < 2.4.4... */
   1912 #			ifndef PT_RBS_END
   1913 #			  define PT_RBS_END	PT_AR_BSP
   1914 #			endif
   1915 
   1916 			if (upeek(pid, PT_RBS_END, (long *) &rbs_end) < 0)
   1917 				return -1;
   1918 			if (upeek(pid, PT_CFM, (long *) &cfm) < 0)
   1919 				return -1;
   1920 
   1921 			sof = (cfm >> 0) & 0x7f;
   1922 			sol = (cfm >> 7) & 0x7f;
   1923 			out0 = ia64_rse_skip_regs(rbs_end, -sof + sol);
   1924 
   1925 			if (tcp->scno >= 0 && tcp->scno < nsyscalls
   1926 			    && sysent[tcp->scno].nargs != -1)
   1927 				tcp->u_nargs = sysent[tcp->scno].nargs;
   1928 			else
   1929 				tcp->u_nargs = MAX_ARGS;
   1930 			for (i = 0; i < tcp->u_nargs; ++i) {
   1931 				if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
   1932 					   sizeof(long), (char *) &tcp->u_arg[i]) < 0)
   1933 					return -1;
   1934 			}
   1935 		} else {
   1936 			int i;
   1937 
   1938 			if (/* EBX = out0 */
   1939 			    upeek(pid, PT_R11, (long *) &tcp->u_arg[0]) < 0
   1940 			    /* ECX = out1 */
   1941 			    || upeek(pid, PT_R9,  (long *) &tcp->u_arg[1]) < 0
   1942 			    /* EDX = out2 */
   1943 			    || upeek(pid, PT_R10, (long *) &tcp->u_arg[2]) < 0
   1944 			    /* ESI = out3 */
   1945 			    || upeek(pid, PT_R14, (long *) &tcp->u_arg[3]) < 0
   1946 			    /* EDI = out4 */
   1947 			    || upeek(pid, PT_R15, (long *) &tcp->u_arg[4]) < 0
   1948 			    /* EBP = out5 */
   1949 			    || upeek(pid, PT_R13, (long *) &tcp->u_arg[5]) < 0)
   1950 				return -1;
   1951 
   1952 			for (i = 0; i < 6; ++i)
   1953 				/* truncate away IVE sign-extension */
   1954 				tcp->u_arg[i] &= 0xffffffff;
   1955 
   1956 			if (tcp->scno >= 0 && tcp->scno < nsyscalls
   1957 			    && sysent[tcp->scno].nargs != -1)
   1958 				tcp->u_nargs = sysent[tcp->scno].nargs;
   1959 			else
   1960 				tcp->u_nargs = 5;
   1961 		}
   1962 	}
   1963 #elif defined (MIPS)
   1964 	{
   1965 	  	long sp;
   1966 	  	int i, nargs;
   1967 
   1968 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   1969 			nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
   1970 		else
   1971      	        	nargs = tcp->u_nargs = MAX_ARGS;
   1972 		if(nargs > 4) {
   1973 		  	if(upeek(pid, REG_SP, &sp) < 0)
   1974 			  	return -1;
   1975 			for(i = 0; i < 4; i++) {
   1976 			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i])<0)
   1977 				  	return -1;
   1978 			}
   1979 			umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
   1980 			       (char *)(tcp->u_arg + 4));
   1981 		} else {
   1982 		  	for(i = 0; i < nargs; i++) {
   1983 			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i]) < 0)
   1984 				  	return -1;
   1985 			}
   1986 		}
   1987 	}
   1988 #elif defined (POWERPC)
   1989 #ifndef PT_ORIG_R3
   1990 #define PT_ORIG_R3 34
   1991 #endif
   1992 	{
   1993 		int i;
   1994 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   1995 			tcp->u_nargs = sysent[tcp->scno].nargs;
   1996 		else
   1997      	        	tcp->u_nargs = MAX_ARGS;
   1998 		for (i = 0; i < tcp->u_nargs; i++) {
   1999 			if (upeek(pid, (i==0) ?
   2000 				(sizeof(unsigned long)*PT_ORIG_R3) :
   2001 				((i+PT_R3)*sizeof(unsigned long)),
   2002 					&tcp->u_arg[i]) < 0)
   2003 				return -1;
   2004 		}
   2005 	}
   2006 #elif defined (SPARC) || defined (SPARC64)
   2007 	{
   2008 		int i;
   2009 
   2010 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2011 			tcp->u_nargs = sysent[tcp->scno].nargs;
   2012 		else
   2013      	        	tcp->u_nargs = MAX_ARGS;
   2014 		for (i = 0; i < tcp->u_nargs; i++)
   2015 			tcp->u_arg[i] = *((&regs.r_o0) + i);
   2016 	}
   2017 #elif defined (HPPA)
   2018 	{
   2019 		int i;
   2020 
   2021 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2022 			tcp->u_nargs = sysent[tcp->scno].nargs;
   2023 		else
   2024      	        	tcp->u_nargs = MAX_ARGS;
   2025 		for (i = 0; i < tcp->u_nargs; i++) {
   2026 			if (upeek(pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
   2027 				return -1;
   2028 		}
   2029 	}
   2030 #elif defined(ARM)
   2031 	{
   2032 		int i;
   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 = MAX_ARGS;
   2038 		for (i = 0; i < tcp->u_nargs; i++)
   2039 			tcp->u_arg[i] = regs.uregs[i];
   2040  	}
   2041 #elif defined(SH)
   2042        {
   2043                int i;
   2044                static int syscall_regs[] = {
   2045                    REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
   2046                    REG_REG0, REG_REG0+1, REG_REG0+2
   2047                    };
   2048 
   2049                tcp->u_nargs = sysent[tcp->scno].nargs;
   2050                for (i = 0; i < tcp->u_nargs; i++) {
   2051                        if (upeek(pid, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
   2052                                return -1;
   2053                }
   2054         }
   2055 #elif defined(SH64)
   2056 	{
   2057 		int i;
   2058                 /* Registers used by SH5 Linux system calls for parameters */
   2059 		static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
   2060 
   2061 		/*
   2062 		 * TODO: should also check that the number of arguments encoded
   2063 		 *       in the trap number matches the number strace expects.
   2064 		 */
   2065 		/*
   2066 		    assert(sysent[tcp->scno].nargs <
   2067 		    	sizeof(syscall_regs)/sizeof(syscall_regs[0]));
   2068 		 */
   2069 
   2070 		tcp->u_nargs = sysent[tcp->scno].nargs;
   2071 		for (i = 0; i < tcp->u_nargs; i++) {
   2072 			if (upeek(pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
   2073 				return -1;
   2074 		}
   2075 	}
   2076 
   2077 #elif defined(X86_64)
   2078 	{
   2079 		int i;
   2080 		static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
   2081 			{RDI,RSI,RDX,R10,R8,R9},	/* x86-64 ABI */
   2082 			{RBX,RCX,RDX,RSI,RDI,RBP}	/* i386 ABI */
   2083 		};
   2084 
   2085 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2086 			tcp->u_nargs = sysent[tcp->scno].nargs;
   2087 		else
   2088      	        	tcp->u_nargs = MAX_ARGS;
   2089 		for (i = 0; i < tcp->u_nargs; i++) {
   2090 			if (upeek(pid, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
   2091 				return -1;
   2092 		}
   2093 	}
   2094 #else /* Other architecture (like i386) (32bits specific) */
   2095 	{
   2096 		int i;
   2097 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2098 			tcp->u_nargs = sysent[tcp->scno].nargs;
   2099 		else
   2100      	        	tcp->u_nargs = MAX_ARGS;
   2101 		for (i = 0; i < tcp->u_nargs; i++) {
   2102 			if (upeek(pid, i*4, &tcp->u_arg[i]) < 0)
   2103 				return -1;
   2104 		}
   2105 	}
   2106 #endif
   2107 #endif /* LINUX */
   2108 #ifdef SUNOS4
   2109 	{
   2110 		int i;
   2111 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2112 			tcp->u_nargs = sysent[tcp->scno].nargs;
   2113 		else
   2114      	        	tcp->u_nargs = MAX_ARGS;
   2115 		for (i = 0; i < tcp->u_nargs; i++) {
   2116 			struct user *u;
   2117 
   2118 			if (upeek(pid, uoff(u_arg[0]) +
   2119 			    (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
   2120 				return -1;
   2121 		}
   2122 	}
   2123 #endif /* SUNOS4 */
   2124 #ifdef SVR4
   2125 #ifdef MIPS
   2126 	/*
   2127 	 * SGI is broken: even though it has pr_sysarg, it doesn't
   2128 	 * set them on system call entry.  Get a clue.
   2129 	 */
   2130 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2131 		tcp->u_nargs = sysent[tcp->scno].nargs;
   2132 	else
   2133 		tcp->u_nargs = tcp->status.pr_nsysarg;
   2134 	if (tcp->u_nargs > 4) {
   2135 		memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
   2136 			4*sizeof(tcp->u_arg[0]));
   2137 		umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
   2138 			(tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
   2139 	}
   2140 	else {
   2141 		memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
   2142 			tcp->u_nargs*sizeof(tcp->u_arg[0]));
   2143 	}
   2144 #elif UNIXWARE >= 2
   2145 	/*
   2146 	 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
   2147 	 */
   2148 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2149 		tcp->u_nargs = sysent[tcp->scno].nargs;
   2150 	else
   2151 		tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
   2152 	umoven(tcp, tcp->status.PR_REG[UESP] + 4,
   2153 		tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
   2154 #elif defined (HAVE_PR_SYSCALL)
   2155 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2156 		tcp->u_nargs = sysent[tcp->scno].nargs;
   2157 	else
   2158 		tcp->u_nargs = tcp->status.pr_nsysarg;
   2159 	{
   2160 		int i;
   2161 		for (i = 0; i < tcp->u_nargs; i++)
   2162 			tcp->u_arg[i] = tcp->status.pr_sysarg[i];
   2163 	}
   2164 #elif defined (I386)
   2165 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
   2166 		tcp->u_nargs = sysent[tcp->scno].nargs;
   2167 	else
   2168 		tcp->u_nargs = 5;
   2169 	umoven(tcp, tcp->status.PR_REG[UESP] + 4,
   2170 		tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
   2171 #else
   2172 	I DONT KNOW WHAT TO DO
   2173 #endif /* !HAVE_PR_SYSCALL */
   2174 #endif /* SVR4 */
   2175 #ifdef FREEBSD
   2176 	if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
   2177 	    sysent[tcp->scno].nargs > tcp->status.val)
   2178 		tcp->u_nargs = sysent[tcp->scno].nargs;
   2179 	else
   2180 	  	tcp->u_nargs = tcp->status.val;
   2181 	if (tcp->u_nargs < 0)
   2182 		tcp->u_nargs = 0;
   2183 	if (tcp->u_nargs > MAX_ARGS)
   2184 		tcp->u_nargs = MAX_ARGS;
   2185 	switch(regs.r_eax) {
   2186 	case SYS___syscall:
   2187 		pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
   2188 		      regs.r_esp + sizeof(int) + sizeof(quad_t));
   2189 	  break;
   2190         case SYS_syscall:
   2191 		pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
   2192 		      regs.r_esp + 2 * sizeof(int));
   2193 	  break;
   2194         default:
   2195 		pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
   2196 		      regs.r_esp + sizeof(int));
   2197 	  break;
   2198 	}
   2199 #endif /* FREEBSD */
   2200 	return 1;
   2201 }
   2202 
   2203 int
   2204 trace_syscall(tcp)
   2205 struct tcb *tcp;
   2206 {
   2207 	int sys_res;
   2208 	struct timeval tv;
   2209 	int res;
   2210 
   2211 	/* Measure the exit time as early as possible to avoid errors. */
   2212 	if (dtime && (tcp->flags & TCB_INSYSCALL))
   2213 		gettimeofday(&tv, NULL);
   2214 
   2215 	res = get_scno(tcp);
   2216 	if (res != 1)
   2217 		return res;
   2218 
   2219 	res = syscall_fixup(tcp);
   2220 	if (res != 1)
   2221 		return res;
   2222 
   2223 	if (tcp->flags & TCB_INSYSCALL) {
   2224 		long u_error;
   2225 		res = get_error(tcp);
   2226 		if (res != 1)
   2227 			return res;
   2228 
   2229 		internal_syscall(tcp);
   2230 		if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
   2231 		    !(qual_flags[tcp->scno] & QUAL_TRACE)) {
   2232 			tcp->flags &= ~TCB_INSYSCALL;
   2233 			return 0;
   2234 		}
   2235 
   2236 		if (tcp->flags & TCB_REPRINT) {
   2237 			printleader(tcp);
   2238 			tprintf("<... ");
   2239 			if (tcp->scno >= nsyscalls || tcp->scno < 0)
   2240 				tprintf("syscall_%lu", tcp->scno);
   2241 			else
   2242 				tprintf("%s", sysent[tcp->scno].sys_name);
   2243 			tprintf(" resumed> ");
   2244 		}
   2245 
   2246 		if (cflag && tcp->scno < nsyscalls && tcp->scno >= 0) {
   2247 			if (counts == NULL) {
   2248 				counts = calloc(sizeof *counts, nsyscalls);
   2249 				if (counts == NULL) {
   2250 					fprintf(stderr, "\
   2251 strace: out of memory for call counts\n");
   2252 					exit(1);
   2253 				}
   2254 			}
   2255 
   2256 			counts[tcp->scno].calls++;
   2257 			if (tcp->u_error)
   2258 				counts[tcp->scno].errors++;
   2259 			tv_sub(&tv, &tv, &tcp->etime);
   2260 #ifndef HAVE_ANDROID_OS
   2261 #ifdef LINUX
   2262 			if (tv_cmp(&tv, &tcp->dtime) > 0) {
   2263 				static struct timeval one_tick;
   2264 				if (one_tick.tv_usec == 0) {
   2265 					/* Initialize it.  */
   2266 					struct itimerval it;
   2267 					memset(&it, 0, sizeof it);
   2268 					it.it_interval.tv_usec = 1;
   2269 					setitimer(ITIMER_REAL, &it, NULL);
   2270 					getitimer(ITIMER_REAL, &it);
   2271 					one_tick = it.it_interval;
   2272 				}
   2273 
   2274 				if (tv_nz(&tcp->dtime))
   2275 					tv = tcp->dtime;
   2276 				else if (tv_cmp(&tv, &one_tick) > 0) {
   2277 					if (tv_cmp(&shortest, &one_tick) < 0)
   2278 						tv = shortest;
   2279 					else
   2280 						tv = one_tick;
   2281 				}
   2282 			}
   2283 #endif /* LINUX */
   2284 #endif
   2285 			if (tv_cmp(&tv, &shortest) < 0)
   2286 				shortest = tv;
   2287 			tv_add(&counts[tcp->scno].time,
   2288 				&counts[tcp->scno].time, &tv);
   2289 			tcp->flags &= ~TCB_INSYSCALL;
   2290 			return 0;
   2291 		}
   2292 
   2293 		if (tcp->scno >= nsyscalls || tcp->scno < 0
   2294 		    || (qual_flags[tcp->scno] & QUAL_RAW))
   2295 			sys_res = printargs(tcp);
   2296 		else {
   2297 			if (not_failing_only && tcp->u_error)
   2298 				return 0;	/* ignore failed syscalls */
   2299 			sys_res = (*sysent[tcp->scno].sys_func)(tcp);
   2300 		}
   2301 		u_error = tcp->u_error;
   2302 		tprintf(") ");
   2303 		tabto(acolumn);
   2304 		if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
   2305 		    qual_flags[tcp->scno] & QUAL_RAW) {
   2306 			if (u_error)
   2307 				tprintf("= -1 (errno %ld)", u_error);
   2308 			else
   2309 				tprintf("= %#lx", tcp->u_rval);
   2310 		}
   2311 		else if (!(sys_res & RVAL_NONE) && u_error) {
   2312 			switch (u_error) {
   2313 #ifdef LINUX
   2314 			case ERESTARTSYS:
   2315 				tprintf("= ? ERESTARTSYS (To be restarted)");
   2316 				break;
   2317 			case ERESTARTNOINTR:
   2318 				tprintf("= ? ERESTARTNOINTR (To be restarted)");
   2319 				break;
   2320 			case ERESTARTNOHAND:
   2321 				tprintf("= ? ERESTARTNOHAND (To be restarted)");
   2322 				break;
   2323 			case ERESTART_RESTARTBLOCK:
   2324 				tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
   2325 				break;
   2326 #endif /* LINUX */
   2327 			default:
   2328 				tprintf("= -1 ");
   2329 				if (u_error < 0)
   2330 					tprintf("E??? (errno %ld)", u_error);
   2331 				else if (u_error < nerrnos)
   2332 					tprintf("%s (%s)", errnoent[u_error],
   2333 						strerror(u_error));
   2334 				else
   2335 					tprintf("ERRNO_%ld (%s)", u_error,
   2336 						strerror(u_error));
   2337 				break;
   2338 			}
   2339 		}
   2340 		else {
   2341 			if (sys_res & RVAL_NONE)
   2342 				tprintf("= ?");
   2343 			else {
   2344 				switch (sys_res & RVAL_MASK) {
   2345 				case RVAL_HEX:
   2346 					tprintf("= %#lx", tcp->u_rval);
   2347 					break;
   2348 				case RVAL_OCTAL:
   2349 					tprintf("= %#lo", tcp->u_rval);
   2350 					break;
   2351 				case RVAL_UDECIMAL:
   2352 					tprintf("= %lu", tcp->u_rval);
   2353 					break;
   2354 				case RVAL_DECIMAL:
   2355 					tprintf("= %ld", tcp->u_rval);
   2356 					break;
   2357 #ifdef HAVE_LONG_LONG
   2358 				case RVAL_LHEX:
   2359 					tprintf("= %#llx", tcp->u_lrval);
   2360 					break;
   2361 				case RVAL_LOCTAL:
   2362 					tprintf("= %#llo", tcp->u_lrval);
   2363 					break;
   2364 				case RVAL_LUDECIMAL:
   2365 					tprintf("= %llu", tcp->u_lrval);
   2366 					break;
   2367 				case RVAL_LDECIMAL:
   2368 					tprintf("= %lld", tcp->u_lrval);
   2369 					break;
   2370 #endif
   2371 				default:
   2372 					fprintf(stderr,
   2373 						"invalid rval format\n");
   2374 					break;
   2375 				}
   2376 			}
   2377 			if ((sys_res & RVAL_STR) && tcp->auxstr)
   2378 				tprintf(" (%s)", tcp->auxstr);
   2379 		}
   2380 		if (dtime) {
   2381 			tv_sub(&tv, &tv, &tcp->etime);
   2382 			tprintf(" <%ld.%06ld>",
   2383 				(long) tv.tv_sec, (long) tv.tv_usec);
   2384 		}
   2385 		printtrailer(tcp);
   2386 
   2387 		dumpio(tcp);
   2388 		if (fflush(tcp->outf) == EOF)
   2389 			return -1;
   2390 		tcp->flags &= ~TCB_INSYSCALL;
   2391 		return 0;
   2392 	}
   2393 
   2394 	/* Entering system call */
   2395 	res = syscall_enter(tcp);
   2396 	if (res != 1)
   2397 		return res;
   2398 
   2399 	switch (known_scno(tcp)) {
   2400 #ifdef LINUX
   2401 #if !defined (ALPHA) && !defined(SPARC) && !defined(SPARC64) && !defined(MIPS) && !defined(HPPA) && !defined(__ARM_EABI__) //ANDROID
   2402 	case SYS_socketcall:
   2403 		decode_subcall(tcp, SYS_socket_subcall,
   2404 			SYS_socket_nsubcalls, deref_style);
   2405 		break;
   2406 	case SYS_ipc:
   2407 		decode_subcall(tcp, SYS_ipc_subcall,
   2408 			SYS_ipc_nsubcalls, shift_style);
   2409 		break;
   2410 #endif /* !ALPHA && !MIPS && !SPARC && !SPARC64 && !HPPA */
   2411 #if defined (SPARC) || defined (SPARC64)
   2412 	case SYS_socketcall:
   2413 		sparc_socket_decode (tcp);
   2414 		break;
   2415 #endif
   2416 #endif /* LINUX */
   2417 #ifdef SVR4
   2418 #ifdef SYS_pgrpsys_subcall
   2419 	case SYS_pgrpsys:
   2420 		decode_subcall(tcp, SYS_pgrpsys_subcall,
   2421 			SYS_pgrpsys_nsubcalls, shift_style);
   2422 		break;
   2423 #endif /* SYS_pgrpsys_subcall */
   2424 #ifdef SYS_sigcall_subcall
   2425 	case SYS_sigcall:
   2426 		decode_subcall(tcp, SYS_sigcall_subcall,
   2427 			SYS_sigcall_nsubcalls, mask_style);
   2428 		break;
   2429 #endif /* SYS_sigcall_subcall */
   2430 	case SYS_msgsys:
   2431 		decode_subcall(tcp, SYS_msgsys_subcall,
   2432 			SYS_msgsys_nsubcalls, shift_style);
   2433 		break;
   2434 	case SYS_shmsys:
   2435 		decode_subcall(tcp, SYS_shmsys_subcall,
   2436 			SYS_shmsys_nsubcalls, shift_style);
   2437 		break;
   2438 	case SYS_semsys:
   2439 		decode_subcall(tcp, SYS_semsys_subcall,
   2440 			SYS_semsys_nsubcalls, shift_style);
   2441 		break;
   2442 #if 0 /* broken */
   2443 	case SYS_utssys:
   2444 		decode_subcall(tcp, SYS_utssys_subcall,
   2445 			SYS_utssys_nsubcalls, shift_style);
   2446 		break;
   2447 #endif
   2448 	case SYS_sysfs:
   2449 		decode_subcall(tcp, SYS_sysfs_subcall,
   2450 			SYS_sysfs_nsubcalls, shift_style);
   2451 		break;
   2452 	case SYS_spcall:
   2453 		decode_subcall(tcp, SYS_spcall_subcall,
   2454 			SYS_spcall_nsubcalls, shift_style);
   2455 		break;
   2456 #ifdef SYS_context_subcall
   2457 	case SYS_context:
   2458 		decode_subcall(tcp, SYS_context_subcall,
   2459 			SYS_context_nsubcalls, shift_style);
   2460 		break;
   2461 #endif /* SYS_context_subcall */
   2462 #ifdef SYS_door_subcall
   2463 	case SYS_door:
   2464 		decode_subcall(tcp, SYS_door_subcall,
   2465 			SYS_door_nsubcalls, door_style);
   2466 		break;
   2467 #endif /* SYS_door_subcall */
   2468 #ifdef SYS_kaio_subcall
   2469 	case SYS_kaio:
   2470 		decode_subcall(tcp, SYS_kaio_subcall,
   2471 			SYS_kaio_nsubcalls, shift_style);
   2472 		break;
   2473 #endif
   2474 #endif /* SVR4 */
   2475 #ifdef FREEBSD
   2476 	case SYS_msgsys:
   2477 	case SYS_shmsys:
   2478 	case SYS_semsys:
   2479 		decode_subcall(tcp, 0, 0, table_style);
   2480 		break;
   2481 #endif
   2482 #ifdef SUNOS4
   2483 	case SYS_semsys:
   2484 		decode_subcall(tcp, SYS_semsys_subcall,
   2485 			SYS_semsys_nsubcalls, shift_style);
   2486 		break;
   2487 	case SYS_msgsys:
   2488 		decode_subcall(tcp, SYS_msgsys_subcall,
   2489 			SYS_msgsys_nsubcalls, shift_style);
   2490 		break;
   2491 	case SYS_shmsys:
   2492 		decode_subcall(tcp, SYS_shmsys_subcall,
   2493 			SYS_shmsys_nsubcalls, shift_style);
   2494 		break;
   2495 #endif
   2496 	}
   2497 
   2498 	internal_syscall(tcp);
   2499 	if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
   2500 		tcp->flags |= TCB_INSYSCALL;
   2501 		return 0;
   2502 	}
   2503 
   2504 	if (cflag) {
   2505 		gettimeofday(&tcp->etime, NULL);
   2506 		tcp->flags |= TCB_INSYSCALL;
   2507 		return 0;
   2508 	}
   2509 
   2510 	printleader(tcp);
   2511 	tcp->flags &= ~TCB_REPRINT;
   2512 	tcp_last = tcp;
   2513 	if (tcp->scno >= nsyscalls || tcp->scno < 0)
   2514 		tprintf("syscall_%lu(", tcp->scno);
   2515 	else
   2516 		tprintf("%s(", sysent[tcp->scno].sys_name);
   2517 	if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
   2518 	    ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
   2519 		sys_res = printargs(tcp);
   2520 	else
   2521 		sys_res = (*sysent[tcp->scno].sys_func)(tcp);
   2522 	if (fflush(tcp->outf) == EOF)
   2523 		return -1;
   2524 	tcp->flags |= TCB_INSYSCALL;
   2525 	/* Measure the entrance time as late as possible to avoid errors. */
   2526 	if (dtime)
   2527 		gettimeofday(&tcp->etime, NULL);
   2528 	return sys_res;
   2529 }
   2530 
   2531 int
   2532 printargs(tcp)
   2533 struct tcb *tcp;
   2534 {
   2535 	if (entering(tcp)) {
   2536 		int i;
   2537 
   2538 		for (i = 0; i < tcp->u_nargs; i++)
   2539 			tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
   2540 	}
   2541 	return 0;
   2542 }
   2543 
   2544 long
   2545 getrval2(tcp)
   2546 struct tcb *tcp;
   2547 {
   2548 	long val = -1;
   2549 
   2550 #ifdef LINUX
   2551 #if defined (SPARC) || defined (SPARC64)
   2552 	struct regs regs;
   2553 	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
   2554 		return -1;
   2555 	val = regs.r_o1;
   2556 #elif defined(SH)
   2557 	if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0)
   2558 		return -1;
   2559 #elif defined(IA64)
   2560 	if (upeek(tcp->pid, PT_R9, &val) < 0)
   2561 		return -1;
   2562 #endif /* SPARC || SPARC64 */
   2563 #endif /* LINUX */
   2564 
   2565 #ifdef SUNOS4
   2566 	if (upeek(tcp->pid, uoff(u_rval2), &val) < 0)
   2567 		return -1;
   2568 #endif /* SUNOS4 */
   2569 
   2570 #ifdef SVR4
   2571 #ifdef SPARC
   2572 	val = tcp->status.PR_REG[R_O1];
   2573 #endif /* SPARC */
   2574 #ifdef I386
   2575 	val = tcp->status.PR_REG[EDX];
   2576 #endif /* I386 */
   2577 #ifdef X86_64
   2578 	val = tcp->status.PR_REG[RDX];
   2579 #endif /* X86_64 */
   2580 #ifdef MIPS
   2581 	val = tcp->status.PR_REG[CTX_V1];
   2582 #endif /* MIPS */
   2583 #endif /* SVR4 */
   2584 #ifdef FREEBSD
   2585 	struct reg regs;
   2586 	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
   2587 	val = regs.r_edx;
   2588 #endif
   2589 	return val;
   2590 }
   2591 
   2592 /*
   2593  * Apparently, indirect system calls have already be converted by ptrace(2),
   2594  * so if you see "indir" this program has gone astray.
   2595  */
   2596 int
   2597 sys_indir(tcp)
   2598 struct tcb *tcp;
   2599 {
   2600 	int i, scno, nargs;
   2601 
   2602 	if (entering(tcp)) {
   2603 		if ((scno = tcp->u_arg[0]) > nsyscalls) {
   2604 			fprintf(stderr, "Bogus syscall: %u\n", scno);
   2605 			return 0;
   2606 		}
   2607 		nargs = sysent[scno].nargs;
   2608 		tprintf("%s", sysent[scno].sys_name);
   2609 		for (i = 0; i < nargs; i++)
   2610 			tprintf(", %#lx", tcp->u_arg[i+1]);
   2611 	}
   2612 	return 0;
   2613 }
   2614 
   2615 static int
   2616 time_cmp(a, b)
   2617 void *a;
   2618 void *b;
   2619 {
   2620 	return -tv_cmp(&counts[*((int *) a)].time, &counts[*((int *) b)].time);
   2621 }
   2622 
   2623 static int
   2624 syscall_cmp(a, b)
   2625 void *a;
   2626 void *b;
   2627 {
   2628 	return strcmp(sysent[*((int *) a)].sys_name,
   2629 		sysent[*((int *) b)].sys_name);
   2630 }
   2631 
   2632 static int
   2633 count_cmp(a, b)
   2634 void *a;
   2635 void *b;
   2636 {
   2637 	int m = counts[*((int *) a)].calls, n = counts[*((int *) b)].calls;
   2638 
   2639 	return (m < n) ? 1 : (m > n) ? -1 : 0;
   2640 }
   2641 
   2642 static int (*sortfun)();
   2643 static struct timeval overhead = { -1, -1 };
   2644 
   2645 void
   2646 set_sortby(sortby)
   2647 char *sortby;
   2648 {
   2649 	if (strcmp(sortby, "time") == 0)
   2650 		sortfun = time_cmp;
   2651 	else if (strcmp(sortby, "calls") == 0)
   2652 		sortfun = count_cmp;
   2653 	else if (strcmp(sortby, "name") == 0)
   2654 		sortfun = syscall_cmp;
   2655 	else if (strcmp(sortby, "nothing") == 0)
   2656 		sortfun = NULL;
   2657 	else {
   2658 		fprintf(stderr, "invalid sortby: `%s'\n", sortby);
   2659 		exit(1);
   2660 	}
   2661 }
   2662 
   2663 void set_overhead(n)
   2664 int n;
   2665 {
   2666 	overhead.tv_sec = n / 1000000;
   2667 	overhead.tv_usec = n % 1000000;
   2668 }
   2669 
   2670 void
   2671 call_summary(outf)
   2672 FILE *outf;
   2673 {
   2674 	int i, j;
   2675 	int call_cum, error_cum;
   2676 	struct timeval tv_cum, dtv;
   2677 	double percent;
   2678 	char *dashes = "-------------------------";
   2679 	char error_str[16];
   2680 
   2681 	int *sorted_count = malloc(nsyscalls * sizeof(int));
   2682 
   2683 	call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
   2684 	if (overhead.tv_sec == -1) {
   2685 		tv_mul(&overhead, &shortest, 8);
   2686 		tv_div(&overhead, &overhead, 10);
   2687 	}
   2688 	for (i = 0; i < nsyscalls; i++) {
   2689 		sorted_count[i] = i;
   2690 		if (counts == NULL || counts[i].calls == 0)
   2691 			continue;
   2692 		tv_mul(&dtv, &overhead, counts[i].calls);
   2693 		tv_sub(&counts[i].time, &counts[i].time, &dtv);
   2694 		call_cum += counts[i].calls;
   2695 		error_cum += counts[i].errors;
   2696 		tv_add(&tv_cum, &tv_cum, &counts[i].time);
   2697 	}
   2698 	if (counts && sortfun)
   2699 		qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun);
   2700 	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
   2701 		"% time", "seconds", "usecs/call",
   2702 		"calls", "errors", "syscall");
   2703 	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
   2704 		dashes, dashes, dashes, dashes, dashes, dashes);
   2705 	if (counts) {
   2706 		for (i = 0; i < nsyscalls; i++) {
   2707 			j = sorted_count[i];
   2708 			if (counts[j].calls == 0)
   2709 				continue;
   2710 			tv_div(&dtv, &counts[j].time, counts[j].calls);
   2711 			if (counts[j].errors)
   2712 				sprintf(error_str, "%d", counts[j].errors);
   2713 			else
   2714 				error_str[0] = '\0';
   2715 			percent = (100.0 * tv_float(&counts[j].time)
   2716 				   / tv_float(&tv_cum));
   2717 			fprintf(outf, "%6.2f %4ld.%06ld %11ld %9d %9.9s %s\n",
   2718 				percent, (long) counts[j].time.tv_sec,
   2719 				(long) counts[j].time.tv_usec,
   2720 				(long) 1000000 * dtv.tv_sec + dtv.tv_usec,
   2721 				counts[j].calls,
   2722 				error_str, sysent[j].sys_name);
   2723 		}
   2724 	}
   2725 	free(sorted_count);
   2726 
   2727 	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
   2728 		dashes, dashes, dashes, dashes, dashes, dashes);
   2729 	if (error_cum)
   2730 		sprintf(error_str, "%d", error_cum);
   2731 	else
   2732 		error_str[0] = '\0';
   2733 	fprintf(outf, "%6.6s %4ld.%06ld %11.11s %9d %9.9s %s\n",
   2734 		"100.00", (long) tv_cum.tv_sec, (long) tv_cum.tv_usec, "",
   2735 		call_cum, error_str, "total");
   2736 
   2737 }
   2738