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