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