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