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