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