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