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