Merge remote-tracking branch 'strace/master' into HEAD
Change-Id: I71324955ac973323aa790485c240e553272ff266
diff --git a/Makefile.am b/Makefile.am
index 48fe1d7..8193c9e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -77,6 +77,7 @@
personality.c \
prctl.c \
printmode.c \
+ printsiginfo.c \
printstat.h \
process.c \
process_vm.c \
@@ -92,6 +93,7 @@
sched.c \
scsi.c \
seccomp.c \
+ sigaltstack.c \
signal.c \
sigreturn.c \
sock.c \
@@ -164,77 +166,173 @@
linux/32/syscallent.h \
linux/64/ioctls_inc.h \
linux/64/syscallent.h \
+ linux/aarch64/arch_regs.c \
linux/aarch64/arch_regs.h \
+ linux/aarch64/arch_sigreturn.c \
linux/aarch64/errnoent1.h \
+ linux/aarch64/get_error.c \
+ linux/aarch64/get_scno.c \
+ linux/aarch64/get_syscall_args.c\
linux/aarch64/ioctls_arch0.h \
linux/aarch64/ioctls_arch1.h \
linux/aarch64/ioctls_inc0.h \
linux/aarch64/ioctls_inc1.h \
+ linux/aarch64/print_pc.c \
linux/aarch64/signalent1.h \
linux/aarch64/syscallent.h \
linux/aarch64/syscallent1.h \
+ linux/alpha/arch_getrval2.c \
+ linux/alpha/arch_regs.c \
linux/alpha/arch_regs.h \
+ linux/alpha/arch_sigreturn.c \
linux/alpha/errnoent.h \
+ linux/alpha/get_error.c \
+ linux/alpha/get_scno.c \
+ linux/alpha/get_syscall_args.c \
+ linux/alpha/get_syscall_result.c\
linux/alpha/ioctls_arch0.h \
linux/alpha/ioctls_inc0.h \
+ linux/alpha/print_pc.c \
linux/alpha/signalent.h \
linux/alpha/syscallent.h \
linux/alpha/userent.h \
+ linux/arc/arch_regs.c \
+ linux/arc/get_error.c \
+ linux/arc/get_scno.c \
+ linux/arc/get_syscall_args.c \
linux/arc/ioctls_arch0.h \
linux/arc/ioctls_inc0.h \
+ linux/arc/print_pc.c \
linux/arc/syscallent.h \
linux/arch_regs.h \
+ linux/arch_sigreturn.c \
+ linux/arm/arch_regs.c \
linux/arm/arch_regs.h \
+ linux/arm/arch_sigreturn.c \
+ linux/arm/get_error.c \
+ linux/arm/get_scno.c \
+ linux/arm/get_syscall_args.c \
linux/arm/ioctls_arch0.h \
linux/arm/ioctls_inc0.h \
+ linux/arm/print_pc.c \
linux/arm/syscallent.h \
linux/arm/userent.h \
+ linux/avr32/arch_regs.c \
+ linux/avr32/get_error.c \
+ linux/avr32/get_scno.c \
+ linux/avr32/get_syscall_args.c \
linux/avr32/ioctls_arch0.h \
linux/avr32/ioctls_inc0.h \
+ linux/avr32/print_pc.c \
linux/avr32/syscallent.h \
linux/avr32/userent.h \
+ linux/bfin/arch_regs.c \
+ linux/bfin/get_error.c \
+ linux/bfin/get_scno.c \
+ linux/bfin/get_syscall_args.c \
+ linux/bfin/get_syscall_result.c \
linux/bfin/ioctls_arch0.h \
linux/bfin/ioctls_inc0.h \
+ linux/bfin/print_pc.c \
linux/bfin/syscallent.h \
linux/bfin/userent.h \
+ linux/crisv10/arch_regs.c \
+ linux/crisv10/arch_sigreturn.c \
+ linux/crisv10/get_error.c \
+ linux/crisv10/get_scno.c \
+ linux/crisv10/get_syscall_args.c \
+ linux/crisv10/get_syscall_result.c \
+ linux/crisv10/print_pc.c \
linux/crisv10/userent.h \
+ linux/crisv32/arch_regs.c \
+ linux/crisv32/arch_sigreturn.c \
+ linux/crisv32/get_error.c \
+ linux/crisv32/get_scno.c \
+ linux/crisv32/get_syscall_args.c \
+ linux/crisv32/get_syscall_result.c \
+ linux/crisv32/print_pc.c \
linux/crisv32/userent.h \
linux/dummy.h \
linux/errnoent.h \
+ linux/hppa/arch_regs.c \
linux/hppa/arch_regs.h \
linux/hppa/errnoent.h \
+ linux/hppa/get_error.c \
+ linux/hppa/get_scno.c \
+ linux/hppa/get_syscall_args.c \
+ linux/hppa/get_syscall_result.c \
linux/hppa/ioctls_arch0.h \
linux/hppa/ioctls_inc0.h \
+ linux/hppa/print_pc.c \
linux/hppa/signalent.h \
linux/hppa/syscallent.h \
+ linux/i386/arch_regs.c \
linux/i386/arch_regs.h \
+ linux/i386/arch_sigreturn.c \
+ linux/i386/get_error.c \
+ linux/i386/get_scno.c \
+ linux/i386/get_syscall_args.c \
linux/i386/ioctls_arch0.h \
linux/i386/ioctls_inc0.h \
+ linux/i386/print_pc.c \
linux/i386/syscallent.h \
linux/i386/userent.h \
linux/i386/userent0.h \
+ linux/ia64/arch_getrval2.c \
+ linux/ia64/arch_regs.c \
linux/ia64/arch_regs.h \
+ linux/ia64/arch_sigreturn.c \
+ linux/ia64/get_error.c \
+ linux/ia64/get_scno.c \
+ linux/ia64/get_syscall_args.c \
linux/ia64/ioctls_arch0.h \
linux/ia64/ioctls_inc0.h \
+ linux/ia64/print_pc.c \
linux/ia64/syscallent.h \
linux/ia64/userent.h \
linux/inet_diag.h \
+ linux/m68k/arch_regs.c \
+ linux/m68k/arch_sigreturn.c \
+ linux/m68k/get_error.c \
+ linux/m68k/get_scno.c \
+ linux/m68k/get_syscall_args.c \
+ linux/m68k/get_syscall_result.c \
linux/m68k/ioctls_arch0.h \
linux/m68k/ioctls_inc0.h \
+ linux/m68k/print_pc.c \
linux/m68k/syscallent.h \
linux/m68k/userent.h \
+ linux/metag/arch_regs.c \
+ linux/metag/get_error.c \
+ linux/metag/get_scno.c \
+ linux/metag/get_syscall_args.c \
linux/metag/ioctls_arch0.h \
linux/metag/ioctls_inc0.h \
+ linux/metag/print_pc.c \
linux/metag/syscallent.h \
+ linux/microblaze/arch_regs.c \
+ linux/microblaze/arch_sigreturn.c \
+ linux/microblaze/get_error.c \
+ linux/microblaze/get_scno.c \
+ linux/microblaze/get_syscall_args.c \
+ linux/microblaze/get_syscall_result.c \
linux/microblaze/ioctls_arch0.h \
linux/microblaze/ioctls_inc0.h \
+ linux/microblaze/print_pc.c \
linux/microblaze/syscallent.h \
linux/microblaze/userent.h \
+ linux/mips/arch_getrval2.c \
+ linux/mips/arch_regs.c \
linux/mips/arch_regs.h \
+ linux/mips/arch_sigreturn.c \
linux/mips/errnoent.h \
linux/mips/genstub.sh \
+ linux/mips/get_error.c \
+ linux/mips/get_scno.c \
+ linux/mips/get_syscall_args.c \
linux/mips/ioctls_arch0.h \
linux/mips/ioctls_inc0.h \
+ linux/mips/print_pc.c \
linux/mips/signalent.h \
linux/mips/syscallent-compat.h \
linux/mips/syscallent-n32.h \
@@ -243,93 +341,145 @@
linux/mips/syscallent.h \
linux/mips/userent.h \
linux/mtd-abi.h \
+ linux/or1k/arch_regs.c \
+ linux/or1k/get_error.c \
+ linux/or1k/get_scno.c \
+ linux/or1k/get_syscall_args.c \
linux/or1k/ioctls_arch0.h \
linux/or1k/ioctls_inc0.h \
+ linux/or1k/print_pc.c \
linux/or1k/syscallent.h \
linux/or1k/userent.h \
linux/personality.h \
+ linux/powerpc/arch_regs.c \
linux/powerpc/arch_regs.h \
+ linux/powerpc/arch_sigreturn.c \
linux/powerpc/errnoent.h \
+ linux/powerpc/get_error.c \
+ linux/powerpc/get_scno.c \
+ linux/powerpc/get_syscall_args.c \
+ linux/powerpc/getregs_old.c \
linux/powerpc/ioctls_arch0.h \
linux/powerpc/ioctls_inc0.h \
+ linux/powerpc/print_pc.c \
linux/powerpc/syscallent.h \
linux/powerpc/userent.h \
+ linux/powerpc64/arch_regs.c \
linux/powerpc64/arch_regs.h \
+ linux/powerpc64/arch_sigreturn.c \
linux/powerpc64/errnoent.h \
linux/powerpc64/errnoent1.h \
+ linux/powerpc64/get_error.c \
+ linux/powerpc64/get_scno.c \
+ linux/powerpc64/get_syscall_args.c \
+ linux/powerpc64/getregs_old.c \
linux/powerpc64/ioctls_arch0.h \
linux/powerpc64/ioctls_arch1.h \
linux/powerpc64/ioctls_inc0.h \
linux/powerpc64/ioctls_inc1.h \
+ linux/powerpc64/print_pc.c \
linux/powerpc64/signalent1.h \
linux/powerpc64/syscallent.h \
linux/powerpc64/syscallent1.h \
linux/powerpc64/userent.h \
linux/ptp_clock.h \
+ linux/s390/arch_regs.c \
linux/s390/arch_regs.h \
+ linux/s390/arch_sigreturn.c \
+ linux/s390/get_error.c \
+ linux/s390/get_scno.c \
+ linux/s390/get_syscall_args.c \
linux/s390/ioctls_arch0.h \
linux/s390/ioctls_inc0.h \
+ linux/s390/print_pc.c \
linux/s390/syscallent.h \
linux/s390/userent.h \
linux/s390/userent0.h \
linux/s390/userent1.h \
+ linux/s390x/arch_regs.c \
linux/s390x/arch_regs.h \
+ linux/s390x/arch_sigreturn.c \
+ linux/s390x/get_error.c \
+ linux/s390x/get_scno.c \
+ linux/s390x/get_syscall_args.c \
linux/s390x/ioctls_arch0.h \
linux/s390x/ioctls_inc0.h \
+ linux/s390x/print_pc.c \
linux/s390x/syscallent.h \
linux/s390x/userent.h \
+ linux/sh/arch_getrval2.c \
+ linux/sh/arch_regs.c \
+ linux/sh/get_error.c \
+ linux/sh/get_scno.c \
+ linux/sh/get_syscall_args.c \
+ linux/sh/get_syscall_result.c \
linux/sh/ioctls_arch0.h \
linux/sh/ioctls_inc0.h \
+ linux/sh/print_pc.c \
linux/sh/syscallent.h \
linux/sh/userent.h \
linux/sh/userent0.h \
+ linux/sh64/arch_regs.c \
linux/sh64/arch_regs.h \
+ linux/sh64/get_error.c \
+ linux/sh64/get_scno.c \
+ linux/sh64/get_syscall_args.c \
+ linux/sh64/get_syscall_result.c \
linux/sh64/ioctls_arch0.h \
linux/sh64/ioctls_inc0.h \
+ linux/sh64/print_pc.c \
linux/sh64/syscallent.h \
linux/sh64/userent.h \
linux/signalent.h \
linux/sock_diag.h \
+ linux/sparc/arch_getrval2.c \
+ linux/sparc/arch_regs.c \
linux/sparc/arch_regs.h \
- linux/sparc/dummy2.h \
+ linux/sparc/arch_sigreturn.c \
linux/sparc/errnoent.h \
- linux/sparc/errnoent1.h \
linux/sparc/gen.pl \
- linux/sparc/ioctlent1.h \
+ linux/sparc/get_error.c \
+ linux/sparc/get_scno.c \
+ linux/sparc/get_syscall_args.c \
linux/sparc/ioctls_arch0.h \
linux/sparc/ioctls_inc0.h \
+ linux/sparc/print_pc.c \
linux/sparc/signalent.h \
- linux/sparc/signalent1.h \
- linux/sparc/syscall1.h \
linux/sparc/syscallent.h \
- linux/sparc/syscallent1.h \
linux/sparc/userent.h \
+ linux/sparc64/arch_getrval2.c \
+ linux/sparc64/arch_regs.c \
linux/sparc64/arch_regs.h \
- linux/sparc64/dummy2.h \
+ linux/sparc64/arch_sigreturn.c \
linux/sparc64/errnoent.h \
linux/sparc64/errnoent1.h \
- linux/sparc64/errnoent2.h \
- linux/sparc64/ioctlent1.h \
+ linux/sparc64/get_error.c \
+ linux/sparc64/get_scno.c \
+ linux/sparc64/get_syscall_args.c\
linux/sparc64/ioctls_arch0.h \
- linux/sparc64/ioctls_arch2.h \
+ linux/sparc64/ioctls_arch1.h \
linux/sparc64/ioctls_inc0.h \
- linux/sparc64/ioctls_inc2.h \
+ linux/sparc64/ioctls_inc1.h \
+ linux/sparc64/print_pc.c \
linux/sparc64/signalent.h \
linux/sparc64/signalent1.h \
- linux/sparc64/signalent2.h \
- linux/sparc64/syscall1.h \
linux/sparc64/syscallent.h \
linux/sparc64/syscallent1.h \
- linux/sparc64/syscallent2.h \
linux/sparc64/userent.h \
linux/subcall.h \
linux/syscall.h \
+ linux/tile/arch_regs.c \
linux/tile/arch_regs.h \
+ linux/tile/arch_sigreturn.c \
linux/tile/errnoent1.h \
+ linux/tile/get_error.c \
+ linux/tile/get_scno.c \
+ linux/tile/get_syscall_args.c \
linux/tile/ioctls_arch0.h \
linux/tile/ioctls_arch1.h \
linux/tile/ioctls_inc0.h \
linux/tile/ioctls_inc1.h \
+ linux/tile/print_pc.c \
linux/tile/signalent1.h \
linux/tile/syscallent.h \
linux/tile/syscallent1.h \
@@ -338,34 +488,53 @@
linux/unix_diag.h \
linux/userent.h \
linux/userent0.h \
+ linux/x32/arch_regs.c \
linux/x32/arch_regs.h \
+ linux/x32/arch_sigreturn.c \
linux/x32/errnoent1.h \
+ linux/x32/get_error.c \
+ linux/x32/get_scno.c \
+ linux/x32/get_syscall_args.c \
linux/x32/ioctls_arch0.h \
linux/x32/ioctls_arch1.h \
linux/x32/ioctls_inc0.h \
linux/x32/ioctls_inc1.h \
+ linux/x32/print_pc.c \
linux/x32/signalent1.h \
linux/x32/syscallent.h \
linux/x32/syscallent1.h \
linux/x32/userent.h \
+ linux/x86_64/arch_regs.c \
linux/x86_64/arch_regs.h \
+ linux/x86_64/arch_sigreturn.c \
linux/x86_64/errnoent1.h \
linux/x86_64/errnoent2.h \
linux/x86_64/gentab.pl \
+ linux/x86_64/get_error.c \
+ linux/x86_64/get_scno.c \
+ linux/x86_64/get_syscall_args.c \
+ linux/x86_64/getregs_old.c \
linux/x86_64/ioctls_arch0.h \
linux/x86_64/ioctls_arch1.h \
linux/x86_64/ioctls_arch2.h \
linux/x86_64/ioctls_inc0.h \
linux/x86_64/ioctls_inc1.h \
linux/x86_64/ioctls_inc2.h \
+ linux/x86_64/print_pc.c \
linux/x86_64/signalent1.h \
linux/x86_64/signalent2.h \
linux/x86_64/syscallent.h \
linux/x86_64/syscallent1.h \
linux/x86_64/syscallent2.h \
linux/x86_64/userent.h \
+ linux/xtensa/arch_regs.c \
+ linux/xtensa/get_error.c \
+ linux/xtensa/get_scno.c \
+ linux/xtensa/get_syscall_args.c \
+ linux/xtensa/get_syscall_result.c \
linux/xtensa/ioctls_arch0.h \
linux/xtensa/ioctls_inc0.h \
+ linux/xtensa/print_pc.c \
linux/xtensa/syscallent.h \
linux/xtensa/userent.h \
maint/ioctls_gen.sh \
diff --git a/capability.c b/capability.c
index bbd5544..26d9c66 100644
--- a/capability.c
+++ b/capability.c
@@ -103,7 +103,7 @@
else
len = 1;
- if (umoven(tcp, addr, len * sizeof(data[0]), (char *) data) < 0) {
+ if (umoven(tcp, addr, len * sizeof(data[0]), data) < 0) {
tprintf("%#lx", addr);
return;
}
diff --git a/configure.ac b/configure.ac
index e73958c..d829e18 100644
--- a/configure.ac
+++ b/configure.ac
@@ -228,6 +228,7 @@
fputs_unlocked
if_indextoname
inet_ntop
+ pipe2
prctl
preadv
process_vm_readv
diff --git a/defs.h b/defs.h
index dad4fe8..34f1603 100644
--- a/defs.h
+++ b/defs.h
@@ -67,8 +67,46 @@
extern char *stpcpy(char *dst, const char *src);
#endif
-#if !defined __GNUC__
-# define __attribute__(x) /*nothing*/
+#if defined __GNUC__ && defined __GNUC_MINOR__
+# define GNUC_PREREQ(maj, min) \
+ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+#else
+# define __attribute__(x) /* empty */
+# define GNUC_PREREQ(maj, min) 0
+#endif
+
+#if GNUC_PREREQ(2, 5)
+# define ATTRIBUTE_NORETURN __attribute__((__noreturn__))
+#else
+# define ATTRIBUTE_NORETURN /* empty */
+#endif
+
+#if GNUC_PREREQ(2, 7)
+# define ATTRIBUTE_FORMAT(args) __attribute__((__format__ args))
+# define ATTRIBUTE_ALIGNED(arg) __attribute__((__aligned__(arg)))
+# define ATTRIBUTE_PACKED __attribute__((__packed__))
+#else
+# define ATTRIBUTE_FORMAT(args) /* empty */
+# define ATTRIBUTE_ALIGNED(arg) /* empty */
+# define ATTRIBUTE_PACKED /* empty */
+#endif
+
+#if GNUC_PREREQ(3, 0)
+# define ATTRIBUTE_MALLOC __attribute__((__malloc__))
+#else
+# define ATTRIBUTE_MALLOC /* empty */
+#endif
+
+#if GNUC_PREREQ(3, 1)
+# define ATTRIBUTE_NOINLINE __attribute__((__noinline__))
+#else
+# define ATTRIBUTE_NOINLINE /* empty */
+#endif
+
+#if GNUC_PREREQ(4, 3)
+# define ATTRIBUTE_ALLOC_SIZE(args) __attribute__((__alloc_size__ args))
+#else
+# define ATTRIBUTE_ALLOC_SIZE(args) /* empty */
#endif
#ifndef offsetof
@@ -152,14 +190,11 @@
#if defined(SPARC) || defined(SPARC64)
# define PERSONALITY0_WORDSIZE 4
-# define PERSONALITY1_WORDSIZE 4
# if defined(SPARC64)
-# define SUPPORTED_PERSONALITIES 3
-# define PERSONALITY2_WORDSIZE 8
-# else
# define SUPPORTED_PERSONALITIES 2
-# endif /* SPARC64 */
-#endif /* SPARC[64] */
+# define PERSONALITY1_WORDSIZE 8
+# endif
+#endif
#ifdef X86_64
# define SUPPORTED_PERSONALITIES 3
@@ -243,11 +278,10 @@
FILE *outf; /* Output file for this process */
const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */
const struct_sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */
+ const struct_sysent *s_prev_ent; /* for "resuming interrupted SYSCALL" msg */
struct timeval stime; /* System time usage as of last process wait */
struct timeval dtime; /* Delta for system time usage */
struct timeval etime; /* Syscall entry time */
- /* Support for tracing forked processes: */
- long inst[2]; /* Saved clone args (badly named) */
#ifdef USE_LIBUNWIND
struct UPT_info* libunwind_ui;
@@ -392,11 +426,13 @@
enum bitness_t { BITNESS_CURRENT = 0, BITNESS_32 };
-void error_msg(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
-void perror_msg(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
-void error_msg_and_die(const char *fmt, ...) __attribute__ ((noreturn, format(printf, 1, 2)));
-void perror_msg_and_die(const char *fmt, ...) __attribute__ ((noreturn, format(printf, 1, 2)));
-void die_out_of_memory(void) __attribute__ ((noreturn));
+void error_msg(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
+void perror_msg(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
+void error_msg_and_die(const char *fmt, ...)
+ ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
+void perror_msg_and_die(const char *fmt, ...)
+ ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
+void die_out_of_memory(void) ATTRIBUTE_NORETURN;
#if USE_CUSTOM_PRINTF
/*
@@ -418,14 +454,20 @@
extern void clear_regs(void);
extern void get_regs(pid_t pid);
+extern int get_scno(struct tcb *tcp);
-extern int umoven(struct tcb *, long, unsigned int, char *);
+extern int umoven(struct tcb *, long, unsigned int, void *);
#define umove(pid, addr, objp) \
- umoven((pid), (addr), sizeof(*(objp)), (char *) (objp))
+ umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
extern int umovestr(struct tcb *, long, unsigned int, char *);
extern int upeek(int pid, long, long *);
-#if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH)
+
+#if defined ALPHA || defined IA64 || defined MIPS \
+ || defined SH || defined SPARC || defined SPARC64
+# define HAVE_GETRVAL2
extern long getrval2(struct tcb *);
+#else
+# undef HAVE_GETRVAL2
#endif
extern const char *signame(const int);
@@ -436,6 +478,7 @@
extern const char *xlookup(const struct xlat *, const unsigned int);
extern const char *xlat_search(const struct xlat *, const size_t, const unsigned int);
+extern unsigned long get_pagesize(void);
extern int string_to_uint(const char *str);
extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits);
@@ -456,7 +499,7 @@
#endif
extern int getllval(struct tcb *, unsigned long long *, int);
extern int printllval(struct tcb *, const char *, int)
- __attribute__ ((format (printf, 2, 0)));
+ ATTRIBUTE_FORMAT((printf, 2, 0));
extern void printxval(const struct xlat *, const unsigned int, const char *);
extern int printargs(struct tcb *);
@@ -473,9 +516,9 @@
extern void dumpstr(struct tcb *, long, int);
extern void printstr(struct tcb *, long, long);
extern void printnum_int(struct tcb *, long, const char *)
- __attribute__ ((format (printf, 3, 0)));
+ ATTRIBUTE_FORMAT((printf, 3, 0));
extern void printnum_long(struct tcb *, long, const char *)
- __attribute__ ((format (printf, 3, 0)));
+ ATTRIBUTE_FORMAT((printf, 3, 0));
extern void printpath(struct tcb *, long);
extern void printpathn(struct tcb *, long, unsigned int);
#define TIMESPEC_TEXT_BUFSIZE (sizeof(long)*3 * 2 + sizeof("{%u, %u}"))
@@ -488,7 +531,7 @@
extern char *sprinttv(char *, struct tcb *, long, enum bitness_t, int special);
extern void print_timespec(struct tcb *, long);
extern void sprint_timespec(char *, struct tcb *, long);
-extern void printsiginfo(const siginfo_t *, int);
+extern void printsiginfo(const siginfo_t *, bool);
extern void printsiginfo_at(struct tcb *tcp, long addr);
extern void printfd(struct tcb *, int);
extern bool print_sockaddr_by_inode(const unsigned long, const char *);
@@ -567,7 +610,7 @@
extern void printleader(struct tcb *);
extern void line_ended(void);
extern void tabto(void);
-extern void tprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
+extern void tprintf(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
extern void tprints(const char *str);
#if SUPPORTED_PERSONALITIES > 1
diff --git a/desc.c b/desc.c
index 24de51d..485c802 100644
--- a/desc.c
+++ b/desc.c
@@ -353,7 +353,7 @@
tprintf(", %#lx", arg);
continue;
}
- if (umoven(tcp, arg, fdsize, (char *) fds) < 0) {
+ if (umoven(tcp, arg, fdsize, fds) < 0) {
tprints(", [?]");
continue;
}
@@ -397,7 +397,7 @@
int first = 1;
arg = args[i+1];
- if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0)
+ if (!arg || umoven(tcp, arg, fdsize, fds) < 0)
continue;
for (j = 0;; j++) {
j = next_set_bit(fds, j, nfds);
@@ -445,7 +445,7 @@
{
long args[5];
- if (umoven(tcp, tcp->u_arg[0], sizeof args, (char *) args) < 0) {
+ if (umoven(tcp, tcp->u_arg[0], sizeof args, args) < 0) {
tprints("[...]");
return 0;
}
diff --git a/evdev.c b/evdev.c
index 9a7430d..e06f9c1 100644
--- a/evdev.c
+++ b/evdev.c
@@ -28,6 +28,8 @@
#include "defs.h"
+#include <linux/ioctl.h>
+
#ifdef HAVE_LINUX_INPUT_H
#include <linux/input.h>
#include "xlat/evdev_abs.h"
diff --git a/file.c b/file.c
index ae74d5a..9dc7595 100644
--- a/file.c
+++ b/file.c
@@ -305,7 +305,6 @@
* Linux x86_64 and x32 have unified `struct stat' but their i386 personality
* needs `struct stat64'.
* linux/arch/x86/include/uapi/asm/stat.h defines `struct stat64' only for i386.
- * __GNUC__ is needed for the required __attribute__ below.
*
* Similarly, aarch64 has a unified `struct stat' but its arm personality
* needs `struct stat64' (unlike x86, it shouldn't be packed).
@@ -332,7 +331,7 @@
unsigned long long st_ino;
}
# if defined X86_64 || defined X32
- __attribute__((packed))
+ ATTRIBUTE_PACKED
# define STAT64_SIZE 96
# else
# define STAT64_SIZE 104
diff --git a/io.c b/io.c
index 3626c77..0618509 100644
--- a/io.c
+++ b/io.c
@@ -112,7 +112,7 @@
tprints("...");
break;
}
- if (umoven(tcp, cur, sizeof_iov, (char *) &iov) < 0) {
+ if (umoven(tcp, cur, sizeof_iov, &iov) < 0) {
tprints("?");
failed = 1;
break;
diff --git a/ioctl.c b/ioctl.c
index 46f8334..c67d048 100644
--- a/ioctl.c
+++ b/ioctl.c
@@ -29,7 +29,7 @@
*/
#include "defs.h"
-#include <asm/ioctl.h>
+#include <linux/ioctl.h>
#include "xlat/ioctl_dirs.h"
#ifdef HAVE_LINUX_INPUT_H
diff --git a/ioctlsort.c b/ioctlsort.c
index 333556c..9c31691 100644
--- a/ioctlsort.c
+++ b/ioctlsort.c
@@ -33,7 +33,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <asm/ioctl.h>
+#include <linux/ioctl.h>
struct ioctlent {
const char *info;
diff --git a/kexec.c b/kexec.c
index e277668..6bec51c 100644
--- a/kexec.c
+++ b/kexec.c
@@ -58,8 +58,7 @@
for (i = 0; i < len; ++i) {
if (i)
tprints(", ");
- if (umoven(tcp, addr + i * sizeof_seg, sizeof_seg,
- (char *) &seg) < 0) {
+ if (umoven(tcp, addr + i * sizeof_seg, sizeof_seg, &seg) < 0) {
tprints("?");
failed = 1;
break;
diff --git a/linux/aarch64/arch_regs.c b/linux/aarch64/arch_regs.c
new file mode 100644
index 0000000..3b9c2f6
--- /dev/null
+++ b/linux/aarch64/arch_regs.c
@@ -0,0 +1,37 @@
+struct arm_pt_regs {
+ int uregs[18];
+};
+#define ARM_cpsr uregs[16]
+#define ARM_pc uregs[15]
+#define ARM_lr uregs[14]
+#define ARM_sp uregs[13]
+#define ARM_ip uregs[12]
+#define ARM_fp uregs[11]
+#define ARM_r10 uregs[10]
+#define ARM_r9 uregs[9]
+#define ARM_r8 uregs[8]
+#define ARM_r7 uregs[7]
+#define ARM_r6 uregs[6]
+#define ARM_r5 uregs[5]
+#define ARM_r4 uregs[4]
+#define ARM_r3 uregs[3]
+#define ARM_r2 uregs[2]
+#define ARM_r1 uregs[1]
+#define ARM_r0 uregs[0]
+#define ARM_ORIG_r0 uregs[17]
+
+static union {
+ struct user_pt_regs aarch64_r;
+ struct arm_pt_regs arm_r;
+} arm_regs_union;
+#define aarch64_regs arm_regs_union.aarch64_r
+#define arm_regs arm_regs_union.arm_r
+
+uint64_t *const aarch64_sp_ptr = (uint64_t *) &aarch64_regs.sp;
+uint32_t *const arm_sp_ptr = (uint32_t *) &arm_regs.ARM_sp;
+static struct iovec aarch64_io = {
+ .iov_base = &arm_regs_union
+};
+
+#define ARCH_REGS_FOR_GETREGSET arm_regs_union
+#define ARCH_IOVEC_FOR_GETREGSET aarch64_io
diff --git a/linux/aarch64/arch_sigreturn.c b/linux/aarch64/arch_sigreturn.c
new file mode 100644
index 0000000..f0e29c2
--- /dev/null
+++ b/linux/aarch64/arch_sigreturn.c
@@ -0,0 +1 @@
+#include "arm/arch_sigreturn.c"
diff --git a/linux/aarch64/get_error.c b/linux/aarch64/get_error.c
new file mode 100644
index 0000000..7dd6779
--- /dev/null
+++ b/linux/aarch64/get_error.c
@@ -0,0 +1,10 @@
+if (tcp->currpers == 1) {
+ if (check_errno && is_negated_errno(aarch64_regs.regs[0])) {
+ tcp->u_rval = -1;
+ tcp->u_error = -aarch64_regs.regs[0];
+ } else {
+ tcp->u_rval = aarch64_regs.regs[0];
+ }
+} else {
+#include "arm/get_error.c"
+}
diff --git a/linux/aarch64/get_scno.c b/linux/aarch64/get_scno.c
new file mode 100644
index 0000000..610b38d
--- /dev/null
+++ b/linux/aarch64/get_scno.c
@@ -0,0 +1,14 @@
+switch (aarch64_io.iov_len) {
+ case sizeof(aarch64_regs):
+ /* We are in 64-bit mode */
+ scno = aarch64_regs.regs[8];
+ update_personality(tcp, 1);
+ break;
+ case sizeof(arm_regs):
+ /* We are in 32-bit mode */
+ /* Note: we don't support OABI, unlike 32-bit ARM build */
+ scno = arm_regs.ARM_r7;
+ scno = shuffle_scno(scno);
+ update_personality(tcp, 0);
+ break;
+}
diff --git a/linux/aarch64/get_syscall_args.c b/linux/aarch64/get_syscall_args.c
new file mode 100644
index 0000000..41ce8b4
--- /dev/null
+++ b/linux/aarch64/get_syscall_args.c
@@ -0,0 +1,10 @@
+if (tcp->currpers == 1) {
+ tcp->u_arg[0] = aarch64_regs.regs[0];
+ tcp->u_arg[1] = aarch64_regs.regs[1];
+ tcp->u_arg[2] = aarch64_regs.regs[2];
+ tcp->u_arg[3] = aarch64_regs.regs[3];
+ tcp->u_arg[4] = aarch64_regs.regs[4];
+ tcp->u_arg[5] = aarch64_regs.regs[5];
+} else {
+#include "arm/get_syscall_args.c"
+}
diff --git a/linux/aarch64/print_pc.c b/linux/aarch64/print_pc.c
new file mode 100644
index 0000000..23c0e5c
--- /dev/null
+++ b/linux/aarch64/print_pc.c
@@ -0,0 +1,4 @@
+if (aarch64_io.iov_len == sizeof(arm_regs))
+ tprintf(fmt, (unsigned long) arm_regs.ARM_pc);
+else
+ tprintf(fmt, (unsigned long) aarch64_regs.pc);
diff --git a/linux/alpha/arch_getrval2.c b/linux/alpha/arch_getrval2.c
new file mode 100644
index 0000000..90ee392
--- /dev/null
+++ b/linux/alpha/arch_getrval2.c
@@ -0,0 +1,8 @@
+long
+getrval2(struct tcb *tcp)
+{
+ long r20;
+ if (upeek(tcp->pid, 20, &r20) < 0)
+ return -1;
+ return r20;
+}
diff --git a/linux/alpha/arch_regs.c b/linux/alpha/arch_regs.c
new file mode 100644
index 0000000..e2783ca
--- /dev/null
+++ b/linux/alpha/arch_regs.c
@@ -0,0 +1,2 @@
+static long alpha_r0;
+static long alpha_a3;
diff --git a/linux/alpha/arch_sigreturn.c b/linux/alpha/arch_sigreturn.c
new file mode 100644
index 0000000..278bae1
--- /dev/null
+++ b/linux/alpha/arch_sigreturn.c
@@ -0,0 +1,9 @@
+long addr;
+
+if (upeek(tcp->pid, REG_FP, &addr) < 0)
+ return 0;
+addr += offsetof(struct sigcontext, sc_mask);
+
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/alpha/get_error.c b/linux/alpha/get_error.c
new file mode 100644
index 0000000..5b615a5
--- /dev/null
+++ b/linux/alpha/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && alpha_a3) {
+ tcp->u_rval = -1;
+ tcp->u_error = alpha_r0;
+} else {
+ tcp->u_rval = alpha_r0;
+}
diff --git a/linux/alpha/get_scno.c b/linux/alpha/get_scno.c
new file mode 100644
index 0000000..4959e15
--- /dev/null
+++ b/linux/alpha/get_scno.c
@@ -0,0 +1,16 @@
+if (upeek(tcp->pid, REG_A3, &alpha_a3) < 0)
+ return -1;
+if (upeek(tcp->pid, REG_R0, &scno) < 0)
+ return -1;
+
+/*
+ * Do some sanity checks to figure out if it's
+ * really a syscall entry
+ */
+if (!SCNO_IN_RANGE(scno)) {
+ if (alpha_a3 == 0 || alpha_a3 == -1) {
+ if (debug_flag)
+ fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
+ return 0;
+ }
+}
diff --git a/linux/alpha/get_syscall_args.c b/linux/alpha/get_syscall_args.c
new file mode 100644
index 0000000..7f7d493
--- /dev/null
+++ b/linux/alpha/get_syscall_args.c
@@ -0,0 +1,5 @@
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, REG_A0+i, &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/alpha/get_syscall_result.c b/linux/alpha/get_syscall_result.c
new file mode 100644
index 0000000..11e2736
--- /dev/null
+++ b/linux/alpha/get_syscall_result.c
@@ -0,0 +1,4 @@
+if (upeek(tcp->pid, REG_A3, &alpha_a3) < 0)
+ return -1;
+if (upeek(tcp->pid, REG_R0, &alpha_r0) < 0)
+ return -1;
diff --git a/linux/alpha/print_pc.c b/linux/alpha/print_pc.c
new file mode 100644
index 0000000..c0232e5
--- /dev/null
+++ b/linux/alpha/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, REG_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/arc/arch_regs.c b/linux/arc/arch_regs.c
new file mode 100644
index 0000000..0d57ae4
--- /dev/null
+++ b/linux/arc/arch_regs.c
@@ -0,0 +1,2 @@
+static struct user_regs_struct arc_regs;
+#define ARCH_REGS_FOR_GETREGSET arc_regs
diff --git a/linux/arc/get_error.c b/linux/arc/get_error.c
new file mode 100644
index 0000000..1741c17
--- /dev/null
+++ b/linux/arc/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(arc_regs.scratch.r0)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -arc_regs.scratch.r0;
+} else {
+ tcp->u_rval = arc_regs.scratch.r0;
+}
diff --git a/linux/arc/get_scno.c b/linux/arc/get_scno.c
new file mode 100644
index 0000000..cc45d46
--- /dev/null
+++ b/linux/arc/get_scno.c
@@ -0,0 +1 @@
+scno = arc_regs.scratch.r8;
diff --git a/linux/arc/get_syscall_args.c b/linux/arc/get_syscall_args.c
new file mode 100644
index 0000000..bb003c8
--- /dev/null
+++ b/linux/arc/get_syscall_args.c
@@ -0,0 +1,5 @@
+long *arc_args = &arc_regs.scratch.r0;
+unsigned int i;
+
+for (i = 0; i < MAX_ARGS; ++i)
+ tcp->u_arg[i] = *arc_args--;
diff --git a/linux/arc/print_pc.c b/linux/arc/print_pc.c
new file mode 100644
index 0000000..f904544
--- /dev/null
+++ b/linux/arc/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, arc_regs.efa);
diff --git a/linux/arch_sigreturn.c b/linux/arch_sigreturn.c
new file mode 100644
index 0000000..80ec984
--- /dev/null
+++ b/linux/arch_sigreturn.c
@@ -0,0 +1 @@
+#warning sigreturn/rt_sigreturn signal mask decoding is not implemented for this architecture
diff --git a/linux/arm/arch_regs.c b/linux/arm/arch_regs.c
new file mode 100644
index 0000000..ca1fb6d
--- /dev/null
+++ b/linux/arm/arch_regs.c
@@ -0,0 +1,4 @@
+static struct pt_regs arm_regs;
+long *const arm_sp_ptr = &arm_regs.ARM_sp;
+
+#define ARCH_REGS_FOR_GETREGS arm_regs
diff --git a/linux/arm/arch_sigreturn.c b/linux/arm/arch_sigreturn.c
new file mode 100644
index 0000000..046e19a
--- /dev/null
+++ b/linux/arm/arch_sigreturn.c
@@ -0,0 +1,15 @@
+#define SIZEOF_STRUCT_SIGINFO 128
+#define SIZEOF_STRUCT_SIGCONTEXT (21 * 4)
+#define OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK (5 * 4 + SIZEOF_STRUCT_SIGCONTEXT)
+
+const long addr =
+#ifdef AARCH64
+ current_personality == 1 ?
+ (*aarch64_sp_ptr + SIZEOF_STRUCT_SIGINFO +
+ offsetof(struct ucontext, uc_sigmask)) :
+#endif
+ (*arm_sp_ptr +
+ OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK);
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/arm/get_error.c b/linux/arm/get_error.c
new file mode 100644
index 0000000..d2ae09b
--- /dev/null
+++ b/linux/arm/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(arm_regs.ARM_r0)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -arm_regs.ARM_r0;
+} else {
+ tcp->u_rval = arm_regs.ARM_r0;
+}
diff --git a/linux/arm/get_scno.c b/linux/arm/get_scno.c
new file mode 100644
index 0000000..f9dcd65
--- /dev/null
+++ b/linux/arm/get_scno.c
@@ -0,0 +1,46 @@
+/* Note: we support only 32-bit CPUs, not 26-bit */
+
+#if !defined(__ARM_EABI__) || ENABLE_ARM_OABI
+if (arm_regs.ARM_cpsr & 0x20) {
+ /* Thumb mode */
+ goto scno_in_r7;
+}
+/* ARM mode */
+/* Check EABI/OABI by examining SVC insn's low 24 bits */
+errno = 0;
+scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
+if (errno)
+ return -1;
+/* EABI syscall convention? */
+if ((unsigned long) scno != 0xef000000) {
+ /* No, it's OABI */
+ if ((scno & 0x0ff00000) != 0x0f900000) {
+ fprintf(stderr, "pid %d unknown syscall trap 0x%08lx\n",
+ tcp->pid, scno);
+ return -1;
+ }
+ /* Fixup the syscall number */
+ scno &= 0x000fffff;
+} else {
+scno_in_r7:
+ scno = arm_regs.ARM_r7;
+}
+#else /* __ARM_EABI__ || !ENABLE_ARM_OABI */
+
+scno = arm_regs.ARM_r7;
+
+#endif
+
+scno = shuffle_scno(scno);
+
+/*
+ * Do some sanity checks to figure out
+ * whether it's really a syscall entry.
+ */
+if (arm_regs.ARM_ip && !SCNO_IN_RANGE(scno)) {
+ if (debug_flag)
+ fprintf(stderr,
+ "pid %d stray syscall exit: ARM_ip = %ld, scno = %ld\n",
+ tcp->pid, arm_regs.ARM_ip, shuffle_scno(scno));
+ return 0;
+}
diff --git a/linux/arm/get_syscall_args.c b/linux/arm/get_syscall_args.c
new file mode 100644
index 0000000..1bd4faf
--- /dev/null
+++ b/linux/arm/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = arm_regs.uregs[0];
+tcp->u_arg[1] = arm_regs.uregs[1];
+tcp->u_arg[2] = arm_regs.uregs[2];
+tcp->u_arg[3] = arm_regs.uregs[3];
+tcp->u_arg[4] = arm_regs.uregs[4];
+tcp->u_arg[5] = arm_regs.uregs[5];
diff --git a/linux/arm/print_pc.c b/linux/arm/print_pc.c
new file mode 100644
index 0000000..b9d9622
--- /dev/null
+++ b/linux/arm/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, arm_regs.ARM_pc);
diff --git a/linux/avr32/arch_regs.c b/linux/avr32/arch_regs.c
new file mode 100644
index 0000000..aab0338
--- /dev/null
+++ b/linux/avr32/arch_regs.c
@@ -0,0 +1,2 @@
+static struct pt_regs avr32_regs;
+#define ARCH_REGS_FOR_GETREGS avr32_regs
diff --git a/linux/avr32/get_error.c b/linux/avr32/get_error.c
new file mode 100644
index 0000000..ef44584
--- /dev/null
+++ b/linux/avr32/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(avr32_regs.r12)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -avr32_regs.r12;
+} else {
+ tcp->u_rval = avr32_regs.r12;
+}
diff --git a/linux/avr32/get_scno.c b/linux/avr32/get_scno.c
new file mode 100644
index 0000000..0142329
--- /dev/null
+++ b/linux/avr32/get_scno.c
@@ -0,0 +1 @@
+scno = avr32_regs.r8;
diff --git a/linux/avr32/get_syscall_args.c b/linux/avr32/get_syscall_args.c
new file mode 100644
index 0000000..2e3cd3b
--- /dev/null
+++ b/linux/avr32/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = avr32_regs.r12;
+tcp->u_arg[1] = avr32_regs.r11;
+tcp->u_arg[2] = avr32_regs.r10;
+tcp->u_arg[3] = avr32_regs.r9;
+tcp->u_arg[4] = avr32_regs.r5;
+tcp->u_arg[5] = avr32_regs.r3;
diff --git a/linux/avr32/print_pc.c b/linux/avr32/print_pc.c
new file mode 100644
index 0000000..ca293e6
--- /dev/null
+++ b/linux/avr32/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, avr32_regs.pc);
diff --git a/linux/bfin/arch_regs.c b/linux/bfin/arch_regs.c
new file mode 100644
index 0000000..f6f4204
--- /dev/null
+++ b/linux/bfin/arch_regs.c
@@ -0,0 +1 @@
+static long bfin_r0;
diff --git a/linux/bfin/get_error.c b/linux/bfin/get_error.c
new file mode 100644
index 0000000..d7ff247
--- /dev/null
+++ b/linux/bfin/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(bfin_r0)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -bfin_r0;
+} else {
+ tcp->u_rval = bfin_r0;
+}
diff --git a/linux/bfin/get_scno.c b/linux/bfin/get_scno.c
new file mode 100644
index 0000000..dfdb0a7
--- /dev/null
+++ b/linux/bfin/get_scno.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, PT_ORIG_P0, &scno))
+ return -1;
diff --git a/linux/bfin/get_syscall_args.c b/linux/bfin/get_syscall_args.c
new file mode 100644
index 0000000..ac6e6cd
--- /dev/null
+++ b/linux/bfin/get_syscall_args.c
@@ -0,0 +1,6 @@
+static const int argreg[MAX_ARGS] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 };
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, argreg[i], &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/bfin/get_syscall_result.c b/linux/bfin/get_syscall_result.c
new file mode 100644
index 0000000..c9d94d4
--- /dev/null
+++ b/linux/bfin/get_syscall_result.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, PT_R0, &bfin_r0) < 0)
+ return -1;
diff --git a/linux/bfin/print_pc.c b/linux/bfin/print_pc.c
new file mode 100644
index 0000000..b1eef14
--- /dev/null
+++ b/linux/bfin/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, PT_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/crisv10/arch_regs.c b/linux/crisv10/arch_regs.c
new file mode 100644
index 0000000..573f593
--- /dev/null
+++ b/linux/crisv10/arch_regs.c
@@ -0,0 +1 @@
+static long cris_r10;
diff --git a/linux/crisv10/arch_sigreturn.c b/linux/crisv10/arch_sigreturn.c
new file mode 100644
index 0000000..b9e6a24
--- /dev/null
+++ b/linux/crisv10/arch_sigreturn.c
@@ -0,0 +1,11 @@
+long regs[PT_MAX + 1];
+
+if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long)regs) < 0) {
+ perror_msg("sigreturn: PTRACE_GETREGS");
+ return 0;
+}
+const long addr = regs[PT_USP] + offsetof(struct sigcontext, oldmask);
+
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/crisv10/get_error.c b/linux/crisv10/get_error.c
new file mode 100644
index 0000000..3f947ae
--- /dev/null
+++ b/linux/crisv10/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(cris_r10)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -cris_r10;
+} else {
+ tcp->u_rval = cris_r10;
+}
diff --git a/linux/crisv10/get_scno.c b/linux/crisv10/get_scno.c
new file mode 100644
index 0000000..5bbbe8b
--- /dev/null
+++ b/linux/crisv10/get_scno.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, 4*PT_R9, &scno) < 0)
+ return -1;
diff --git a/linux/crisv10/get_syscall_args.c b/linux/crisv10/get_syscall_args.c
new file mode 100644
index 0000000..66b5ac7
--- /dev/null
+++ b/linux/crisv10/get_syscall_args.c
@@ -0,0 +1,9 @@
+static const int crisregs[MAX_ARGS] = {
+ 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
+ 4*PT_R13 , 4*PT_MOF, 4*PT_SRP
+};
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, crisregs[i], &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/crisv10/get_syscall_result.c b/linux/crisv10/get_syscall_result.c
new file mode 100644
index 0000000..53b087a
--- /dev/null
+++ b/linux/crisv10/get_syscall_result.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, 4*PT_R10, &cris_r10) < 0)
+ return -1;
diff --git a/linux/crisv10/print_pc.c b/linux/crisv10/print_pc.c
new file mode 100644
index 0000000..cc76216
--- /dev/null
+++ b/linux/crisv10/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, 4*PT_IRP, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/crisv32/arch_regs.c b/linux/crisv32/arch_regs.c
new file mode 100644
index 0000000..a088e17
--- /dev/null
+++ b/linux/crisv32/arch_regs.c
@@ -0,0 +1 @@
+#include "crisv10/arch_regs.c"
diff --git a/linux/crisv32/arch_sigreturn.c b/linux/crisv32/arch_sigreturn.c
new file mode 100644
index 0000000..6c0fc03
--- /dev/null
+++ b/linux/crisv32/arch_sigreturn.c
@@ -0,0 +1 @@
+#include "crisv10/arch_sigreturn.c"
diff --git a/linux/crisv32/get_error.c b/linux/crisv32/get_error.c
new file mode 100644
index 0000000..f7bb1e0
--- /dev/null
+++ b/linux/crisv32/get_error.c
@@ -0,0 +1 @@
+#include "crisv10/get_error.c"
diff --git a/linux/crisv32/get_scno.c b/linux/crisv32/get_scno.c
new file mode 100644
index 0000000..edfd60f
--- /dev/null
+++ b/linux/crisv32/get_scno.c
@@ -0,0 +1 @@
+#include "crisv10/get_scno.c"
diff --git a/linux/crisv32/get_syscall_args.c b/linux/crisv32/get_syscall_args.c
new file mode 100644
index 0000000..4d98465
--- /dev/null
+++ b/linux/crisv32/get_syscall_args.c
@@ -0,0 +1 @@
+#include "crisv10/get_syscall_args.c"
diff --git a/linux/crisv32/get_syscall_result.c b/linux/crisv32/get_syscall_result.c
new file mode 100644
index 0000000..ebefdb2
--- /dev/null
+++ b/linux/crisv32/get_syscall_result.c
@@ -0,0 +1 @@
+#include "crisv10/get_syscall_result.c"
diff --git a/linux/crisv32/print_pc.c b/linux/crisv32/print_pc.c
new file mode 100644
index 0000000..b4af692
--- /dev/null
+++ b/linux/crisv32/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, 4*PT_ERP, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/hppa/arch_regs.c b/linux/hppa/arch_regs.c
new file mode 100644
index 0000000..56d1ee3
--- /dev/null
+++ b/linux/hppa/arch_regs.c
@@ -0,0 +1 @@
+static long hppa_r28;
diff --git a/linux/hppa/get_error.c b/linux/hppa/get_error.c
new file mode 100644
index 0000000..901aa54
--- /dev/null
+++ b/linux/hppa/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(hppa_r28)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -hppa_r28;
+} else {
+ tcp->u_rval = hppa_r28;
+}
diff --git a/linux/hppa/get_scno.c b/linux/hppa/get_scno.c
new file mode 100644
index 0000000..0dc1a46
--- /dev/null
+++ b/linux/hppa/get_scno.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, PT_GR20, &scno) < 0)
+ return -1;
diff --git a/linux/hppa/get_syscall_args.c b/linux/hppa/get_syscall_args.c
new file mode 100644
index 0000000..117b68b
--- /dev/null
+++ b/linux/hppa/get_syscall_args.c
@@ -0,0 +1,5 @@
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/hppa/get_syscall_result.c b/linux/hppa/get_syscall_result.c
new file mode 100644
index 0000000..d929b9f
--- /dev/null
+++ b/linux/hppa/get_syscall_result.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, PT_GR28, &hppa_r28) < 0)
+ return -1;
diff --git a/linux/hppa/print_pc.c b/linux/hppa/print_pc.c
new file mode 100644
index 0000000..7656346
--- /dev/null
+++ b/linux/hppa/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, PT_IAOQ0, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/i386/arch_regs.c b/linux/i386/arch_regs.c
new file mode 100644
index 0000000..15b5615
--- /dev/null
+++ b/linux/i386/arch_regs.c
@@ -0,0 +1,4 @@
+static struct user_regs_struct i386_regs;
+long *const i386_esp_ptr = &i386_regs.esp;
+
+#define ARCH_REGS_FOR_GETREGS i386_regs
diff --git a/linux/i386/arch_sigreturn.c b/linux/i386/arch_sigreturn.c
new file mode 100644
index 0000000..e726bf1
--- /dev/null
+++ b/linux/i386/arch_sigreturn.c
@@ -0,0 +1,20 @@
+/*
+ * On i386, sigcontext is followed on stack by struct fpstate
+ * and after it an additional u32 extramask which holds
+ * upper half of the mask.
+ */
+struct {
+ uint32_t struct_sigcontext_padding1[20];
+ uint32_t oldmask;
+ uint32_t struct_sigcontext_padding2;
+ uint32_t struct_fpstate_padding[156];
+ uint32_t extramask;
+} frame;
+
+if (umove(tcp, *i386_esp_ptr, &frame) < 0) {
+ tprintf("{mask=%#lx}", (unsigned long) *i386_esp_ptr);
+} else {
+ uint32_t mask[2] = { frame.oldmask, frame.extramask };
+ tprintsigmask_addr("{mask=", mask);
+ tprints("}");
+}
diff --git a/linux/i386/get_error.c b/linux/i386/get_error.c
new file mode 100644
index 0000000..465118b
--- /dev/null
+++ b/linux/i386/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(i386_regs.eax)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -i386_regs.eax;
+} else {
+ tcp->u_rval = i386_regs.eax;
+}
diff --git a/linux/i386/get_scno.c b/linux/i386/get_scno.c
new file mode 100644
index 0000000..fa22fa6
--- /dev/null
+++ b/linux/i386/get_scno.c
@@ -0,0 +1 @@
+scno = i386_regs.orig_eax;
diff --git a/linux/i386/get_syscall_args.c b/linux/i386/get_syscall_args.c
new file mode 100644
index 0000000..30cce6a
--- /dev/null
+++ b/linux/i386/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = i386_regs.ebx;
+tcp->u_arg[1] = i386_regs.ecx;
+tcp->u_arg[2] = i386_regs.edx;
+tcp->u_arg[3] = i386_regs.esi;
+tcp->u_arg[4] = i386_regs.edi;
+tcp->u_arg[5] = i386_regs.ebp;
diff --git a/linux/i386/print_pc.c b/linux/i386/print_pc.c
new file mode 100644
index 0000000..0d5c957
--- /dev/null
+++ b/linux/i386/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, i386_regs.eip);
diff --git a/linux/ia64/arch_getrval2.c b/linux/ia64/arch_getrval2.c
new file mode 100644
index 0000000..7a6875f
--- /dev/null
+++ b/linux/ia64/arch_getrval2.c
@@ -0,0 +1,5 @@
+long
+getrval2(struct tcb *tcp)
+{
+ return ia64_regs.gr[9];
+}
diff --git a/linux/ia64/arch_regs.c b/linux/ia64/arch_regs.c
new file mode 100644
index 0000000..d7de201
--- /dev/null
+++ b/linux/ia64/arch_regs.c
@@ -0,0 +1,7 @@
+static struct pt_all_user_regs ia64_regs;
+unsigned long *const ia64_frame_ptr = &ia64_regs.gr[12];
+
+#define IA64_PSR_IS ((long)1 << 34)
+#define ia64_ia32mode (ia64_regs.cr_ipsr & IA64_PSR_IS)
+
+#define ARCH_REGS_FOR_GETREGS ia64_regs
diff --git a/linux/ia64/arch_sigreturn.c b/linux/ia64/arch_sigreturn.c
new file mode 100644
index 0000000..94e89cf
--- /dev/null
+++ b/linux/ia64/arch_sigreturn.c
@@ -0,0 +1,8 @@
+/* offsetof(struct sigframe, sc) */
+#define OFFSETOF_STRUCT_SIGFRAME_SC 0xA0
+const long addr = *ia64_frame_ptr + 16 +
+ OFFSETOF_STRUCT_SIGFRAME_SC +
+ offsetof(struct sigcontext, sc_mask);
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/ia64/get_error.c b/linux/ia64/get_error.c
new file mode 100644
index 0000000..fb6b9f4
--- /dev/null
+++ b/linux/ia64/get_error.c
@@ -0,0 +1,16 @@
+if (ia64_ia32mode) {
+ int err = ia64_regs.gr[8];
+ if (check_errno && is_negated_errno(err)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -err;
+ } else {
+ tcp->u_rval = err;
+ }
+} else {
+ if (check_errno && ia64_regs.gr[10]) {
+ tcp->u_rval = -1;
+ tcp->u_error = ia64_regs.gr[8];
+ } else {
+ tcp->u_rval = ia64_regs.gr[8];
+ }
+}
diff --git a/linux/ia64/get_scno.c b/linux/ia64/get_scno.c
new file mode 100644
index 0000000..86333fd
--- /dev/null
+++ b/linux/ia64/get_scno.c
@@ -0,0 +1,5 @@
+if (ia64_ia32mode) {
+ scno = ia64_regs.gr[0];
+} else {
+ scno = ia64_regs.gr[15];
+}
diff --git a/linux/ia64/get_syscall_args.c b/linux/ia64/get_syscall_args.c
new file mode 100644
index 0000000..9527396
--- /dev/null
+++ b/linux/ia64/get_syscall_args.c
@@ -0,0 +1,22 @@
+if (!ia64_ia32mode) {
+ unsigned long *rbs_end =
+ (unsigned long *) ia64_regs.ar[PT_AUR_BSP];
+ unsigned long sof = (ia64_regs.cfm >> 0) & 0x7f;
+ unsigned long sol = (ia64_regs.cfm >> 7) & 0x7f;
+ unsigned long *out0 = ia64_rse_skip_regs(rbs_end, -sof + sol);
+ unsigned int i;
+
+ for (i = 0; i < tcp->s_ent->nargs; ++i) {
+ if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
+ sizeof(long), &tcp->u_arg[i]) < 0)
+ return -1;
+ }
+} else {
+ /* truncate away IVE sign-extension */
+ tcp->u_arg[0] = 0xffffffff & ia64_regs.gr[11]; /* EBX */
+ tcp->u_arg[1] = 0xffffffff & ia64_regs.gr[ 9]; /* ECX */
+ tcp->u_arg[2] = 0xffffffff & ia64_regs.gr[10]; /* EDX */
+ tcp->u_arg[3] = 0xffffffff & ia64_regs.gr[14]; /* ESI */
+ tcp->u_arg[4] = 0xffffffff & ia64_regs.gr[15]; /* EDI */
+ tcp->u_arg[5] = 0xffffffff & ia64_regs.gr[13]; /* EBP */
+}
diff --git a/linux/ia64/print_pc.c b/linux/ia64/print_pc.c
new file mode 100644
index 0000000..fe96780
--- /dev/null
+++ b/linux/ia64/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, ia64_regs.br[0]);
diff --git a/linux/m68k/arch_regs.c b/linux/m68k/arch_regs.c
new file mode 100644
index 0000000..5d41825
--- /dev/null
+++ b/linux/m68k/arch_regs.c
@@ -0,0 +1 @@
+static long m68k_d0;
diff --git a/linux/m68k/arch_sigreturn.c b/linux/m68k/arch_sigreturn.c
new file mode 100644
index 0000000..c3d3ea1
--- /dev/null
+++ b/linux/m68k/arch_sigreturn.c
@@ -0,0 +1,20 @@
+long addr;
+
+if (upeek(tcp->pid, 4*PT_USP, &addr) < 0)
+ return 0;
+/* Fetch pointer to struct sigcontext. */
+if (umove(tcp, addr + 2 * sizeof(int), &addr) < 0)
+ return 0;
+
+unsigned long mask[NSIG / 8 / sizeof(long)];
+/* Fetch first word of signal mask. */
+if (umove(tcp, addr, &mask[0]) < 0)
+ return 0;
+
+/* Fetch remaining words of signal mask, located immediately before. */
+addr -= sizeof(mask) - sizeof(long);
+if (umoven(tcp, addr, sizeof(mask) - sizeof(long), &mask[1]) < 0)
+ return 0;
+
+tprintsigmask_addr("{mask=", mask);
+tprints("}");
diff --git a/linux/m68k/get_error.c b/linux/m68k/get_error.c
new file mode 100644
index 0000000..8bf5359
--- /dev/null
+++ b/linux/m68k/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(m68k_d0)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -m68k_d0;
+} else {
+ tcp->u_rval = m68k_d0;
+}
diff --git a/linux/m68k/get_scno.c b/linux/m68k/get_scno.c
new file mode 100644
index 0000000..1a6d28e
--- /dev/null
+++ b/linux/m68k/get_scno.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, 4*PT_ORIG_D0, &scno) < 0)
+ return -1;
diff --git a/linux/m68k/get_syscall_args.c b/linux/m68k/get_syscall_args.c
new file mode 100644
index 0000000..bdffcb1
--- /dev/null
+++ b/linux/m68k/get_syscall_args.c
@@ -0,0 +1,5 @@
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/m68k/get_syscall_result.c b/linux/m68k/get_syscall_result.c
new file mode 100644
index 0000000..fc452b4
--- /dev/null
+++ b/linux/m68k/get_syscall_result.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, 4*PT_D0, &m68k_d0) < 0)
+ return -1;
diff --git a/linux/m68k/print_pc.c b/linux/m68k/print_pc.c
new file mode 100644
index 0000000..aa4497d
--- /dev/null
+++ b/linux/m68k/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/metag/arch_regs.c b/linux/metag/arch_regs.c
new file mode 100644
index 0000000..b7923ba
--- /dev/null
+++ b/linux/metag/arch_regs.c
@@ -0,0 +1,2 @@
+static struct user_gp_regs metag_regs;
+#define ARCH_REGS_FOR_GETREGSET metag_regs
diff --git a/linux/metag/get_error.c b/linux/metag/get_error.c
new file mode 100644
index 0000000..809eec5
--- /dev/null
+++ b/linux/metag/get_error.c
@@ -0,0 +1,7 @@
+/* result pointer in D0Re0 (D0.0) */
+if (check_errno && is_negated_errno(metag_regs.dx[0][0])) {
+ tcp->u_rval = -1;
+ tcp->u_error = -metag_regs.dx[0][0];
+} else {
+ tcp->u_rval = metag_regs.dx[0][0];
+}
diff --git a/linux/metag/get_scno.c b/linux/metag/get_scno.c
new file mode 100644
index 0000000..45cfa48
--- /dev/null
+++ b/linux/metag/get_scno.c
@@ -0,0 +1 @@
+scno = metag_regs.dx[0][1]; /* syscall number in D1Re0 (D1.0) */
diff --git a/linux/metag/get_syscall_args.c b/linux/metag/get_syscall_args.c
new file mode 100644
index 0000000..269f4eb
--- /dev/null
+++ b/linux/metag/get_syscall_args.c
@@ -0,0 +1,5 @@
+unsigned int i;
+
+for (i = 0; i < MAX_ARGS; i++)
+ /* arguments go backwards from D1Ar1 (D1.3) */
+ tcp->u_arg[i] = ((unsigned long *)&metag_regs.dx[3][1])[-i];
diff --git a/linux/metag/print_pc.c b/linux/metag/print_pc.c
new file mode 100644
index 0000000..4415f67
--- /dev/null
+++ b/linux/metag/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, metag_regs.pc);
diff --git a/linux/microblaze/arch_regs.c b/linux/microblaze/arch_regs.c
new file mode 100644
index 0000000..9c26aad
--- /dev/null
+++ b/linux/microblaze/arch_regs.c
@@ -0,0 +1 @@
+static long microblaze_r3;
diff --git a/linux/microblaze/arch_sigreturn.c b/linux/microblaze/arch_sigreturn.c
new file mode 100644
index 0000000..8e2e7b8
--- /dev/null
+++ b/linux/microblaze/arch_sigreturn.c
@@ -0,0 +1,12 @@
+/* TODO: Verify that this is correct... */
+
+long addr;
+
+/* Read r1, the stack pointer. */
+if (upeek(tcp->pid, 1 * 4, &addr) < 0)
+ return 0;
+addr += offsetof(struct sigcontext, oldmask);
+
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/microblaze/get_error.c b/linux/microblaze/get_error.c
new file mode 100644
index 0000000..d36e281
--- /dev/null
+++ b/linux/microblaze/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(microblaze_r3)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -microblaze_r3;
+} else {
+ tcp->u_rval = microblaze_r3;
+}
diff --git a/linux/microblaze/get_scno.c b/linux/microblaze/get_scno.c
new file mode 100644
index 0000000..cf1d919
--- /dev/null
+++ b/linux/microblaze/get_scno.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, 0, &scno) < 0)
+ return -1;
diff --git a/linux/microblaze/get_syscall_args.c b/linux/microblaze/get_syscall_args.c
new file mode 100644
index 0000000..373911c
--- /dev/null
+++ b/linux/microblaze/get_syscall_args.c
@@ -0,0 +1,5 @@
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, (5 + i) * 4, &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/microblaze/get_syscall_result.c b/linux/microblaze/get_syscall_result.c
new file mode 100644
index 0000000..b7ec27f
--- /dev/null
+++ b/linux/microblaze/get_syscall_result.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, 3 * 4, µblaze_r3) < 0)
+ return -1;
diff --git a/linux/microblaze/print_pc.c b/linux/microblaze/print_pc.c
new file mode 100644
index 0000000..b1eef14
--- /dev/null
+++ b/linux/microblaze/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, PT_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/mips/arch_getrval2.c b/linux/mips/arch_getrval2.c
new file mode 100644
index 0000000..332f270
--- /dev/null
+++ b/linux/mips/arch_getrval2.c
@@ -0,0 +1,5 @@
+long
+getrval2(struct tcb *tcp)
+{
+ return mips_regs.uregs[3];
+}
diff --git a/linux/mips/arch_regs.c b/linux/mips/arch_regs.c
new file mode 100644
index 0000000..c46e6eb
--- /dev/null
+++ b/linux/mips/arch_regs.c
@@ -0,0 +1,3 @@
+struct mips_regs mips_regs; /* not static */
+/* PTRACE_GETREGS on MIPS is available since linux v2.6.15. */
+#define ARCH_REGS_FOR_GETREGS mips_regs
diff --git a/linux/mips/arch_sigreturn.c b/linux/mips/arch_sigreturn.c
new file mode 100644
index 0000000..687f871
--- /dev/null
+++ b/linux/mips/arch_sigreturn.c
@@ -0,0 +1,22 @@
+#if defined LINUX_MIPSO32
+/*
+ * offsetof(struct sigframe, sf_mask) ==
+ * sizeof(sf_ass) + sizeof(sf_pad) + sizeof(struct sigcontext)
+ */
+const long addr = mips_REG_SP + 6 * 4 +
+ sizeof(struct sigcontext);
+#else
+/*
+ * This decodes rt_sigreturn.
+ * The 64-bit ABIs do not have sigreturn.
+ *
+ * offsetof(struct rt_sigframe, rs_uc) ==
+ * sizeof(sf_ass) + sizeof(sf_pad) + sizeof(struct siginfo)
+ */
+const long addr = mips_REG_SP + 6 * 4 + 128 +
+ offsetof(struct ucontext, uc_sigmask);
+#endif
+
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/mips/get_error.c b/linux/mips/get_error.c
new file mode 100644
index 0000000..e934af0
--- /dev/null
+++ b/linux/mips/get_error.c
@@ -0,0 +1,9 @@
+if (check_errno && mips_REG_A3) {
+ tcp->u_rval = -1;
+ tcp->u_error = mips_REG_V0;
+} else {
+# if defined LINUX_MIPSN32
+ tcp->u_lrval = mips_REG_V0;
+# endif
+ tcp->u_rval = mips_REG_V0;
+}
diff --git a/linux/mips/get_scno.c b/linux/mips/get_scno.c
new file mode 100644
index 0000000..967235d
--- /dev/null
+++ b/linux/mips/get_scno.c
@@ -0,0 +1,9 @@
+scno = mips_REG_V0;
+
+if (!SCNO_IN_RANGE(scno)) {
+ if (mips_REG_A3 == 0 || mips_REG_A3 == (uint64_t) -1) {
+ if (debug_flag)
+ fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
+ return 0;
+ }
+}
diff --git a/linux/mips/get_syscall_args.c b/linux/mips/get_syscall_args.c
new file mode 100644
index 0000000..4e4a22b
--- /dev/null
+++ b/linux/mips/get_syscall_args.c
@@ -0,0 +1,27 @@
+#if defined LINUX_MIPSN64
+ tcp->u_arg[0] = mips_REG_A0;
+ tcp->u_arg[1] = mips_REG_A1;
+ tcp->u_arg[2] = mips_REG_A2;
+ tcp->u_arg[3] = mips_REG_A3;
+ tcp->u_arg[4] = mips_REG_A4;
+ tcp->u_arg[5] = mips_REG_A5;
+#elif defined LINUX_MIPSN32
+ tcp->u_arg[0] = tcp->ext_arg[0] = mips_REG_A0;
+ tcp->u_arg[1] = tcp->ext_arg[1] = mips_REG_A1;
+ tcp->u_arg[2] = tcp->ext_arg[2] = mips_REG_A2;
+ tcp->u_arg[3] = tcp->ext_arg[3] = mips_REG_A3;
+ tcp->u_arg[4] = tcp->ext_arg[4] = mips_REG_A4;
+ tcp->u_arg[5] = tcp->ext_arg[5] = mips_REG_A5;
+#elif defined LINUX_MIPSO32
+ tcp->u_arg[0] = mips_REG_A0;
+ tcp->u_arg[1] = mips_REG_A1;
+ tcp->u_arg[2] = mips_REG_A2;
+ tcp->u_arg[3] = mips_REG_A3;
+ if (tcp->s_ent->nargs > 4) {
+ umoven(tcp, mips_REG_SP + 4 * 4,
+ (tcp->s_ent->nargs - 4) * sizeof(tcp->u_arg[0]),
+ &tcp->u_arg[4]);
+ }
+#else
+# error unsupported mips abi
+#endif
diff --git a/linux/mips/print_pc.c b/linux/mips/print_pc.c
new file mode 100644
index 0000000..569b0b6
--- /dev/null
+++ b/linux/mips/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, (unsigned long) mips_REG_EPC);
diff --git a/linux/or1k/arch_regs.c b/linux/or1k/arch_regs.c
new file mode 100644
index 0000000..7415e08
--- /dev/null
+++ b/linux/or1k/arch_regs.c
@@ -0,0 +1,2 @@
+static struct user_regs_struct or1k_regs;
+#define ARCH_REGS_FOR_GETREGSET or1k_regs
diff --git a/linux/or1k/get_error.c b/linux/or1k/get_error.c
new file mode 100644
index 0000000..cbf9a6e
--- /dev/null
+++ b/linux/or1k/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(or1k_regs.gpr[11])) {
+ tcp->u_rval = -1;
+ tcp->u_error = -or1k_regs.gpr[11];
+} else {
+ tcp->u_rval = or1k_regs.gpr[11];
+}
diff --git a/linux/or1k/get_scno.c b/linux/or1k/get_scno.c
new file mode 100644
index 0000000..99fada2
--- /dev/null
+++ b/linux/or1k/get_scno.c
@@ -0,0 +1 @@
+scno = or1k_regs.gpr[11];
diff --git a/linux/or1k/get_syscall_args.c b/linux/or1k/get_syscall_args.c
new file mode 100644
index 0000000..751cba0
--- /dev/null
+++ b/linux/or1k/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = or1k_regs.gpr[3 + 0];
+tcp->u_arg[1] = or1k_regs.gpr[3 + 1];
+tcp->u_arg[2] = or1k_regs.gpr[3 + 2];
+tcp->u_arg[3] = or1k_regs.gpr[3 + 3];
+tcp->u_arg[4] = or1k_regs.gpr[3 + 4];
+tcp->u_arg[5] = or1k_regs.gpr[3 + 5];
diff --git a/linux/or1k/print_pc.c b/linux/or1k/print_pc.c
new file mode 100644
index 0000000..3fe4a1a
--- /dev/null
+++ b/linux/or1k/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, or1k_regs.pc);
diff --git a/linux/powerpc/arch_regs.c b/linux/powerpc/arch_regs.c
new file mode 100644
index 0000000..cd92d21
--- /dev/null
+++ b/linux/powerpc/arch_regs.c
@@ -0,0 +1,3 @@
+struct pt_regs ppc_regs; /* not static */
+
+#define ARCH_REGS_FOR_GETREGS ppc_regs
diff --git a/linux/powerpc/arch_sigreturn.c b/linux/powerpc/arch_sigreturn.c
new file mode 100644
index 0000000..bc4802a
--- /dev/null
+++ b/linux/powerpc/arch_sigreturn.c
@@ -0,0 +1,24 @@
+long esp = ppc_regs.gpr[1];
+struct sigcontext sc;
+
+/* Skip dummy stack frame. */
+#ifdef POWERPC64
+if (current_personality == 0)
+ esp += 128;
+else
+#endif
+ esp += 64;
+
+if (umove(tcp, esp, &sc) < 0) {
+ tprintf("{mask=%#lx}", esp);
+} else {
+ unsigned long mask[NSIG / 8 / sizeof(long)];
+#ifdef POWERPC64
+ mask[0] = sc.oldmask | (sc._unused[3] << 32);
+#else
+ mask[0] = sc.oldmask;
+ mask[1] = sc._unused[3];
+#endif
+ tprintsigmask_addr("{mask=", mask);
+ tprints("}");
+}
diff --git a/linux/powerpc/get_error.c b/linux/powerpc/get_error.c
new file mode 100644
index 0000000..f0f0a4e
--- /dev/null
+++ b/linux/powerpc/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && (ppc_regs.ccr & 0x10000000)) {
+ tcp->u_rval = -1;
+ tcp->u_error = ppc_regs.gpr[3];
+} else {
+ tcp->u_rval = ppc_regs.gpr[3];
+}
diff --git a/linux/powerpc/get_scno.c b/linux/powerpc/get_scno.c
new file mode 100644
index 0000000..a311734
--- /dev/null
+++ b/linux/powerpc/get_scno.c
@@ -0,0 +1 @@
+scno = ppc_regs.gpr[0];
diff --git a/linux/powerpc/get_syscall_args.c b/linux/powerpc/get_syscall_args.c
new file mode 100644
index 0000000..237cf77
--- /dev/null
+++ b/linux/powerpc/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = ppc_regs.orig_gpr3;
+tcp->u_arg[1] = ppc_regs.gpr[4];
+tcp->u_arg[2] = ppc_regs.gpr[5];
+tcp->u_arg[3] = ppc_regs.gpr[6];
+tcp->u_arg[4] = ppc_regs.gpr[7];
+tcp->u_arg[5] = ppc_regs.gpr[8];
diff --git a/linux/powerpc/getregs_old.c b/linux/powerpc/getregs_old.c
new file mode 100644
index 0000000..22167cb
--- /dev/null
+++ b/linux/powerpc/getregs_old.c
@@ -0,0 +1,35 @@
+/*
+ * PTRACE_GETREGS was added to the PowerPC kernel in v2.6.23,
+ * we provide a slow fallback for old kernels.
+ */
+static int
+getregs_old(pid_t pid)
+{
+ int i;
+ long r;
+
+ if (iflag) {
+ r = upeek(pid, sizeof(long) * PT_NIP, (long *)&ppc_regs.nip);
+ if (r)
+ goto out;
+ }
+#ifdef POWERPC64 /* else we never use it */
+ r = upeek(pid, sizeof(long) * PT_MSR, (long *)&ppc_regs.msr);
+ if (r)
+ goto out;
+#endif
+ r = upeek(pid, sizeof(long) * PT_CCR, (long *)&ppc_regs.ccr);
+ if (r)
+ goto out;
+ r = upeek(pid, sizeof(long) * PT_ORIG_R3, (long *)&ppc_regs.orig_gpr3);
+ if (r)
+ goto out;
+ for (i = 0; i <= 8; i++) {
+ r = upeek(pid, sizeof(long) * (PT_R0 + i),
+ (long *)&ppc_regs.gpr[i]);
+ if (r)
+ goto out;
+ }
+ out:
+ return r;
+}
diff --git a/linux/powerpc/print_pc.c b/linux/powerpc/print_pc.c
new file mode 100644
index 0000000..34112fb
--- /dev/null
+++ b/linux/powerpc/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, ppc_regs.nip);
diff --git a/linux/powerpc64/arch_regs.c b/linux/powerpc64/arch_regs.c
new file mode 100644
index 0000000..b5c572d
--- /dev/null
+++ b/linux/powerpc64/arch_regs.c
@@ -0,0 +1 @@
+#include "powerpc/arch_regs.c"
diff --git a/linux/powerpc64/arch_sigreturn.c b/linux/powerpc64/arch_sigreturn.c
new file mode 100644
index 0000000..316022f
--- /dev/null
+++ b/linux/powerpc64/arch_sigreturn.c
@@ -0,0 +1 @@
+#include "powerpc/arch_sigreturn.c"
diff --git a/linux/powerpc64/get_error.c b/linux/powerpc64/get_error.c
new file mode 100644
index 0000000..209bfd8
--- /dev/null
+++ b/linux/powerpc64/get_error.c
@@ -0,0 +1 @@
+#include "powerpc/get_error.c"
diff --git a/linux/powerpc64/get_scno.c b/linux/powerpc64/get_scno.c
new file mode 100644
index 0000000..1e67010
--- /dev/null
+++ b/linux/powerpc64/get_scno.c
@@ -0,0 +1,11 @@
+scno = ppc_regs.gpr[0];
+unsigned int currpers;
+
+/*
+ * Check for 64/32 bit mode.
+ * Embedded implementations covered by Book E extension of PPC use
+ * bit 0 (CM) of 32-bit Machine state register (MSR).
+ * Other implementations use bit 0 (SF) of 64-bit MSR.
+ */
+currpers = (ppc_regs.msr & 0x8000000080000000) ? 0 : 1;
+update_personality(tcp, currpers);
diff --git a/linux/powerpc64/get_syscall_args.c b/linux/powerpc64/get_syscall_args.c
new file mode 100644
index 0000000..5561a55
--- /dev/null
+++ b/linux/powerpc64/get_syscall_args.c
@@ -0,0 +1 @@
+#include "powerpc/get_syscall_args.c"
diff --git a/linux/powerpc64/getregs_old.c b/linux/powerpc64/getregs_old.c
new file mode 100644
index 0000000..177ff74
--- /dev/null
+++ b/linux/powerpc64/getregs_old.c
@@ -0,0 +1 @@
+#include "powerpc/getregs_old.c"
diff --git a/linux/powerpc64/print_pc.c b/linux/powerpc64/print_pc.c
new file mode 100644
index 0000000..ddaf880
--- /dev/null
+++ b/linux/powerpc64/print_pc.c
@@ -0,0 +1 @@
+#include "powerpc/print_pc.c"
diff --git a/linux/s390/arch_regs.c b/linux/s390/arch_regs.c
new file mode 100644
index 0000000..32c50a1
--- /dev/null
+++ b/linux/s390/arch_regs.c
@@ -0,0 +1,4 @@
+/* PTRACE_GETREGSET on S390 is available since linux v2.6.27. */
+static struct user_regs_struct s390_regset;
+unsigned long *const s390_frame_ptr = &s390_regset.gprs[15];
+#define ARCH_REGS_FOR_GETREGSET s390_regset
diff --git a/linux/s390/arch_sigreturn.c b/linux/s390/arch_sigreturn.c
new file mode 100644
index 0000000..43afd95
--- /dev/null
+++ b/linux/s390/arch_sigreturn.c
@@ -0,0 +1,14 @@
+long mask[NSIG / 8 / sizeof(long)];
+const long addr = *s390_frame_ptr + __SIGNAL_FRAMESIZE;
+
+if (umove(tcp, addr, &mask) < 0) {
+ tprintf("{mask=%#lx}", addr);
+} else {
+#ifdef S390
+ long v = mask[0];
+ mask[0] = mask[1];
+ mask[1] = v;
+#endif
+ tprintsigmask_addr("{mask=", mask);
+ tprints("}");
+}
diff --git a/linux/s390/get_error.c b/linux/s390/get_error.c
new file mode 100644
index 0000000..29fffbd
--- /dev/null
+++ b/linux/s390/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(s390_regset.gprs[2])) {
+ tcp->u_rval = -1;
+ tcp->u_error = -s390_regset.gprs[2];
+} else {
+ tcp->u_rval = s390_regset.gprs[2];
+}
diff --git a/linux/s390/get_scno.c b/linux/s390/get_scno.c
new file mode 100644
index 0000000..b9e1c19
--- /dev/null
+++ b/linux/s390/get_scno.c
@@ -0,0 +1 @@
+scno = s390_regset.gprs[2];
diff --git a/linux/s390/get_syscall_args.c b/linux/s390/get_syscall_args.c
new file mode 100644
index 0000000..85f2585
--- /dev/null
+++ b/linux/s390/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = s390_regset.orig_gpr2;
+tcp->u_arg[1] = s390_regset.gprs[3];
+tcp->u_arg[2] = s390_regset.gprs[4];
+tcp->u_arg[3] = s390_regset.gprs[5];
+tcp->u_arg[4] = s390_regset.gprs[6];
+tcp->u_arg[5] = s390_regset.gprs[7];
diff --git a/linux/s390/print_pc.c b/linux/s390/print_pc.c
new file mode 100644
index 0000000..f92ccd4
--- /dev/null
+++ b/linux/s390/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, s390_regset.psw.addr);
diff --git a/linux/s390x/arch_regs.c b/linux/s390x/arch_regs.c
new file mode 100644
index 0000000..62aece7
--- /dev/null
+++ b/linux/s390x/arch_regs.c
@@ -0,0 +1 @@
+#include "s390/arch_regs.c"
diff --git a/linux/s390x/arch_sigreturn.c b/linux/s390x/arch_sigreturn.c
new file mode 100644
index 0000000..679a395
--- /dev/null
+++ b/linux/s390x/arch_sigreturn.c
@@ -0,0 +1 @@
+#include "s390/arch_sigreturn.c"
diff --git a/linux/s390x/get_error.c b/linux/s390x/get_error.c
new file mode 100644
index 0000000..8e3944c
--- /dev/null
+++ b/linux/s390x/get_error.c
@@ -0,0 +1 @@
+#include "s390/get_error.c"
diff --git a/linux/s390x/get_scno.c b/linux/s390x/get_scno.c
new file mode 100644
index 0000000..71816fb
--- /dev/null
+++ b/linux/s390x/get_scno.c
@@ -0,0 +1 @@
+#include "s390/get_scno.c"
diff --git a/linux/s390x/get_syscall_args.c b/linux/s390x/get_syscall_args.c
new file mode 100644
index 0000000..4ded41d
--- /dev/null
+++ b/linux/s390x/get_syscall_args.c
@@ -0,0 +1 @@
+#include "s390/get_syscall_args.c"
diff --git a/linux/s390x/print_pc.c b/linux/s390x/print_pc.c
new file mode 100644
index 0000000..9a445f7
--- /dev/null
+++ b/linux/s390x/print_pc.c
@@ -0,0 +1 @@
+#include "s390/print_pc.c"
diff --git a/linux/sh/arch_getrval2.c b/linux/sh/arch_getrval2.c
new file mode 100644
index 0000000..8f60de7
--- /dev/null
+++ b/linux/sh/arch_getrval2.c
@@ -0,0 +1,8 @@
+long
+getrval2(struct tcb *tcp)
+{
+ long val;
+ if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0)
+ return -1;
+ return val;
+}
diff --git a/linux/sh/arch_regs.c b/linux/sh/arch_regs.c
new file mode 100644
index 0000000..9d24ee7
--- /dev/null
+++ b/linux/sh/arch_regs.c
@@ -0,0 +1 @@
+static long sh_r0;
diff --git a/linux/sh/get_error.c b/linux/sh/get_error.c
new file mode 100644
index 0000000..2375e3c
--- /dev/null
+++ b/linux/sh/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(sh_r0)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -sh_r0;
+} else {
+ tcp->u_rval = sh_r0;
+}
diff --git a/linux/sh/get_scno.c b/linux/sh/get_scno.c
new file mode 100644
index 0000000..90dbf0f
--- /dev/null
+++ b/linux/sh/get_scno.c
@@ -0,0 +1,19 @@
+/*
+ * In the new syscall ABI, the system call number is in R3.
+ */
+if (upeek(tcp->pid, 4*(REG_REG0+3), &scno) < 0)
+ return -1;
+
+if (scno < 0) {
+ /* Odd as it may seem, a glibc bug has been known to cause
+ glibc to issue bogus negative syscall numbers. So for
+ our purposes, make strace print what it *should* have been */
+ long correct_scno = (scno & 0xff);
+ if (debug_flag)
+ fprintf(stderr,
+ "Detected glibc bug: bogus system call"
+ " number = %ld, correcting to %ld\n",
+ scno,
+ correct_scno);
+ scno = correct_scno;
+}
diff --git a/linux/sh/get_syscall_args.c b/linux/sh/get_syscall_args.c
new file mode 100644
index 0000000..7c94f48
--- /dev/null
+++ b/linux/sh/get_syscall_args.c
@@ -0,0 +1,10 @@
+static const int syscall_regs[MAX_ARGS] = {
+ 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6),
+ 4 * (REG_REG0+7), 4 * (REG_REG0 ), 4 * (REG_REG0+1)
+};
+
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, syscall_regs[i], &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/sh/get_syscall_result.c b/linux/sh/get_syscall_result.c
new file mode 100644
index 0000000..3ee0546
--- /dev/null
+++ b/linux/sh/get_syscall_result.c
@@ -0,0 +1,3 @@
+/* new syscall ABI returns result in R0 */
+if (upeek(tcp->pid, 4*REG_REG0, (long *)&sh_r0) < 0)
+ return -1;
diff --git a/linux/sh/print_pc.c b/linux/sh/print_pc.c
new file mode 100644
index 0000000..2f43eff
--- /dev/null
+++ b/linux/sh/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/sh64/arch_regs.c b/linux/sh64/arch_regs.c
new file mode 100644
index 0000000..e09cac5
--- /dev/null
+++ b/linux/sh64/arch_regs.c
@@ -0,0 +1 @@
+static long sh64_r9;
diff --git a/linux/sh64/get_error.c b/linux/sh64/get_error.c
new file mode 100644
index 0000000..9e8aeaf
--- /dev/null
+++ b/linux/sh64/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(sh64_r9)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -sh64_r9;
+} else {
+ tcp->u_rval = sh64_r9;
+}
diff --git a/linux/sh64/get_scno.c b/linux/sh64/get_scno.c
new file mode 100644
index 0000000..9e7ecd4
--- /dev/null
+++ b/linux/sh64/get_scno.c
@@ -0,0 +1,3 @@
+if (upeek(tcp->pid, REG_SYSCALL, &scno) < 0)
+ return -1;
+scno &= 0xFFFF;
diff --git a/linux/sh64/get_syscall_args.c b/linux/sh64/get_syscall_args.c
new file mode 100644
index 0000000..dcc8967
--- /dev/null
+++ b/linux/sh64/get_syscall_args.c
@@ -0,0 +1,7 @@
+/* Registers used by SH5 Linux system calls for parameters */
+static const int syscall_regs[MAX_ARGS] = { 2, 3, 4, 5, 6, 7 };
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/sh64/get_syscall_result.c b/linux/sh64/get_syscall_result.c
new file mode 100644
index 0000000..e53bd0f
--- /dev/null
+++ b/linux/sh64/get_syscall_result.c
@@ -0,0 +1,3 @@
+/* ABI defines result returned in r9 */
+if (upeek(tcp->pid, REG_GENERAL(9), (long *)&sh64_r9) < 0)
+ return -1;
diff --git a/linux/sh64/print_pc.c b/linux/sh64/print_pc.c
new file mode 100644
index 0000000..c0232e5
--- /dev/null
+++ b/linux/sh64/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, REG_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/linux/sparc/arch_getrval2.c b/linux/sparc/arch_getrval2.c
new file mode 100644
index 0000000..9079482
--- /dev/null
+++ b/linux/sparc/arch_getrval2.c
@@ -0,0 +1,5 @@
+long
+getrval2(struct tcb *tcp)
+{
+ return sparc_regs.u_regs[U_REG_O1];
+}
diff --git a/linux/sparc/arch_regs.c b/linux/sparc/arch_regs.c
new file mode 100644
index 0000000..ed13029
--- /dev/null
+++ b/linux/sparc/arch_regs.c
@@ -0,0 +1,2 @@
+struct pt_regs sparc_regs; /* not static */
+#define ARCH_REGS_FOR_GETREGS sparc_regs
diff --git a/linux/sparc/arch_sigreturn.c b/linux/sparc/arch_sigreturn.c
new file mode 100644
index 0000000..144b3a6
--- /dev/null
+++ b/linux/sparc/arch_sigreturn.c
@@ -0,0 +1,19 @@
+long fp = sparc_regs.u_regs[U_REG_FP] + sizeof(struct sparc_stackf);
+struct {
+ struct pt_regs si_regs;
+ int si_mask;
+ void *fpu_save;
+ long insns[2] ATTRIBUTE_ALIGNED(8);
+ unsigned int extramask[NSIG / 8 / sizeof(int) - 1];
+} frame;
+
+if (umove(tcp, fp, &frame) < 0) {
+ tprintf("{mask=%#lx}", fp);
+} else {
+ unsigned int mask[NSIG / 8 / sizeof(int)];
+
+ mask[0] = frame.si_mask;
+ memcpy(mask + 1, frame.extramask, sizeof(frame.extramask));
+ tprintsigmask_addr("{mask=", mask);
+ tprints("}");
+}
diff --git a/linux/sparc/dummy2.h b/linux/sparc/dummy2.h
deleted file mode 100644
index 783d4ee..0000000
--- a/linux/sparc/dummy2.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995 Rick Sladkey <jrs@world.std.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* still unfinished */
-
-#define solaris_sysmp printargs
-#define solaris_sginap printargs
-#define solaris_sgikopt printargs
-#define solaris_sysmips printargs
-#define solaris_sigreturn printargs
-#define solaris_recvmsg printargs
-#define solaris_sendmsg printargs
-#define solaris_nfssvc printargs
-#define solaris_getfh printargs
-#define solaris_async_daemon printargs
-#define solaris_exportfs printargs
-#define solaris_BSD_getime printargs
-#define solaris_sproc printargs
-#define solaris_procblk printargs
-#define solaris_sprocsp printargs
-#define solaris_msync printargs
-#define solaris_madvise printargs
-#define solaris_pagelock printargs
-#define solaris_quotactl printargs
-#define solaris_cacheflush printargs
-#define solaris_cachectl printargs
-#define solaris_nuname printargs
-#define solaris_sigpoll printargs
-#define solaris_swapctl printargs
-#define solaris_sigstack printargs
-#define solaris_sigsendset printargs
-#define solaris_priocntl printargs
-#define solaris_ksigqueue printargs
-#define solaris_lwp_sema_wait printargs
-#define solaris_memcntl printargs
-#define solaris_syscall printargs
-#define solaris_clocal printargs
-#define solaris_syssun printargs
-#define solaris_sysi86 printargs
-#define solaris_sysmachine printargs
-#define solaris_plock printargs
-#define solaris_pathconf printargs
-#define solaris_sigtimedwait printargs
-#define solaris_ulimit printargs
-#define solaris_ptrace printargs
-#define solaris_stty printargs
-#define solaris_lwp_info printargs
-#define solaris_priocntlsys printargs
-#define solaris_hrtsys printargs
-#define solaris_xenix printargs
-#define solaris_statfs printargs
-#define solaris_fstatfs printargs
-#define solaris_statvfs printargs
-#define solaris_fstatvfs printargs
-#define solaris_fork1 printargs
-#define solaris_sigsendsys printargs
-#define solaris_gtty printargs
-#define solaris_vtrace printargs
-#define solaris_fpathconf printargs
-#define solaris_evsys printargs
-#define solaris_acct printargs
-#define solaris_exec printargs
-#define solaris_lwp_sema_post printargs
-#define solaris_nfssys printargs
-#define solaris_sigaltstack printargs
-#define solaris_uadmin printargs
-#define solaris_umount printargs
-#define solaris_modctl printargs
-#define solaris_acancel printargs
-#define solaris_async printargs
-#define solaris_evtrapret printargs
-#define solaris_lwp_create printargs
-#define solaris_lwp_exit printargs
-#define solaris_lwp_suspend printargs
-#define solaris_lwp_continue printargs
-#define solaris_lwp_kill printargs
-#define solaris_lwp_self printargs
-#define solaris_lwp_setprivate printargs
-#define solaris_lwp_getprivate printargs
-#define solaris_lwp_wait printargs
-#define solaris_lwp_mutex_unlock printargs
-#define solaris_lwp_mutex_lock printargs
-#define solaris_lwp_cond_wait printargs
-#define solaris_lwp_cond_signal printargs
-#define solaris_lwp_cond_broadcast printargs
-#define solaris_llseek printargs
-#define solaris_inst_sync printargs
-#define solaris_auditsys printargs
-#define solaris_processor_bind printargs
-#define solaris_processor_info printargs
-#define solaris_p_online printargs
-#define solaris_sigqueue printargs
-#define solaris_clock_gettime printargs
-#define solaris_clock_settime printargs
-#define solaris_clock_getres printargs
-#define solaris_nanosleep printargs
-#define solaris_timer_create printargs
-#define solaris_timer_delete printargs
-#define solaris_timer_settime printargs
-#define solaris_timer_gettime printargs
-#define solaris_timer_getoverrun printargs
-#define solaris_signal printargs
-#define solaris_sigset printargs
-#define solaris_sighold printargs
-#define solaris_sigrelse printargs
-#define solaris_sigignore printargs
-#define solaris_sigpause printargs
-#define solaris_msgctl printargs
-#define solaris_msgget printargs
-#define solaris_msgrcv printargs
-#define solaris_msgsnd printargs
-#define solaris_shmat printargs
-#define solaris_shmctl printargs
-#define solaris_shmdt printargs
-#define solaris_shmget printargs
-#define solaris_semctl printargs
-#define solaris_semget printargs
-#define solaris_semop printargs
-#define solaris_olduname printargs
-#define solaris_ustat printargs
-#define solaris_fusers printargs
-#define solaris_sysfs1 printargs
-#define solaris_sysfs2 printargs
-#define solaris_sysfs3 printargs
-
-/* like another call */
-#define solaris_lchown solaris_chown
-#define solaris_setuid solaris_close
-#define solaris_seteuid solaris_close
-#define solaris_setgid solaris_close
-#define solaris_setegid solaris_close
-#define solaris_vhangup solaris_close
-#define solaris_fdsync solaris_close
-#define solaris_sigfillset solaris_sigpending
-#define solaris_vfork solaris_fork
-#define solaris_ksigaction solaris_sigaction
-#define solaris_BSDgetpgrp solaris_getpgrp
-#define solaris_BSDsetpgrp solaris_setpgrp
-#define solaris_waitsys solaris_waitid
-
-/* printargs does the right thing */
-#define solaris_sync printargs
-#define solaris_profil printargs
-#define solaris_yield printargs
-#define solaris_pause printargs
-#define solaris_sethostid printargs
-
-/* subfunction entry points */
-#define solaris_pgrpsys printargs
-#define solaris_sigcall printargs
-#define solaris_msgsys printargs
-#define solaris_shmsys printargs
-#define solaris_semsys printargs
-#define solaris_utssys printargs
-#define solaris_sysfs printargs
-#define solaris_spcall printargs
-#define solaris_context printargs
-
-/* same as linux */
-#define solaris_exit sys_exit
-#define solaris_fork sys_fork
-#define solaris_read sys_read
-#define solaris_write sys_write
-#define solaris_close sys_close
-#define solaris_creat sys_creat
-#define solaris_link sys_link
-#define solaris_unlink sys_unlink
-#define solaris_chdir sys_chdir
-#define solaris_time sys_time
-#define solaris_chmod sys_chmod
-#define solaris_lseek sys_lseek
-#define solaris_stime sys_stime
-#define solaris_alarm sys_alarm
-#define solaris_utime sys_utime
-#define solaris_access sys_access
-#define solaris_nice sys_nice
-#define solaris_dup sys_dup
-#define solaris_pipe sys_pipe
-#define solaris_times sys_times
-#define solaris_execve sys_execve
-#define solaris_umask sys_umask
-#define solaris_chroot sys_chroot
-#define solaris_rmdir sys_rmdir
-#define solaris_mkdir sys_mkdir
-#define solaris_getdents sys_getdents
-#define solaris_poll sys_poll
-#define solaris_symlink sys_symlink
-#define solaris_readlink sys_readlink
-#define solaris_setgroups sys_setgroups
-#define solaris_getgroups sys_getgroups
-#define solaris_fchmod sys_fchmod
-#define solaris_fchown sys_fchown
-#define solaris_mprotect sys_mprotect
-#define solaris_munmap sys_munmap
-#define solaris_readv sys_readv
-#define solaris_writev sys_writev
-#define solaris_chown sys_chown
-#define solaris_rename sys_rename
-#define solaris_gettimeofday sys_gettimeofday
-#define solaris_getitimer sys_getitimer
-#define solaris_setitimer sys_setitimer
-#define solaris_brk sys_brk
-#define solaris_mmap sys_mmap
-#define solaris_getsid sys_getsid
-#define solaris_setsid sys_setsid
-#define solaris_getpgid sys_getpgid
-#define solaris_setpgid sys_setpgid
-#define solaris_getpgrp sys_getpgrp
-
-/* These are handled according to current_personality */
-#define solaris_xstat sys_xstat
-#define solaris_fxstat sys_fxstat
-#define solaris_lxstat sys_xstat
-#define solaris_xmknod sys_xmknod
-#define solaris_stat sys_stat
-#define solaris_fstat sys_fstat
-#define solaris_lstat sys_lstat
-#define solaris_pread sys_pread
-#define solaris_pwrite sys_pwrite
-#define solaris_ioctl sys_ioctl
-#define solaris_mknod sys_mknod
-
-/* To be done */
-#define solaris_mount printargs
-#define solaris_sysinfo printargs
-#define solaris_sysconfig printargs
-#define solaris_getpmsg printargs
-#define solaris_putpmsg printargs
-#define solaris_wait printargs
-#define solaris_waitid printargs
-#define solaris_sigsuspend printargs
-#define solaris_setpgrp printargs
-#define solaris_getcontext printargs
-#define solaris_setcontext printargs
-#define solaris_getpid printargs
-#define solaris_getuid printargs
-#define solaris_kill printargs
-#define solaris_getgid printargs
-#define solaris_fcntl printargs
-#define solaris_getmsg printargs
-#define solaris_putmsg printargs
-#define solaris_sigprocmask printargs
-#define solaris_sigaction printargs
-#define solaris_sigpending printargs
-#define solaris_mincore printargs
-#define solaris_fchdir printargs
-#define solaris_setrlimit printargs
-#define solaris_getrlimit printargs
-#define solaris_uname printargs
-#define solaris_adjtime printargs
-#define solaris_fchroot printargs
-#define solaris_utimes printargs
diff --git a/linux/sparc/errnoent1.h b/linux/sparc/errnoent1.h
deleted file mode 100644
index e4311a4..0000000
--- a/linux/sparc/errnoent1.h
+++ /dev/null
@@ -1,116 +0,0 @@
-[ 1] = "EPERM",
-[ 2] = "ENOENT",
-[ 3] = "ESRCH",
-[ 4] = "EINTR",
-[ 5] = "EIO",
-[ 6] = "ENXIO",
-[ 7] = "E2BIG",
-[ 8] = "ENOEXEC",
-[ 9] = "EBADF",
-[ 10] = "ECHILD",
-[ 11] = "EAGAIN",
-[ 12] = "ENOMEM",
-[ 13] = "EACCES",
-[ 14] = "EFAULT",
-[ 15] = "ENOTBLK",
-[ 16] = "EBUSY",
-[ 17] = "EEXIST",
-[ 18] = "EXDEV",
-[ 19] = "ENODEV",
-[ 20] = "ENOTDIR",
-[ 21] = "EISDIR",
-[ 22] = "EINVAL",
-[ 23] = "ENFILE",
-[ 24] = "EMFILE",
-[ 25] = "ENOTTY",
-[ 26] = "ETXTBSY",
-[ 27] = "EFBIG",
-[ 28] = "ENOSPC",
-[ 29] = "ESPIPE",
-[ 30] = "EROFS",
-[ 31] = "EMLINK",
-[ 32] = "EPIPE",
-[ 33] = "EDOM",
-[ 34] = "ERANGE",
-[ 35] = "ENOMSG",
-[ 36] = "EIDRM",
-[ 37] = "ECHRNG",
-[ 38] = "EL2NSYNC",
-[ 39] = "EL3HLT",
-[ 40] = "EL3RST",
-[ 41] = "ELNRNG",
-[ 42] = "EUNATCH",
-[ 43] = "ENOCSI",
-[ 44] = "EL2HLT",
-[ 45] = "EDEADLK",
-[ 46] = "ENOLCK",
-[ 47] = "ECANCELED",
-[ 48] = "ENOTSUP",
-[ 50] = "EBADE",
-[ 51] = "EBADR",
-[ 52] = "EXFULL",
-[ 53] = "ENOANO",
-[ 54] = "EBADRQC",
-[ 55] = "EBADSLT",
-[ 56] = "EDEADLOCK",
-[ 57] = "EBFONT",
-[ 60] = "ENOSTR",
-[ 61] = "ENODATA",
-[ 62] = "ETIME",
-[ 63] = "ENOSR",
-[ 64] = "ENONET",
-[ 65] = "ENOPKG",
-[ 66] = "EREMOTE",
-[ 67] = "ENOLINK",
-[ 68] = "EADV",
-[ 69] = "ESRMNT",
-[ 70] = "ECOMM",
-[ 71] = "EPROTO",
-[ 74] = "EMULTIHOP",
-[ 77] = "EBADMSG",
-[ 78] = "ENAMETOOLONG",
-[ 79] = "EOVERFLOW",
-[ 80] = "ENOTUNIQ",
-[ 81] = "EBADFD",
-[ 82] = "EREMCHG",
-[ 83] = "ELIBACC",
-[ 84] = "ELIBBAD",
-[ 85] = "ELIBSCN",
-[ 86] = "ELIBMAX",
-[ 87] = "ELIBEXEC",
-[ 88] = "EILSEQ",
-[ 89] = "ENOSYS",
-[ 90] = "ELOOP",
-[ 91] = "ERESTART",
-[ 92] = "ESTRPIPE",
-[ 93] = "ENOTEMPTY",
-[ 94] = "EUSERS",
-[ 95] = "ENOTSOCK",
-[ 96] = "EDESTADDRREQ",
-[ 97] = "EMSGSIZE",
-[ 98] = "EPROTOTYPE",
-[ 99] = "ENOPROTOOPT",
-[120] = "EPROTONOSUPPORT",
-[121] = "ESOCKTNOSUPPORT",
-[122] = "EOPNOTSUPP",
-[123] = "EPFNOSUPPORT",
-[124] = "EAFNOSUPPORT",
-[125] = "EADDRINUSE",
-[126] = "EADDRNOTAVAIL",
-[127] = "ENETDOWN",
-[128] = "ENETUNREACH",
-[129] = "ENETRESET",
-[130] = "ECONNABORTED",
-[131] = "ECONNRESET",
-[132] = "ENOBUFS",
-[133] = "EISCONN",
-[134] = "ENOTCONN",
-[143] = "ESHUTDOWN",
-[144] = "ETOOMANYREFS",
-[145] = "ETIMEDOUT",
-[146] = "ECONNREFUSED",
-[147] = "EHOSTDOWN",
-[148] = "EHOSTUNREACH",
-[149] = "EALREADY",
-[150] = "EINPROGRESS",
-[151] = "ESTALE",
diff --git a/linux/sparc/get_error.c b/linux/sparc/get_error.c
new file mode 100644
index 0000000..3531f01
--- /dev/null
+++ b/linux/sparc/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && sparc_regs.psr & PSR_C) {
+ tcp->u_rval = -1;
+ tcp->u_error = sparc_regs.u_regs[U_REG_O0];
+} else {
+ tcp->u_rval = sparc_regs.u_regs[U_REG_O0];
+}
diff --git a/linux/sparc/get_scno.c b/linux/sparc/get_scno.c
new file mode 100644
index 0000000..b190b6c
--- /dev/null
+++ b/linux/sparc/get_scno.c
@@ -0,0 +1 @@
+scno = sparc_regs.u_regs[U_REG_G1];
diff --git a/linux/sparc/get_syscall_args.c b/linux/sparc/get_syscall_args.c
new file mode 100644
index 0000000..14bce8f
--- /dev/null
+++ b/linux/sparc/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = sparc_regs.u_regs[U_REG_O0 + 0];
+tcp->u_arg[1] = sparc_regs.u_regs[U_REG_O0 + 1];
+tcp->u_arg[2] = sparc_regs.u_regs[U_REG_O0 + 2];
+tcp->u_arg[3] = sparc_regs.u_regs[U_REG_O0 + 3];
+tcp->u_arg[4] = sparc_regs.u_regs[U_REG_O0 + 4];
+tcp->u_arg[5] = sparc_regs.u_regs[U_REG_O0 + 5];
diff --git a/linux/sparc/ioctlent1.h b/linux/sparc/ioctlent1.h
deleted file mode 100644
index 72efe42..0000000
--- a/linux/sparc/ioctlent1.h
+++ /dev/null
@@ -1,429 +0,0 @@
-{"DKIOCGGEOM", 0x401},
-{"DKIOCSGEOM", 0x402},
-{"DKIOCINFO", 0x403},
-{"DKIOCSAPART", 0x404},
-{"DKIOCGAPART", 0x405},
-{"DKIOCEJECT", 0x406},
-{"DKIOCLOCK", 0x407},
-{"DKIOCUNLOCK", 0x408},
-{"DKIOCGVTOC", 0x40b},
-{"DKIOCSVTOC", 0x40c},
-{"DKIOCSTATE", 0x40d},
-{"FDIOGCHAR", 0x433},
-{"FDIOSCHAR", 0x434},
-{"FDEJECT", 0x435},
-{"FDGETCHANGE", 0x436},
-{"FDGETDRIVECHAR", 0x437},
-{"FDSETDRIVECHAR", 0x438},
-{"FDGETSEARCH", 0x439},
-{"FDSETSEARCH", 0x43a},
-{"FDIOCMD", 0x43b},
-{"FDRAW", 0x446},
-{"FDDEFGEOCHAR", 0x456},
-{"HDKIOCSTYPE", 0x465},
-{"HDKIOCGTYPE", 0x466},
-{"HDKIOCSBAD", 0x467},
-{"HDKIOCGBAD", 0x468},
-{"HDKIOCSCMD", 0x469},
-{"HDKIOCGDIAG", 0x46a},
-{"CDROMPAUSE", 0x497},
-{"CDROMRESUME", 0x498},
-{"CDROMPLAYMSF", 0x499},
-{"CDROMPLAYTRKIND", 0x49a},
-{"CDROMREADTOCHDR", 0x49b},
-{"CDROMREADTOCENTRY", 0x49c},
-{"CDROMSTOP", 0x49d},
-{"CDROMSTART", 0x49e},
-{"CDROMEJECT", 0x49f},
-{"CDROMVOLCTRL", 0x4a0},
-{"CDROMSUBCHNL", 0x4a1},
-{"CDROMREADMODE2", 0x4a2},
-{"CDROMREADMODE1", 0x4a3},
-{"CDROMREADOFFSET", 0x4a4},
-{"CDROMGBLKMODE", 0x4a5},
-{"CDROMSBLKMODE", 0x4a6},
-{"CDROMCDDA", 0x4a7},
-{"CDROMCDXA", 0x4a8},
-{"CDROMSUBCODE", 0x4a9},
-{"CDROMGDRVSPEED", 0x4aa},
-{"CDROMSDRVSPEED", 0x4ab},
-{"USCSICMD", 0x4c9},
-{"SBIOCSTIME", 0x4201},
-{"SBIOCGTIME", 0x4202},
-{"SBIOCCTIME", 0x4203},
-{"SBIOCSCHUNK", 0x4204},
-{"SBIOCGCHUNK", 0x4205},
-{"SBIOCSSNAP", 0x4206},
-{"SBIOCGSNAP", 0x4207},
-{"SBIOCSFLAGS", 0x4208},
-{"SBIOCGFLAGS", 0x4209},
-{"LDOPEN", 0x4400},
-{"LDCLOSE", 0x4401},
-{"DLIOCRAW", 0x4401},
-{"SAD_SAP", 0x4401},
-{"LDCHG", 0x4402},
-{"SAD_GAP", 0x4402},
-{"SAD_VML", 0x4403},
-{"LDGETT", 0x4408},
-{"LDSETT", 0x4409},
-{"DL_IOC_HDR_INFO", 0x440a},
-{"LDSMAP", 0x446e},
-{"LDGMAP", 0x446f},
-{"LDNMAP", 0x4470},
-{"LDEMAP", 0x4471},
-{"LDDMAP", 0x4472},
-{"FBIOGTYPE", 0x4600},
-{"FBIOGINFO", 0x4602},
-{"FBIOPUTCMAP", 0x4603},
-{"FBIOGETCMAP", 0x4604},
-{"FBIOSATTR", 0x4605},
-{"FBIOGATTR", 0x4606},
-{"FBIOSVIDEO", 0x4607},
-{"FBIOGVIDEO", 0x4608},
-{"FBIOVERTICAL", 0x4609},
-{"GRABPAGEALLOC", 0x460a},
-{"GRABPAGEFREE", 0x460b},
-{"GRABATTACH", 0x460c},
-{"FBIOGPLNGRP", 0x460d},
-{"FBIOGCMSIZE", 0x460e},
-{"FBIOSCMSIZE", 0x460f},
-{"FBIOSCMS", 0x4610},
-{"FBIOAVAILPLNGRP", 0x4611},
-{"FBIODBLGINFO", 0x4612},
-{"FBIODBLSINFO", 0x4613},
-{"FBIOSWINFD", 0x4614},
-{"FBIOSAVWINFD", 0x4615},
-{"FBIORESWINFD", 0x4616},
-{"FBIOSRWINFD", 0x4617},
-{"VIS_SETCURSOR", 0x4618},
-{"FBIOSCURSOR", 0x4618},
-{"FBIOGCURSOR", 0x4619},
-{"VIS_GETCURSOR", 0x4619},
-{"FBIOSCURPOS", 0x461a},
-{"VIS_MOVECURSOR", 0x461a},
-{"FBIOGCURPOS", 0x461b},
-{"VIS_GETCURSORPOS", 0x461b},
-{"FBIOGCURMAX", 0x461c},
-{"GRABLOCKINFO", 0x461d},
-{"FBIO_WID_ALLOC", 0x461e},
-{"FBIO_WID_FREE", 0x461f},
-{"FBIO_WID_PUT", 0x4620},
-{"FBIO_WID_GET", 0x4621},
-{"FBIO_DEVID", 0x4622},
-{"FBIO_U_RST", 0x4623},
-{"FBIO_FULLSCREEN_ELIMINATION_GROUPS", 0x4624},
-{"FBIO_WID_DBL_SET", 0x4625},
-{"FBIOVRTOFFSET", 0x4626},
-{"FBIOGXINFO", 0x4627},
-{"FBIOMONINFO", 0x4628},
-{"FBIOPUTCMAPI", 0x4629},
-{"FBIOGETCMAPI", 0x462a},
-{"FBIO_ASSIGNWID", 0x462b},
-{"FBIO_STEREO", 0x462c},
-{"GP1IO_PUT_INFO", 0x4700},
-{"GP1IO_GET_STATIC_BLOCK", 0x4701},
-{"GP1IO_FREE_STATIC_BLOCK", 0x4702},
-{"GP1IO_GET_GBUFFER_STATE", 0x4703},
-{"GP1IO_CHK_GP", 0x4704},
-{"GP1IO_GET_RESTART_COUNT", 0x4705},
-{"GP1IO_REDIRECT_DEVFB", 0x4706},
-{"GP1IO_GET_REQDEV", 0x4707},
-{"GP1IO_GET_TRUMINORDEV", 0x4708},
-{"GP1IO_CHK_FOR_GBUFFER", 0x4709},
-{"GP1IO_SET_USING_GBUFFER", 0x470a},
-{"GP1IO_INFO_STATIC_BLOCK", 0x470b},
-{"O_SI_GETUDATA", 0x4965},
-{"SI_SHUTDOWN", 0x4966},
-{"SI_LISTEN", 0x4967},
-{"SI_SETMYNAME", 0x4968},
-{"SI_SETPEERNAME", 0x4969},
-{"SI_GETINTRANSIT", 0x496a},
-{"SI_SOCKPARAMS", 0x496d},
-{"SI_GETUDATA", 0x496e},
-{"I_TRCLOG", 0x4c01},
-{"I_ERRLOG", 0x4c02},
-{"I_CONSLOG", 0x4c03},
-{"MDI_RESET", 0x4d01},
-{"MDI_GET_CFGINFO", 0x4d02},
-{"MDI_SET_PIXELMODE", 0x4d03},
-{"MDI_SET_COUNTERS", 0x4d04},
-{"MDI_SET_PPR", 0x4d05},
-{"MDI_VRT_CNTL", 0x4d06},
-{"MDI_SET_CLUT", 0x4d07},
-{"MDI_GET_CLUT", 0x4d08},
-{"MDI_SET_XLUT", 0x4d09},
-{"MDI_GET_XLUT", 0x4d0a},
-{"MDI_GAMMA_CORRECT", 0x4d0b},
-{"MDI_SET_GAMMALUT", 0x4d0c},
-{"MDI_GET_GAMMALUT", 0x4d0d},
-{"MDI_SET_DEGAMMALUT", 0x4d0e},
-{"MDI_GET_DEGAMMALUT", 0x4d0f},
-{"MDI_GET_BUFFER_INFO", 0x4d10},
-{"MDI_SET_CURSOR", 0x4d11},
-{"MDI_GET_DIAGINFO", 0x4d12},
-{"MDI_SET_RESOLUTION", 0x4d13},
-{"SET_MONITOR_POWER", 0x4d14},
-{"OPROMGETBOOTARGS", 0x4f0c},
-{"PFIOCSETF", 0x5001},
-{"I_NREAD", 0x5301},
-{"I_PUSH", 0x5302},
-{"I_POP", 0x5303},
-{"I_LOOK", 0x5304},
-{"I_FLUSH", 0x5305},
-{"I_SRDOPT", 0x5306},
-{"I_GRDOPT", 0x5307},
-{"I_STR", 0x5308},
-{"I_SETSIG", 0x5309},
-{"I_GETSIG", 0x530a},
-{"I_FIND", 0x530b},
-{"I_LINK", 0x530c},
-{"I_UNLINK", 0x530d},
-{"I_RECVFD", 0x530e},
-{"I_PEEK", 0x530f},
-{"I_FDINSERT", 0x5310},
-{"I_SENDFD", 0x5311},
-{"I_SWROPT", 0x5313},
-{"I_GWROPT", 0x5314},
-{"I_LIST", 0x5315},
-{"I_PLINK", 0x5316},
-{"I_PUNLINK", 0x5317},
-{"I_SETEV", 0x5318},
-{"I_GETEV", 0x5319},
-{"I_STREV", 0x531a},
-{"I_UNSTREV", 0x531b},
-{"I_FLUSHBAND", 0x531c},
-{"I_CKBAND", 0x531d},
-{"I_GETBAND", 0x531e},
-{"I_ATMARK", 0x531f},
-{"I_SETCLTIME", 0x5320},
-{"I_GETCLTIME", 0x5321},
-{"I_CANPUT", 0x5322},
-{"TCGETA", 0x5401},
-{"TCSETA", 0x5402},
-{"TCSETAW", 0x5403},
-{"TCSETAF", 0x5404},
-{"TCSBRK", 0x5405},
-{"TCXONC", 0x5406},
-{"TCFLSH", 0x5407},
-{"TIOCKBON", 0x5408},
-{"TIOCKBOF", 0x5409},
-{"KBENABLED", 0x540a},
-{"TCGETS", 0x540d},
-{"TCSETS", 0x540e},
-{"TCSANOW", 0x540e},
-{"TCSADRAIN", 0x540f},
-{"TCSETSW", 0x540f},
-{"TCSAFLUSH", 0x5410},
-{"TCSETSF", 0x5410},
-{"TCDSET", 0x5420},
-{"TCDSET", 0x5420},
-{"RTS_TOG", 0x5421},
-{"TIOCSWINSZ", 0x5467},
-{"TIOCSWINSZ", 0x5467},
-{"TIOCGWINSZ", 0x5468},
-{"TIOCGWINSZ", 0x5468},
-{"TIOCGSOFTCAR", 0x5469},
-{"TIOCSSOFTCAR", 0x546a},
-{"TI_GETINFO", 0x548c},
-{"TI_OPTMGMT", 0x548d},
-{"TI_BIND", 0x548e},
-{"TI_UNBIND", 0x548f},
-{"TI_GETMYNAME", 0x5490},
-{"TI_GETPEERNAME", 0x5491},
-{"TI_SETMYNAME", 0x5492},
-{"TI_SETPEERNAME", 0x5493},
-{"TCGETX", 0x5801},
-{"TCSETX", 0x5802},
-{"TCSETXW", 0x5803},
-{"TCSETXF", 0x5804},
-{"DIOCGETC", 0x6401},
-{"DIOCGETB", 0x6402},
-{"DIOCSETE", 0x6403},
-{"DIOCGETP", 0x6408},
-{"DIOCSETP", 0x6409},
-{"JBOOT", 0x6a01},
-{"JTERM", 0x6a02},
-{"JMPX", 0x6a03},
-{"JWINSIZE", 0x6a05},
-{"JZOMBOOT", 0x6a07},
-{"JAGENT", 0x6a09},
-{"JTRUN", 0x6a0a},
-{"JXTPROTO", 0x6a0b},
-{"KIOCTRANS", 0x6b00},
-{"KIOCSETKEY", 0x6b01},
-{"KIOCGETKEY", 0x6b02},
-{"KIOCGTRANS", 0x6b05},
-{"KIOCTRANSABLE", 0x6b06},
-{"KIOCGTRANSABLE", 0x6b07},
-{"KIOCCMD", 0x6b08},
-{"KIOCTYPE", 0x6b09},
-{"KIOCSDIRECT", 0x6b0a},
-{"KIOCGDIRECT", 0x6b0b},
-{"KIOCSKEY", 0x6b0c},
-{"KIOCGKEY", 0x6b0d},
-{"KIOCSLED", 0x6b0e},
-{"KIOCGLED", 0x6b0f},
-{"KIOCSCOMPAT", 0x6b10},
-{"KIOCGCOMPAT", 0x6b11},
-{"KIOCLAYOUT", 0x6b14},
-{"LIOCGETP", 0x6c01},
-{"LIOCSETP", 0x6c02},
-{"LIOCGETS", 0x6c05},
-{"LIOCSETS", 0x6c06},
-{"MTIOCTOP", 0x6d01},
-{"MSIOGETPARMS", 0x6d01},
-{"MSIOSETPARMS", 0x6d02},
-{"MTIOCGET", 0x6d02},
-{"MTIOCGETDRIVETYPE", 0x6d03},
-{"PIOCSTATUS", 0x7101},
-{"PIOCSTOP", 0x7102},
-{"PIOCWSTOP", 0x7103},
-{"PIOCRUN", 0x7104},
-{"PIOCGTRACE", 0x7105},
-{"PIOCSTRACE", 0x7106},
-{"PIOCSSIG", 0x7107},
-{"PIOCKILL", 0x7108},
-{"PIOCUNKILL", 0x7109},
-{"PIOCGHOLD", 0x710a},
-{"PIOCSHOLD", 0x710b},
-{"PIOCMAXSIG", 0x710c},
-{"PIOCACTION", 0x710d},
-{"PIOCGFAULT", 0x710e},
-{"PIOCSFAULT", 0x710f},
-{"PIOCCFAULT", 0x7110},
-{"PIOCGENTRY", 0x7111},
-{"PIOCSENTRY", 0x7112},
-{"PIOCGEXIT", 0x7113},
-{"PIOCSEXIT", 0x7114},
-{"PIOCSFORK", 0x7115},
-{"PIOCRFORK", 0x7116},
-{"PIOCSRLC", 0x7117},
-{"PIOCRRLC", 0x7118},
-{"PIOCGREG", 0x7119},
-{"PIOCSREG", 0x711a},
-{"PIOCGFPREG", 0x711b},
-{"PIOCSFPREG", 0x711c},
-{"PIOCNICE", 0x711d},
-{"PIOCPSINFO", 0x711e},
-{"PIOCNMAP", 0x711f},
-{"PIOCMAP", 0x7120},
-{"PIOCOPENM", 0x7121},
-{"PIOCCRED", 0x7122},
-{"PIOCGROUPS", 0x7123},
-{"PIOCGETPR", 0x7124},
-{"PIOCGETU", 0x7125},
-{"PIOCSET", 0x7126},
-{"PIOCRESET", 0x7127},
-{"PIOCNWATCH", 0x7128},
-{"PIOCGWATCH", 0x7129},
-{"PIOCSWATCH", 0x712a},
-{"PIOCUSAGE", 0x712b},
-{"PIOCOPENPD", 0x712c},
-{"PIOCLWPIDS", 0x712d},
-{"PIOCOPENLWP", 0x712e},
-{"PIOCLSTATUS", 0x712f},
-{"PIOCLUSAGE", 0x7130},
-{"PIOCNAUXV", 0x7131},
-{"PIOCAUXV", 0x7132},
-{"PIOCGWIN", 0x7165},
-{"TIOCGETD", 0x7400},
-{"TIOCGETD", 0x7400},
-{"TIOCSETD", 0x7401},
-{"TIOCSETD", 0x7401},
-{"TIOCHPCL", 0x7402},
-{"TIOCHPCL", 0x7402},
-{"TIOCGETP", 0x7408},
-{"TIOCGETP", 0x7408},
-{"TIOCSETP", 0x7409},
-{"TIOCSETP", 0x7409},
-{"TIOCSETN", 0x740a},
-{"TIOCSETN", 0x740a},
-{"TIOCEXCL", 0x740d},
-{"TIOCEXCL", 0x740d},
-{"TIOCNXCL", 0x740e},
-{"TIOCNXCL", 0x740e},
-{"TIOCFLUSH", 0x7410},
-{"TIOCFLUSH", 0x7410},
-{"TIOCSETC", 0x7411},
-{"TIOCSETC", 0x7411},
-{"TIOCGETC", 0x7412},
-{"TIOCGETC", 0x7412},
-{"TIOCGPGRP", 0x7414},
-{"TIOCSPGRP", 0x7415},
-{"TIOCGSID", 0x7416},
-{"TIOCSTI", 0x7417},
-{"TIOCSSID", 0x7418},
-{"TIOCMSET", 0x741a},
-{"TIOCMBIS", 0x741b},
-{"TIOCMBIC", 0x741c},
-{"TIOCMGET", 0x741d},
-{"TIOCREMOTE", 0x741e},
-{"TIOCREMOTE", 0x741e},
-{"TIOCSIGNAL", 0x741f},
-{"TIOCSTART", 0x746e},
-{"TIOCSTART", 0x746e},
-{"TIOCSTOP", 0x746f},
-{"TIOCSTOP", 0x746f},
-{"TIOCNOTTY", 0x7471},
-{"TIOCNOTTY", 0x7471},
-{"TIOCOUTQ", 0x7473},
-{"TIOCOUTQ", 0x7473},
-{"TIOCGLTC", 0x7474},
-{"TIOCGLTC", 0x7474},
-{"TIOCSLTC", 0x7475},
-{"TIOCSLTC", 0x7475},
-{"TIOCCDTR", 0x7478},
-{"TIOCCDTR", 0x7478},
-{"TIOCSDTR", 0x7479},
-{"TIOCSDTR", 0x7479},
-{"TIOCCBRK", 0x747a},
-{"TIOCCBRK", 0x747a},
-{"TIOCSBRK", 0x747b},
-{"TIOCSBRK", 0x747b},
-{"TIOCLGET", 0x747c},
-{"TIOCLGET", 0x747c},
-{"TIOCLSET", 0x747d},
-{"TIOCLSET", 0x747d},
-{"TIOCLBIC", 0x747e},
-{"TIOCLBIC", 0x747e},
-{"TIOCLBIS", 0x747f},
-{"TIOCLBIS", 0x747f},
-{"VOLIOCMAP", 0x7601},
-{"VUIDSFORMAT", 0x7601},
-{"VUIDSFORMAT", 0x7601},
-{"VUIDGFORMAT", 0x7602},
-{"VUIDGFORMAT", 0x7602},
-{"VOLIOCUNMAP", 0x7602},
-{"VOLIOCEVENT", 0x7603},
-{"VUIDSADDR", 0x7603},
-{"VUIDSADDR", 0x7603},
-{"VUIDGADDR", 0x7604},
-{"VUIDGADDR", 0x7604},
-{"VOLIOCEJECT", 0x7604},
-{"VOLIOCCHECK", 0x7605},
-{"VOLIOCINUSE", 0x7606},
-{"VOLIOCDGATTR", 0x7607},
-{"VOLIOCDSATTR", 0x7608},
-{"VOLIOCDCHECK", 0x7609},
-{"VOLIOCCANCEL", 0x760a},
-{"VOLIOCINFO", 0x760b},
-{"VOLIOCSATTR", 0x760c},
-{"VOLIOCGATTR", 0x760d},
-{"VOLIOCDINUSE", 0x760e},
-{"VOLIOCDAEMON", 0x760f},
-{"VOLIOCFLAGS", 0x7610},
-{"VOLIOCEXTRA4", 0x7611},
-{"VOLIOCEXTRA5", 0x7612},
-{"VOLIOCEXTRA6", 0x7613},
-{"VOLIOCEXTRA7", 0x7614},
-{"S_IOCGETMODE", 0x7a01},
-{"S_IOCSETMODE", 0x7a02},
-{"S_IOCGETSTATS", 0x7a03},
-{"S_IOCCLRSTATS", 0x7a04},
-{"S_IOCGETSPEED", 0x7a05},
-{"S_IOCGETMRU", 0x7a06},
-{"S_IOCSETMRU", 0x7a07},
-{"S_IOCGETMTU", 0x7a08},
-{"S_IOCSETMTU", 0x7a09},
-{"S_IOCGETMCTL", 0x7a0a},
-{"TL_IOC_CREDOPT", 0x544c01},
diff --git a/linux/sparc/print_pc.c b/linux/sparc/print_pc.c
new file mode 100644
index 0000000..683e3b1
--- /dev/null
+++ b/linux/sparc/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, sparc_regs.pc);
diff --git a/linux/sparc/signalent1.h b/linux/sparc/signalent1.h
deleted file mode 100644
index 58869a5..0000000
--- a/linux/sparc/signalent1.h
+++ /dev/null
@@ -1,36 +0,0 @@
- "SIG_0", /* 0 */
- "SIGHUP", /* 1 */
- "SIGINT", /* 2 */
- "SIGQUIT", /* 3 */
- "SIGILL", /* 4 */
- "SIGTRAP", /* 5 */
- "SIGABRT", /* 6 */
- "SIGEMT", /* 7 */
- "SIGFPE", /* 8 */
- "SIGKILL", /* 9 */
- "SIGBUS", /* 10 */
- "SIGSEGV", /* 11 */
- "SIGSYS", /* 12 */
- "SIGPIPE", /* 13 */
- "SIGALRM", /* 14 */
- "SIGTERM", /* 15 */
- "SIGUSR1", /* 16 */
- "SIGUSR2", /* 17 */
- "SIGCHLD", /* 18 */
- "SIGPWR", /* 19 */
- "SIGWINCH", /* 20 */
- "SIGURG", /* 21 */
- "SIGPOLL", /* 22 */
- "SIGSTOP", /* 23 */
- "SIGTSTP", /* 24 */
- "SIGCONT", /* 25 */
- "SIGTTIN", /* 26 */
- "SIGTTOU", /* 27 */
- "SIGVTALRM", /* 28 */
- "SIGPROF", /* 29 */
- "SIGXCPU", /* 30 */
- "SIGXFSZ", /* 31 */
- "SIGWAITING", /* 32 */
- "SIGLWP", /* 33 */
- "SIGFREEZE", /* 34 */
- "SIGTHAW", /* 35 */
diff --git a/linux/sparc/syscall1.h b/linux/sparc/syscall1.h
deleted file mode 100644
index 6f30b74..0000000
--- a/linux/sparc/syscall1.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995 Rick Sladkey <jrs@world.std.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define SOLARIS_syscall 0
-#define SOLARIS_exit 1
-#define SOLARIS_fork 2
-#define SOLARIS_read 3
-#define SOLARIS_write 4
-#define SOLARIS_open 5
-#define SOLARIS_close 6
-#define SOLARIS_wait 7
-#define SOLARIS_creat 8
-#define SOLARIS_link 9
-#define SOLARIS_unlink 10
-#define SOLARIS_exec 11
-#define SOLARIS_chdir 12
-#define SOLARIS_time 13
-#define SOLARIS_mknod 14
-#define SOLARIS_chmod 15
-#define SOLARIS_chown 16
-#define SOLARIS_brk 17
-#define SOLARIS_stat 18
-#define SOLARIS_lseek 19
-#define SOLARIS_getpid 20
-#define SOLARIS_mount 21
-#define SOLARIS_umount 22
-#define SOLARIS_setuid 23
-#define SOLARIS_getuid 24
-#define SOLARIS_stime 25
-#define SOLARIS_ptrace 26
-#define SOLARIS_alarm 27
-#define SOLARIS_fstat 28
-#define SOLARIS_pause 29
-#define SOLARIS_utime 30
-#define SOLARIS_stty 31
-#define SOLARIS_gtty 32
-#define SOLARIS_access 33
-#define SOLARIS_nice 34
-#define SOLARIS_statfs 35
-#define SOLARIS_sync 36
-#define SOLARIS_kill 37
-#define SOLARIS_fstatfs 38
-#define SOLARIS_pgrpsys 39
-#define SOLARIS_xenix 40
-#define SOLARIS_dup 41
-#define SOLARIS_pipe 42
-#define SOLARIS_times 43
-#define SOLARIS_profil 44
-#define SOLARIS_plock 45
-#define SOLARIS_setgid 46
-#define SOLARIS_getgid 47
-#define SOLARIS_signal 48
-#define SOLARIS_msgsys 49
-#define SOLARIS_syssun 50
-#define SOLARIS_acct 51
-#define SOLARIS_shmsys 52
-#define SOLARIS_semsys 53
-#define SOLARIS_ioctl 54
-#define SOLARIS_uadmin 55
-#define SOLARIS_utssys 57
-#define SOLARIS_fdsync 58
-#define SOLARIS_execve 59
-#define SOLARIS_umask 60
-#define SOLARIS_chroot 61
-#define SOLARIS_fcntl 62
-#define SOLARIS_ulimit 63
-#define SOLARIS_rmdir 79
-#define SOLARIS_mkdir 80
-#define SOLARIS_getdents 81
-#define SOLARIS_sysfs 84
-#define SOLARIS_getmsg 85
-#define SOLARIS_putmsg 86
-#define SOLARIS_poll 87
-#define SOLARIS_lstat 88
-#define SOLARIS_symlink 89
-#define SOLARIS_readlink 90
-#define SOLARIS_setgroups 91
-#define SOLARIS_getgroups 92
-#define SOLARIS_fchmod 93
-#define SOLARIS_fchown 94
-#define SOLARIS_sigprocmask 95
-#define SOLARIS_sigsuspend 96
-#define SOLARIS_sigaltstack 97
-#define SOLARIS_sigaction 98
-#define SOLARIS_sigpending 99
-#define SOLARIS_context 100
-#define SOLARIS_evsys 101
-#define SOLARIS_evtrapret 102
-#define SOLARIS_statvfs 103
-#define SOLARIS_fstatvfs 104
-#define SOLARIS_nfssys 106
-#define SOLARIS_waitsys 107
-#define SOLARIS_sigsendsys 108
-#define SOLARIS_hrtsys 109
-#define SOLARIS_acancel 110
-#define SOLARIS_async 111
-#define SOLARIS_priocntlsys 112
-#define SOLARIS_pathconf 113
-#define SOLARIS_mincore 114
-#define SOLARIS_mmap 115
-#define SOLARIS_mprotect 116
-#define SOLARIS_munmap 117
-#define SOLARIS_fpathconf 118
-#define SOLARIS_vfork 119
-#define SOLARIS_fchdir 120
-#define SOLARIS_readv 121
-#define SOLARIS_writev 122
-#define SOLARIS_xstat 123
-#define SOLARIS_lxstat 124
-#define SOLARIS_fxstat 125
-#define SOLARIS_xmknod 126
-#define SOLARIS_clocal 127
-#define SOLARIS_setrlimit 128
-#define SOLARIS_getrlimit 129
-#define SOLARIS_lchown 130
-#define SOLARIS_memcntl 131
-#define SOLARIS_getpmsg 132
-#define SOLARIS_putpmsg 133
-#define SOLARIS_rename 134
-#define SOLARIS_uname 135
-#define SOLARIS_setegid 136
-#define SOLARIS_sysconfig 137
-#define SOLARIS_adjtime 138
-#define SOLARIS_systeminfo 139
-#define SOLARIS_seteuid 141
-#define SOLARIS_vtrace 142
-#define SOLARIS_fork1 143
-#define SOLARIS_sigtimedwait 144
-#define SOLARIS_lwp_info 145
-#define SOLARIS_yield 146
-#define SOLARIS_lwp_sema_wait 147
-#define SOLARIS_lwp_sema_post 148
-#define SOLARIS_modctl 152
-#define SOLARIS_fchroot 153
-#define SOLARIS_utimes 154
-#define SOLARIS_vhangup 155
-#define SOLARIS_gettimeofday 156
-#define SOLARIS_getitimer 157
-#define SOLARIS_setitimer 158
-#define SOLARIS_lwp_create 159
-#define SOLARIS_lwp_exit 160
-#define SOLARIS_lwp_suspend 161
-#define SOLARIS_lwp_continue 162
-#define SOLARIS_lwp_kill 163
-#define SOLARIS_lwp_self 164
-#define SOLARIS_lwp_setprivate 165
-#define SOLARIS_lwp_getprivate 166
-#define SOLARIS_lwp_wait 167
-#define SOLARIS_lwp_mutex_unlock 168
-#define SOLARIS_lwp_mutex_lock 169
-#define SOLARIS_lwp_cond_wait 170
-#define SOLARIS_lwp_cond_signal 171
-#define SOLARIS_lwp_cond_broadcast 172
-#define SOLARIS_pread 173
-#define SOLARIS_pwrite 174
-#define SOLARIS_llseek 175
-#define SOLARIS_inst_sync 176
-#define SOLARIS_kaio 178
-#define SOLARIS_tsolsys 184
-#define SOLARIS_acl 185
-#define SOLARIS_auditsys 186
-#define SOLARIS_processor_bind 187
-#define SOLARIS_processor_info 188
-#define SOLARIS_p_online 189
-#define SOLARIS_sigqueue 190
-#define SOLARIS_clock_gettime 191
-#define SOLARIS_clock_settime 192
-#define SOLARIS_clock_getres 193
-#define SOLARIS_timer_create 194
-#define SOLARIS_timer_delete 195
-#define SOLARIS_timer_settime 196
-#define SOLARIS_timer_gettime 197
-#define SOLARIS_timer_getoverrun 198
-#define SOLARIS_nanosleep 199
-#define SOLARIS_facl 200
-#define SOLARIS_door 201
-#define SOLARIS_setreuid 202
-#define SOLARIS_setregid 203
-#define SOLARIS_signotifywait 210
-#define SOLARIS_lwp_sigredirect 211
-#define SOLARIS_lwp_alarm 212
-
-#include "dummy2.h"
-
-extern int solaris_syscall();
-extern int solaris_exit();
-extern int solaris_fork();
-extern int solaris_read();
-extern int solaris_write();
-extern int solaris_open();
-extern int solaris_close();
-extern int solaris_wait();
-extern int solaris_creat();
-extern int solaris_link();
-extern int solaris_unlink();
-extern int solaris_exec();
-extern int solaris_chdir();
-extern int solaris_time();
-extern int solaris_mknod();
-extern int solaris_chmod();
-extern int solaris_chown();
-extern int solaris_brk();
-extern int solaris_stat();
-extern int solaris_lseek();
-extern int solaris_getpid();
-extern int solaris_mount();
-extern int solaris_umount();
-extern int solaris_setuid();
-extern int solaris_getuid();
-extern int solaris_stime();
-extern int solaris_ptrace();
-extern int solaris_alarm();
-extern int solaris_fstat();
-extern int solaris_pause();
-extern int solaris_utime();
-extern int solaris_stty();
-extern int solaris_gtty();
-extern int solaris_access();
-extern int solaris_nice();
-extern int solaris_statfs();
-extern int solaris_sync();
-extern int solaris_kill();
-extern int solaris_fstatfs();
-extern int solaris_pgrpsys();
-extern int solaris_setpgrp();
-extern int solaris_xenix();
-extern int solaris_syssgi();
-extern int solaris_dup();
-extern int solaris_pipe();
-extern int solaris_times();
-extern int solaris_profil();
-extern int solaris_plock();
-extern int solaris_setgid();
-extern int solaris_getgid();
-extern int solaris_sigcall();
-extern int solaris_msgsys();
-extern int solaris_syssun();
-extern int solaris_sysi86();
-extern int solaris_sysmips();
-extern int solaris_sysmachine();
-extern int solaris_acct();
-extern int solaris_shmsys();
-extern int solaris_semsys();
-extern int solaris_ioctl();
-extern int solaris_uadmin();
-extern int solaris_utssys();
-extern int solaris_fdsync();
-extern int solaris_execve();
-extern int solaris_umask();
-extern int solaris_chroot();
-extern int solaris_fcntl();
-extern int solaris_ulimit();
-extern int solaris_rmdir();
-extern int solaris_mkdir();
-extern int solaris_getdents();
-extern int solaris_sysfs();
-extern int solaris_getmsg();
-extern int solaris_putmsg();
-extern int solaris_poll();
-extern int solaris_lstat();
-extern int solaris_symlink();
-extern int solaris_readlink();
-extern int solaris_setgroups();
-extern int solaris_getgroups();
-extern int solaris_fchmod();
-extern int solaris_fchown();
-extern int solaris_sigprocmask();
-extern int solaris_sigsuspend();
-extern int solaris_sigaltstack();
-extern int solaris_sigaction();
-extern int solaris_spcall();
-extern int solaris_context();
-extern int solaris_evsys();
-extern int solaris_evtrapret();
-extern int solaris_statvfs();
-extern int solaris_fstatvfs();
-extern int solaris_nfssys();
-extern int solaris_waitid();
-extern int solaris_sigsendsys();
-extern int solaris_hrtsys();
-extern int solaris_acancel();
-extern int solaris_async();
-extern int solaris_priocntlsys();
-extern int solaris_pathconf();
-extern int solaris_mincore();
-extern int solaris_mmap();
-extern int solaris_mprotect();
-extern int solaris_munmap();
-extern int solaris_fpathconf();
-extern int solaris_vfork();
-extern int solaris_fchdir();
-extern int solaris_readv();
-extern int solaris_writev();
-extern int solaris_xstat();
-extern int solaris_lxstat();
-extern int solaris_fxstat();
-extern int solaris_xmknod();
-extern int solaris_clocal();
-extern int solaris_setrlimit();
-extern int solaris_getrlimit();
-extern int solaris_lchown();
-extern int solaris_memcntl();
-extern int solaris_getpmsg();
-extern int solaris_putpmsg();
-extern int solaris_rename();
-extern int solaris_uname();
-extern int solaris_setegid();
-extern int solaris_sysconfig();
-extern int solaris_adjtime();
-extern int solaris_sysinfo();
-extern int solaris_seteuid();
-extern int solaris_vtrace();
-extern int solaris_fork1();
-extern int solaris_sigtimedwait();
-extern int solaris_lwp_info();
-extern int solaris_yield();
-extern int solaris_lwp_sema_wait();
-extern int solaris_lwp_sema_post();
-extern int solaris_modctl();
-extern int solaris_fchroot();
-extern int solaris_utimes();
-extern int solaris_vhangup();
-extern int solaris_gettimeofday();
-extern int solaris_getitimer();
-extern int solaris_setitimer();
-extern int solaris_lwp_create();
-extern int solaris_lwp_exit();
-extern int solaris_lwp_suspend();
-extern int solaris_lwp_continue();
-extern int solaris_lwp_kill();
-extern int solaris_lwp_self();
-extern int solaris_lwp_setprivate();
-extern int solaris_lwp_getprivate();
-extern int solaris_lwp_wait();
-extern int solaris_lwp_mutex_unlock();
-extern int solaris_lwp_mutex_lock();
-extern int solaris_lwp_cond_wait();
-extern int solaris_lwp_cond_signal();
-extern int solaris_lwp_cond_broadcast();
-extern int solaris_pread();
-extern int solaris_pwrite();
-extern int solaris_llseek();
-extern int solaris_inst_sync();
-extern int solaris_auditsys();
-extern int solaris_processor_bind();
-extern int solaris_processor_info();
-extern int solaris_p_online();
-extern int solaris_sigqueue();
-extern int solaris_clock_gettime();
-extern int solaris_clock_settime();
-extern int solaris_clock_getres();
-extern int solaris_timer_create();
-extern int solaris_timer_delete();
-extern int solaris_timer_settime();
-extern int solaris_timer_gettime();
-extern int solaris_timer_getoverrun();
-extern int solaris_nanosleep();
-
-/* solaris_pgrpsys subcalls */
-
-extern int solaris_getpgrp(), solaris_setpgrp(), solaris_getsid();
-extern int solaris_setsid(), solaris_getpgid(), solaris_setpgid();
-
-#define SOLARIS_pgrpsys_subcall 300
-#define SOLARIS_getpgrp (SOLARIS_pgrpsys_subcall + 0)
-#define SOLARIS_setpgrp (SOLARIS_pgrpsys_subcall + 1)
-#define SOLARIS_getsid (SOLARIS_pgrpsys_subcall + 2)
-#define SOLARIS_setsid (SOLARIS_pgrpsys_subcall + 3)
-#define SOLARIS_getpgid (SOLARIS_pgrpsys_subcall + 4)
-#define SOLARIS_setpgid (SOLARIS_pgrpsys_subcall + 5)
-
-#define SOLARIS_pgrpsys_nsubcalls 6
-
-/* solaris_sigcall subcalls */
-
-#undef SOLARIS_signal
-#define SOLARIS_sigcall 48
-
-extern int solaris_signal(), solaris_sigset(), solaris_sighold();
-extern int solaris_sigrelse(), solaris_sigignore(), solaris_sigpause();
-
-#define SOLARIS_sigcall_subcall 310
-#define SOLARIS_signal (SOLARIS_sigcall_subcall + 0)
-#define SOLARIS_sigset (SOLARIS_sigcall_subcall + 1)
-#define SOLARIS_sighold (SOLARIS_sigcall_subcall + 2)
-#define SOLARIS_sigrelse (SOLARIS_sigcall_subcall + 3)
-#define SOLARIS_sigignore (SOLARIS_sigcall_subcall + 4)
-#define SOLARIS_sigpause (SOLARIS_sigcall_subcall + 5)
-
-#define SOLARIS_sigcall_nsubcalls 6
-
-/* msgsys subcalls */
-
-extern int solaris_msgget(), solaris_msgctl(), solaris_msgrcv(), solaris_msgsnd();
-
-#define SOLARIS_msgsys_subcall 320
-#define SOLARIS_msgget (SOLARIS_msgsys_subcall + 0)
-#define SOLARIS_msgctl (SOLARIS_msgsys_subcall + 1)
-#define SOLARIS_msgrcv (SOLARIS_msgsys_subcall + 2)
-#define SOLARIS_msgsnd (SOLARIS_msgsys_subcall + 3)
-
-#define SOLARIS_msgsys_nsubcalls 4
-
-/* shmsys subcalls */
-
-extern int solaris_shmat(), solaris_shmctl(), solaris_shmdt(), solaris_shmget();
-
-#define SOLARIS_shmsys_subcall 330
-#define SOLARIS_shmat (SOLARIS_shmsys_subcall + 0)
-#define SOLARIS_shmctl (SOLARIS_shmsys_subcall + 1)
-#define SOLARIS_shmdt (SOLARIS_shmsys_subcall + 2)
-#define SOLARIS_shmget (SOLARIS_shmsys_subcall + 3)
-
-#define SOLARIS_shmsys_nsubcalls 4
-
-/* semsys subcalls */
-
-extern int solaris_semctl(), solaris_semget(), solaris_semop();
-
-#define SOLARIS_semsys_subcall 340
-#define SOLARIS_semctl (SOLARIS_semsys_subcall + 0)
-#define SOLARIS_semget (SOLARIS_semsys_subcall + 1)
-#define SOLARIS_semop (SOLARIS_semsys_subcall + 2)
-
-#define SOLARIS_semsys_nsubcalls 3
-
-/* utssys subcalls */
-
-extern int solaris_olduname(), solaris_ustat(), solaris_fusers();
-
-#define SOLARIS_utssys_subcall 350
-
-#define SOLARIS_olduname (SOLARIS_utssys_subcall + 0)
- /* 1 is unused */
-#define SOLARIS_ustat (SOLARIS_utssys_subcall + 2)
-#define SOLARIS_fusers (SOLARIS_utssys_subcall + 3)
-
-#define SOLARIS_utssys_nsubcalls 4
-
-/* sysfs subcalls */
-
-extern int solaris_sysfs1(), solaris_sysfs2(), solaris_sysfs3();
-
-#define SOLARIS_sysfs_subcall 360
- /* 0 is unused */
-#define SOLARIS_sysfs1 (SOLARIS_sysfs_subcall + 1)
-#define SOLARIS_sysfs2 (SOLARIS_sysfs_subcall + 2)
-#define SOLARIS_sysfs3 (SOLARIS_sysfs_subcall + 3)
-
-#define SOLARIS_sysfs_nsubcalls 4
-
-/* solaris_spcall subcalls */
-
-#undef SOLARIS_sigpending
-#define SOLARIS_spcall 99
-
-extern int solaris_sigpending(), solaris_sigfillset();
-
-#define SOLARIS_spcall_subcall 370
- /* 0 is unused */
-#define SOLARIS_sigpending (SOLARIS_spcall_subcall + 1)
-#define SOLARIS_sigfillset (SOLARIS_spcall_subcall + 2)
-
-#define SOLARIS_spcall_nsubcalls 3
-
-/* solaris_context subcalls */
-
-extern int solaris_getcontext(), solaris_setcontext();
-
-#define SOLARIS_context_subcall 380
-#define SOLARIS_getcontext (SOLARIS_context_subcall + 0)
-#define SOLARIS_setcontext (SOLARIS_context_subcall + 1)
-
-#define SOLARIS_context_nsubcalls 2
diff --git a/linux/sparc/syscallent.h b/linux/sparc/syscallent.h
index 3ccbd71..18fd65e 100644
--- a/linux/sparc/syscallent.h
+++ b/linux/sparc/syscallent.h
@@ -54,7 +54,7 @@
[ 53] = { 0, NF, sys_getgid, "getgid32" },
[ 54] = { 3, TD, sys_ioctl, "ioctl" },
[ 55] = { 4, 0, sys_reboot, "reboot" },
-[ 56] = { 6, TD|TM|SI, sys_mmap, "mmap2" },
+[ 56] = { 6, TD|TM|SI, sys_mmap_4koff, "mmap2" },
[ 57] = { 2, TF, sys_symlink, "symlink" },
[ 58] = { 3, TF, sys_readlink, "readlink" },
[ 59] = { 3, TF|TP|SE|SI, sys_execve, "execve" },
diff --git a/linux/sparc/syscallent1.h b/linux/sparc/syscallent1.h
deleted file mode 100644
index 2e2805b..0000000
--- a/linux/sparc/syscallent1.h
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
- { 6, 0, solaris_syscall, "syscall" }, /* 0 */
- { 6, TP, solaris_exit, "_exit" }, /* 1 */
- { 6, TP, solaris_fork, "fork" }, /* 2 */
- { 6, 0, solaris_read, "read" }, /* 3 */
- { 6, 0, solaris_write, "write" }, /* 4 */
- { 6, TF, solaris_open, "open" }, /* 5 */
- { 6, 0, solaris_close, "close" }, /* 6 */
- { 6, TP, solaris_wait, "wait" }, /* 7 */
- { 6, TF, solaris_creat, "creat" }, /* 8 */
- { 6, TF, solaris_link, "link" }, /* 9 */
- { 6, TF, solaris_unlink, "unlink" }, /* 10 */
- { 6, TF|TP, solaris_exec, "exec" }, /* 11 */
- { 6, TF, solaris_chdir, "chdir" }, /* 12 */
- { 6, 0, solaris_time, "time" }, /* 13 */
- { 6, TF, solaris_mknod, "mknod" }, /* 14 */
- { 6, TF, solaris_chmod, "chmod" }, /* 15 */
- { 6, TF, solaris_chown, "chown" }, /* 16 */
- { 6, 0, solaris_brk, "brk" }, /* 17 */
- { 6, TF, solaris_stat, "stat" }, /* 18 */
- { 6, 0, solaris_lseek, "lseek" }, /* 19 */
- { 6, 0, solaris_getpid, "getpid" }, /* 20 */
- { 6, TF, solaris_mount, "mount" }, /* 21 */
- { 6, TF, solaris_umount, "umount" }, /* 22 */
- { 6, 0, solaris_setuid, "setuid" }, /* 23 */
- { 6, 0, solaris_getuid, "getuid" }, /* 24 */
- { 6, 0, solaris_stime, "stime" }, /* 25 */
- { 6, 0, solaris_ptrace, "ptrace" }, /* 26 */
- { 6, 0, solaris_alarm, "alarm" }, /* 27 */
- { 6, 0, solaris_fstat, "fstat" }, /* 28 */
- { 6, TS, solaris_pause, "pause" }, /* 29 */
- { 6, TF, solaris_utime, "utime" }, /* 30 */
- { 6, 0, solaris_stty, "stty" }, /* 31 */
- { 6, 0, solaris_gtty, "gtty" }, /* 32 */
- { 6, TF, solaris_access, "access" }, /* 33 */
- { 6, 0, solaris_nice, "nice" }, /* 34 */
- { 6, TF, solaris_statfs, "statfs" }, /* 35 */
- { 6, 0, solaris_sync, "sync" }, /* 36 */
- { 6, TS, solaris_kill, "kill" }, /* 37 */
- { 6, 0, solaris_fstatfs, "fstatfs" }, /* 38 */
- { 6, 0, solaris_pgrpsys, "pgrpsys" }, /* 39 */
- { 6, 0, solaris_xenix, "xenix" }, /* 40 */
- { 6, 0, solaris_dup, "dup" }, /* 41 */
- { 6, 0, solaris_pipe, "pipe" }, /* 42 */
- { 6, 0, solaris_times, "times" }, /* 43 */
- { 6, 0, solaris_profil, "profil" }, /* 44 */
- { 6, 0, solaris_plock, "plock" }, /* 45 */
- { 6, 0, solaris_setgid, "setgid" }, /* 46 */
- { 6, 0, solaris_getgid, "getgid" }, /* 47 */
- { 6, 0, solaris_sigcall, "sigcall" }, /* 48 */
- { 6, TI, solaris_msgsys, "msgsys" }, /* 49 */
- { 6, 0, solaris_syssun, "syssun" }, /* 50 */
- { 6, TF, solaris_acct, "acct" }, /* 51 */
- { 6, TI, solaris_shmsys, "shmsys" }, /* 52 */
- { 6, TI, solaris_semsys, "semsys" }, /* 53 */
- { 6, 0, solaris_ioctl, "ioctl" }, /* 54 */
- { 6, 0, solaris_uadmin, "uadmin" }, /* 55 */
- { 6, 0, solaris_sysmp, "sysmp" }, /* 56 */
- { 6, 0, solaris_utssys, "utssys" }, /* 57 */
- { 6, 0, solaris_fdsync, "fdsync" }, /* 58 */
- { 6, TF|TP, solaris_execve, "execve" }, /* 59 */
- { 6, 0, solaris_umask, "umask" }, /* 60 */
- { 6, TF, solaris_chroot, "chroot" }, /* 61 */
- { 6, 0, solaris_fcntl, "fcntl" }, /* 62 */
- { 6, 0, solaris_ulimit, "ulimit" }, /* 63 */
- { 6, 0, NULL, NULL }, /* 64 */
- { 6, 0, NULL, NULL }, /* 65 */
- { 6, 0, NULL, NULL }, /* 66 */
- { 6, 0, NULL, NULL }, /* 67 */
- { 6, 0, NULL, NULL }, /* 68 */
- { 6, 0, NULL, NULL }, /* 69 */
- { 6, 0, NULL, NULL }, /* 70 */
- { 6, 0, NULL, NULL }, /* 71 */
- { 6, 0, NULL, NULL }, /* 72 */
- { 6, 0, NULL, NULL }, /* 73 */
- { 6, 0, NULL, NULL }, /* 74 */
- { 6, 0, NULL, NULL }, /* 75 */
- { 6, 0, NULL, NULL }, /* 76 */
- { 6, 0, NULL, NULL }, /* 77 */
- { 6, 0, NULL, NULL }, /* 78 */
- { 6, TF, solaris_rmdir, "rmdir" }, /* 79 */
- { 6, TF, solaris_mkdir, "mkdir" }, /* 80 */
- { 6, 0, solaris_getdents, "getdents" }, /* 81 */
- { 6, 0, solaris_sginap, "sginap" }, /* 82 */
- { 6, 0, solaris_sgikopt, "sgikopt" }, /* 83 */
- { 6, 0, solaris_sysfs, "sysfs" }, /* 84 */
- { 6, TN, sys_getmsg, "getmsg" }, /* 85 */
- { 6, TN, sys_putmsg, "putmsg" }, /* 86 */
- { 6, TN, solaris_poll, "poll" }, /* 87 */
- { 6, TF, solaris_lstat, "lstat" }, /* 88 */
- { 6, TF, solaris_symlink, "symlink" }, /* 89 */
- { 6, TF, solaris_readlink, "readlink" }, /* 90 */
- { 6, 0, solaris_setgroups, "setgroups" }, /* 91 */
- { 6, 0, solaris_getgroups, "getgroups" }, /* 92 */
- { 6, 0, solaris_fchmod, "fchmod" }, /* 93 */
- { 6, 0, solaris_fchown, "fchown" }, /* 94 */
- { 6, TS, solaris_sigprocmask, "sigprocmask" }, /* 95 */
- { 6, TS, solaris_sigsuspend, "sigsuspend" }, /* 96 */
- { 6, TS, solaris_sigaltstack, "sigaltstack" }, /* 97 */
- { 6, TS, solaris_sigaction, "sigaction" }, /* 98 */
- { 6, 0, solaris_spcall, "spcall" }, /* 99 */
- { 6, 0, solaris_context, "context" }, /* 100 */
- { 6, 0, solaris_evsys, "evsys" }, /* 101 */
- { 6, 0, solaris_evtrapret, "evtrapret" }, /* 102 */
- { 6, TF, solaris_statvfs, "statvfs" }, /* 103 */
- { 6, 0, solaris_fstatvfs, "fstatvfs" }, /* 104 */
- { 6, 0, NULL, NULL }, /* 105 */
- { 6, 0, solaris_nfssys, "nfssys" }, /* 106 */
- { 6, TP, solaris_waitid, "waitid" }, /* 107 */
- { 6, 0, solaris_sigsendsys, "sigsendsys" }, /* 108 */
- { 6, 0, solaris_hrtsys, "hrtsys" }, /* 109 */
- { 6, 0, solaris_acancel, "acancel" }, /* 110 */
- { 6, 0, solaris_async, "async" }, /* 111 */
- { 6, 0, solaris_priocntlsys, "priocntlsys" }, /* 112 */
- { 6, TF, solaris_pathconf, "pathconf" }, /* 113 */
- { 6, 0, solaris_mincore, "mincore" }, /* 114 */
- { 6, TD|TM, solaris_mmap, "mmap" }, /* 115 */
- { 6, 0, solaris_mprotect, "mprotect" }, /* 116 */
- { 6, 0, solaris_munmap, "munmap" }, /* 117 */
- { 6, 0, solaris_fpathconf, "fpathconf" }, /* 118 */
- { 6, TP, solaris_vfork, "vfork" }, /* 119 */
- { 6, 0, solaris_fchdir, "fchdir" }, /* 120 */
- { 6, 0, solaris_readv, "readv" }, /* 121 */
- { 6, 0, solaris_writev, "writev" }, /* 122 */
- { 6, TF, solaris_xstat, "xstat" }, /* 123 */
- { 6, TF, solaris_lxstat, "lxstat" }, /* 124 */
- { 6, 0, solaris_fxstat, "fxstat" }, /* 125 */
- { 6, TF, solaris_xmknod, "xmknod" }, /* 126 */
- { 6, 0, solaris_clocal, "clocal" }, /* 127 */
- { 6, 0, solaris_setrlimit, "setrlimit" }, /* 128 */
- { 6, 0, solaris_getrlimit, "getrlimit" }, /* 129 */
- { 6, TF, solaris_lchown, "lchown" }, /* 130 */
- { 6, 0, solaris_memcntl, "memcntl" }, /* 131 */
- { 6, TN, solaris_getpmsg, "getpmsg" }, /* 132 */
- { 6, TN, solaris_putpmsg, "putpmsg" }, /* 133 */
- { 6, TF, solaris_rename, "rename" }, /* 134 */
- { 6, 0, solaris_uname, "uname" }, /* 135 */
- { 6, 0, solaris_setegid, "setegid" }, /* 136 */
- { 6, 0, solaris_sysconfig, "sysconfig" }, /* 137 */
- { 6, 0, solaris_adjtime, "adjtime" }, /* 138 */
- { 6, 0, solaris_sysinfo, "sysinfo" }, /* 139 */
- { 6, 0, NULL, NULL }, /* 140 */
- { 6, 0, solaris_seteuid, "seteuid" }, /* 141 */
- { 6, 0, solaris_vtrace, "vtrace" }, /* 142 */
- { 6, TP, solaris_fork1, "fork1" }, /* 143 */
- { 6, TS, solaris_sigtimedwait, "sigtimedwait" }, /* 144 */
- { 6, 0, solaris_lwp_info, "lwp_info" }, /* 145 */
- { 6, 0, solaris_yield, "yield" }, /* 146 */
- { 6, 0, solaris_lwp_sema_wait, "lwp_sema_wait" }, /* 147 */
- { 6, 0, solaris_lwp_sema_post, "lwp_sema_post" }, /* 148 */
- { 6, 0, NULL, NULL }, /* 149 */
- { 6, 0, NULL, NULL }, /* 150 */
- { 6, 0, NULL, NULL }, /* 151 */
- { 6, 0, solaris_modctl, "modctl" }, /* 152 */
- { 6, 0, solaris_fchroot, "fchroot" }, /* 153 */
- { 6, TF, solaris_utimes, "utimes" }, /* 154 */
- { 6, 0, solaris_vhangup, "vhangup" }, /* 155 */
- { 6, 0, solaris_gettimeofday, "gettimeofday" }, /* 156 */
- { 6, 0, solaris_getitimer, "getitimer" }, /* 157 */
- { 6, 0, solaris_setitimer, "setitimer" }, /* 158 */
- { 6, 0, solaris_lwp_create, "lwp_create" }, /* 159 */
- { 6, 0, solaris_lwp_exit, "lwp_exit" }, /* 160 */
- { 6, 0, solaris_lwp_suspend, "lwp_suspend" }, /* 161 */
- { 6, 0, solaris_lwp_continue, "lwp_continue" }, /* 162 */
- { 6, 0, solaris_lwp_kill, "lwp_kill" }, /* 163 */
- { 6, 0, solaris_lwp_self, "lwp_self" }, /* 164 */
- { 6, 0, solaris_lwp_setprivate, "lwp_setprivate"}, /* 165 */
- { 6, 0, solaris_lwp_getprivate, "lwp_getprivate"}, /* 166 */
- { 6, 0, solaris_lwp_wait, "lwp_wait" }, /* 167 */
- { 6, 0, solaris_lwp_mutex_unlock,"lwp_mutex_unlock"}, /* 168 */
- { 6, 0, solaris_lwp_mutex_lock, "lwp_mutex_lock"}, /* 169 */
- { 6, 0, solaris_lwp_cond_wait, "lwp_cond_wait"}, /* 170 */
- { 6, 0, solaris_lwp_cond_signal,"lwp_cond_signal"}, /* 171 */
- { 6, 0, solaris_lwp_cond_broadcast,"lwp_cond_broadcast"}, /* 172 */
- { 6, 0, solaris_pread, "pread" }, /* 173 */
- { 6, 0, solaris_pwrite, "pwrite" }, /* 174 */
- { 6, 0, solaris_llseek, "llseek" }, /* 175 */
- { 6, 0, solaris_inst_sync, "inst_sync" }, /* 176 */
- { 6, 0, NULL, NULL }, /* 177 */
- { 6, 0, NULL, NULL }, /* 178 */
- { 6, 0, NULL, NULL }, /* 179 */
- { 6, 0, NULL, NULL }, /* 180 */
- { 6, 0, NULL, NULL }, /* 181 */
- { 6, 0, NULL, NULL }, /* 182 */
- { 6, 0, NULL, NULL }, /* 183 */
- { 6, 0, NULL, NULL }, /* 184 */
- { 6, 0, NULL, NULL }, /* 185 */
- { 6, 0, solaris_auditsys, "auditsys" }, /* 186 */
- { 6, 0, solaris_processor_bind, "processor_bind"}, /* 187 */
- { 6, 0, solaris_processor_info, "processor_info"}, /* 188 */
- { 6, 0, solaris_p_online, "p_online" }, /* 189 */
- { 6, 0, solaris_sigqueue, "sigqueue" }, /* 190 */
- { 6, 0, solaris_clock_gettime, "clock_gettime" }, /* 191 */
- { 6, 0, solaris_clock_settime, "clock_settime" }, /* 192 */
- { 6, 0, solaris_clock_getres, "clock_getres" }, /* 193 */
- { 6, 0, solaris_timer_create, "timer_create" }, /* 194 */
- { 6, 0, solaris_timer_delete, "timer_delete" }, /* 195 */
- { 6, 0, solaris_timer_settime, "timer_settime" }, /* 196 */
- { 6, 0, solaris_timer_gettime, "timer_gettime" }, /* 197 */
- { 6, 0, solaris_timer_getoverrun,"timer_getoverrun"}, /* 198 */
- { 6, 0, solaris_nanosleep, "nanosleep" }, /* 199 */
- { 6, 0, NULL, NULL }, /* 200 */
- { 6, 0, NULL, NULL }, /* 201 */
- { 6, 0, NULL, NULL }, /* 202 */
- { 6, 0, NULL, NULL }, /* 203 */
- { 6, 0, NULL, NULL }, /* 204 */
- { 6, 0, NULL, NULL }, /* 205 */
- { 6, 0, NULL, NULL }, /* 206 */
- { 6, 0, NULL, NULL }, /* 207 */
- { 6, 0, NULL, NULL }, /* 208 */
- { 6, 0, NULL, NULL }, /* 209 */
- { 6, 0, NULL, NULL }, /* 210 */
- { 6, 0, NULL, NULL }, /* 211 */
- { 6, 0, NULL, NULL }, /* 212 */
- { 6, 0, NULL, NULL }, /* 213 */
- { 6, 0, NULL, NULL }, /* 214 */
- { 6, 0, NULL, NULL }, /* 215 */
- { 6, 0, NULL, NULL }, /* 216 */
- { 6, 0, NULL, NULL }, /* 217 */
- { 6, 0, NULL, NULL }, /* 218 */
- { 6, 0, NULL, NULL }, /* 219 */
- { 6, 0, NULL, NULL }, /* 220 */
- { 6, 0, NULL, NULL }, /* 221 */
- { 6, 0, NULL, NULL }, /* 222 */
- { 6, 0, NULL, NULL }, /* 223 */
- { 6, 0, NULL, NULL }, /* 224 */
- { 6, 0, NULL, NULL }, /* 225 */
- { 6, 0, NULL, NULL }, /* 226 */
- { 6, 0, NULL, NULL }, /* 227 */
- { 6, 0, NULL, NULL }, /* 228 */
- { 6, 0, NULL, NULL }, /* 229 */
- { 6, 0, NULL, NULL }, /* 230 */
- { 6, 0, NULL, NULL }, /* 231 */
- { 6, 0, NULL, NULL }, /* 232 */
- { 6, 0, NULL, NULL }, /* 233 */
- { 6, 0, NULL, NULL }, /* 234 */
- { 6, 0, NULL, NULL }, /* 235 */
- { 6, 0, NULL, NULL }, /* 236 */
- { 6, 0, NULL, NULL }, /* 237 */
- { 6, 0, NULL, NULL }, /* 238 */
- { 6, 0, NULL, NULL }, /* 239 */
- { 6, 0, NULL, NULL }, /* 240 */
- { 6, 0, NULL, NULL }, /* 241 */
- { 6, 0, NULL, NULL }, /* 242 */
- { 6, 0, NULL, NULL }, /* 243 */
- { 6, 0, NULL, NULL }, /* 244 */
- { 6, 0, NULL, NULL }, /* 245 */
- { 6, 0, NULL, NULL }, /* 246 */
- { 6, 0, NULL, NULL }, /* 247 */
- { 6, 0, NULL, NULL }, /* 248 */
- { 6, 0, NULL, NULL }, /* 249 */
- { 6, 0, NULL, NULL }, /* 250 */
- { 6, 0, NULL, NULL }, /* 251 */
- { 6, 0, NULL, NULL }, /* 252 */
- { 6, 0, NULL, NULL }, /* 253 */
- { 6, 0, NULL, NULL }, /* 254 */
- { 6, 0, NULL, NULL }, /* 255 */
- { 6, 0, NULL, NULL }, /* 256 */
- { 6, 0, NULL, NULL }, /* 257 */
- { 6, 0, NULL, NULL }, /* 258 */
- { 6, 0, NULL, NULL }, /* 259 */
- { 6, 0, NULL, NULL }, /* 260 */
- { 6, 0, NULL, NULL }, /* 261 */
- { 6, 0, NULL, NULL }, /* 262 */
- { 6, 0, NULL, NULL }, /* 263 */
- { 6, 0, NULL, NULL }, /* 264 */
- { 6, 0, NULL, NULL }, /* 265 */
- { 6, 0, NULL, NULL }, /* 266 */
- { 6, 0, NULL, NULL }, /* 267 */
- { 6, 0, NULL, NULL }, /* 268 */
- { 6, 0, NULL, NULL }, /* 269 */
- { 6, 0, NULL, NULL }, /* 270 */
- { 6, 0, NULL, NULL }, /* 271 */
- { 6, 0, NULL, NULL }, /* 272 */
- { 6, 0, NULL, NULL }, /* 273 */
- { 6, 0, NULL, NULL }, /* 274 */
- { 6, 0, NULL, NULL }, /* 275 */
- { 6, 0, NULL, NULL }, /* 276 */
- { 6, 0, NULL, NULL }, /* 277 */
- { 6, 0, NULL, NULL }, /* 278 */
- { 6, 0, NULL, NULL }, /* 279 */
- { 6, 0, NULL, NULL }, /* 280 */
- { 6, 0, NULL, NULL }, /* 281 */
- { 6, 0, NULL, NULL }, /* 282 */
- { 6, 0, NULL, NULL }, /* 283 */
- { 6, 0, NULL, NULL }, /* 284 */
- { 6, 0, NULL, NULL }, /* 285 */
- { 6, 0, NULL, NULL }, /* 286 */
- { 6, 0, NULL, NULL }, /* 287 */
- { 6, 0, NULL, NULL }, /* 288 */
- { 6, 0, NULL, NULL }, /* 289 */
- { 6, 0, NULL, NULL }, /* 290 */
- { 6, 0, NULL, NULL }, /* 291 */
- { 6, 0, NULL, NULL }, /* 292 */
- { 6, 0, NULL, NULL }, /* 293 */
- { 6, 0, NULL, NULL }, /* 294 */
- { 6, 0, NULL, NULL }, /* 295 */
- { 6, 0, NULL, NULL }, /* 296 */
- { 6, 0, NULL, NULL }, /* 297 */
- { 6, 0, NULL, NULL }, /* 298 */
- { 6, 0, NULL, NULL }, /* 299 */
-
- { 6, 0, solaris_getpgrp, "getpgrp" }, /* 300 */
- { 6, 0, solaris_setpgrp, "setpgrp" }, /* 301 */
- { 6, 0, solaris_getsid, "getsid" }, /* 302 */
- { 6, 0, solaris_setsid, "setsid" }, /* 303 */
- { 6, 0, solaris_getpgid, "getpgid" }, /* 304 */
- { 6, 0, solaris_setpgid, "setpgid" }, /* 305 */
- { 6, 0, NULL, NULL }, /* 306 */
- { 6, 0, NULL, NULL }, /* 307 */
- { 6, 0, NULL, NULL }, /* 308 */
- { 6, 0, NULL, NULL }, /* 309 */
-
- { 6, TS, solaris_signal, "signal" }, /* 310 */
- { 6, TS, solaris_sigset, "sigset" }, /* 311 */
- { 6, TS, solaris_sighold, "sighold" }, /* 312 */
- { 6, TS, solaris_sigrelse, "sigrelse" }, /* 313 */
- { 6, TS, solaris_sigignore, "sigignore" }, /* 314 */
- { 6, TS, solaris_sigpause, "sigpause" }, /* 315 */
- { 6, 0, NULL, NULL }, /* 316 */
- { 6, 0, NULL, NULL }, /* 317 */
- { 6, 0, NULL, NULL }, /* 318 */
- { 6, 0, NULL, NULL }, /* 319 */
-
- { 6, TI, solaris_msgget, "msgget" }, /* 320 */
- { 6, TI, solaris_msgctl, "msgctl" }, /* 321 */
- { 6, TI, solaris_msgrcv, "msgrcv" }, /* 322 */
- { 6, TI, solaris_msgsnd, "msgsnd" }, /* 323 */
- { 6, 0, NULL, NULL }, /* 324 */
- { 6, 0, NULL, NULL }, /* 325 */
- { 6, 0, NULL, NULL }, /* 326 */
- { 6, 0, NULL, NULL }, /* 327 */
- { 6, 0, NULL, NULL }, /* 328 */
- { 6, 0, NULL, NULL }, /* 329 */
-
- { 6, TI|TM, solaris_shmat, "shmat" }, /* 330 */
- { 6, TI, solaris_shmctl, "shmctl" }, /* 331 */
- { 6, TI|TM, solaris_shmdt, "shmdt" }, /* 332 */
- { 6, TI, solaris_shmget, "shmget" }, /* 333 */
- { 6, 0, NULL, NULL }, /* 334 */
- { 6, 0, NULL, NULL }, /* 335 */
- { 6, 0, NULL, NULL }, /* 336 */
- { 6, 0, NULL, NULL }, /* 337 */
- { 6, 0, NULL, NULL }, /* 338 */
- { 6, 0, NULL, NULL }, /* 339 */
-
- { 6, TI, solaris_semctl, "semctl" }, /* 340 */
- { 6, TI, solaris_semget, "semget" }, /* 341 */
- { 6, TI, solaris_semop, "semop" }, /* 342 */
- { 6, 0, NULL, NULL }, /* 343 */
- { 6, 0, NULL, NULL }, /* 344 */
- { 6, 0, NULL, NULL }, /* 345 */
- { 6, 0, NULL, NULL }, /* 346 */
- { 6, 0, NULL, NULL }, /* 347 */
- { 6, 0, NULL, NULL }, /* 348 */
- { 6, 0, NULL, NULL }, /* 349 */
-
- { 6, 0, solaris_olduname, "olduname" }, /* 350 */
- { 6, 0, printargs, "utssys1" }, /* 351 */
- { 6, 0, solaris_ustat, "ustat" }, /* 352 */
- { 6, 0, solaris_fusers, "fusers" }, /* 353 */
- { 6, 0, NULL, NULL }, /* 354 */
- { 6, 0, NULL, NULL }, /* 355 */
- { 6, 0, NULL, NULL }, /* 356 */
- { 6, 0, NULL, NULL }, /* 357 */
- { 6, 0, NULL, NULL }, /* 358 */
- { 6, 0, NULL, NULL }, /* 359 */
-
- { 6, 0, printargs, "sysfs0" }, /* 360 */
- { 6, 0, solaris_sysfs1, "sysfs1" }, /* 361 */
- { 6, 0, solaris_sysfs2, "sysfs2" }, /* 362 */
- { 6, 0, solaris_sysfs3, "sysfs3" }, /* 363 */
- { 6, 0, NULL, NULL }, /* 364 */
- { 6, 0, NULL, NULL }, /* 365 */
- { 6, 0, NULL, NULL }, /* 366 */
- { 6, 0, NULL, NULL }, /* 367 */
- { 6, 0, NULL, NULL }, /* 368 */
- { 6, 0, NULL, NULL }, /* 369 */
-
- { 6, 0, printargs, "spcall0" }, /* 370 */
- { 6, TS, solaris_sigpending, "sigpending" }, /* 371 */
- { 6, TS, solaris_sigfillset, "sigfillset" }, /* 372 */
- { 6, 0, NULL, NULL }, /* 373 */
- { 6, 0, NULL, NULL }, /* 374 */
- { 6, 0, NULL, NULL }, /* 375 */
- { 6, 0, NULL, NULL }, /* 376 */
- { 6, 0, NULL, NULL }, /* 377 */
- { 6, 0, NULL, NULL }, /* 378 */
- { 6, 0, NULL, NULL }, /* 379 */
-
- { 6, 0, solaris_getcontext, "getcontext" }, /* 380 */
- { 6, 0, solaris_setcontext, "setcontext" }, /* 381 */
- { 6, 0, NULL, NULL }, /* 382 */
- { 6, 0, NULL, NULL }, /* 383 */
- { 6, 0, NULL, NULL }, /* 384 */
- { 6, 0, NULL, NULL }, /* 385 */
- { 6, 0, NULL, NULL }, /* 386 */
- { 6, 0, NULL, NULL }, /* 387 */
- { 6, 0, NULL, NULL }, /* 388 */
- { 6, 0, NULL, NULL }, /* 389 */
-
- { 6, 0, NULL, NULL }, /* 390 */
- { 6, 0, NULL, NULL }, /* 391 */
- { 6, 0, NULL, NULL }, /* 392 */
- { 6, 0, NULL, NULL }, /* 393 */
- { 6, 0, NULL, NULL }, /* 394 */
- { 6, 0, NULL, NULL }, /* 395 */
- { 6, 0, NULL, NULL }, /* 396 */
- { 6, 0, NULL, NULL }, /* 397 */
- { 6, 0, NULL, NULL }, /* 398 */
- { 6, 0, NULL, NULL }, /* 399 */
diff --git a/linux/sparc64/arch_getrval2.c b/linux/sparc64/arch_getrval2.c
new file mode 100644
index 0000000..81f1556
--- /dev/null
+++ b/linux/sparc64/arch_getrval2.c
@@ -0,0 +1 @@
+#include "sparc/arch_getrval2.c"
diff --git a/linux/sparc64/arch_regs.c b/linux/sparc64/arch_regs.c
new file mode 100644
index 0000000..db38d88
--- /dev/null
+++ b/linux/sparc64/arch_regs.c
@@ -0,0 +1 @@
+#include "sparc/arch_regs.c"
diff --git a/linux/sparc64/arch_sigreturn.c b/linux/sparc64/arch_sigreturn.c
new file mode 100644
index 0000000..aeec981
--- /dev/null
+++ b/linux/sparc64/arch_sigreturn.c
@@ -0,0 +1 @@
+#include "sparc/arch_sigreturn.c"
diff --git a/linux/sparc64/dummy2.h b/linux/sparc64/dummy2.h
deleted file mode 100644
index 783d4ee..0000000
--- a/linux/sparc64/dummy2.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995 Rick Sladkey <jrs@world.std.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* still unfinished */
-
-#define solaris_sysmp printargs
-#define solaris_sginap printargs
-#define solaris_sgikopt printargs
-#define solaris_sysmips printargs
-#define solaris_sigreturn printargs
-#define solaris_recvmsg printargs
-#define solaris_sendmsg printargs
-#define solaris_nfssvc printargs
-#define solaris_getfh printargs
-#define solaris_async_daemon printargs
-#define solaris_exportfs printargs
-#define solaris_BSD_getime printargs
-#define solaris_sproc printargs
-#define solaris_procblk printargs
-#define solaris_sprocsp printargs
-#define solaris_msync printargs
-#define solaris_madvise printargs
-#define solaris_pagelock printargs
-#define solaris_quotactl printargs
-#define solaris_cacheflush printargs
-#define solaris_cachectl printargs
-#define solaris_nuname printargs
-#define solaris_sigpoll printargs
-#define solaris_swapctl printargs
-#define solaris_sigstack printargs
-#define solaris_sigsendset printargs
-#define solaris_priocntl printargs
-#define solaris_ksigqueue printargs
-#define solaris_lwp_sema_wait printargs
-#define solaris_memcntl printargs
-#define solaris_syscall printargs
-#define solaris_clocal printargs
-#define solaris_syssun printargs
-#define solaris_sysi86 printargs
-#define solaris_sysmachine printargs
-#define solaris_plock printargs
-#define solaris_pathconf printargs
-#define solaris_sigtimedwait printargs
-#define solaris_ulimit printargs
-#define solaris_ptrace printargs
-#define solaris_stty printargs
-#define solaris_lwp_info printargs
-#define solaris_priocntlsys printargs
-#define solaris_hrtsys printargs
-#define solaris_xenix printargs
-#define solaris_statfs printargs
-#define solaris_fstatfs printargs
-#define solaris_statvfs printargs
-#define solaris_fstatvfs printargs
-#define solaris_fork1 printargs
-#define solaris_sigsendsys printargs
-#define solaris_gtty printargs
-#define solaris_vtrace printargs
-#define solaris_fpathconf printargs
-#define solaris_evsys printargs
-#define solaris_acct printargs
-#define solaris_exec printargs
-#define solaris_lwp_sema_post printargs
-#define solaris_nfssys printargs
-#define solaris_sigaltstack printargs
-#define solaris_uadmin printargs
-#define solaris_umount printargs
-#define solaris_modctl printargs
-#define solaris_acancel printargs
-#define solaris_async printargs
-#define solaris_evtrapret printargs
-#define solaris_lwp_create printargs
-#define solaris_lwp_exit printargs
-#define solaris_lwp_suspend printargs
-#define solaris_lwp_continue printargs
-#define solaris_lwp_kill printargs
-#define solaris_lwp_self printargs
-#define solaris_lwp_setprivate printargs
-#define solaris_lwp_getprivate printargs
-#define solaris_lwp_wait printargs
-#define solaris_lwp_mutex_unlock printargs
-#define solaris_lwp_mutex_lock printargs
-#define solaris_lwp_cond_wait printargs
-#define solaris_lwp_cond_signal printargs
-#define solaris_lwp_cond_broadcast printargs
-#define solaris_llseek printargs
-#define solaris_inst_sync printargs
-#define solaris_auditsys printargs
-#define solaris_processor_bind printargs
-#define solaris_processor_info printargs
-#define solaris_p_online printargs
-#define solaris_sigqueue printargs
-#define solaris_clock_gettime printargs
-#define solaris_clock_settime printargs
-#define solaris_clock_getres printargs
-#define solaris_nanosleep printargs
-#define solaris_timer_create printargs
-#define solaris_timer_delete printargs
-#define solaris_timer_settime printargs
-#define solaris_timer_gettime printargs
-#define solaris_timer_getoverrun printargs
-#define solaris_signal printargs
-#define solaris_sigset printargs
-#define solaris_sighold printargs
-#define solaris_sigrelse printargs
-#define solaris_sigignore printargs
-#define solaris_sigpause printargs
-#define solaris_msgctl printargs
-#define solaris_msgget printargs
-#define solaris_msgrcv printargs
-#define solaris_msgsnd printargs
-#define solaris_shmat printargs
-#define solaris_shmctl printargs
-#define solaris_shmdt printargs
-#define solaris_shmget printargs
-#define solaris_semctl printargs
-#define solaris_semget printargs
-#define solaris_semop printargs
-#define solaris_olduname printargs
-#define solaris_ustat printargs
-#define solaris_fusers printargs
-#define solaris_sysfs1 printargs
-#define solaris_sysfs2 printargs
-#define solaris_sysfs3 printargs
-
-/* like another call */
-#define solaris_lchown solaris_chown
-#define solaris_setuid solaris_close
-#define solaris_seteuid solaris_close
-#define solaris_setgid solaris_close
-#define solaris_setegid solaris_close
-#define solaris_vhangup solaris_close
-#define solaris_fdsync solaris_close
-#define solaris_sigfillset solaris_sigpending
-#define solaris_vfork solaris_fork
-#define solaris_ksigaction solaris_sigaction
-#define solaris_BSDgetpgrp solaris_getpgrp
-#define solaris_BSDsetpgrp solaris_setpgrp
-#define solaris_waitsys solaris_waitid
-
-/* printargs does the right thing */
-#define solaris_sync printargs
-#define solaris_profil printargs
-#define solaris_yield printargs
-#define solaris_pause printargs
-#define solaris_sethostid printargs
-
-/* subfunction entry points */
-#define solaris_pgrpsys printargs
-#define solaris_sigcall printargs
-#define solaris_msgsys printargs
-#define solaris_shmsys printargs
-#define solaris_semsys printargs
-#define solaris_utssys printargs
-#define solaris_sysfs printargs
-#define solaris_spcall printargs
-#define solaris_context printargs
-
-/* same as linux */
-#define solaris_exit sys_exit
-#define solaris_fork sys_fork
-#define solaris_read sys_read
-#define solaris_write sys_write
-#define solaris_close sys_close
-#define solaris_creat sys_creat
-#define solaris_link sys_link
-#define solaris_unlink sys_unlink
-#define solaris_chdir sys_chdir
-#define solaris_time sys_time
-#define solaris_chmod sys_chmod
-#define solaris_lseek sys_lseek
-#define solaris_stime sys_stime
-#define solaris_alarm sys_alarm
-#define solaris_utime sys_utime
-#define solaris_access sys_access
-#define solaris_nice sys_nice
-#define solaris_dup sys_dup
-#define solaris_pipe sys_pipe
-#define solaris_times sys_times
-#define solaris_execve sys_execve
-#define solaris_umask sys_umask
-#define solaris_chroot sys_chroot
-#define solaris_rmdir sys_rmdir
-#define solaris_mkdir sys_mkdir
-#define solaris_getdents sys_getdents
-#define solaris_poll sys_poll
-#define solaris_symlink sys_symlink
-#define solaris_readlink sys_readlink
-#define solaris_setgroups sys_setgroups
-#define solaris_getgroups sys_getgroups
-#define solaris_fchmod sys_fchmod
-#define solaris_fchown sys_fchown
-#define solaris_mprotect sys_mprotect
-#define solaris_munmap sys_munmap
-#define solaris_readv sys_readv
-#define solaris_writev sys_writev
-#define solaris_chown sys_chown
-#define solaris_rename sys_rename
-#define solaris_gettimeofday sys_gettimeofday
-#define solaris_getitimer sys_getitimer
-#define solaris_setitimer sys_setitimer
-#define solaris_brk sys_brk
-#define solaris_mmap sys_mmap
-#define solaris_getsid sys_getsid
-#define solaris_setsid sys_setsid
-#define solaris_getpgid sys_getpgid
-#define solaris_setpgid sys_setpgid
-#define solaris_getpgrp sys_getpgrp
-
-/* These are handled according to current_personality */
-#define solaris_xstat sys_xstat
-#define solaris_fxstat sys_fxstat
-#define solaris_lxstat sys_xstat
-#define solaris_xmknod sys_xmknod
-#define solaris_stat sys_stat
-#define solaris_fstat sys_fstat
-#define solaris_lstat sys_lstat
-#define solaris_pread sys_pread
-#define solaris_pwrite sys_pwrite
-#define solaris_ioctl sys_ioctl
-#define solaris_mknod sys_mknod
-
-/* To be done */
-#define solaris_mount printargs
-#define solaris_sysinfo printargs
-#define solaris_sysconfig printargs
-#define solaris_getpmsg printargs
-#define solaris_putpmsg printargs
-#define solaris_wait printargs
-#define solaris_waitid printargs
-#define solaris_sigsuspend printargs
-#define solaris_setpgrp printargs
-#define solaris_getcontext printargs
-#define solaris_setcontext printargs
-#define solaris_getpid printargs
-#define solaris_getuid printargs
-#define solaris_kill printargs
-#define solaris_getgid printargs
-#define solaris_fcntl printargs
-#define solaris_getmsg printargs
-#define solaris_putmsg printargs
-#define solaris_sigprocmask printargs
-#define solaris_sigaction printargs
-#define solaris_sigpending printargs
-#define solaris_mincore printargs
-#define solaris_fchdir printargs
-#define solaris_setrlimit printargs
-#define solaris_getrlimit printargs
-#define solaris_uname printargs
-#define solaris_adjtime printargs
-#define solaris_fchroot printargs
-#define solaris_utimes printargs
diff --git a/linux/sparc64/errnoent1.h b/linux/sparc64/errnoent1.h
index d194023..c0f7787 100644
--- a/linux/sparc64/errnoent1.h
+++ b/linux/sparc64/errnoent1.h
@@ -1 +1 @@
-#include "sparc/errnoent1.h"
+#include "errnoent.h"
diff --git a/linux/sparc64/errnoent2.h b/linux/sparc64/errnoent2.h
deleted file mode 100644
index c0f7787..0000000
--- a/linux/sparc64/errnoent2.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "errnoent.h"
diff --git a/linux/sparc64/get_error.c b/linux/sparc64/get_error.c
new file mode 100644
index 0000000..ee3a7e5
--- /dev/null
+++ b/linux/sparc64/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && sparc_regs.tstate & 0x1100000000UL) {
+ tcp->u_rval = -1;
+ tcp->u_error = sparc_regs.u_regs[U_REG_O0];
+} else {
+ tcp->u_rval = sparc_regs.u_regs[U_REG_O0];
+}
diff --git a/linux/sparc64/get_scno.c b/linux/sparc64/get_scno.c
new file mode 100644
index 0000000..b92366e
--- /dev/null
+++ b/linux/sparc64/get_scno.c
@@ -0,0 +1,19 @@
+/* Retrieve the syscall trap instruction. */
+unsigned long trap;
+errno = 0;
+trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)sparc_regs.tpc, 0);
+if (errno)
+ return -1;
+trap >>= 32;
+switch (trap) {
+case 0x91d02010:
+ /* Linux/SPARC syscall trap. */
+ update_personality(tcp, 0);
+ break;
+case 0x91d0206d:
+ /* Linux/SPARC64 syscall trap. */
+ update_personality(tcp, 1);
+ break;
+}
+
+scno = sparc_regs.u_regs[U_REG_G1];
diff --git a/linux/sparc64/get_syscall_args.c b/linux/sparc64/get_syscall_args.c
new file mode 100644
index 0000000..821c331
--- /dev/null
+++ b/linux/sparc64/get_syscall_args.c
@@ -0,0 +1 @@
+#include "sparc/get_syscall_args.c"
diff --git a/linux/sparc64/ioctlent1.h b/linux/sparc64/ioctlent1.h
deleted file mode 100644
index 8daf265..0000000
--- a/linux/sparc64/ioctlent1.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "sparc/ioctlent1.h"
diff --git a/linux/sparc64/ioctls_arch2.h b/linux/sparc64/ioctls_arch1.h
similarity index 100%
rename from linux/sparc64/ioctls_arch2.h
rename to linux/sparc64/ioctls_arch1.h
diff --git a/linux/sparc64/ioctls_inc2.h b/linux/sparc64/ioctls_inc1.h
similarity index 100%
rename from linux/sparc64/ioctls_inc2.h
rename to linux/sparc64/ioctls_inc1.h
diff --git a/linux/sparc64/print_pc.c b/linux/sparc64/print_pc.c
new file mode 100644
index 0000000..11c0ac4
--- /dev/null
+++ b/linux/sparc64/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, sparc_regs.tpc);
diff --git a/linux/sparc64/signalent1.h b/linux/sparc64/signalent1.h
index 9df023e..093cba7 100644
--- a/linux/sparc64/signalent1.h
+++ b/linux/sparc64/signalent1.h
@@ -1 +1 @@
-#include "sparc/signalent1.h"
+#include "signalent.h"
diff --git a/linux/sparc64/signalent2.h b/linux/sparc64/signalent2.h
deleted file mode 100644
index 093cba7..0000000
--- a/linux/sparc64/signalent2.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "signalent.h"
diff --git a/linux/sparc64/syscall1.h b/linux/sparc64/syscall1.h
deleted file mode 100644
index 6f30b74..0000000
--- a/linux/sparc64/syscall1.h
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995 Rick Sladkey <jrs@world.std.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#define SOLARIS_syscall 0
-#define SOLARIS_exit 1
-#define SOLARIS_fork 2
-#define SOLARIS_read 3
-#define SOLARIS_write 4
-#define SOLARIS_open 5
-#define SOLARIS_close 6
-#define SOLARIS_wait 7
-#define SOLARIS_creat 8
-#define SOLARIS_link 9
-#define SOLARIS_unlink 10
-#define SOLARIS_exec 11
-#define SOLARIS_chdir 12
-#define SOLARIS_time 13
-#define SOLARIS_mknod 14
-#define SOLARIS_chmod 15
-#define SOLARIS_chown 16
-#define SOLARIS_brk 17
-#define SOLARIS_stat 18
-#define SOLARIS_lseek 19
-#define SOLARIS_getpid 20
-#define SOLARIS_mount 21
-#define SOLARIS_umount 22
-#define SOLARIS_setuid 23
-#define SOLARIS_getuid 24
-#define SOLARIS_stime 25
-#define SOLARIS_ptrace 26
-#define SOLARIS_alarm 27
-#define SOLARIS_fstat 28
-#define SOLARIS_pause 29
-#define SOLARIS_utime 30
-#define SOLARIS_stty 31
-#define SOLARIS_gtty 32
-#define SOLARIS_access 33
-#define SOLARIS_nice 34
-#define SOLARIS_statfs 35
-#define SOLARIS_sync 36
-#define SOLARIS_kill 37
-#define SOLARIS_fstatfs 38
-#define SOLARIS_pgrpsys 39
-#define SOLARIS_xenix 40
-#define SOLARIS_dup 41
-#define SOLARIS_pipe 42
-#define SOLARIS_times 43
-#define SOLARIS_profil 44
-#define SOLARIS_plock 45
-#define SOLARIS_setgid 46
-#define SOLARIS_getgid 47
-#define SOLARIS_signal 48
-#define SOLARIS_msgsys 49
-#define SOLARIS_syssun 50
-#define SOLARIS_acct 51
-#define SOLARIS_shmsys 52
-#define SOLARIS_semsys 53
-#define SOLARIS_ioctl 54
-#define SOLARIS_uadmin 55
-#define SOLARIS_utssys 57
-#define SOLARIS_fdsync 58
-#define SOLARIS_execve 59
-#define SOLARIS_umask 60
-#define SOLARIS_chroot 61
-#define SOLARIS_fcntl 62
-#define SOLARIS_ulimit 63
-#define SOLARIS_rmdir 79
-#define SOLARIS_mkdir 80
-#define SOLARIS_getdents 81
-#define SOLARIS_sysfs 84
-#define SOLARIS_getmsg 85
-#define SOLARIS_putmsg 86
-#define SOLARIS_poll 87
-#define SOLARIS_lstat 88
-#define SOLARIS_symlink 89
-#define SOLARIS_readlink 90
-#define SOLARIS_setgroups 91
-#define SOLARIS_getgroups 92
-#define SOLARIS_fchmod 93
-#define SOLARIS_fchown 94
-#define SOLARIS_sigprocmask 95
-#define SOLARIS_sigsuspend 96
-#define SOLARIS_sigaltstack 97
-#define SOLARIS_sigaction 98
-#define SOLARIS_sigpending 99
-#define SOLARIS_context 100
-#define SOLARIS_evsys 101
-#define SOLARIS_evtrapret 102
-#define SOLARIS_statvfs 103
-#define SOLARIS_fstatvfs 104
-#define SOLARIS_nfssys 106
-#define SOLARIS_waitsys 107
-#define SOLARIS_sigsendsys 108
-#define SOLARIS_hrtsys 109
-#define SOLARIS_acancel 110
-#define SOLARIS_async 111
-#define SOLARIS_priocntlsys 112
-#define SOLARIS_pathconf 113
-#define SOLARIS_mincore 114
-#define SOLARIS_mmap 115
-#define SOLARIS_mprotect 116
-#define SOLARIS_munmap 117
-#define SOLARIS_fpathconf 118
-#define SOLARIS_vfork 119
-#define SOLARIS_fchdir 120
-#define SOLARIS_readv 121
-#define SOLARIS_writev 122
-#define SOLARIS_xstat 123
-#define SOLARIS_lxstat 124
-#define SOLARIS_fxstat 125
-#define SOLARIS_xmknod 126
-#define SOLARIS_clocal 127
-#define SOLARIS_setrlimit 128
-#define SOLARIS_getrlimit 129
-#define SOLARIS_lchown 130
-#define SOLARIS_memcntl 131
-#define SOLARIS_getpmsg 132
-#define SOLARIS_putpmsg 133
-#define SOLARIS_rename 134
-#define SOLARIS_uname 135
-#define SOLARIS_setegid 136
-#define SOLARIS_sysconfig 137
-#define SOLARIS_adjtime 138
-#define SOLARIS_systeminfo 139
-#define SOLARIS_seteuid 141
-#define SOLARIS_vtrace 142
-#define SOLARIS_fork1 143
-#define SOLARIS_sigtimedwait 144
-#define SOLARIS_lwp_info 145
-#define SOLARIS_yield 146
-#define SOLARIS_lwp_sema_wait 147
-#define SOLARIS_lwp_sema_post 148
-#define SOLARIS_modctl 152
-#define SOLARIS_fchroot 153
-#define SOLARIS_utimes 154
-#define SOLARIS_vhangup 155
-#define SOLARIS_gettimeofday 156
-#define SOLARIS_getitimer 157
-#define SOLARIS_setitimer 158
-#define SOLARIS_lwp_create 159
-#define SOLARIS_lwp_exit 160
-#define SOLARIS_lwp_suspend 161
-#define SOLARIS_lwp_continue 162
-#define SOLARIS_lwp_kill 163
-#define SOLARIS_lwp_self 164
-#define SOLARIS_lwp_setprivate 165
-#define SOLARIS_lwp_getprivate 166
-#define SOLARIS_lwp_wait 167
-#define SOLARIS_lwp_mutex_unlock 168
-#define SOLARIS_lwp_mutex_lock 169
-#define SOLARIS_lwp_cond_wait 170
-#define SOLARIS_lwp_cond_signal 171
-#define SOLARIS_lwp_cond_broadcast 172
-#define SOLARIS_pread 173
-#define SOLARIS_pwrite 174
-#define SOLARIS_llseek 175
-#define SOLARIS_inst_sync 176
-#define SOLARIS_kaio 178
-#define SOLARIS_tsolsys 184
-#define SOLARIS_acl 185
-#define SOLARIS_auditsys 186
-#define SOLARIS_processor_bind 187
-#define SOLARIS_processor_info 188
-#define SOLARIS_p_online 189
-#define SOLARIS_sigqueue 190
-#define SOLARIS_clock_gettime 191
-#define SOLARIS_clock_settime 192
-#define SOLARIS_clock_getres 193
-#define SOLARIS_timer_create 194
-#define SOLARIS_timer_delete 195
-#define SOLARIS_timer_settime 196
-#define SOLARIS_timer_gettime 197
-#define SOLARIS_timer_getoverrun 198
-#define SOLARIS_nanosleep 199
-#define SOLARIS_facl 200
-#define SOLARIS_door 201
-#define SOLARIS_setreuid 202
-#define SOLARIS_setregid 203
-#define SOLARIS_signotifywait 210
-#define SOLARIS_lwp_sigredirect 211
-#define SOLARIS_lwp_alarm 212
-
-#include "dummy2.h"
-
-extern int solaris_syscall();
-extern int solaris_exit();
-extern int solaris_fork();
-extern int solaris_read();
-extern int solaris_write();
-extern int solaris_open();
-extern int solaris_close();
-extern int solaris_wait();
-extern int solaris_creat();
-extern int solaris_link();
-extern int solaris_unlink();
-extern int solaris_exec();
-extern int solaris_chdir();
-extern int solaris_time();
-extern int solaris_mknod();
-extern int solaris_chmod();
-extern int solaris_chown();
-extern int solaris_brk();
-extern int solaris_stat();
-extern int solaris_lseek();
-extern int solaris_getpid();
-extern int solaris_mount();
-extern int solaris_umount();
-extern int solaris_setuid();
-extern int solaris_getuid();
-extern int solaris_stime();
-extern int solaris_ptrace();
-extern int solaris_alarm();
-extern int solaris_fstat();
-extern int solaris_pause();
-extern int solaris_utime();
-extern int solaris_stty();
-extern int solaris_gtty();
-extern int solaris_access();
-extern int solaris_nice();
-extern int solaris_statfs();
-extern int solaris_sync();
-extern int solaris_kill();
-extern int solaris_fstatfs();
-extern int solaris_pgrpsys();
-extern int solaris_setpgrp();
-extern int solaris_xenix();
-extern int solaris_syssgi();
-extern int solaris_dup();
-extern int solaris_pipe();
-extern int solaris_times();
-extern int solaris_profil();
-extern int solaris_plock();
-extern int solaris_setgid();
-extern int solaris_getgid();
-extern int solaris_sigcall();
-extern int solaris_msgsys();
-extern int solaris_syssun();
-extern int solaris_sysi86();
-extern int solaris_sysmips();
-extern int solaris_sysmachine();
-extern int solaris_acct();
-extern int solaris_shmsys();
-extern int solaris_semsys();
-extern int solaris_ioctl();
-extern int solaris_uadmin();
-extern int solaris_utssys();
-extern int solaris_fdsync();
-extern int solaris_execve();
-extern int solaris_umask();
-extern int solaris_chroot();
-extern int solaris_fcntl();
-extern int solaris_ulimit();
-extern int solaris_rmdir();
-extern int solaris_mkdir();
-extern int solaris_getdents();
-extern int solaris_sysfs();
-extern int solaris_getmsg();
-extern int solaris_putmsg();
-extern int solaris_poll();
-extern int solaris_lstat();
-extern int solaris_symlink();
-extern int solaris_readlink();
-extern int solaris_setgroups();
-extern int solaris_getgroups();
-extern int solaris_fchmod();
-extern int solaris_fchown();
-extern int solaris_sigprocmask();
-extern int solaris_sigsuspend();
-extern int solaris_sigaltstack();
-extern int solaris_sigaction();
-extern int solaris_spcall();
-extern int solaris_context();
-extern int solaris_evsys();
-extern int solaris_evtrapret();
-extern int solaris_statvfs();
-extern int solaris_fstatvfs();
-extern int solaris_nfssys();
-extern int solaris_waitid();
-extern int solaris_sigsendsys();
-extern int solaris_hrtsys();
-extern int solaris_acancel();
-extern int solaris_async();
-extern int solaris_priocntlsys();
-extern int solaris_pathconf();
-extern int solaris_mincore();
-extern int solaris_mmap();
-extern int solaris_mprotect();
-extern int solaris_munmap();
-extern int solaris_fpathconf();
-extern int solaris_vfork();
-extern int solaris_fchdir();
-extern int solaris_readv();
-extern int solaris_writev();
-extern int solaris_xstat();
-extern int solaris_lxstat();
-extern int solaris_fxstat();
-extern int solaris_xmknod();
-extern int solaris_clocal();
-extern int solaris_setrlimit();
-extern int solaris_getrlimit();
-extern int solaris_lchown();
-extern int solaris_memcntl();
-extern int solaris_getpmsg();
-extern int solaris_putpmsg();
-extern int solaris_rename();
-extern int solaris_uname();
-extern int solaris_setegid();
-extern int solaris_sysconfig();
-extern int solaris_adjtime();
-extern int solaris_sysinfo();
-extern int solaris_seteuid();
-extern int solaris_vtrace();
-extern int solaris_fork1();
-extern int solaris_sigtimedwait();
-extern int solaris_lwp_info();
-extern int solaris_yield();
-extern int solaris_lwp_sema_wait();
-extern int solaris_lwp_sema_post();
-extern int solaris_modctl();
-extern int solaris_fchroot();
-extern int solaris_utimes();
-extern int solaris_vhangup();
-extern int solaris_gettimeofday();
-extern int solaris_getitimer();
-extern int solaris_setitimer();
-extern int solaris_lwp_create();
-extern int solaris_lwp_exit();
-extern int solaris_lwp_suspend();
-extern int solaris_lwp_continue();
-extern int solaris_lwp_kill();
-extern int solaris_lwp_self();
-extern int solaris_lwp_setprivate();
-extern int solaris_lwp_getprivate();
-extern int solaris_lwp_wait();
-extern int solaris_lwp_mutex_unlock();
-extern int solaris_lwp_mutex_lock();
-extern int solaris_lwp_cond_wait();
-extern int solaris_lwp_cond_signal();
-extern int solaris_lwp_cond_broadcast();
-extern int solaris_pread();
-extern int solaris_pwrite();
-extern int solaris_llseek();
-extern int solaris_inst_sync();
-extern int solaris_auditsys();
-extern int solaris_processor_bind();
-extern int solaris_processor_info();
-extern int solaris_p_online();
-extern int solaris_sigqueue();
-extern int solaris_clock_gettime();
-extern int solaris_clock_settime();
-extern int solaris_clock_getres();
-extern int solaris_timer_create();
-extern int solaris_timer_delete();
-extern int solaris_timer_settime();
-extern int solaris_timer_gettime();
-extern int solaris_timer_getoverrun();
-extern int solaris_nanosleep();
-
-/* solaris_pgrpsys subcalls */
-
-extern int solaris_getpgrp(), solaris_setpgrp(), solaris_getsid();
-extern int solaris_setsid(), solaris_getpgid(), solaris_setpgid();
-
-#define SOLARIS_pgrpsys_subcall 300
-#define SOLARIS_getpgrp (SOLARIS_pgrpsys_subcall + 0)
-#define SOLARIS_setpgrp (SOLARIS_pgrpsys_subcall + 1)
-#define SOLARIS_getsid (SOLARIS_pgrpsys_subcall + 2)
-#define SOLARIS_setsid (SOLARIS_pgrpsys_subcall + 3)
-#define SOLARIS_getpgid (SOLARIS_pgrpsys_subcall + 4)
-#define SOLARIS_setpgid (SOLARIS_pgrpsys_subcall + 5)
-
-#define SOLARIS_pgrpsys_nsubcalls 6
-
-/* solaris_sigcall subcalls */
-
-#undef SOLARIS_signal
-#define SOLARIS_sigcall 48
-
-extern int solaris_signal(), solaris_sigset(), solaris_sighold();
-extern int solaris_sigrelse(), solaris_sigignore(), solaris_sigpause();
-
-#define SOLARIS_sigcall_subcall 310
-#define SOLARIS_signal (SOLARIS_sigcall_subcall + 0)
-#define SOLARIS_sigset (SOLARIS_sigcall_subcall + 1)
-#define SOLARIS_sighold (SOLARIS_sigcall_subcall + 2)
-#define SOLARIS_sigrelse (SOLARIS_sigcall_subcall + 3)
-#define SOLARIS_sigignore (SOLARIS_sigcall_subcall + 4)
-#define SOLARIS_sigpause (SOLARIS_sigcall_subcall + 5)
-
-#define SOLARIS_sigcall_nsubcalls 6
-
-/* msgsys subcalls */
-
-extern int solaris_msgget(), solaris_msgctl(), solaris_msgrcv(), solaris_msgsnd();
-
-#define SOLARIS_msgsys_subcall 320
-#define SOLARIS_msgget (SOLARIS_msgsys_subcall + 0)
-#define SOLARIS_msgctl (SOLARIS_msgsys_subcall + 1)
-#define SOLARIS_msgrcv (SOLARIS_msgsys_subcall + 2)
-#define SOLARIS_msgsnd (SOLARIS_msgsys_subcall + 3)
-
-#define SOLARIS_msgsys_nsubcalls 4
-
-/* shmsys subcalls */
-
-extern int solaris_shmat(), solaris_shmctl(), solaris_shmdt(), solaris_shmget();
-
-#define SOLARIS_shmsys_subcall 330
-#define SOLARIS_shmat (SOLARIS_shmsys_subcall + 0)
-#define SOLARIS_shmctl (SOLARIS_shmsys_subcall + 1)
-#define SOLARIS_shmdt (SOLARIS_shmsys_subcall + 2)
-#define SOLARIS_shmget (SOLARIS_shmsys_subcall + 3)
-
-#define SOLARIS_shmsys_nsubcalls 4
-
-/* semsys subcalls */
-
-extern int solaris_semctl(), solaris_semget(), solaris_semop();
-
-#define SOLARIS_semsys_subcall 340
-#define SOLARIS_semctl (SOLARIS_semsys_subcall + 0)
-#define SOLARIS_semget (SOLARIS_semsys_subcall + 1)
-#define SOLARIS_semop (SOLARIS_semsys_subcall + 2)
-
-#define SOLARIS_semsys_nsubcalls 3
-
-/* utssys subcalls */
-
-extern int solaris_olduname(), solaris_ustat(), solaris_fusers();
-
-#define SOLARIS_utssys_subcall 350
-
-#define SOLARIS_olduname (SOLARIS_utssys_subcall + 0)
- /* 1 is unused */
-#define SOLARIS_ustat (SOLARIS_utssys_subcall + 2)
-#define SOLARIS_fusers (SOLARIS_utssys_subcall + 3)
-
-#define SOLARIS_utssys_nsubcalls 4
-
-/* sysfs subcalls */
-
-extern int solaris_sysfs1(), solaris_sysfs2(), solaris_sysfs3();
-
-#define SOLARIS_sysfs_subcall 360
- /* 0 is unused */
-#define SOLARIS_sysfs1 (SOLARIS_sysfs_subcall + 1)
-#define SOLARIS_sysfs2 (SOLARIS_sysfs_subcall + 2)
-#define SOLARIS_sysfs3 (SOLARIS_sysfs_subcall + 3)
-
-#define SOLARIS_sysfs_nsubcalls 4
-
-/* solaris_spcall subcalls */
-
-#undef SOLARIS_sigpending
-#define SOLARIS_spcall 99
-
-extern int solaris_sigpending(), solaris_sigfillset();
-
-#define SOLARIS_spcall_subcall 370
- /* 0 is unused */
-#define SOLARIS_sigpending (SOLARIS_spcall_subcall + 1)
-#define SOLARIS_sigfillset (SOLARIS_spcall_subcall + 2)
-
-#define SOLARIS_spcall_nsubcalls 3
-
-/* solaris_context subcalls */
-
-extern int solaris_getcontext(), solaris_setcontext();
-
-#define SOLARIS_context_subcall 380
-#define SOLARIS_getcontext (SOLARIS_context_subcall + 0)
-#define SOLARIS_setcontext (SOLARIS_context_subcall + 1)
-
-#define SOLARIS_context_nsubcalls 2
diff --git a/linux/sparc64/syscallent1.h b/linux/sparc64/syscallent1.h
index 821d77c..5f73f3c 100644
--- a/linux/sparc64/syscallent1.h
+++ b/linux/sparc64/syscallent1.h
@@ -1 +1,3 @@
-#include "../sparc/syscallent1.h"
+#define sys_mmap_4koff sys_mmap_pgoff
+#include "../sparc/syscallent.h"
+#undef sys_mmap_4koff
diff --git a/linux/sparc64/syscallent2.h b/linux/sparc64/syscallent2.h
deleted file mode 100644
index 776b5f1..0000000
--- a/linux/sparc64/syscallent2.h
+++ /dev/null
@@ -1 +0,0 @@
-#include "../sparc/syscallent.h"
diff --git a/linux/syscall.h b/linux/syscall.h
index 45d261a..dbf2d20 100644
--- a/linux/syscall.h
+++ b/linux/syscall.h
@@ -348,7 +348,6 @@
#endif
#if defined SPARC || defined SPARC64
-#include "sparc/syscall1.h"
int sys_execv();
int sys_getmsg();
int sys_putmsg();
diff --git a/linux/tile/arch_regs.c b/linux/tile/arch_regs.c
new file mode 100644
index 0000000..455077c
--- /dev/null
+++ b/linux/tile/arch_regs.c
@@ -0,0 +1,2 @@
+struct pt_regs tile_regs; /* not static */
+#define ARCH_REGS_FOR_GETREGS tile_regs
diff --git a/linux/tile/arch_sigreturn.c b/linux/tile/arch_sigreturn.c
new file mode 100644
index 0000000..99e2bf8
--- /dev/null
+++ b/linux/tile/arch_sigreturn.c
@@ -0,0 +1,8 @@
+/* offset of ucontext in the kernel's sigframe structure */
+# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(siginfo_t)
+const long addr = tile_regs.sp + SIGFRAME_UC_OFFSET +
+ offsetof(struct ucontext, uc_sigmask);
+
+tprints("{mask=");
+print_sigset_addr_len(tcp, addr, NSIG / 8);
+tprints("}");
diff --git a/linux/tile/get_error.c b/linux/tile/get_error.c
new file mode 100644
index 0000000..8b73dfa
--- /dev/null
+++ b/linux/tile/get_error.c
@@ -0,0 +1,12 @@
+/*
+ * The standard tile calling convention returns the value (or negative
+ * errno) in r0, and zero (or positive errno) in r1.
+ * Until at least kernel 3.8, however, the r1 value is not reflected
+ * in ptregs at this point, so we use r0 here.
+ */
+if (check_errno && is_negated_errno(tile_regs.regs[0])) {
+ tcp->u_rval = -1;
+ tcp->u_error = -tile_regs.regs[0];
+} else {
+ tcp->u_rval = tile_regs.regs[0];
+}
diff --git a/linux/tile/get_scno.c b/linux/tile/get_scno.c
new file mode 100644
index 0000000..1ae65c9
--- /dev/null
+++ b/linux/tile/get_scno.c
@@ -0,0 +1,17 @@
+unsigned int currpers;
+
+scno = tile_regs.regs[10];
+
+#ifdef __tilepro__
+currpers = 1;
+#else
+# ifndef PT_FLAGS_COMPAT
+# define PT_FLAGS_COMPAT 0x10000 /* from Linux 3.8 on */
+# endif
+if (tile_regs.flags & PT_FLAGS_COMPAT)
+ currpers = 1;
+else
+ currpers = 0;
+#endif
+
+update_personality(tcp, currpers);
diff --git a/linux/tile/get_syscall_args.c b/linux/tile/get_syscall_args.c
new file mode 100644
index 0000000..33371d5
--- /dev/null
+++ b/linux/tile/get_syscall_args.c
@@ -0,0 +1,6 @@
+tcp->u_arg[0] = tile_regs.regs[0];
+tcp->u_arg[1] = tile_regs.regs[1];
+tcp->u_arg[2] = tile_regs.regs[2];
+tcp->u_arg[3] = tile_regs.regs[3];
+tcp->u_arg[4] = tile_regs.regs[4];
+tcp->u_arg[5] = tile_regs.regs[5];
diff --git a/linux/tile/print_pc.c b/linux/tile/print_pc.c
new file mode 100644
index 0000000..8a6894f
--- /dev/null
+++ b/linux/tile/print_pc.c
@@ -0,0 +1 @@
+tprintf(fmt, (unsigned long) tile_regs.pc);
diff --git a/linux/ubi-user.h b/linux/ubi-user.h
index a12c884..e9e56b3 100644
--- a/linux/ubi-user.h
+++ b/linux/ubi-user.h
@@ -307,7 +307,7 @@
__s16 name_len;
__s8 padding2[4];
char name[UBI_MAX_VOLUME_NAME + 1];
-} __attribute__((packed));
+} ATTRIBUTE_PACKED;
/**
* struct ubi_rsvol_req - a data structure used in volume re-size requests.
@@ -323,7 +323,7 @@
struct ubi_rsvol_req {
__s64 bytes;
__s32 vol_id;
-} __attribute__((packed));
+} ATTRIBUTE_PACKED;
/**
* struct ubi_rnvol_req - volumes re-name request.
@@ -365,7 +365,7 @@
__s8 padding2[2];
char name[UBI_MAX_VOLUME_NAME + 1];
} ents[UBI_MAX_RNVOL];
-} __attribute__((packed));
+} ATTRIBUTE_PACKED;
/**
* struct ubi_leb_change_req - a data structure used in atomic LEB change
@@ -389,7 +389,7 @@
__s32 bytes;
__s8 dtype; /* obsolete, do not use! */
__s8 padding[7];
-} __attribute__((packed));
+} ATTRIBUTE_PACKED;
/**
* struct ubi_map_req - a data structure used in map LEB requests.
@@ -401,7 +401,7 @@
__s32 lnum;
__s8 dtype; /* obsolete, do not use! */
__s8 padding[3];
-} __attribute__((packed));
+} ATTRIBUTE_PACKED;
/**
@@ -415,6 +415,6 @@
__u8 property;
__u8 padding[7];
__u64 value;
-} __attribute__((packed));
+} ATTRIBUTE_PACKED;
#endif /* __UBI_USER_H__ */
diff --git a/linux/x32/arch_regs.c b/linux/x32/arch_regs.c
new file mode 100644
index 0000000..62c70be
--- /dev/null
+++ b/linux/x32/arch_regs.c
@@ -0,0 +1 @@
+#include "x86_64/arch_regs.c"
diff --git a/linux/x32/arch_sigreturn.c b/linux/x32/arch_sigreturn.c
new file mode 100644
index 0000000..9a778fc
--- /dev/null
+++ b/linux/x32/arch_sigreturn.c
@@ -0,0 +1 @@
+#include "x86_64/arch_sigreturn.c"
diff --git a/linux/x32/get_error.c b/linux/x32/get_error.c
new file mode 100644
index 0000000..6c6fbaf
--- /dev/null
+++ b/linux/x32/get_error.c
@@ -0,0 +1 @@
+#include "x86_64/get_error.c"
diff --git a/linux/x32/get_scno.c b/linux/x32/get_scno.c
new file mode 100644
index 0000000..492863f
--- /dev/null
+++ b/linux/x32/get_scno.c
@@ -0,0 +1 @@
+#include "x86_64/get_scno.c"
diff --git a/linux/x32/get_syscall_args.c b/linux/x32/get_syscall_args.c
new file mode 100644
index 0000000..6cdb465
--- /dev/null
+++ b/linux/x32/get_syscall_args.c
@@ -0,0 +1 @@
+#include "x86_64/get_syscall_args.c"
diff --git a/linux/x32/print_pc.c b/linux/x32/print_pc.c
new file mode 100644
index 0000000..13ccdc2
--- /dev/null
+++ b/linux/x32/print_pc.c
@@ -0,0 +1 @@
+#include "x86_64/print_pc.c"
diff --git a/linux/x86_64/arch_regs.c b/linux/x86_64/arch_regs.c
new file mode 100644
index 0000000..1925dad
--- /dev/null
+++ b/linux/x86_64/arch_regs.c
@@ -0,0 +1,40 @@
+/*
+ * On i386, pt_regs and user_regs_struct are the same,
+ * but on 64 bit x86, user_regs_struct has six more fields:
+ * fs_base, gs_base, ds, es, fs, gs.
+ * PTRACE_GETREGS fills them too, so struct pt_regs would overflow.
+ */
+struct i386_user_regs_struct {
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+ uint32_t eax;
+ uint32_t xds;
+ uint32_t xes;
+ uint32_t xfs;
+ uint32_t xgs;
+ uint32_t orig_eax;
+ uint32_t eip;
+ uint32_t xcs;
+ uint32_t eflags;
+ uint32_t esp;
+ uint32_t xss;
+};
+static union {
+ struct user_regs_struct x86_64_r;
+ struct i386_user_regs_struct i386_r;
+} x86_regs_union;
+#define x86_64_regs x86_regs_union.x86_64_r
+#define i386_regs x86_regs_union.i386_r
+
+uint32_t *const i386_esp_ptr = &i386_regs.esp;
+uint64_t *const x86_64_rsp_ptr = (uint64_t *) &x86_64_regs.rsp;
+static struct iovec x86_io = {
+ .iov_base = &x86_regs_union
+};
+
+#define ARCH_REGS_FOR_GETREGSET x86_regs_union
+#define ARCH_IOVEC_FOR_GETREGSET x86_io
diff --git a/linux/x86_64/arch_sigreturn.c b/linux/x86_64/arch_sigreturn.c
new file mode 100644
index 0000000..62aeca5
--- /dev/null
+++ b/linux/x86_64/arch_sigreturn.c
@@ -0,0 +1,10 @@
+if (current_personality != 1) {
+ const unsigned long addr =
+ (unsigned long) *x86_64_rsp_ptr +
+ offsetof(struct ucontext, uc_sigmask);
+ tprints("{mask=");
+ print_sigset_addr_len(tcp, addr, NSIG / 8);
+ tprints("}");
+ return 0;
+}
+#include "i386/arch_sigreturn.c"
diff --git a/linux/x86_64/get_error.c b/linux/x86_64/get_error.c
new file mode 100644
index 0000000..29b7816
--- /dev/null
+++ b/linux/x86_64/get_error.c
@@ -0,0 +1,23 @@
+/*
+ * In X32, return value is 64-bit (llseek uses one).
+ * Using merely "long rax" would not work.
+ */
+long long rax;
+
+if (x86_io.iov_len == sizeof(i386_regs)) {
+ /* Sign extend from 32 bits */
+ rax = (int32_t) i386_regs.eax;
+} else {
+ rax = x86_64_regs.rax;
+}
+
+if (check_errno && is_negated_errno(rax)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -rax;
+} else {
+ tcp->u_rval = rax;
+# ifdef X32
+ /* tcp->u_rval contains a truncated value */
+ tcp->u_lrval = rax;
+# endif
+}
diff --git a/linux/x86_64/get_scno.c b/linux/x86_64/get_scno.c
new file mode 100644
index 0000000..2eb0d5d
--- /dev/null
+++ b/linux/x86_64/get_scno.c
@@ -0,0 +1,107 @@
+#ifndef __X32_SYSCALL_BIT
+# define __X32_SYSCALL_BIT 0x40000000
+#endif
+
+unsigned int currpers;
+
+#if 1
+/* GETREGSET of NT_PRSTATUS tells us regset size,
+ * which unambiguously detects i386.
+ *
+ * Linux kernel distinguishes x86-64 and x32 processes
+ * solely by looking at __X32_SYSCALL_BIT:
+ * arch/x86/include/asm/compat.h::is_x32_task():
+ * if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
+ * return true;
+ */
+if (x86_io.iov_len == sizeof(i386_regs)) {
+ scno = i386_regs.orig_eax;
+ currpers = 1;
+} else {
+ scno = x86_64_regs.orig_rax;
+ currpers = 0;
+ if (scno & __X32_SYSCALL_BIT) {
+ /*
+ * Syscall number -1 requires special treatment:
+ * it might be a side effect of SECCOMP_RET_ERRNO
+ * filtering that sets orig_rax to -1
+ * in some versions of linux kernel.
+ * If that is the case, then
+ * __X32_SYSCALL_BIT logic does not apply.
+ */
+ if ((long long) x86_64_regs.orig_rax != -1) {
+ scno -= __X32_SYSCALL_BIT;
+ currpers = 2;
+ } else {
+# ifdef X32
+ currpers = 2;
+# endif
+ }
+ }
+}
+
+#elif 0
+/* cs = 0x33 for long mode (native 64 bit and x32)
+ * cs = 0x23 for compatibility mode (32 bit)
+ * ds = 0x2b for x32 mode (x86-64 in 32 bit)
+ */
+scno = x86_64_regs.orig_rax;
+switch (x86_64_regs.cs) {
+ case 0x23: currpers = 1; break;
+ case 0x33:
+ if (x86_64_regs.ds == 0x2b) {
+ currpers = 2;
+ scno &= ~__X32_SYSCALL_BIT;
+ } else
+ currpers = 0;
+ break;
+ default:
+ fprintf(stderr, "Unknown value CS=0x%08X while "
+ "detecting personality of process "
+ "PID=%d\n", (int)x86_64_regs.cs, tcp->pid);
+ currpers = current_personality;
+ break;
+}
+#elif 0
+/* This version analyzes the opcode of a syscall instruction.
+ * (int 0x80 on i386 vs. syscall on x86-64)
+ * It works, but is too complicated, and strictly speaking, unreliable.
+ */
+unsigned long call, rip = x86_64_regs.rip;
+/* sizeof(syscall) == sizeof(int 0x80) == 2 */
+rip -= 2;
+errno = 0;
+call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0);
+if (errno)
+ fprintf(stderr, "ptrace_peektext failed: %s\n",
+ strerror(errno));
+switch (call & 0xffff) {
+ /* x86-64: syscall = 0x0f 0x05 */
+ case 0x050f: currpers = 0; break;
+ /* i386: int 0x80 = 0xcd 0x80 */
+ case 0x80cd: currpers = 1; break;
+ default:
+ currpers = current_personality;
+ fprintf(stderr,
+ "Unknown syscall opcode (0x%04X) while "
+ "detecting personality of process "
+ "PID=%d\n", (int)call, tcp->pid);
+ break;
+}
+#endif
+
+#ifdef X32
+/* If we are built for a x32 system, then personality 0 is x32
+ * (not x86_64), and stracing of x86_64 apps is not supported.
+ * Stracing of i386 apps is still supported.
+ */
+if (currpers == 0) {
+ fprintf(stderr, "syscall_%lu(...) in unsupported "
+ "64-bit mode of process PID=%d\n",
+ scno, tcp->pid);
+ return 0;
+}
+currpers &= ~2; /* map 2,1 to 0,1 */
+#endif /* X32 */
+
+update_personality(tcp, currpers);
diff --git a/linux/x86_64/get_syscall_args.c b/linux/x86_64/get_syscall_args.c
new file mode 100644
index 0000000..0ccecdf
--- /dev/null
+++ b/linux/x86_64/get_syscall_args.c
@@ -0,0 +1,29 @@
+if (x86_io.iov_len != sizeof(i386_regs)) {
+ /* x86-64 or x32 ABI */
+ tcp->u_arg[0] = x86_64_regs.rdi;
+ tcp->u_arg[1] = x86_64_regs.rsi;
+ tcp->u_arg[2] = x86_64_regs.rdx;
+ tcp->u_arg[3] = x86_64_regs.r10;
+ tcp->u_arg[4] = x86_64_regs.r8;
+ tcp->u_arg[5] = x86_64_regs.r9;
+#ifdef X32
+ tcp->ext_arg[0] = x86_64_regs.rdi;
+ tcp->ext_arg[1] = x86_64_regs.rsi;
+ tcp->ext_arg[2] = x86_64_regs.rdx;
+ tcp->ext_arg[3] = x86_64_regs.r10;
+ tcp->ext_arg[4] = x86_64_regs.r8;
+ tcp->ext_arg[5] = x86_64_regs.r9;
+#endif
+} else {
+ /* i386 ABI */
+ /* Zero-extend from 32 bits */
+ /* Use widen_to_long(tcp->u_arg[N]) in syscall handlers
+ * if you need to use *sign-extended* parameter.
+ */
+ tcp->u_arg[0] = (long)(uint32_t)i386_regs.ebx;
+ tcp->u_arg[1] = (long)(uint32_t)i386_regs.ecx;
+ tcp->u_arg[2] = (long)(uint32_t)i386_regs.edx;
+ tcp->u_arg[3] = (long)(uint32_t)i386_regs.esi;
+ tcp->u_arg[4] = (long)(uint32_t)i386_regs.edi;
+ tcp->u_arg[5] = (long)(uint32_t)i386_regs.ebp;
+}
diff --git a/linux/x86_64/getregs_old.c b/linux/x86_64/getregs_old.c
new file mode 100644
index 0000000..6911eee
--- /dev/null
+++ b/linux/x86_64/getregs_old.c
@@ -0,0 +1,39 @@
+/*
+ * PTRACE_GETREGSET was added to the kernel in v2.6.25,
+ * a PTRACE_GETREGS based fallback is provided for old kernels.
+ */
+static void
+getregs_old(pid_t pid)
+{
+ /* Use old method, with unreliable heuristical detection of 32-bitness. */
+ get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &x86_64_regs);
+ if (get_regs_error)
+ return;
+
+ if (x86_64_regs.cs == 0x23) {
+ x86_io.iov_len = sizeof(i386_regs);
+ /*
+ * The order is important: i386_regs and x86_64_regs
+ * are overlaid in memory!
+ */
+ i386_regs.ebx = x86_64_regs.rbx;
+ i386_regs.ecx = x86_64_regs.rcx;
+ i386_regs.edx = x86_64_regs.rdx;
+ i386_regs.esi = x86_64_regs.rsi;
+ i386_regs.edi = x86_64_regs.rdi;
+ i386_regs.ebp = x86_64_regs.rbp;
+ i386_regs.eax = x86_64_regs.rax;
+ /* i386_regs.xds = x86_64_regs.ds; unused by strace */
+ /* i386_regs.xes = x86_64_regs.es; ditto... */
+ /* i386_regs.xfs = x86_64_regs.fs; */
+ /* i386_regs.xgs = x86_64_regs.gs; */
+ i386_regs.orig_eax = x86_64_regs.orig_rax;
+ i386_regs.eip = x86_64_regs.rip;
+ /* i386_regs.xcs = x86_64_regs.cs; */
+ /* i386_regs.eflags = x86_64_regs.eflags; */
+ i386_regs.esp = x86_64_regs.rsp;
+ /* i386_regs.xss = x86_64_regs.ss; */
+ } else {
+ x86_io.iov_len = sizeof(x86_64_regs);
+ }
+}
diff --git a/linux/x86_64/print_pc.c b/linux/x86_64/print_pc.c
new file mode 100644
index 0000000..71b080a
--- /dev/null
+++ b/linux/x86_64/print_pc.c
@@ -0,0 +1,4 @@
+if (x86_io.iov_len == sizeof(i386_regs))
+ tprintf(fmt, (unsigned long) i386_regs.eip);
+else
+ tprintf(fmt, (unsigned long) x86_64_regs.rip);
diff --git a/linux/xtensa/arch_regs.c b/linux/xtensa/arch_regs.c
new file mode 100644
index 0000000..1114cab
--- /dev/null
+++ b/linux/xtensa/arch_regs.c
@@ -0,0 +1 @@
+static long xtensa_a2;
diff --git a/linux/xtensa/get_error.c b/linux/xtensa/get_error.c
new file mode 100644
index 0000000..6efbb6e
--- /dev/null
+++ b/linux/xtensa/get_error.c
@@ -0,0 +1,6 @@
+if (check_errno && is_negated_errno(xtensa_a2)) {
+ tcp->u_rval = -1;
+ tcp->u_error = -xtensa_a2;
+} else {
+ tcp->u_rval = xtensa_a2;
+}
diff --git a/linux/xtensa/get_scno.c b/linux/xtensa/get_scno.c
new file mode 100644
index 0000000..4299163
--- /dev/null
+++ b/linux/xtensa/get_scno.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, SYSCALL_NR, &scno) < 0)
+ return -1;
diff --git a/linux/xtensa/get_syscall_args.c b/linux/xtensa/get_syscall_args.c
new file mode 100644
index 0000000..dca8788
--- /dev/null
+++ b/linux/xtensa/get_syscall_args.c
@@ -0,0 +1,7 @@
+/* arg0: a6, arg1: a3, arg2: a4, arg3: a5, arg4: a8, arg5: a9 */
+static const int xtensaregs[MAX_ARGS] = { 6, 3, 4, 5, 8, 9 };
+unsigned int i;
+
+for (i = 0; i < tcp->s_ent->nargs; ++i)
+ if (upeek(tcp->pid, REG_A_BASE + xtensaregs[i], &tcp->u_arg[i]) < 0)
+ return -1;
diff --git a/linux/xtensa/get_syscall_result.c b/linux/xtensa/get_syscall_result.c
new file mode 100644
index 0000000..0d2e697
--- /dev/null
+++ b/linux/xtensa/get_syscall_result.c
@@ -0,0 +1,2 @@
+if (upeek(tcp->pid, REG_A_BASE + 2, &xtensa_a2) < 0)
+ return -1;
diff --git a/linux/xtensa/print_pc.c b/linux/xtensa/print_pc.c
new file mode 100644
index 0000000..c0232e5
--- /dev/null
+++ b/linux/xtensa/print_pc.c
@@ -0,0 +1,6 @@
+long pc;
+if (upeek(tcp->pid, REG_PC, &pc) < 0) {
+ PRINTBADPC;
+ return;
+}
+tprintf(fmt, pc);
diff --git a/mem.c b/mem.c
index 5e1822f..4082658 100644
--- a/mem.c
+++ b/mem.c
@@ -34,8 +34,8 @@
#include <asm/mman.h>
#include <sys/mman.h>
-static unsigned long
-get_pagesize()
+unsigned long
+get_pagesize(void)
{
static unsigned long pagesize;
@@ -106,7 +106,7 @@
*/
int i;
unsigned narrow_arg[6];
- if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
+ if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
return 0;
for (i = 0; i < 6; i++)
u_arg[i] = (unsigned long) narrow_arg[i];
@@ -114,12 +114,12 @@
/* We are here only in personality 1 (i386) */
int i;
unsigned narrow_arg[6];
- if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
+ if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
return 0;
for (i = 0; i < 6; ++i)
u_arg[i] = (unsigned long) narrow_arg[i];
#else
- if (umoven(tcp, tcp->u_arg[0], sizeof(u_arg), (char *) u_arg) == -1)
+ if (umoven(tcp, tcp->u_arg[0], sizeof(u_arg), u_arg) == -1)
return 0;
#endif
return print_mmap(tcp, u_arg, (unsigned long) u_arg[5]);
@@ -134,7 +134,7 @@
int i;
unsigned narrow_arg[6];
unsigned long long offset;
- if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), (char *) narrow_arg) == -1)
+ if (umoven(tcp, tcp->u_arg[0], sizeof(narrow_arg), narrow_arg) == -1)
return 0;
for (i = 0; i < 5; i++)
u_arg[i] = (unsigned long) narrow_arg[i];
@@ -362,7 +362,7 @@
tprints("...");
break;
}
- if (umoven(tcp, cur, sizeof(n), (char *) &n) < 0) {
+ if (umoven(tcp, cur, sizeof(n), &n) < 0) {
tprints("?");
failed = 1;
break;
diff --git a/mknod.c b/mknod.c
index 07e9a45..1463232 100644
--- a/mknod.c
+++ b/mknod.c
@@ -1,6 +1,7 @@
#include "defs.h"
#include <fcntl.h>
+#include <sys/stat.h>
#ifdef MAJOR_IN_SYSMACROS
# include <sys/sysmacros.h>
diff --git a/net.c b/net.c
index cb29faa..58c54c8 100644
--- a/net.c
+++ b/net.c
@@ -1068,18 +1068,19 @@
if (syserror(tcp)) {
tprintf("%#lx", tcp->u_arg[0]);
} else {
-#if !defined(SPARC) && !defined(SPARC64) && !defined(SH) && !defined(IA64)
- int fds[2];
-
- if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
- tprints("[...]");
- else
- tprintf("[%u, %u]", fds[0], fds[1]);
-#elif defined(SPARC) || defined(SPARC64) || defined(SH) || defined(IA64)
- tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
-#else
- tprintf("%#lx", tcp->u_arg[0]);
+#ifdef HAVE_GETRVAL2
+ if (flags_arg < 0) {
+ tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
+ } else
#endif
+ {
+ int fds[2];
+
+ if (umove(tcp, tcp->u_arg[0], &fds) < 0)
+ tprintf("%#lx", tcp->u_arg[0]);
+ else
+ tprintf("[%u, %u]", fds[0], fds[1]);
+ }
}
if (flags_arg >= 0) {
tprints(", ");
@@ -1116,7 +1117,7 @@
tprintf(", %#lx", tcp->u_arg[3]);
return 0;
}
- if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
+ if (umoven(tcp, tcp->u_arg[3], sizeof fds, fds) < 0)
tprints(", [...]");
else
tprintf(", [%u, %u]", fds[0], fds[1]);
diff --git a/open.c b/open.c
index e97be42..5d82981 100644
--- a/open.c
+++ b/open.c
@@ -120,24 +120,3 @@
}
return RVAL_FD;
}
-
-#if defined(SPARC) || defined(SPARC64)
-# include "xlat/openmodessol.h"
-
-int
-solaris_open(struct tcb *tcp)
-{
- if (entering(tcp)) {
- printpath(tcp, tcp->u_arg[0]);
- tprints(", ");
- /* flags */
- printflags(openmodessol, tcp->u_arg[1] + 1, "O_???");
- if (tcp->u_arg[1] & 0x100) {
- /* mode */
- tprintf(", %#lo", tcp->u_arg[2]);
- }
- }
- return 0;
-}
-
-#endif /* SPARC || SPARC64 */
diff --git a/pathtrace.c b/pathtrace.c
index 28fc7c9..0db7fe3 100644
--- a/pathtrace.c
+++ b/pathtrace.c
@@ -270,7 +270,7 @@
args = tcp->u_arg;
if (s->sys_func == sys_oldselect) {
if (umoven(tcp, tcp->u_arg[0], sizeof oldargs,
- (char*) oldargs) < 0)
+ oldargs) < 0)
{
fprintf(stderr, "umoven() failed\n");
return 0;
@@ -294,7 +294,7 @@
for (i = 1; i <= 3; ++i) {
if (args[i] == 0)
continue;
- if (umoven(tcp, args[i], fdsize, (char *) fds) < 0) {
+ if (umoven(tcp, args[i], fdsize, fds) < 0) {
fprintf(stderr, "umoven() failed\n");
continue;
}
@@ -328,7 +328,7 @@
return 0;
for (cur = start; cur < end; cur += sizeof(fds))
- if ((umoven(tcp, cur, sizeof fds, (char *) &fds) == 0)
+ if ((umoven(tcp, cur, sizeof fds, &fds) == 0)
&& fdmatch(tcp, fds.fd))
return 1;
diff --git a/printmode.c b/printmode.c
index 4df1b9f..a721936 100644
--- a/printmode.c
+++ b/printmode.c
@@ -1,6 +1,7 @@
#include "defs.h"
#include <fcntl.h>
+#include <sys/stat.h>
#include "xlat/modetypes.h"
diff --git a/printsiginfo.c b/printsiginfo.c
new file mode 100644
index 0000000..4e23453
--- /dev/null
+++ b/printsiginfo.c
@@ -0,0 +1,201 @@
+#include "defs.h"
+
+#include "xlat/sigbus_codes.h"
+#include "xlat/sigchld_codes.h"
+#include "xlat/sigfpe_codes.h"
+#include "xlat/sigill_codes.h"
+#include "xlat/siginfo_codes.h"
+#include "xlat/sigpoll_codes.h"
+#include "xlat/sigprof_codes.h"
+#include "xlat/sigsegv_codes.h"
+#include "xlat/sigsys_codes.h"
+#include "xlat/sigtrap_codes.h"
+
+#ifdef SIGEMT
+# include "xlat/sigemt_codes.h"
+#endif
+
+#ifndef SI_FROMUSER
+# define SI_FROMUSER(sip) ((sip)->si_code <= 0)
+#endif
+
+static void
+printsigsource(const siginfo_t *sip)
+{
+ tprintf(", si_pid=%lu, si_uid=%lu",
+ (unsigned long) sip->si_pid,
+ (unsigned long) sip->si_uid);
+}
+
+static void
+printsigval(const siginfo_t *sip, bool verbose)
+{
+ if (!verbose)
+ tprints(", ...");
+ else
+ tprintf(", si_value={int=%u, ptr=%#lx}",
+ sip->si_int,
+ (unsigned long) sip->si_ptr);
+}
+
+static void
+print_si_code(int si_signo, int si_code)
+{
+ const char *code = xlookup(siginfo_codes, si_code);
+
+ if (!code) {
+ switch (si_signo) {
+ case SIGTRAP:
+ code = xlookup(sigtrap_codes, si_code);
+ break;
+ case SIGCHLD:
+ code = xlookup(sigchld_codes, si_code);
+ break;
+ case SIGPOLL:
+ code = xlookup(sigpoll_codes, si_code);
+ break;
+ case SIGPROF:
+ code = xlookup(sigprof_codes, si_code);
+ break;
+ case SIGILL:
+ code = xlookup(sigill_codes, si_code);
+ break;
+#ifdef SIGEMT
+ case SIGEMT:
+ code = xlookup(sigemt_codes, si_code);
+ break;
+#endif
+ case SIGFPE:
+ code = xlookup(sigfpe_codes, si_code);
+ break;
+ case SIGSEGV:
+ code = xlookup(sigsegv_codes, si_code);
+ break;
+ case SIGBUS:
+ code = xlookup(sigbus_codes, si_code);
+ break;
+ case SIGSYS:
+ code = xlookup(sigsys_codes, si_code);
+ break;
+ }
+ }
+
+ if (code)
+ tprints(code);
+ else
+ tprintf("%#x", si_code);
+}
+
+static void
+print_si_info(const siginfo_t *sip, bool verbose)
+{
+ if (sip->si_errno) {
+ tprints(", si_errno=");
+ if ((unsigned) sip->si_errno < nerrnos
+ && errnoent[sip->si_errno])
+ tprints(errnoent[sip->si_errno]);
+ else
+ tprintf("%d", sip->si_errno);
+ }
+
+ if (SI_FROMUSER(sip)) {
+ switch (sip->si_code) {
+ case SI_USER:
+ printsigsource(sip);
+ break;
+ case SI_TKILL:
+ printsigsource(sip);
+ break;
+#if defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
+ case SI_TIMER:
+ tprintf(", si_timerid=%#x, si_overrun=%d",
+ sip->si_timerid, sip->si_overrun);
+ printsigval(sip, verbose);
+ break;
+#endif
+ default:
+ printsigsource(sip);
+ if (sip->si_ptr)
+ printsigval(sip, verbose);
+ break;
+ }
+ } else {
+ switch (sip->si_signo) {
+ case SIGCHLD:
+ printsigsource(sip);
+ tprints(", si_status=");
+ if (sip->si_code == CLD_EXITED)
+ tprintf("%d", sip->si_status);
+ else
+ printsignal(sip->si_status);
+ if (!verbose)
+ tprints(", ...");
+ else
+ tprintf(", si_utime=%llu, si_stime=%llu",
+ (unsigned long long) sip->si_utime,
+ (unsigned long long) sip->si_stime);
+ break;
+ case SIGILL: case SIGFPE:
+ case SIGSEGV: case SIGBUS:
+ tprintf(", si_addr=%#lx",
+ (unsigned long) sip->si_addr);
+ break;
+ case SIGPOLL:
+ switch (sip->si_code) {
+ case POLL_IN: case POLL_OUT: case POLL_MSG:
+ tprintf(", si_band=%ld",
+ (long) sip->si_band);
+ break;
+ }
+ break;
+#ifdef HAVE_SIGINFO_T_SI_SYSCALL
+ case SIGSYS:
+ tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u",
+ (unsigned long) sip->si_call_addr,
+ sip->si_syscall, sip->si_arch);
+ break;
+#endif
+ default:
+ if (sip->si_pid || sip->si_uid)
+ printsigsource(sip);
+ if (sip->si_ptr)
+ printsigval(sip, verbose);
+ }
+ }
+}
+
+void
+printsiginfo(const siginfo_t *sip, bool verbose)
+{
+ if (sip->si_signo == 0) {
+ tprints("{}");
+ return;
+ }
+ tprints("{si_signo=");
+ printsignal(sip->si_signo);
+
+ tprints(", si_code=");
+ print_si_code(sip->si_signo, sip->si_code);
+
+#ifdef SI_NOINFO
+ if (sip->si_code != SI_NOINFO)
+#endif
+ print_si_info(sip, verbose);
+
+ tprints("}");
+}
+
+void
+printsiginfo_at(struct tcb *tcp, long addr)
+{
+ siginfo_t si;
+ if (!addr) {
+ tprints("NULL");
+ return;
+ }
+ if (syserror(tcp) || umove(tcp, addr, &si) < 0) {
+ tprintf("%#lx", addr);
+ return;
+ }
+ printsiginfo(&si, verbose(tcp));
+}
diff --git a/process_vm.c b/process_vm.c
index 9bd85a8..02058a5 100644
--- a/process_vm.c
+++ b/process_vm.c
@@ -35,17 +35,11 @@
/* arg 1: pid */
tprintf("%ld, ", tcp->u_arg[0]);
/* arg 2: local iov */
- if (syserror(tcp))
- tprintf("%#lx", tcp->u_arg[1]);
- else
- tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1);
+ tprint_iov(tcp, tcp->u_arg[2], tcp->u_arg[1], 1);
/* arg 3: local iovcnt */
tprintf(", %lu, ", tcp->u_arg[2]);
/* arg 4: remote iov */
- if (syserror(tcp))
- tprintf("%#lx", tcp->u_arg[3]);
- else
- tprint_iov(tcp, tcp->u_arg[4], tcp->u_arg[3], 0);
+ tprint_iov(tcp, tcp->u_arg[4], tcp->u_arg[3], 0);
/* arg 5: remote iovcnt */
/* arg 6: flags */
tprintf(", %lu, %lu", tcp->u_arg[4], tcp->u_arg[5]);
diff --git a/qemu_multiarch_testing/README b/qemu_multiarch_testing/README
index 3dc5581..9e4ef00 100644
--- a/qemu_multiarch_testing/README
+++ b/qemu_multiarch_testing/README
@@ -39,3 +39,11 @@
system-image-m68k - qemu-system-m68k: -M q800: Unsupported machine type
system-image-mips64 - init dies before reaching /mnt/init
system-image-sh4 - hdc does not mount (no support for 2 disks)
+
+
+To debug a build problem in one of sandboxes, change keep_hdb
+to "keep_hdb=true" in parallel-build-hdc-img.sh
+
+This preserves system-image-DIR1/hdb.img after the build,
+so you can go into system-image-DIR1 and run
+"HDB=hdb.img ./dev-environment.sh" to debug the problem.
diff --git a/qemu_multiarch_testing/parallel-build-hdc-img.sh b/qemu_multiarch_testing/parallel-build-hdc-img.sh
index d98f954..8d27367 100755
--- a/qemu_multiarch_testing/parallel-build-hdc-img.sh
+++ b/qemu_multiarch_testing/parallel-build-hdc-img.sh
@@ -1,13 +1,14 @@
#!/bin/sh
export HDBMEGS=64
+keep_hdb=false
build_in_dir()
{
cd "$1" || exit 1
rm -f hdb.img
nice -n10 time ./native-build.sh ../hdc.img
- rm -f hdb.img
+ $keep_hdb || rm -f hdb.img
echo >&3 "Finished: $1"
}
diff --git a/scsi.c b/scsi.c
index 867b74c..73c97ea 100644
--- a/scsi.c
+++ b/scsi.c
@@ -53,7 +53,7 @@
goto out;
allocated = (len > max_strlen) ? max_strlen : len;
if ((buf = malloc(allocated)) == NULL ||
- umoven(tcp, addr, allocated, (char *) buf) < 0) {
+ umoven(tcp, addr, allocated, buf) < 0) {
tprintf("%#lx", addr);
goto out;
}
diff --git a/sigaltstack.c b/sigaltstack.c
new file mode 100644
index 0000000..feba59b
--- /dev/null
+++ b/sigaltstack.c
@@ -0,0 +1,53 @@
+#include "defs.h"
+#include "xlat/sigaltstack_flags.h"
+
+static void
+print_stack_t(struct tcb *tcp, unsigned long addr)
+{
+ stack_t ss;
+ int r;
+
+ if (!addr) {
+ tprints("NULL");
+ return;
+ }
+
+#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+ if (current_wordsize != sizeof(ss.ss_sp) && current_wordsize == 4) {
+ struct {
+ uint32_t ss_sp;
+ int32_t ss_flags;
+ uint32_t ss_size;
+ } ss32;
+ r = umove(tcp, addr, &ss32);
+ if (r >= 0) {
+ memset(&ss, 0, sizeof(ss));
+ ss.ss_sp = (void*)(unsigned long) ss32.ss_sp;
+ ss.ss_flags = ss32.ss_flags;
+ ss.ss_size = (unsigned long) ss32.ss_size;
+ }
+ } else
+#endif
+ {
+ r = umove(tcp, addr, &ss);
+ }
+ if (r < 0) {
+ tprintf("%#lx", addr);
+ } else {
+ tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
+ printflags(sigaltstack_flags, ss.ss_flags, "SS_???");
+ tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
+ }
+}
+
+int
+sys_sigaltstack(struct tcb *tcp)
+{
+ if (entering(tcp)) {
+ print_stack_t(tcp, tcp->u_arg[0]);
+ } else {
+ tprints(", ");
+ print_stack_t(tcp, tcp->u_arg[1]);
+ }
+ return 0;
+}
diff --git a/signal.c b/signal.c
index 867e156..0b52ddb 100644
--- a/signal.c
+++ b/signal.c
@@ -249,258 +249,6 @@
tprints(sprintsigmask_n("", mask, len));
}
-#ifndef ILL_ILLOPC
-#define ILL_ILLOPC 1 /* illegal opcode */
-#define ILL_ILLOPN 2 /* illegal operand */
-#define ILL_ILLADR 3 /* illegal addressing mode */
-#define ILL_ILLTRP 4 /* illegal trap */
-#define ILL_PRVOPC 5 /* privileged opcode */
-#define ILL_PRVREG 6 /* privileged register */
-#define ILL_COPROC 7 /* coprocessor error */
-#define ILL_BADSTK 8 /* internal stack error */
-#define FPE_INTDIV 1 /* integer divide by zero */
-#define FPE_INTOVF 2 /* integer overflow */
-#define FPE_FLTDIV 3 /* floating point divide by zero */
-#define FPE_FLTOVF 4 /* floating point overflow */
-#define FPE_FLTUND 5 /* floating point underflow */
-#define FPE_FLTRES 6 /* floating point inexact result */
-#define FPE_FLTINV 7 /* floating point invalid operation */
-#define FPE_FLTSUB 8 /* subscript out of range */
-#define SEGV_MAPERR 1 /* address not mapped to object */
-#define SEGV_ACCERR 2 /* invalid permissions for mapped object */
-#define BUS_ADRALN 1 /* invalid address alignment */
-#define BUS_ADRERR 2 /* non-existant physical address */
-#define BUS_OBJERR 3 /* object specific hardware error */
-#define SYS_SECCOMP 1 /* seccomp triggered */
-#define TRAP_BRKPT 1 /* process breakpoint */
-#define TRAP_TRACE 2 /* process trace trap */
-#define CLD_EXITED 1 /* child has exited */
-#define CLD_KILLED 2 /* child was killed */
-#define CLD_DUMPED 3 /* child terminated abnormally */
-#define CLD_TRAPPED 4 /* traced child has trapped */
-#define CLD_STOPPED 5 /* child has stopped */
-#define CLD_CONTINUED 6 /* stopped child has continued */
-#define POLL_IN 1 /* data input available */
-#define POLL_OUT 2 /* output buffers available */
-#define POLL_MSG 3 /* input message available */
-#define POLL_ERR 4 /* i/o error */
-#define POLL_PRI 5 /* high priority input available */
-#define POLL_HUP 6 /* device disconnected */
-#define SI_KERNEL 0x80 /* sent by kernel */
-#define SI_USER 0 /* sent by kill, sigsend, raise */
-#define SI_QUEUE -1 /* sent by sigqueue */
-#define SI_TIMER -2 /* sent by timer expiration */
-#define SI_MESGQ -3 /* sent by real time mesq state change */
-#define SI_ASYNCIO -4 /* sent by AIO completion */
-#define SI_SIGIO -5 /* sent by SIGIO */
-#define SI_TKILL -6 /* sent by tkill */
-#define SI_DETHREAD -7 /* sent by execve killing subsidiary threads */
-#define SI_ASYNCNL -60 /* sent by asynch name lookup completion */
-#endif
-
-#ifndef SI_FROMUSER
-# define SI_FROMUSER(sip) ((sip)->si_code <= 0)
-#endif
-
-#include "xlat/siginfo_codes.h"
-#include "xlat/sigill_codes.h"
-#include "xlat/sigfpe_codes.h"
-#include "xlat/sigtrap_codes.h"
-#include "xlat/sigchld_codes.h"
-#include "xlat/sigpoll_codes.h"
-#include "xlat/sigprof_codes.h"
-
-#ifdef SIGEMT
-#include "xlat/sigemt_codes.h"
-#endif
-
-#include "xlat/sigsegv_codes.h"
-#include "xlat/sigbus_codes.h"
-
-#ifndef SYS_SECCOMP
-# define SYS_SECCOMP 1
-#endif
-#include "xlat/sigsys_codes.h"
-
-static void
-printsigsource(const siginfo_t *sip)
-{
- tprintf(", si_pid=%lu, si_uid=%lu",
- (unsigned long) sip->si_pid,
- (unsigned long) sip->si_uid);
-}
-
-static void
-printsigval(const siginfo_t *sip, int verbose)
-{
- if (!verbose)
- tprints(", ...");
- else
- tprintf(", si_value={int=%u, ptr=%#lx}",
- sip->si_int,
- (unsigned long) sip->si_ptr);
-}
-
-void
-printsiginfo(const siginfo_t *sip, int verbose)
-{
- const char *code;
-
- if (sip->si_signo == 0) {
- tprints("{}");
- return;
- }
- tprints("{si_signo=");
- printsignal(sip->si_signo);
- code = xlookup(siginfo_codes, sip->si_code);
- if (!code) {
- switch (sip->si_signo) {
- case SIGTRAP:
- code = xlookup(sigtrap_codes, sip->si_code);
- break;
- case SIGCHLD:
- code = xlookup(sigchld_codes, sip->si_code);
- break;
- case SIGPOLL:
- code = xlookup(sigpoll_codes, sip->si_code);
- break;
- case SIGPROF:
- code = xlookup(sigprof_codes, sip->si_code);
- break;
- case SIGILL:
- code = xlookup(sigill_codes, sip->si_code);
- break;
-#ifdef SIGEMT
- case SIGEMT:
- code = xlookup(sigemt_codes, sip->si_code);
- break;
-#endif
- case SIGFPE:
- code = xlookup(sigfpe_codes, sip->si_code);
- break;
- case SIGSEGV:
- code = xlookup(sigsegv_codes, sip->si_code);
- break;
- case SIGBUS:
- code = xlookup(sigbus_codes, sip->si_code);
- break;
- case SIGSYS:
- code = xlookup(sigsys_codes, sip->si_code);
- break;
- }
- }
- if (code)
- tprintf(", si_code=%s", code);
- else
- tprintf(", si_code=%#x", sip->si_code);
-#ifdef SI_NOINFO
- if (sip->si_code != SI_NOINFO)
-#endif
- {
- if (sip->si_errno) {
- tprints(", si_errno=");
- if ((unsigned) sip->si_errno < nerrnos
- && errnoent[sip->si_errno])
- tprints(errnoent[sip->si_errno]);
- else
- tprintf("%d", sip->si_errno);
- }
-#ifdef SI_FROMUSER
- if (SI_FROMUSER(sip)) {
- switch (sip->si_code) {
-#ifdef SI_USER
- case SI_USER:
- printsigsource(sip);
- break;
-#endif
-#ifdef SI_TKILL
- case SI_TKILL:
- printsigsource(sip);
- break;
-#endif
-#if defined SI_TIMER \
- && defined HAVE_SIGINFO_T_SI_TIMERID && defined HAVE_SIGINFO_T_SI_OVERRUN
- case SI_TIMER:
- tprintf(", si_timerid=%#x, si_overrun=%d",
- sip->si_timerid, sip->si_overrun);
- printsigval(sip, verbose);
- break;
-#endif
- default:
- printsigsource(sip);
- if (sip->si_ptr)
- printsigval(sip, verbose);
- break;
- }
- }
- else
-#endif /* SI_FROMUSER */
- {
- switch (sip->si_signo) {
- case SIGCHLD:
- printsigsource(sip);
- tprints(", si_status=");
- if (sip->si_code == CLD_EXITED)
- tprintf("%d", sip->si_status);
- else
- printsignal(sip->si_status);
- if (!verbose)
- tprints(", ...");
- else
- tprintf(", si_utime=%llu, si_stime=%llu",
- (unsigned long long) sip->si_utime,
- (unsigned long long) sip->si_stime);
- break;
- case SIGILL: case SIGFPE:
- case SIGSEGV: case SIGBUS:
- tprintf(", si_addr=%#lx",
- (unsigned long) sip->si_addr);
- break;
- case SIGPOLL:
- switch (sip->si_code) {
- case POLL_IN: case POLL_OUT: case POLL_MSG:
- tprintf(", si_band=%ld",
- (long) sip->si_band);
- break;
- }
- break;
-#ifdef HAVE_SIGINFO_T_SI_SYSCALL
- case SIGSYS:
- tprintf(", si_call_addr=%#lx, si_syscall=%d, si_arch=%u",
- (unsigned long) sip->si_call_addr,
- sip->si_syscall, sip->si_arch);
- break;
-#endif
- default:
- if (sip->si_pid || sip->si_uid)
- printsigsource(sip);
- if (sip->si_ptr)
- printsigval(sip, verbose);
- }
- }
- }
- tprints("}");
-}
-
-void
-printsiginfo_at(struct tcb *tcp, long addr)
-{
- siginfo_t si;
- if (!addr) {
- tprints("NULL");
- return;
- }
- if (syserror(tcp)) {
- tprintf("%#lx", addr);
- return;
- }
- if (umove(tcp, addr, &si) < 0) {
- tprints("{???}");
- return;
- }
- printsiginfo(&si, verbose(tcp));
-}
-
int
sys_sigsetmask(struct tcb *tcp)
{
@@ -681,65 +429,6 @@
return 0;
}
-#if !defined SS_ONSTACK
-#define SS_ONSTACK 1
-#define SS_DISABLE 2
-#endif
-
-#include "xlat/sigaltstack_flags.h"
-
-static void
-print_stack_t(struct tcb *tcp, unsigned long addr)
-{
- stack_t ss;
- int r;
-
- if (!addr) {
- tprints("NULL");
- return;
- }
-
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- if (current_wordsize != sizeof(ss.ss_sp) && current_wordsize == 4) {
- struct {
- uint32_t ss_sp;
- int32_t ss_flags;
- uint32_t ss_size;
- } ss32;
- r = umove(tcp, addr, &ss32);
- if (r >= 0) {
- memset(&ss, 0, sizeof(ss));
- ss.ss_sp = (void*)(unsigned long) ss32.ss_sp;
- ss.ss_flags = ss32.ss_flags;
- ss.ss_size = (unsigned long) ss32.ss_size;
- }
- } else
-#endif
- {
- r = umove(tcp, addr, &ss);
- }
- if (r < 0) {
- tprintf("%#lx", addr);
- } else {
- tprintf("{ss_sp=%#lx, ss_flags=", (unsigned long) ss.ss_sp);
- printflags(sigaltstack_flags, ss.ss_flags, "SS_???");
- tprintf(", ss_size=%lu}", (unsigned long) ss.ss_size);
- }
-}
-
-int
-sys_sigaltstack(struct tcb *tcp)
-{
- if (entering(tcp)) {
- print_stack_t(tcp, tcp->u_arg[0]);
- }
- else {
- tprints(", ");
- print_stack_t(tcp, tcp->u_arg[1]);
- }
- return 0;
-}
-
#ifdef HAVE_SIGACTION
/* "Old" sigprocmask, which operates with word-sized signal masks */
@@ -1056,8 +745,13 @@
int
sys_restart_syscall(struct tcb *tcp)
{
- if (entering(tcp))
- tprints("<... resuming interrupted call ...>");
+ if (entering(tcp)) {
+ tprintf("<... resuming interrupted %s ...>",
+ tcp->s_prev_ent
+ ? tcp->s_prev_ent->sys_name
+ : "system call"
+ );
+ }
return 0;
}
diff --git a/sigreturn.c b/sigreturn.c
index 365ef1a..b3fc038 100644
--- a/sigreturn.c
+++ b/sigreturn.c
@@ -16,228 +16,8 @@
int
sys_sigreturn(struct tcb *tcp)
{
-#if defined AARCH64 || defined ARM
if (entering(tcp)) {
-# define SIZEOF_STRUCT_SIGINFO 128
-# define SIZEOF_STRUCT_SIGCONTEXT (21 * 4)
-# define OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK (5 * 4 + SIZEOF_STRUCT_SIGCONTEXT)
- const long addr =
-# ifdef AARCH64
- current_personality == 1 ?
- (*aarch64_sp_ptr + SIZEOF_STRUCT_SIGINFO +
- offsetof(struct ucontext, uc_sigmask)) :
-# endif
- (*arm_sp_ptr +
- OFFSETOF_STRUCT_UCONTEXT_UC_SIGMASK);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
+#include "arch_sigreturn.c"
}
-#elif defined(S390) || defined(S390X)
- if (entering(tcp)) {
- long mask[NSIG / 8 / sizeof(long)];
- tprints("{mask=");
- const long addr = *s390_frame_ptr + __SIGNAL_FRAMESIZE;
- if (umove(tcp, addr, &mask) < 0) {
- tprintf("%#lx", addr);
- } else {
-# ifdef S390
- long v = mask[0];
- mask[0] = mask[1];
- mask[1] = v;
-# endif
- tprintsigmask_addr("", mask);
- }
- tprints("}");
- }
-#elif defined I386 || defined X86_64 || defined X32
- if (entering(tcp)) {
-# ifndef I386
- if (current_personality != 1) {
- const unsigned long addr =
- (unsigned long) *x86_64_rsp_ptr +
- offsetof(struct ucontext, uc_sigmask);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- return 0;
- }
-# endif
- /*
- * On i386, sigcontext is followed on stack by struct fpstate
- * and after it an additional u32 extramask which holds
- * upper half of the mask.
- */
- struct {
- uint32_t struct_sigcontext_padding1[20];
- uint32_t oldmask;
- uint32_t struct_sigcontext_padding2;
- uint32_t struct_fpstate_padding[156];
- uint32_t extramask;
- } frame;
- tprints("{mask=");
- if (umove(tcp, *i386_esp_ptr, &frame) < 0) {
- tprintf("%#lx", (unsigned long) *i386_esp_ptr);
- } else {
- uint32_t mask[2] = { frame.oldmask, frame.extramask };
- tprintsigmask_addr("", mask);
- }
- tprints("}");
- }
-#elif defined(IA64)
- if (entering(tcp)) {
- /* offsetof(struct sigframe, sc) */
-# define OFFSETOF_STRUCT_SIGFRAME_SC 0xA0
- const long addr = *ia64_frame_ptr + 16 +
- OFFSETOF_STRUCT_SIGFRAME_SC +
- offsetof(struct sigcontext, sc_mask);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- }
-#elif defined(POWERPC)
- if (entering(tcp)) {
- long esp = ppc_regs.gpr[1];
- struct sigcontext sc;
-
- /* Skip dummy stack frame. */
-#ifdef POWERPC64
- if (current_personality == 0)
- esp += 128;
- else
-#endif
- esp += 64;
-
- tprints("{mask=");
- if (umove(tcp, esp, &sc) < 0) {
- tprintf("%#lx", esp);
- } else {
- unsigned long mask[NSIG / 8 / sizeof(long)];
-#ifdef POWERPC64
- mask[0] = sc.oldmask | (sc._unused[3] << 32);
-#else
- mask[0] = sc.oldmask;
- mask[1] = sc._unused[3];
-#endif
- tprintsigmask_addr("", mask);
- }
- tprints("}");
- }
-#elif defined(M68K)
- if (entering(tcp)) {
- long addr;
- if (upeek(tcp->pid, 4*PT_USP, &addr) < 0)
- return 0;
- /* Fetch pointer to struct sigcontext. */
- if (umove(tcp, addr + 2 * sizeof(int), &addr) < 0)
- return 0;
- unsigned long mask[NSIG / 8 / sizeof(long)];
- /* Fetch first word of signal mask. */
- if (umove(tcp, addr, &mask[0]) < 0)
- return 0;
- /* Fetch remaining words of signal mask, located
- immediately before. */
- addr -= sizeof(mask) - sizeof(long);
- if (umoven(tcp, addr, sizeof(mask) - sizeof(long), (char *) &mask[1]) < 0)
- return 0;
- tprints("{mask=");
- tprintsigmask_addr("", mask);
- tprints("}");
- }
-#elif defined(ALPHA)
- if (entering(tcp)) {
- long addr;
- if (upeek(tcp->pid, REG_FP, &addr) < 0)
- return 0;
- addr += offsetof(struct sigcontext, sc_mask);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- }
-#elif defined(SPARC) || defined(SPARC64)
- if (entering(tcp)) {
- long fp = sparc_regs.u_regs[U_REG_FP] + sizeof(struct sparc_stackf);
- struct {
- struct pt_regs si_regs;
- int si_mask;
- void *fpu_save;
- long insns[2] __attribute__ ((aligned (8)));
- unsigned int extramask[NSIG / 8 / sizeof(int) - 1];
- } frame;
-
- tprints("{mask=");
- if (umove(tcp, fp, &frame) < 0) {
- tprintf("%#lx", fp);
- } else {
- unsigned int mask[NSIG / 8 / sizeof(int)];
-
- mask[0] = frame.si_mask;
- memcpy(mask + 1, frame.extramask, sizeof(frame.extramask));
- tprintsigmask_addr("", mask);
- }
- tprints("}");
- }
-#elif defined MIPS
- if (entering(tcp)) {
-# if defined LINUX_MIPSO32
- /*
- * offsetof(struct sigframe, sf_mask) ==
- * sizeof(sf_ass) + sizeof(sf_pad) + sizeof(struct sigcontext)
- */
- const long addr = mips_REG_SP + 6 * 4 +
- sizeof(struct sigcontext);
-# else
- /*
- * This decodes rt_sigreturn.
- * The 64-bit ABIs do not have sigreturn.
- *
- * offsetof(struct rt_sigframe, rs_uc) ==
- * sizeof(sf_ass) + sizeof(sf_pad) + sizeof(struct siginfo)
- */
- const long addr = mips_REG_SP + 6 * 4 + 128 +
- offsetof(struct ucontext, uc_sigmask);
-# endif
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- }
-#elif defined(CRISV10) || defined(CRISV32)
- if (entering(tcp)) {
- long regs[PT_MAX+1];
- if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long)regs) < 0) {
- perror_msg("sigreturn: PTRACE_GETREGS");
- return 0;
- }
- const long addr = regs[PT_USP] +
- offsetof(struct sigcontext, oldmask);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- }
-#elif defined(TILE)
- if (entering(tcp)) {
- /* offset of ucontext in the kernel's sigframe structure */
-# define SIGFRAME_UC_OFFSET C_ABI_SAVE_AREA_SIZE + sizeof(siginfo_t)
- const long addr = tile_regs.sp + SIGFRAME_UC_OFFSET +
- offsetof(struct ucontext, uc_sigmask);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- }
-#elif defined(MICROBLAZE)
- /* TODO: Verify that this is correct... */
- if (entering(tcp)) {
- long addr;
- /* Read r1, the stack pointer. */
- if (upeek(tcp->pid, 1 * 4, &addr) < 0)
- return 0;
- addr += offsetof(struct sigcontext, oldmask);
- tprints("{mask=");
- print_sigset_addr_len(tcp, addr, NSIG / 8);
- tprints("}");
- }
-#else
-# warning sigreturn/rt_sigreturn signal mask decoding is not implemented for this architecture
-#endif
return 0;
}
diff --git a/sock.c b/sock.c
index b6fc95c..dc8febc 100644
--- a/sock.c
+++ b/sock.c
@@ -256,7 +256,7 @@
struct ifreq ifra[nifra];
if (umoven(tcp, (unsigned long) ifc.ifc_buf,
- sizeof(ifra), (char *) ifra) < 0) {
+ sizeof(ifra), ifra) < 0) {
tprintf("%lx}", (unsigned long) ifc.ifc_buf);
return 1;
}
diff --git a/statfs.c b/statfs.c
index 214e6b2..6373195 100644
--- a/statfs.c
+++ b/statfs.c
@@ -125,7 +125,7 @@
uint32_t f_spare[4];
}
#if defined AARCH64 || defined X86_64 || defined X32 || defined IA64
- __attribute__ ((packed, aligned(4)))
+ ATTRIBUTE_PACKED ATTRIBUTE_ALIGNED(4)
#endif
;
#if defined AARCH64 || defined ARM
diff --git a/strace.c b/strace.c
index b714255..5eab360 100644
--- a/strace.c
+++ b/strace.c
@@ -251,8 +251,8 @@
exit(exitval);
}
-static void die(void) __attribute__ ((noreturn));
-static void die(void)
+static void ATTRIBUTE_NORETURN
+die(void)
{
if (strace_tracer_pid == getpid()) {
cflag = 0;
@@ -1097,7 +1097,8 @@
char *pathname;
};
static struct exec_params params_for_tracee;
-static void __attribute__ ((noinline, noreturn))
+
+static void ATTRIBUTE_NOINLINE ATTRIBUTE_NORETURN
exec_or_die(void)
{
struct exec_params *params = ¶ms_for_tracee;
@@ -1420,7 +1421,7 @@
* Don't want main() to inline us and defeat the reason
* we have a separate function.
*/
-static void __attribute__ ((noinline))
+static void ATTRIBUTE_NOINLINE
init(int argc, char *argv[])
{
struct tcb *tcp;
@@ -2005,7 +2006,7 @@
}
}
-static bool
+static void
startup_tcb(struct tcb *tcp)
{
if (debug_flag)
@@ -2025,8 +2026,6 @@
}
}
}
-
- return true;
}
/* Returns true iff the main trace loop has to continue. */
@@ -2045,8 +2044,26 @@
if (interrupted)
return false;
- if (popen_pid != 0 && nprocs == 0)
- return false;
+ /*
+ * Used to exit simply when nprocs hits zero, but in this testcase:
+ * int main() { _exit(!!fork()); }
+ * under strace -f, parent sometimes (rarely) manages
+ * to exit before we see the first stop of the child,
+ * and we are losing track of it:
+ * 19923 clone(...) = 19924
+ * 19923 exit_group(1) = ?
+ * 19923 +++ exited with 1 +++
+ * Exiting only when wait() returns ECHILD works better.
+ */
+ if (popen_pid != 0) {
+ /* However, if -o|logger is in use, we can't do that.
+ * Can work around that by double-forking the logger,
+ * but that loses the ability to wait for its completion
+ * on exit. Oh well...
+ */
+ if (nprocs == 0)
+ return false;
+ }
if (interactive)
sigprocmask(SIG_SETMASK, &empty_set, NULL);
@@ -2151,8 +2168,9 @@
/* Is this the very first time we see this tracee stopped? */
if (tcp->flags & TCB_STARTUP) {
- if (!startup_tcb(tcp))
- return false;
+ startup_tcb(tcp);
+ if (get_scno(tcp) == 1)
+ tcp->s_prev_ent = tcp->s_ent;
}
sig = WSTOPSIG(status);
@@ -2270,23 +2288,6 @@
{
init(argc, argv);
- /*
- * Run main tracing loop.
- *
- * Used to be "while (nprocs != 0)", but in this testcase:
- * int main() { _exit(!!fork()); }
- * under strace -f, parent sometimes (rarely) manages
- * to exit before we see the first stop of the child,
- * and we are losing track of it:
- * 19923 clone(...) = 19924
- * 19923 exit_group(1) = ?
- * 19923 +++ exited with 1 +++
- * Waiting for ECHILD works better.
- * (However, if -o|logger is in use, we can't do that.
- * Can work around that by double-forking the logger,
- * but that loses the ability to wait for its completion on exit.
- * Oh well...)
- */
while (trace())
;
diff --git a/stream.c b/stream.c
index 2aa6366..3ebbfb7 100644
--- a/stream.c
+++ b/stream.c
@@ -263,7 +263,7 @@
tprints("...");
break;
}
- if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
+ if (umoven(tcp, cur, sizeof fds, &fds) < 0) {
tprints("?");
failed = 1;
break;
@@ -313,7 +313,7 @@
outptr = outstr;
for (cur = start; cur < end; cur += sizeof(fds)) {
- if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
+ if (umoven(tcp, cur, sizeof fds, &fds) < 0) {
if (outptr < end_outstr - 2)
*outptr++ = '?';
failed = 1;
diff --git a/syscall.c b/syscall.c
index b37f43a..d54d8b6 100644
--- a/syscall.c
+++ b/syscall.c
@@ -559,7 +559,7 @@
decode_socket_subcall(struct tcb *tcp)
{
unsigned long addr;
- unsigned int i, n, size;
+ unsigned int n;
if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls)
return;
@@ -568,22 +568,18 @@
tcp->qual_flg = qual_flags[tcp->scno];
tcp->s_ent = &sysent[tcp->scno];
addr = tcp->u_arg[1];
- size = current_wordsize;
n = tcp->s_ent->nargs;
- for (i = 0; i < n; ++i) {
- if (size == sizeof(int)) {
- unsigned int arg;
- if (umove(tcp, addr, &arg) < 0)
- arg = 0;
- tcp->u_arg[i] = arg;
- }
- else {
- unsigned long arg;
- if (umove(tcp, addr, &arg) < 0)
- arg = 0;
- tcp->u_arg[i] = arg;
- }
- addr += size;
+ if (sizeof(tcp->u_arg[0]) == current_wordsize) {
+ memset(tcp->u_arg, 0, n * sizeof(tcp->u_arg[0]));
+ (void) umoven(tcp, addr, n * sizeof(tcp->u_arg[0]), tcp->u_arg);
+ } else {
+ unsigned int args[n];
+ unsigned int i;
+
+ memset(args, 0, sizeof(args));
+ (void) umove(tcp, addr, &args);
+ for (i = 0; i < n; ++i)
+ tcp->u_arg[i] = args[i];
}
}
#endif
@@ -642,297 +638,53 @@
return 0;
}
-#if defined(I386)
-static struct user_regs_struct i386_regs;
-long *const i386_esp_ptr = &i386_regs.esp;
-# define ARCH_REGS_FOR_GETREGS i386_regs
-#elif defined(X86_64) || defined(X32)
-/*
- * On i386, pt_regs and user_regs_struct are the same,
- * but on 64 bit x86, user_regs_struct has six more fields:
- * fs_base, gs_base, ds, es, fs, gs.
- * PTRACE_GETREGS fills them too, so struct pt_regs would overflow.
- */
-struct i386_user_regs_struct {
- uint32_t ebx;
- uint32_t ecx;
- uint32_t edx;
- uint32_t esi;
- uint32_t edi;
- uint32_t ebp;
- uint32_t eax;
- uint32_t xds;
- uint32_t xes;
- uint32_t xfs;
- uint32_t xgs;
- uint32_t orig_eax;
- uint32_t eip;
- uint32_t xcs;
- uint32_t eflags;
- uint32_t esp;
- uint32_t xss;
-};
-static union {
- struct user_regs_struct x86_64_r;
- struct i386_user_regs_struct i386_r;
-} x86_regs_union;
-# define x86_64_regs x86_regs_union.x86_64_r
-# define i386_regs x86_regs_union.i386_r
-uint32_t *const i386_esp_ptr = &i386_regs.esp;
-uint64_t *const x86_64_rsp_ptr = (uint64_t *) &x86_64_regs.rsp;
-static struct iovec x86_io = {
- .iov_base = &x86_regs_union
-};
-# define ARCH_REGS_FOR_GETREGSET x86_regs_union
-# define ARCH_IOVEC_FOR_GETREGSET x86_io
-#elif defined(IA64)
-static struct pt_all_user_regs ia64_regs;
-unsigned long *const ia64_frame_ptr = &ia64_regs.gr[12];
-# define IA64_PSR_IS ((long)1 << 34)
-# define ia64_ia32mode (ia64_regs.cr_ipsr & IA64_PSR_IS)
-# define ARCH_REGS_FOR_GETREGS ia64_regs
-#elif defined(POWERPC)
-struct pt_regs ppc_regs; /* not static */
-# define ARCH_REGS_FOR_GETREGS ppc_regs
-#elif defined(M68K)
-static long m68k_d0;
-#elif defined(BFIN)
-static long bfin_r0;
-#elif defined(ARM)
-static struct pt_regs arm_regs;
-long *const arm_sp_ptr = &arm_regs.ARM_sp;
-# define ARCH_REGS_FOR_GETREGS arm_regs
-#elif defined(AARCH64)
-struct arm_pt_regs {
- int uregs[18];
-};
-# define ARM_cpsr uregs[16]
-# define ARM_pc uregs[15]
-# define ARM_lr uregs[14]
-# define ARM_sp uregs[13]
-# define ARM_ip uregs[12]
-# define ARM_fp uregs[11]
-# define ARM_r10 uregs[10]
-# define ARM_r9 uregs[9]
-# define ARM_r8 uregs[8]
-# define ARM_r7 uregs[7]
-# define ARM_r6 uregs[6]
-# define ARM_r5 uregs[5]
-# define ARM_r4 uregs[4]
-# define ARM_r3 uregs[3]
-# define ARM_r2 uregs[2]
-# define ARM_r1 uregs[1]
-# define ARM_r0 uregs[0]
-# define ARM_ORIG_r0 uregs[17]
-static union {
- struct user_pt_regs aarch64_r;
- struct arm_pt_regs arm_r;
-} arm_regs_union;
-# define aarch64_regs arm_regs_union.aarch64_r
-# define arm_regs arm_regs_union.arm_r
-uint64_t *const aarch64_sp_ptr = (uint64_t *) &aarch64_regs.sp;
-uint32_t *const arm_sp_ptr = (uint32_t *) &arm_regs.ARM_sp;
-static struct iovec aarch64_io = {
- .iov_base = &arm_regs_union
-};
-# define ARCH_REGS_FOR_GETREGSET arm_regs_union
-# define ARCH_IOVEC_FOR_GETREGSET aarch64_io
-#elif defined(ALPHA)
-static long alpha_r0;
-static long alpha_a3;
-#elif defined(AVR32)
-static struct pt_regs avr32_regs;
-# define ARCH_REGS_FOR_GETREGS avr32_regs
-#elif defined(SPARC) || defined(SPARC64)
-struct pt_regs sparc_regs; /* not static */
-# define ARCH_REGS_FOR_GETREGS sparc_regs
-#elif defined(MIPS)
-struct mips_regs mips_regs; /* not static */
-/* PTRACE_GETREGS on MIPS is available since linux v2.6.15. */
-# define ARCH_REGS_FOR_GETREGS mips_regs
-#elif defined(S390) || defined(S390X)
-/* PTRACE_GETREGSET on S390 is available since linux v2.6.27. */
-static struct user_regs_struct s390_regset;
-unsigned long *const s390_frame_ptr = &s390_regset.gprs[15];
-# define ARCH_REGS_FOR_GETREGSET s390_regset
-#elif defined(HPPA)
-static long hppa_r28;
-#elif defined(SH)
-static long sh_r0;
-#elif defined(SH64)
-static long sh64_r9;
-#elif defined(CRISV10) || defined(CRISV32)
-static long cris_r10;
-#elif defined(TILE)
-struct pt_regs tile_regs; /* not static */
-# define ARCH_REGS_FOR_GETREGS tile_regs
-#elif defined(MICROBLAZE)
-static long microblaze_r3;
-#elif defined(OR1K)
-static struct user_regs_struct or1k_regs;
-# define ARCH_REGS_FOR_GETREGSET or1k_regs
-#elif defined(METAG)
-static struct user_gp_regs metag_regs;
-# define ARCH_REGS_FOR_GETREGSET metag_regs
-#elif defined(XTENSA)
-static long xtensa_a2;
-# elif defined(ARC)
-static struct user_regs_struct arc_regs;
-# define ARCH_REGS_FOR_GETREGSET arc_regs
-#endif
-
-static long get_regs_error;
-
-#if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH)
-long
-getrval2(struct tcb *tcp)
+static void
+dumpio(struct tcb *tcp)
{
- long val;
+ int (*func)();
-# if defined(SPARC) || defined(SPARC64)
- val = sparc_regs.u_regs[U_REG_O1];
-# elif defined(SH)
- if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0)
- return -1;
-# elif defined(IA64)
- val = ia64_regs.gr[9];
-# endif
-
- return val;
-}
+ if (syserror(tcp))
+ return;
+ if ((unsigned long) tcp->u_arg[0] >= num_quals)
+ return;
+ func = tcp->s_ent->sys_func;
+ if (func == printargs)
+ return;
+ if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
+ if (func == sys_read ||
+ func == sys_pread ||
+ func == sys_recv ||
+ func == sys_recvfrom) {
+ dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
+ return;
+ } else if (func == sys_readv) {
+ dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
+ return;
+#if HAVE_SENDMSG
+ } else if (func == sys_recvmsg) {
+ dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+ return;
+ } else if (func == sys_recvmmsg) {
+ dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
+ return;
#endif
-
-void
-print_pc(struct tcb *tcp)
-{
- const char *fmt;
- const char *bad;
-
-#ifdef current_wordsize
-# define pc_wordsize current_wordsize
-#else
-# define pc_wordsize personality_wordsize[tcp->currpers]
+ }
+ }
+ if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
+ if (func == sys_write ||
+ func == sys_pwrite ||
+ func == sys_send ||
+ func == sys_sendto)
+ dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
+ else if (func == sys_writev)
+ dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
+#if HAVE_SENDMSG
+ else if (func == sys_sendmsg)
+ dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
+ else if (func == sys_sendmmsg)
+ dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
#endif
-
- if (pc_wordsize == 4) {
- fmt = "[%08lx] ";
- bad = "[????????] ";
- } else {
- fmt = "[%016lx] ";
- bad = "[????????????????] ";
}
-
-#undef pc_wordsize
-#define PRINTBADPC tprints(bad)
-
- if (get_regs_error) {
- PRINTBADPC;
- return;
- }
-
-#if defined(I386)
- tprintf(fmt, i386_regs.eip);
-#elif defined(X86_64) || defined(X32)
- if (x86_io.iov_len == sizeof(i386_regs))
- tprintf(fmt, (unsigned long) i386_regs.eip);
- else
- tprintf(fmt, (unsigned long) x86_64_regs.rip);
-#elif defined(S390) || defined(S390X)
- tprintf(fmt, s390_regset.psw.addr);
-#elif defined(IA64)
- tprintf(fmt, ia64_regs.br[0]);
-#elif defined(POWERPC)
- tprintf(fmt, ppc_regs.nip);
-#elif defined(M68K)
- long pc;
- if (upeek(tcp->pid, 4*PT_PC, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(ALPHA)
- long pc;
- if (upeek(tcp->pid, REG_PC, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(SPARC)
- tprintf(fmt, sparc_regs.pc);
-#elif defined(SPARC64)
- tprintf(fmt, sparc_regs.tpc);
-#elif defined(HPPA)
- long pc;
- if (upeek(tcp->pid, PT_IAOQ0, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined MIPS
- tprintf(fmt, (unsigned long) mips_REG_EPC);
-#elif defined(SH)
- long pc;
- if (upeek(tcp->pid, 4*REG_PC, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(SH64)
- long pc;
- if (upeek(tcp->pid, REG_PC, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(AARCH64)
- if (aarch64_io.iov_len == sizeof(arm_regs))
- tprintf(fmt, (unsigned long) arm_regs.ARM_pc);
- else
- tprintf(fmt, (unsigned long) aarch64_regs.pc);
-#elif defined(ARM)
- tprintf(fmt, arm_regs.ARM_pc);
-#elif defined(AVR32)
- tprintf(fmt, avr32_regs.pc);
-#elif defined(BFIN)
- long pc;
- if (upeek(tcp->pid, PT_PC, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(CRISV10)
- long pc;
- if (upeek(tcp->pid, 4*PT_IRP, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(CRISV32)
- long pc;
- if (upeek(tcp->pid, 4*PT_ERP, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(TILE)
- tprintf(fmt, (unsigned long) tile_regs.pc);
-#elif defined(OR1K)
- tprintf(fmt, or1k_regs.pc);
-#elif defined(METAG)
- tprintf(fmt, metag_regs.pc);
-#elif defined(XTENSA)
- long pc;
- if (upeek(tcp->pid, REG_PC, &pc) < 0) {
- PRINTBADPC;
- return;
- }
- tprintf(fmt, pc);
-#elif defined(ARC)
- tprintf(fmt, arc_regs.efa);
-#else
-# warning print_pc is not implemented for this architecture
- PRINTBADPC;
-#endif /* architecture */
}
/*
@@ -981,42 +733,7 @@
return buf;
}
-#ifdef POWERPC
-/*
- * PTRACE_GETREGS was added to the PowerPC kernel in v2.6.23,
- * we provide a slow fallback for old kernels.
- */
-static int powerpc_getregs_old(pid_t pid)
-{
- int i;
- long r;
-
- if (iflag) {
- r = upeek(pid, sizeof(long) * PT_NIP, (long *)&ppc_regs.nip);
- if (r)
- goto out;
- }
-#ifdef POWERPC64 /* else we never use it */
- r = upeek(pid, sizeof(long) * PT_MSR, (long *)&ppc_regs.msr);
- if (r)
- goto out;
-#endif
- r = upeek(pid, sizeof(long) * PT_CCR, (long *)&ppc_regs.ccr);
- if (r)
- goto out;
- r = upeek(pid, sizeof(long) * PT_ORIG_R3, (long *)&ppc_regs.orig_gpr3);
- if (r)
- goto out;
- for (i = 0; i <= 8; i++) {
- r = upeek(pid, sizeof(long) * (PT_R0 + i),
- (long *)&ppc_regs.gpr[i]);
- if (r)
- goto out;
- }
- out:
- return r;
-}
-#endif
+static long get_regs_error;
void
clear_regs(void)
@@ -1024,736 +741,15 @@
get_regs_error = -1;
}
-#if defined ARCH_REGS_FOR_GETREGSET
-static long
-get_regset(pid_t pid)
-{
-# ifdef ARCH_IOVEC_FOR_GETREGSET
- /* variable iovec */
- ARCH_IOVEC_FOR_GETREGSET.iov_len = sizeof(ARCH_REGS_FOR_GETREGSET);
- return ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS,
- &ARCH_IOVEC_FOR_GETREGSET);
-# else
- /* constant iovec */
- static struct iovec io = {
- .iov_base = &ARCH_REGS_FOR_GETREGSET,
- .iov_len = sizeof(ARCH_REGS_FOR_GETREGSET)
- };
- return ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &io);
-
-# endif
-}
-#endif /* ARCH_REGS_FOR_GETREGSET */
-
-void
-get_regs(pid_t pid)
-{
-#ifdef ARCH_REGS_FOR_GETREGSET
-# ifdef X86_64
- /* Try PTRACE_GETREGSET first, fallback to PTRACE_GETREGS. */
- static int getregset_support;
-
- if (getregset_support >= 0) {
- get_regs_error = get_regset(pid);
- if (getregset_support > 0)
- return;
- if (get_regs_error >= 0) {
- getregset_support = 1;
- return;
- }
- if (errno == EPERM || errno == ESRCH)
- return;
- getregset_support = -1;
- }
- /* Use old method, with unreliable heuristical detection of 32-bitness. */
- x86_io.iov_len = sizeof(x86_64_regs);
- get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &x86_64_regs);
- if (!get_regs_error && x86_64_regs.cs == 0x23) {
- x86_io.iov_len = sizeof(i386_regs);
- /*
- * The order is important: i386_regs and x86_64_regs
- * are overlaid in memory!
- */
- i386_regs.ebx = x86_64_regs.rbx;
- i386_regs.ecx = x86_64_regs.rcx;
- i386_regs.edx = x86_64_regs.rdx;
- i386_regs.esi = x86_64_regs.rsi;
- i386_regs.edi = x86_64_regs.rdi;
- i386_regs.ebp = x86_64_regs.rbp;
- i386_regs.eax = x86_64_regs.rax;
- /* i386_regs.xds = x86_64_regs.ds; unused by strace */
- /* i386_regs.xes = x86_64_regs.es; ditto... */
- /* i386_regs.xfs = x86_64_regs.fs; */
- /* i386_regs.xgs = x86_64_regs.gs; */
- i386_regs.orig_eax = x86_64_regs.orig_rax;
- i386_regs.eip = x86_64_regs.rip;
- /* i386_regs.xcs = x86_64_regs.cs; */
- /* i386_regs.eflags = x86_64_regs.eflags; */
- i386_regs.esp = x86_64_regs.rsp;
- /* i386_regs.xss = x86_64_regs.ss; */
- }
-# else /* !X86_64 */
- /* Assume that PTRACE_GETREGSET works. */
- get_regs_error = get_regset(pid);
-# endif
-#elif defined ARCH_REGS_FOR_GETREGS
-# if defined SPARC || defined SPARC64
- /* SPARC systems have the meaning of data and addr reversed */
- get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)&ARCH_REGS_FOR_GETREGS, 0);
-# elif defined POWERPC
- static bool old_kernel = 0;
- if (old_kernel)
- goto old;
- get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS);
- if (get_regs_error && errno == EIO) {
- old_kernel = 1;
- old:
- get_regs_error = powerpc_getregs_old(pid);
- }
-# else
- /* Assume that PTRACE_GETREGS works. */
- get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS);
-# endif
-
-#else /* !ARCH_REGS_FOR_GETREGSET && !ARCH_REGS_FOR_GETREGS */
-# warning get_regs is not implemented for this architecture yet
- get_regs_error = 0;
-#endif
-}
-
-/* Returns:
- * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently.
- * 1: ok, continue in trace_syscall_entering().
- * other: error, trace_syscall_entering() should print error indicator
- * ("????" etc) and bail out.
- */
-static int
-get_scno(struct tcb *tcp)
-{
- long scno = 0;
-
-#if defined(S390) || defined(S390X)
- scno = s390_regset.gprs[2];
-#elif defined(POWERPC)
- scno = ppc_regs.gpr[0];
-# ifdef POWERPC64
- unsigned int currpers;
-
- /*
- * Check for 64/32 bit mode.
- * Embedded implementations covered by Book E extension of PPC use
- * bit 0 (CM) of 32-bit Machine state register (MSR).
- * Other implementations use bit 0 (SF) of 64-bit MSR.
- */
- currpers = (ppc_regs.msr & 0x8000000080000000) ? 0 : 1;
- update_personality(tcp, currpers);
-# endif
-#elif defined(AVR32)
- scno = avr32_regs.r8;
-#elif defined(BFIN)
- if (upeek(tcp->pid, PT_ORIG_P0, &scno))
- return -1;
-#elif defined(I386)
- scno = i386_regs.orig_eax;
-#elif defined(X86_64) || defined(X32)
-# ifndef __X32_SYSCALL_BIT
-# define __X32_SYSCALL_BIT 0x40000000
-# endif
- unsigned int currpers;
-# if 1
- /* GETREGSET of NT_PRSTATUS tells us regset size,
- * which unambiguously detects i386.
- *
- * Linux kernel distinguishes x86-64 and x32 processes
- * solely by looking at __X32_SYSCALL_BIT:
- * arch/x86/include/asm/compat.h::is_x32_task():
- * if (task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT)
- * return true;
- */
- if (x86_io.iov_len == sizeof(i386_regs)) {
- scno = i386_regs.orig_eax;
- currpers = 1;
- } else {
- scno = x86_64_regs.orig_rax;
- currpers = 0;
- if (scno & __X32_SYSCALL_BIT) {
- /*
- * Syscall number -1 requires special treatment:
- * it might be a side effect of SECCOMP_RET_ERRNO
- * filtering that sets orig_rax to -1
- * in some versions of linux kernel.
- * If that is the case, then
- * __X32_SYSCALL_BIT logic does not apply.
- */
- if ((long long) x86_64_regs.orig_rax != -1) {
- scno -= __X32_SYSCALL_BIT;
- currpers = 2;
- } else {
-# ifdef X32
- currpers = 2;
-# endif
- }
- }
- }
-# elif 0
- /* cs = 0x33 for long mode (native 64 bit and x32)
- * cs = 0x23 for compatibility mode (32 bit)
- * ds = 0x2b for x32 mode (x86-64 in 32 bit)
- */
- scno = x86_64_regs.orig_rax;
- switch (x86_64_regs.cs) {
- case 0x23: currpers = 1; break;
- case 0x33:
- if (x86_64_regs.ds == 0x2b) {
- currpers = 2;
- scno &= ~__X32_SYSCALL_BIT;
- } else
- currpers = 0;
- break;
- default:
- fprintf(stderr, "Unknown value CS=0x%08X while "
- "detecting personality of process "
- "PID=%d\n", (int)x86_64_regs.cs, tcp->pid);
- currpers = current_personality;
- break;
- }
-# elif 0
- /* This version analyzes the opcode of a syscall instruction.
- * (int 0x80 on i386 vs. syscall on x86-64)
- * It works, but is too complicated, and strictly speaking, unreliable.
- */
- unsigned long call, rip = x86_64_regs.rip;
- /* sizeof(syscall) == sizeof(int 0x80) == 2 */
- rip -= 2;
- errno = 0;
- call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0);
- if (errno)
- fprintf(stderr, "ptrace_peektext failed: %s\n",
- strerror(errno));
- switch (call & 0xffff) {
- /* x86-64: syscall = 0x0f 0x05 */
- case 0x050f: currpers = 0; break;
- /* i386: int 0x80 = 0xcd 0x80 */
- case 0x80cd: currpers = 1; break;
- default:
- currpers = current_personality;
- fprintf(stderr,
- "Unknown syscall opcode (0x%04X) while "
- "detecting personality of process "
- "PID=%d\n", (int)call, tcp->pid);
- break;
- }
-# endif
-
-# ifdef X32
- /* If we are built for a x32 system, then personality 0 is x32
- * (not x86_64), and stracing of x86_64 apps is not supported.
- * Stracing of i386 apps is still supported.
- */
- if (currpers == 0) {
- fprintf(stderr, "syscall_%lu(...) in unsupported "
- "64-bit mode of process PID=%d\n",
- scno, tcp->pid);
- return 0;
- }
- currpers &= ~2; /* map 2,1 to 0,1 */
-# endif
- update_personality(tcp, currpers);
-#elif defined(IA64)
- if (ia64_ia32mode) {
- scno = ia64_regs.gr[0];
- } else {
- scno = ia64_regs.gr[15];
- }
-#elif defined(AARCH64)
- switch (aarch64_io.iov_len) {
- case sizeof(aarch64_regs):
- /* We are in 64-bit mode */
- scno = aarch64_regs.regs[8];
- update_personality(tcp, 1);
- break;
- case sizeof(arm_regs):
- /* We are in 32-bit mode */
- /* Note: we don't support OABI, unlike 32-bit ARM build */
- scno = arm_regs.ARM_r7;
- scno = shuffle_scno(scno);
- update_personality(tcp, 0);
- break;
- }
-#elif defined(ARM)
- if (arm_regs.ARM_ip != 0) {
- /* It is not a syscall entry */
- fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
- tcp->flags |= TCB_INSYSCALL;
- return 0;
- }
- /* Note: we support only 32-bit CPUs, not 26-bit */
-
-# if !defined(__ARM_EABI__) || ENABLE_ARM_OABI
- if (arm_regs.ARM_cpsr & 0x20)
- /* Thumb mode */
- goto scno_in_r7;
- /* ARM mode */
- /* Check EABI/OABI by examining SVC insn's low 24 bits */
- errno = 0;
- scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
- if (errno)
- return -1;
- /* EABI syscall convention? */
- if ((unsigned long) scno != 0xef000000) {
- /* No, it's OABI */
- if ((scno & 0x0ff00000) != 0x0f900000) {
- fprintf(stderr, "pid %d unknown syscall trap 0x%08lx\n",
- tcp->pid, scno);
- return -1;
- }
- /* Fixup the syscall number */
- scno &= 0x000fffff;
- } else {
- scno_in_r7:
- scno = arm_regs.ARM_r7;
- }
-# else /* __ARM_EABI__ || !ENABLE_ARM_OABI */
- scno = arm_regs.ARM_r7;
-# endif
- scno = shuffle_scno(scno);
-#elif defined(M68K)
- if (upeek(tcp->pid, 4*PT_ORIG_D0, &scno) < 0)
- return -1;
-#elif defined(MIPS)
- scno = mips_REG_V0;
-
- if (!SCNO_IN_RANGE(scno)) {
- if (mips_REG_A3 == 0 || mips_REG_A3 == (uint64_t) -1) {
- if (debug_flag)
- fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
- return 0;
- }
- }
-#elif defined(ALPHA)
- if (upeek(tcp->pid, REG_A3, &alpha_a3) < 0)
- return -1;
- if (upeek(tcp->pid, REG_R0, &scno) < 0)
- return -1;
-
- /*
- * Do some sanity checks to figure out if it's
- * really a syscall entry
- */
- if (!SCNO_IN_RANGE(scno)) {
- if (alpha_a3 == 0 || alpha_a3 == -1) {
- if (debug_flag)
- fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
- return 0;
- }
- }
-#elif defined(SPARC) || defined(SPARC64)
- /* Disassemble the syscall trap. */
- /* Retrieve the syscall trap instruction. */
- unsigned long trap;
- errno = 0;
-# if defined(SPARC64)
- trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)sparc_regs.tpc, 0);
- trap >>= 32;
-# else
- trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)sparc_regs.pc, 0);
-# endif
- if (errno)
- return -1;
-
- /* Disassemble the trap to see what personality to use. */
- switch (trap) {
- case 0x91d02010:
- /* Linux/SPARC syscall trap. */
- update_personality(tcp, 0);
- break;
- case 0x91d0206d:
- /* Linux/SPARC64 syscall trap. */
- update_personality(tcp, 2);
- break;
- case 0x91d02000:
- /* SunOS syscall trap. (pers 1) */
- fprintf(stderr, "syscall: SunOS no support\n");
- return -1;
- case 0x91d02008:
- /* Solaris 2.x syscall trap. (per 2) */
- update_personality(tcp, 1);
- break;
- case 0x91d02009:
- /* NetBSD/FreeBSD syscall trap. */
- fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n");
- return -1;
- case 0x91d02027:
- /* Solaris 2.x gettimeofday */
- update_personality(tcp, 1);
- break;
- default:
-# if defined(SPARC64)
- fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, sparc_regs.tpc);
-# else
- fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, sparc_regs.pc);
-# endif
- return -1;
- }
-
- /* Extract the system call number from the registers. */
- if (trap == 0x91d02027)
- scno = 156;
- else
- scno = sparc_regs.u_regs[U_REG_G1];
- if (scno == 0) {
- scno = sparc_regs.u_regs[U_REG_O0];
- memmove(&sparc_regs.u_regs[U_REG_O0], &sparc_regs.u_regs[U_REG_O1], 7*sizeof(sparc_regs.u_regs[0]));
- }
-#elif defined(HPPA)
- if (upeek(tcp->pid, PT_GR20, &scno) < 0)
- return -1;
-#elif defined(SH)
- /*
- * In the new syscall ABI, the system call number is in R3.
- */
- if (upeek(tcp->pid, 4*(REG_REG0+3), &scno) < 0)
- return -1;
-
- if (scno < 0) {
- /* Odd as it may seem, a glibc bug has been known to cause
- glibc to issue bogus negative syscall numbers. So for
- our purposes, make strace print what it *should* have been */
- long correct_scno = (scno & 0xff);
- if (debug_flag)
- fprintf(stderr,
- "Detected glibc bug: bogus system call"
- " number = %ld, correcting to %ld\n",
- scno,
- correct_scno);
- scno = correct_scno;
- }
-#elif defined(SH64)
- if (upeek(tcp->pid, REG_SYSCALL, &scno) < 0)
- return -1;
- scno &= 0xFFFF;
-#elif defined(CRISV10) || defined(CRISV32)
- if (upeek(tcp->pid, 4*PT_R9, &scno) < 0)
- return -1;
-#elif defined(TILE)
- unsigned int currpers;
- scno = tile_regs.regs[10];
-# ifdef __tilepro__
- currpers = 1;
-# else
-# ifndef PT_FLAGS_COMPAT
-# define PT_FLAGS_COMPAT 0x10000 /* from Linux 3.8 on */
-# endif
- if (tile_regs.flags & PT_FLAGS_COMPAT)
- currpers = 1;
- else
- currpers = 0;
-# endif
- update_personality(tcp, currpers);
-#elif defined(MICROBLAZE)
- if (upeek(tcp->pid, 0, &scno) < 0)
- return -1;
-#elif defined(OR1K)
- scno = or1k_regs.gpr[11];
-#elif defined(METAG)
- scno = metag_regs.dx[0][1]; /* syscall number in D1Re0 (D1.0) */
-#elif defined(XTENSA)
- if (upeek(tcp->pid, SYSCALL_NR, &scno) < 0)
- return -1;
-# elif defined(ARC)
- scno = arc_regs.scratch.r8;
-#endif
-
- tcp->scno = scno;
- if (SCNO_IS_VALID(tcp->scno)) {
- tcp->s_ent = &sysent[scno];
- tcp->qual_flg = qual_flags[scno];
- } else {
- static const struct_sysent unknown = {
- .nargs = MAX_ARGS,
- .sys_flags = 0,
- .sys_func = printargs,
- .sys_name = "unknown", /* not used */
- };
- tcp->s_ent = &unknown;
- tcp->qual_flg = UNDEFINED_SCNO | QUAL_RAW | DEFAULT_QUAL_FLAGS;
- }
- return 1;
-}
-
-/*
- * Cannot rely on __kernel_[u]long_t being defined,
- * it is quite a recent feature of <asm/posix_types.h>.
- */
-#ifdef __kernel_long_t
-typedef __kernel_long_t kernel_long_t;
-typedef __kernel_ulong_t kernel_ulong_t;
-#else
-# ifdef X32
-typedef long long kernel_long_t;
-typedef unsigned long long kernel_ulong_t;
-# else
-typedef long kernel_long_t;
-typedef unsigned long kernel_ulong_t;
-# endif
-#endif
-
-/*
- * Check the syscall return value register value for whether it is
- * a negated errno code indicating an error, or a success return value.
- */
-static inline bool
-is_negated_errno(kernel_ulong_t val)
-{
- /* Linux kernel defines MAX_ERRNO to 4095. */
- kernel_ulong_t max = -(kernel_long_t) 4095;
-
-#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
- if (current_wordsize < sizeof(val)) {
- val = (uint32_t) val;
- max = (uint32_t) max;
- }
-#elif defined X32
- /*
- * current_wordsize is 4 even in personality 0 (native X32)
- * but truncation _must not_ be done in it.
- * can't check current_wordsize here!
- */
- if (current_personality != 0) {
- val = (uint32_t) val;
- max = (uint32_t) max;
- }
-#endif
-
- return val >= max;
-}
-
-/* Return -1 on error or 1 on success (never 0!) */
-static int
-get_syscall_args(struct tcb *tcp)
-{
- int i, nargs;
-
- nargs = tcp->s_ent->nargs;
-
-#if defined(S390) || defined(S390X)
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = s390_regset.orig_gpr2;
- tcp->u_arg[1] = s390_regset.gprs[3];
- tcp->u_arg[2] = s390_regset.gprs[4];
- tcp->u_arg[3] = s390_regset.gprs[5];
- tcp->u_arg[4] = s390_regset.gprs[6];
- tcp->u_arg[5] = s390_regset.gprs[7];
-#elif defined(ALPHA)
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, REG_A0+i, &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(IA64)
- if (!ia64_ia32mode) {
- unsigned long *rbs_end =
- (unsigned long *) ia64_regs.ar[PT_AUR_BSP];
- unsigned long sof = (ia64_regs.cfm >> 0) & 0x7f;
- unsigned long sol = (ia64_regs.cfm >> 7) & 0x7f;
- unsigned long *out0 = ia64_rse_skip_regs(rbs_end, -sof + sol);
-
- for (i = 0; i < nargs; ++i) {
- if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
- sizeof(long), (char *) &tcp->u_arg[i]) < 0)
- return -1;
- }
- } else {
- (void)i;
- (void)nargs;
- /* truncate away IVE sign-extension */
- tcp->u_arg[0] = 0xffffffff & ia64_regs.gr[11]; /* EBX */
- tcp->u_arg[1] = 0xffffffff & ia64_regs.gr[ 9]; /* ECX */
- tcp->u_arg[2] = 0xffffffff & ia64_regs.gr[10]; /* EDX */
- tcp->u_arg[3] = 0xffffffff & ia64_regs.gr[14]; /* ESI */
- tcp->u_arg[4] = 0xffffffff & ia64_regs.gr[15]; /* EDI */
- tcp->u_arg[5] = 0xffffffff & ia64_regs.gr[13]; /* EBP */
- }
-#elif defined LINUX_MIPSN64
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = mips_REG_A0;
- tcp->u_arg[1] = mips_REG_A1;
- tcp->u_arg[2] = mips_REG_A2;
- tcp->u_arg[3] = mips_REG_A3;
- tcp->u_arg[4] = mips_REG_A4;
- tcp->u_arg[5] = mips_REG_A5;
-#elif defined LINUX_MIPSN32
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = tcp->ext_arg[0] = mips_REG_A0;
- tcp->u_arg[1] = tcp->ext_arg[1] = mips_REG_A1;
- tcp->u_arg[2] = tcp->ext_arg[2] = mips_REG_A2;
- tcp->u_arg[3] = tcp->ext_arg[3] = mips_REG_A3;
- tcp->u_arg[4] = tcp->ext_arg[4] = mips_REG_A4;
- tcp->u_arg[5] = tcp->ext_arg[5] = mips_REG_A5;
-#elif defined LINUX_MIPSO32
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = mips_REG_A0;
- tcp->u_arg[1] = mips_REG_A1;
- tcp->u_arg[2] = mips_REG_A2;
- tcp->u_arg[3] = mips_REG_A3;
- if (nargs > 4) {
- umoven(tcp, mips_REG_SP + 4 * 4,
- (nargs - 4) * sizeof(tcp->u_arg[0]),
- (char *)(tcp->u_arg + 4));
- }
-#elif defined(POWERPC)
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = ppc_regs.orig_gpr3;
- tcp->u_arg[1] = ppc_regs.gpr[4];
- tcp->u_arg[2] = ppc_regs.gpr[5];
- tcp->u_arg[3] = ppc_regs.gpr[6];
- tcp->u_arg[4] = ppc_regs.gpr[7];
- tcp->u_arg[5] = ppc_regs.gpr[8];
-#elif defined(SPARC) || defined(SPARC64)
- for (i = 0; i < nargs; ++i)
- tcp->u_arg[i] = sparc_regs.u_regs[U_REG_O0 + i];
-#elif defined(HPPA)
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(ARM) || defined(AARCH64)
-# if defined(AARCH64)
- if (tcp->currpers == 1)
- for (i = 0; i < nargs; ++i)
- tcp->u_arg[i] = aarch64_regs.regs[i];
- else
-# endif
- for (i = 0; i < nargs; ++i)
- tcp->u_arg[i] = arm_regs.uregs[i];
-#elif defined(AVR32)
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = avr32_regs.r12;
- tcp->u_arg[1] = avr32_regs.r11;
- tcp->u_arg[2] = avr32_regs.r10;
- tcp->u_arg[3] = avr32_regs.r9;
- tcp->u_arg[4] = avr32_regs.r5;
- tcp->u_arg[5] = avr32_regs.r3;
-#elif defined(BFIN)
- static const int argreg[MAX_ARGS] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 };
-
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, argreg[i], &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(SH)
- static const int syscall_regs[MAX_ARGS] = {
- 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6),
- 4 * (REG_REG0+7), 4 * (REG_REG0 ), 4 * (REG_REG0+1)
- };
-
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, syscall_regs[i], &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(SH64)
- int i;
- /* Registers used by SH5 Linux system calls for parameters */
- static const int syscall_regs[MAX_ARGS] = { 2, 3, 4, 5, 6, 7 };
-
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(I386)
- (void)i;
- (void)nargs;
- tcp->u_arg[0] = i386_regs.ebx;
- tcp->u_arg[1] = i386_regs.ecx;
- tcp->u_arg[2] = i386_regs.edx;
- tcp->u_arg[3] = i386_regs.esi;
- tcp->u_arg[4] = i386_regs.edi;
- tcp->u_arg[5] = i386_regs.ebp;
-#elif defined(X86_64) || defined(X32)
- (void)i;
- (void)nargs;
- if (x86_io.iov_len != sizeof(i386_regs)) {
- /* x86-64 or x32 ABI */
- tcp->u_arg[0] = x86_64_regs.rdi;
- tcp->u_arg[1] = x86_64_regs.rsi;
- tcp->u_arg[2] = x86_64_regs.rdx;
- tcp->u_arg[3] = x86_64_regs.r10;
- tcp->u_arg[4] = x86_64_regs.r8;
- tcp->u_arg[5] = x86_64_regs.r9;
-# ifdef X32
- tcp->ext_arg[0] = x86_64_regs.rdi;
- tcp->ext_arg[1] = x86_64_regs.rsi;
- tcp->ext_arg[2] = x86_64_regs.rdx;
- tcp->ext_arg[3] = x86_64_regs.r10;
- tcp->ext_arg[4] = x86_64_regs.r8;
- tcp->ext_arg[5] = x86_64_regs.r9;
-# endif
- } else {
- /* i386 ABI */
- /* Zero-extend from 32 bits */
- /* Use widen_to_long(tcp->u_arg[N]) in syscall handlers
- * if you need to use *sign-extended* parameter.
- */
- tcp->u_arg[0] = (long)(uint32_t)i386_regs.ebx;
- tcp->u_arg[1] = (long)(uint32_t)i386_regs.ecx;
- tcp->u_arg[2] = (long)(uint32_t)i386_regs.edx;
- tcp->u_arg[3] = (long)(uint32_t)i386_regs.esi;
- tcp->u_arg[4] = (long)(uint32_t)i386_regs.edi;
- tcp->u_arg[5] = (long)(uint32_t)i386_regs.ebp;
- }
-#elif defined(MICROBLAZE)
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, (5 + i) * 4, &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(CRISV10) || defined(CRISV32)
- static const int crisregs[MAX_ARGS] = {
- 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
- 4*PT_R13 , 4*PT_MOF, 4*PT_SRP
- };
-
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, crisregs[i], &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(TILE)
- for (i = 0; i < nargs; ++i)
- tcp->u_arg[i] = tile_regs.regs[i];
-#elif defined(M68K)
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
- return -1;
-#elif defined(OR1K)
- (void)nargs;
- for (i = 0; i < 6; ++i)
- tcp->u_arg[i] = or1k_regs.gpr[3 + i];
-#elif defined(METAG)
- for (i = 0; i < nargs; i++)
- /* arguments go backwards from D1Ar1 (D1.3) */
- tcp->u_arg[i] = ((unsigned long *)&metag_regs.dx[3][1])[-i];
-#elif defined(XTENSA)
- /* arg0: a6, arg1: a3, arg2: a4, arg3: a5, arg4: a8, arg5: a9 */
- static const int xtensaregs[MAX_ARGS] = { 6, 3, 4, 5, 8, 9 };
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, REG_A_BASE + xtensaregs[i], &tcp->u_arg[i]) < 0)
- return -1;
-# elif defined(ARC)
- long *arc_args = &arc_regs.scratch.r0;
- for (i = 0; i < nargs; ++i)
- tcp->u_arg[i] = *arc_args--;
-
-#else /* Other architecture (32bits specific) */
- for (i = 0; i < nargs; ++i)
- if (upeek(tcp->pid, i*4, &tcp->u_arg[i]) < 0)
- return -1;
-#endif
- return 1;
-}
+static int get_syscall_args(struct tcb *);
+static int get_syscall_result(struct tcb *);
static int
trace_syscall_entering(struct tcb *tcp)
{
int res, scno_good;
- scno_good = res = (get_regs_error ? -1 : get_scno(tcp));
+ scno_good = res = get_scno(tcp);
if (res == 0)
return res;
if (res == 1)
@@ -1840,350 +836,6 @@
return res;
}
-/* Returns:
- * 1: ok, continue in trace_syscall_exiting().
- * -1: error, trace_syscall_exiting() should print error indicator
- * ("????" etc) and bail out.
- */
-static int
-get_syscall_result(struct tcb *tcp)
-{
-#if defined ARCH_REGS_FOR_GETREGSET || defined ARCH_REGS_FOR_GETREGS
- /* already done by get_regs */
-#elif defined(BFIN)
- if (upeek(tcp->pid, PT_R0, &bfin_r0) < 0)
- return -1;
-#elif defined(M68K)
- if (upeek(tcp->pid, 4*PT_D0, &m68k_d0) < 0)
- return -1;
-#elif defined(ALPHA)
- if (upeek(tcp->pid, REG_A3, &alpha_a3) < 0)
- return -1;
- if (upeek(tcp->pid, REG_R0, &alpha_r0) < 0)
- return -1;
-#elif defined(HPPA)
- if (upeek(tcp->pid, PT_GR28, &hppa_r28) < 0)
- return -1;
-#elif defined(SH)
- /* new syscall ABI returns result in R0 */
- if (upeek(tcp->pid, 4*REG_REG0, (long *)&sh_r0) < 0)
- return -1;
-#elif defined(SH64)
- /* ABI defines result returned in r9 */
- if (upeek(tcp->pid, REG_GENERAL(9), (long *)&sh64_r9) < 0)
- return -1;
-#elif defined(CRISV10) || defined(CRISV32)
- if (upeek(tcp->pid, 4*PT_R10, &cris_r10) < 0)
- return -1;
-#elif defined(MICROBLAZE)
- if (upeek(tcp->pid, 3 * 4, µblaze_r3) < 0)
- return -1;
-#elif defined(XTENSA)
- if (upeek(tcp->pid, REG_A_BASE + 2, &xtensa_a2) < 0)
- return -1;
-#else
-# error get_syscall_result is not implemented for this architecture
-#endif
- return 1;
-}
-
-/* Returns:
- * 1: ok, continue in trace_syscall_exiting().
- * -1: error, trace_syscall_exiting() should print error indicator
- * ("????" etc) and bail out.
- */
-static void
-get_error(struct tcb *tcp)
-{
- int u_error = 0;
- int check_errno = 1;
- if (tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS) {
- check_errno = 0;
- }
-#if defined(S390) || defined(S390X)
- if (check_errno && is_negated_errno(s390_regset.gprs[2])) {
- tcp->u_rval = -1;
- u_error = -s390_regset.gprs[2];
- }
- else {
- tcp->u_rval = s390_regset.gprs[2];
- }
-#elif defined(I386)
- if (check_errno && is_negated_errno(i386_regs.eax)) {
- tcp->u_rval = -1;
- u_error = -i386_regs.eax;
- }
- else {
- tcp->u_rval = i386_regs.eax;
- }
-#elif defined(X86_64) || defined(X32)
- /*
- * In X32, return value is 64-bit (llseek uses one).
- * Using merely "long rax" would not work.
- */
- kernel_long_t rax;
-
- if (x86_io.iov_len == sizeof(i386_regs)) {
- /* Sign extend from 32 bits */
- rax = (int32_t) i386_regs.eax;
- } else {
- rax = x86_64_regs.rax;
- }
- if (check_errno && is_negated_errno(rax)) {
- tcp->u_rval = -1;
- u_error = -rax;
- }
- else {
- tcp->u_rval = rax;
-# ifdef X32
- /* tcp->u_rval contains a truncated value */
- tcp->u_lrval = rax;
-# endif
- }
-#elif defined(IA64)
- if (ia64_ia32mode) {
- int err = ia64_regs.gr[8];
- if (check_errno && is_negated_errno(err)) {
- tcp->u_rval = -1;
- u_error = -err;
- }
- else {
- tcp->u_rval = err;
- }
- } else {
- if (check_errno && ia64_regs.gr[10]) {
- tcp->u_rval = -1;
- u_error = ia64_regs.gr[8];
- } else {
- tcp->u_rval = ia64_regs.gr[8];
- }
- }
-#elif defined(MIPS)
- if (check_errno && mips_REG_A3) {
- tcp->u_rval = -1;
- u_error = mips_REG_V0;
- } else {
-# if defined LINUX_MIPSN32
- tcp->u_lrval = mips_REG_V0;
-# endif
- tcp->u_rval = mips_REG_V0;
- }
-#elif defined(POWERPC)
- if (check_errno && (ppc_regs.ccr & 0x10000000)) {
- tcp->u_rval = -1;
- u_error = ppc_regs.gpr[3];
- }
- else {
- tcp->u_rval = ppc_regs.gpr[3];
- }
-#elif defined(M68K)
- if (check_errno && is_negated_errno(m68k_d0)) {
- tcp->u_rval = -1;
- u_error = -m68k_d0;
- }
- else {
- tcp->u_rval = m68k_d0;
- }
-#elif defined(ARM) || defined(AARCH64)
-# if defined(AARCH64)
- if (tcp->currpers == 1) {
- if (check_errno && is_negated_errno(aarch64_regs.regs[0])) {
- tcp->u_rval = -1;
- u_error = -aarch64_regs.regs[0];
- }
- else {
- tcp->u_rval = aarch64_regs.regs[0];
- }
- }
- else
-# endif
- {
- if (check_errno && is_negated_errno(arm_regs.ARM_r0)) {
- tcp->u_rval = -1;
- u_error = -arm_regs.ARM_r0;
- }
- else {
- tcp->u_rval = arm_regs.ARM_r0;
- }
- }
-#elif defined(AVR32)
- if (check_errno && avr32_regs.r12 && (unsigned) -avr32_regs.r12 < nerrnos) {
- tcp->u_rval = -1;
- u_error = -avr32_regs.r12;
- }
- else {
- tcp->u_rval = avr32_regs.r12;
- }
-#elif defined(BFIN)
- if (check_errno && is_negated_errno(bfin_r0)) {
- tcp->u_rval = -1;
- u_error = -bfin_r0;
- } else {
- tcp->u_rval = bfin_r0;
- }
-#elif defined(ALPHA)
- if (check_errno && alpha_a3) {
- tcp->u_rval = -1;
- u_error = alpha_r0;
- }
- else {
- tcp->u_rval = alpha_r0;
- }
-#elif defined(SPARC)
- if (check_errno && sparc_regs.psr & PSR_C) {
- tcp->u_rval = -1;
- u_error = sparc_regs.u_regs[U_REG_O0];
- }
- else {
- tcp->u_rval = sparc_regs.u_regs[U_REG_O0];
- }
-#elif defined(SPARC64)
- if (check_errno && sparc_regs.tstate & 0x1100000000UL) {
- tcp->u_rval = -1;
- u_error = sparc_regs.u_regs[U_REG_O0];
- }
- else {
- tcp->u_rval = sparc_regs.u_regs[U_REG_O0];
- }
-#elif defined(HPPA)
- if (check_errno && is_negated_errno(hppa_r28)) {
- tcp->u_rval = -1;
- u_error = -hppa_r28;
- }
- else {
- tcp->u_rval = hppa_r28;
- }
-#elif defined(SH)
- if (check_errno && is_negated_errno(sh_r0)) {
- tcp->u_rval = -1;
- u_error = -sh_r0;
- }
- else {
- tcp->u_rval = sh_r0;
- }
-#elif defined(SH64)
- if (check_errno && is_negated_errno(sh64_r9)) {
- tcp->u_rval = -1;
- u_error = -sh64_r9;
- }
- else {
- tcp->u_rval = sh64_r9;
- }
-#elif defined(METAG)
- /* result pointer in D0Re0 (D0.0) */
- if (check_errno && is_negated_errno(metag_regs.dx[0][0])) {
- tcp->u_rval = -1;
- u_error = -metag_regs.dx[0][0];
- }
- else {
- tcp->u_rval = metag_regs.dx[0][0];
- }
-#elif defined(CRISV10) || defined(CRISV32)
- if (check_errno && cris_r10 && (unsigned) -cris_r10 < nerrnos) {
- tcp->u_rval = -1;
- u_error = -cris_r10;
- }
- else {
- tcp->u_rval = cris_r10;
- }
-#elif defined(TILE)
- /*
- * The standard tile calling convention returns the value (or negative
- * errno) in r0, and zero (or positive errno) in r1.
- * Until at least kernel 3.8, however, the r1 value is not reflected
- * in ptregs at this point, so we use r0 here.
- */
- if (check_errno && is_negated_errno(tile_regs.regs[0])) {
- tcp->u_rval = -1;
- u_error = -tile_regs.regs[0];
- } else {
- tcp->u_rval = tile_regs.regs[0];
- }
-#elif defined(MICROBLAZE)
- if (check_errno && is_negated_errno(microblaze_r3)) {
- tcp->u_rval = -1;
- u_error = -microblaze_r3;
- }
- else {
- tcp->u_rval = microblaze_r3;
- }
-#elif defined(OR1K)
- if (check_errno && is_negated_errno(or1k_regs.gpr[11])) {
- tcp->u_rval = -1;
- u_error = -or1k_regs.gpr[11];
- }
- else {
- tcp->u_rval = or1k_regs.gpr[11];
- }
-#elif defined(XTENSA)
- if (check_errno && is_negated_errno(xtensa_a2)) {
- tcp->u_rval = -1;
- u_error = -xtensa_a2;
- }
- else {
- tcp->u_rval = xtensa_a2;
- }
-#elif defined(ARC)
- if (check_errno && is_negated_errno(arc_regs.scratch.r0)) {
- tcp->u_rval = -1;
- u_error = -arc_regs.scratch.r0;
- }
- else {
- tcp->u_rval = arc_regs.scratch.r0;
- }
-#endif
- tcp->u_error = u_error;
-}
-
-static void
-dumpio(struct tcb *tcp)
-{
- int (*func)();
-
- if (syserror(tcp))
- return;
- if ((unsigned long) tcp->u_arg[0] >= num_quals)
- return;
- func = tcp->s_ent->sys_func;
- if (func == printargs)
- return;
- if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
- if (func == sys_read ||
- func == sys_pread ||
- func == sys_recv ||
- func == sys_recvfrom) {
- dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
- return;
- } else if (func == sys_readv) {
- dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
- return;
-#if HAVE_SENDMSG
- } else if (func == sys_recvmsg) {
- dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
- return;
- } else if (func == sys_recvmmsg) {
- dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
- return;
-#endif
- }
- }
- if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
- if (func == sys_write ||
- func == sys_pwrite ||
- func == sys_send ||
- func == sys_sendto)
- dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
- else if (func == sys_writev)
- dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
-#if HAVE_SENDMSG
- else if (func == sys_sendmsg)
- dumpiov_in_msghdr(tcp, tcp->u_arg[1]);
- else if (func == sys_sendmmsg)
- dumpiov_in_mmsghdr(tcp, tcp->u_arg[1]);
-#endif
- }
-}
-
static int
trace_syscall_exiting(struct tcb *tcp)
{
@@ -2208,7 +860,6 @@
#endif
res = (get_regs_error ? -1 : get_syscall_result(tcp));
if (res == 1) {
- get_error(tcp); /* never fails */
if (filtered(tcp) || hide_log_until_execve)
goto ret;
}
@@ -2239,6 +890,7 @@
}
printing_tcp = tcp;
+ tcp->s_prev_ent = NULL;
if (res != 1) {
/* There was error in one of prior ptrace ops */
tprints(") ");
@@ -2248,6 +900,7 @@
tcp->flags &= ~TCB_INSYSCALL;
return res;
}
+ tcp->s_prev_ent = tcp->s_ent;
sys_res = 0;
if (tcp->qual_flg & QUAL_RAW) {
@@ -2426,3 +1079,232 @@
return exiting(tcp) ?
trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
}
+
+/*
+ * Cannot rely on __kernel_[u]long_t being defined,
+ * it is quite a recent feature of <asm/posix_types.h>.
+ */
+#ifdef __kernel_long_t
+typedef __kernel_long_t kernel_long_t;
+typedef __kernel_ulong_t kernel_ulong_t;
+#else
+# ifdef X32
+typedef long long kernel_long_t;
+typedef unsigned long long kernel_ulong_t;
+# else
+typedef long kernel_long_t;
+typedef unsigned long kernel_ulong_t;
+# endif
+#endif
+
+/*
+ * Check the syscall return value register value for whether it is
+ * a negated errno code indicating an error, or a success return value.
+ */
+static inline bool
+is_negated_errno(kernel_ulong_t val)
+{
+ /* Linux kernel defines MAX_ERRNO to 4095. */
+ kernel_ulong_t max = -(kernel_long_t) 4095;
+
+#if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4
+ if (current_wordsize < sizeof(val)) {
+ val = (uint32_t) val;
+ max = (uint32_t) max;
+ }
+#elif defined X32
+ /*
+ * current_wordsize is 4 even in personality 0 (native X32)
+ * but truncation _must not_ be done in it.
+ * can't check current_wordsize here!
+ */
+ if (current_personality != 0) {
+ val = (uint32_t) val;
+ max = (uint32_t) max;
+ }
+#endif
+
+ return val >= max;
+}
+
+#include "arch_regs.c"
+
+#ifdef HAVE_GETRVAL2
+# include "arch_getrval2.c"
+#endif
+
+void
+print_pc(struct tcb *tcp)
+{
+ const char *fmt;
+ const char *bad;
+
+#ifdef current_wordsize
+# define pc_wordsize current_wordsize
+#else
+# define pc_wordsize personality_wordsize[tcp->currpers]
+#endif
+
+ if (pc_wordsize == 4) {
+ fmt = "[%08lx] ";
+ bad = "[????????] ";
+ } else {
+ fmt = "[%016lx] ";
+ bad = "[????????????????] ";
+ }
+
+#undef pc_wordsize
+#define PRINTBADPC tprints(bad)
+
+ if (get_regs_error) {
+ PRINTBADPC;
+ return;
+ }
+
+#include "print_pc.c"
+}
+
+#if defined X86_64 || defined POWERPC
+# include "getregs_old.c"
+#endif
+
+#if defined ARCH_REGS_FOR_GETREGSET
+static long
+get_regset(pid_t pid)
+{
+# ifdef ARCH_IOVEC_FOR_GETREGSET
+ /* variable iovec */
+ ARCH_IOVEC_FOR_GETREGSET.iov_len = sizeof(ARCH_REGS_FOR_GETREGSET);
+ return ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS,
+ &ARCH_IOVEC_FOR_GETREGSET);
+# else
+ /* constant iovec */
+ static struct iovec io = {
+ .iov_base = &ARCH_REGS_FOR_GETREGSET,
+ .iov_len = sizeof(ARCH_REGS_FOR_GETREGSET)
+ };
+ return ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &io);
+
+# endif
+}
+#endif /* ARCH_REGS_FOR_GETREGSET */
+
+void
+get_regs(pid_t pid)
+{
+#ifdef ARCH_REGS_FOR_GETREGSET
+# ifdef X86_64
+ /* Try PTRACE_GETREGSET first, fallback to PTRACE_GETREGS. */
+ static int getregset_support;
+
+ if (getregset_support >= 0) {
+ get_regs_error = get_regset(pid);
+ if (getregset_support > 0)
+ return;
+ if (get_regs_error >= 0) {
+ getregset_support = 1;
+ return;
+ }
+ if (errno == EPERM || errno == ESRCH)
+ return;
+ getregset_support = -1;
+ }
+ getregs_old(pid);
+# else /* !X86_64 */
+ /* Assume that PTRACE_GETREGSET works. */
+ get_regs_error = get_regset(pid);
+# endif
+#elif defined ARCH_REGS_FOR_GETREGS
+# if defined SPARC || defined SPARC64
+ /* SPARC systems have the meaning of data and addr reversed */
+ get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)&ARCH_REGS_FOR_GETREGS, 0);
+# elif defined POWERPC
+ static bool old_kernel = 0;
+ if (old_kernel)
+ goto old;
+ get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS);
+ if (get_regs_error && errno == EIO) {
+ old_kernel = 1;
+ old:
+ get_regs_error = getregs_old(pid);
+ }
+# else
+ /* Assume that PTRACE_GETREGS works. */
+ get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &ARCH_REGS_FOR_GETREGS);
+# endif
+
+#else /* !ARCH_REGS_FOR_GETREGSET && !ARCH_REGS_FOR_GETREGS */
+# warning get_regs is not implemented for this architecture yet
+ get_regs_error = 0;
+#endif
+}
+
+/* Returns:
+ * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently.
+ * 1: ok, continue in trace_syscall_entering().
+ * other: error, trace_syscall_entering() should print error indicator
+ * ("????" etc) and bail out.
+ */
+int
+get_scno(struct tcb *tcp)
+{
+ if (get_regs_error)
+ return -1;
+
+ long scno = 0;
+
+#include "get_scno.c"
+
+ tcp->scno = scno;
+ if (SCNO_IS_VALID(tcp->scno)) {
+ tcp->s_ent = &sysent[scno];
+ tcp->qual_flg = qual_flags[scno];
+ } else {
+ static const struct_sysent unknown = {
+ .nargs = MAX_ARGS,
+ .sys_flags = 0,
+ .sys_func = printargs,
+ .sys_name = "unknown", /* not used */
+ };
+ tcp->s_ent = &unknown;
+ tcp->qual_flg = UNDEFINED_SCNO | QUAL_RAW | DEFAULT_QUAL_FLAGS;
+ if (debug_flag)
+ fprintf(stderr, "pid %d invalid syscall %ld\n",
+ tcp->pid, scno);
+ }
+ return 1;
+}
+
+/* Return -1 on error or 1 on success (never 0!) */
+static int
+get_syscall_args(struct tcb *tcp)
+{
+#include "get_syscall_args.c"
+ return 1;
+}
+
+static void
+get_error(struct tcb *tcp)
+{
+ const bool check_errno = !(tcp->s_ent->sys_flags & SYSCALL_NEVER_FAILS);
+ tcp->u_error = 0;
+
+#include "get_error.c"
+}
+
+/* Returns:
+ * 1: ok, continue in trace_syscall_exiting().
+ * -1: error, trace_syscall_exiting() should print error indicator
+ * ("????" etc) and bail out.
+ */
+static int
+get_syscall_result(struct tcb *tcp)
+{
+#if defined ARCH_REGS_FOR_GETREGSET || defined ARCH_REGS_FOR_GETREGS
+ /* already done by get_regs */
+#else
+# include "get_syscall_result.c"
+#endif
+ get_error(tcp);
+ return 1;
+}
diff --git a/sysctl.c b/sysctl.c
index 70cc5d9..a550eda 100644
--- a/sysctl.c
+++ b/sysctl.c
@@ -27,7 +27,7 @@
size = sizeof(int) * (unsigned long) info.nlen;
name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size);
if (name == NULL ||
- umoven(tcp, (unsigned long) info.name, size, (char *) name) < 0) {
+ umoven(tcp, (unsigned long) info.name, size, name) < 0) {
free(name);
if (entering(tcp))
tprintf("{%p, %d, %p, %p, %p, %lu}",
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..fba8c9d
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,18 @@
+childthread
+clone
+fork
+leaderkill
+many_looping_threads
+mmap_offset_decode
+mtd
+seccomp
+sfd
+sig
+sigkill_rain
+skodic
+threaded_execve
+ubi
+vfork
+wait_must_be_interruptible
+x32_lseek
+x32_mmap
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..dbc5008
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,20 @@
+CFLAGS += -Wall
+
+PROGS = \
+ vfork fork sig skodic clone leaderkill childthread \
+ sigkill_rain wait_must_be_interruptible threaded_execve \
+ mtd ubi seccomp sfd mmap_offset_decode x32_lseek x32_mmap \
+ many_looping_threads
+
+all: $(PROGS)
+
+leaderkill: LDFLAGS += -pthread
+
+childthread: LDFLAGS += -pthread
+
+many_looping_threads: LDFLAGS += -pthread
+
+clean distclean:
+ rm -f *.o core $(PROGS) *.gdb
+
+.PHONY: all clean distclean
diff --git a/test/many_looping_threads.c b/test/many_looping_threads.c
new file mode 100644
index 0000000..918bd9d
--- /dev/null
+++ b/test/many_looping_threads.c
@@ -0,0 +1,49 @@
+// This testcase, when run with large number of threads
+// under stace -f, may never finish because strace does not
+// ensure any fairness in thread scheduling:
+// it restarts threads as they stop. If daughter threads crowd out
+// the "mother" and _they_ get continually restarted by strace,
+// the end of spawning loop will never be reached.
+//
+// Also, it is a testcase which triggers the
+// "strace: Exit of unknown pid 32457 seen"
+// message when on testcase exit, strace sees deaths of newly-attached
+// threads _before_ their first syscall stop.
+//
+#include <stdio.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <stdlib.h>
+
+static int thd_no;
+
+static void *sub_thd(void *c)
+{
+ dprintf(1, "sub-thread %d created\n", ++thd_no);
+ for (;;)
+ getuid();
+ return NULL;
+}
+
+int main(int argc, char *argv[])
+{
+ int i;
+ pthread_t *thd;
+ int num_threads = 1;
+
+ if (argv[1])
+ num_threads = atoi(argv[1]);
+
+ thd = malloc(num_threads * sizeof(thd[0]));
+ dprintf(1, "test start, num_threads:%d...\n", num_threads);
+
+ for (i = 0; i < num_threads; i++) {
+ pthread_create(&thd[i], NULL, sub_thd, NULL);
+ dprintf(1, "after pthread_create\n");
+ }
+
+ /* Exit. This kills all threads */
+ return 0;
+}
diff --git a/tests/.gitignore b/tests/.gitignore
index 8efb0ef..6903a5c 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -6,12 +6,16 @@
ipc_msg
ipc_sem
ipc_shm
+mmap
+mmap64
mmsg
net-accept-connect
netlink_inet_diag
netlink_unix_diag
pc
+pipe
scm_rights
+seccomp
select
set_ptracer_any
sigaction
@@ -24,6 +28,8 @@
uid16
uid32
uio
+umovestr
+umovestr2
unix-pair-send-recv
*.log
*.log.*
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 7f9a11e..e5dae02 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -15,12 +15,16 @@
ipc_msg \
ipc_sem \
ipc_shm \
+ mmap \
+ mmap64 \
mmsg \
net-accept-connect \
netlink_inet_diag \
netlink_unix_diag \
pc \
+ pipe \
scm_rights \
+ seccomp \
select \
set_ptracer_any \
sigaction \
@@ -33,8 +37,11 @@
uid16 \
uid32 \
uio \
+ umovestr \
+ umovestr2 \
unix-pair-send-recv
+mmap64_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
pc_LDADD = $(dl_LIBS)
stat_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
statfs_CFLAGS = $(AM_CFLAGS) -D_FILE_OFFSET_BITS=64
@@ -56,6 +63,7 @@
ipc_shm.test \
ipc_sem.test \
scm_rights-fd.test \
+ seccomp.test \
select.test \
sigaction.test \
sigreturn.test \
@@ -63,12 +71,17 @@
stat32-v.test \
stat64-v.test \
statfs.test \
+ mmap.test \
+ mmap64.test \
mmsg.test \
net.test \
net-fd.test \
net-yy.test \
+ pipe.test \
pc.test \
sun_path.test \
+ umovestr.test \
+ umovestr2.test \
unix-yy.test \
uid.test \
uid16.test \
@@ -84,7 +97,7 @@
TEST_LOG_COMPILER = $(srcdir)/run.sh
-EXTRA_DIST = init.sh run.sh \
+EXTRA_DIST = init.sh run.sh match.awk \
caps.awk \
dumpio.expected \
fanotify_mark.expected \
@@ -98,12 +111,14 @@
net-fd.expected \
net-yy-accept.awk \
net-yy-connect.awk \
+ pipe.expected \
select.awk \
sigaction.awk \
statfs.expected \
sun_path.expected \
uid.awk \
uio.expected \
+ umovestr.expected \
unix-yy-accept.awk \
unix-yy-connect.awk \
$(TESTS)
diff --git a/tests/caps.awk b/tests/caps.awk
index 70f3147..f2f143d 100644
--- a/tests/caps.awk
+++ b/tests/caps.awk
@@ -1,25 +1,12 @@
BEGIN {
- fail = 0
- lines = 3
- cap = "(0|CAP_[A-Z_]+(\\|CAP_[A-Z_]+)*|CAP_[A-Z_]+(\\|CAP_[A-Z_]+){37}\\|0xffffffc0)"
- capget = "^capget\\(\\{_LINUX_CAPABILITY_VERSION_3, 0\\}, \\{" cap ", " cap ", " cap "\\}\\) = 0$"
+ cap = "(0|CAP_[A-Z_]+(\\|CAP_[A-Z_]+)*|CAP_[A-Z_]+(\\|CAP_[A-Z_]+){37}\\|0xffffffc0)"
+ r[1] = "^capget\\(\\{_LINUX_CAPABILITY_VERSION_3, 0\\}, \\{" cap ", " cap ", " cap "\\}\\) = 0$"
+ capset_data = "{CAP_DAC_OVERRIDE|CAP_WAKE_ALARM, CAP_DAC_READ_SEARCH|CAP_BLOCK_SUSPEND, 0}"
+ s[2] = "capset({_LINUX_CAPABILITY_VERSION_3, 0}, " capset_data ") = -1 EPERM (Operation not permitted)"
+ s[3] = "+++ exited with 0 +++"
+
+ lines = 3
+ fail = 0
}
-NR == 1 {if (match($0, capget)) next}
-
-NR == 2 && $0 == "capset({_LINUX_CAPABILITY_VERSION_3, 0}, {CAP_DAC_OVERRIDE|CAP_WAKE_ALARM, CAP_DAC_READ_SEARCH|CAP_BLOCK_SUSPEND, 0}) = -1 EPERM (Operation not permitted)" {next}
-
-NR == lines && $0 == "+++ exited with 0 +++" {next}
-
-{
- print "Line " NR " does not match."
- fail = 1
- exit 1
-}
-
-END {
- if (fail == 0 && NR != lines) {
- print "Expected " lines " lines, found " NR " line(s)."
- exit 1
- }
-}
+@include "match.awk"
diff --git a/tests/getdents.awk b/tests/getdents.awk
index c230e26..8a00133 100644
--- a/tests/getdents.awk
+++ b/tests/getdents.awk
@@ -1,68 +1,51 @@
BEGIN {
- lines = 3
- fail = 0
+ i = "[0-9]+"
+ len = "[1-9]" i
- i = "[0-9]+"
- len = "[1-9]" i
+ d_ino = "d_ino=" i
+ d_off = "d_off=" i
+ d_reclen = "d_reclen=" len
+ d_name_1 = "d_name=\"\\.\""
+ d_name_2 = "d_name=\"\\.\\.\""
+ d_name_3 = "d_name=\"(A\\\\n){127}Z\""
+ # Some older systems might not pass back d_type at all like Alpha.
+ d_type_dir = "d_type=DT_(DIR|UNKNOWN)"
+ d_type_reg = "d_type=DT_(REG|UNKNOWN)"
- d_ino = "d_ino=" i
- d_off = "d_off=" i
- d_reclen = "d_reclen=" len
- d_name_1 = "d_name=\"\\.\""
- d_name_2 = "d_name=\"\\.\\.\""
- d_name_3 = "d_name=\"(A\\\\n){127}Z\""
- # Some older systems might not pass back d_type at all like Alpha.
- d_type_dir = "d_type=DT_(DIR|UNKNOWN)"
- d_type_reg = "d_type=DT_(REG|UNKNOWN)"
+ dirent_1 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_1 ", " d_type_dir "\\}"
+ dirent_2 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_2 ", " d_type_dir "\\}"
+ dirent_3 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_3 ", " d_type_reg "\\}"
- dirent_1 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_1 ", " d_type_dir "\\}"
- dirent_2 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_2 ", " d_type_dir "\\}"
- dirent_3 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_name_3 ", " d_type_reg "\\}"
+ dirent64_1 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_dir ", " d_name_1 "\\}"
+ dirent64_2 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_dir ", " d_name_2 "\\}"
+ dirent64_3 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_reg ", " d_name_3 "\\}"
- dirent64_1 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_dir ", " d_name_1 "\\}"
- dirent64_2 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_dir ", " d_name_2 "\\}"
- dirent64_3 = "\\{" d_ino ", " d_off ", " d_reclen ", " d_type_reg ", " d_name_3 "\\}"
+ d_123 = dirent_1 " " dirent_2 " " dirent_3
+ d_213 = dirent_2 " " dirent_1 " " dirent_3
+ d_132 = dirent_1 " " dirent_3 " " dirent_2
+ d_321 = dirent_3 " " dirent_2 " " dirent_1
+ d_231 = dirent_2 " " dirent_3 " " dirent_1
+ d_312 = dirent_3 " " dirent_1 " " dirent_2
- d_123 = dirent_1 " " dirent_2 " " dirent_3
- d_213 = dirent_2 " " dirent_1 " " dirent_3
- d_132 = dirent_1 " " dirent_3 " " dirent_2
- d_321 = dirent_3 " " dirent_2 " " dirent_1
- d_231 = dirent_2 " " dirent_3 " " dirent_1
- d_312 = dirent_3 " " dirent_1 " " dirent_2
+ d64_123 = dirent64_1 " " dirent64_2 " " dirent64_3
+ d64_213 = dirent64_2 " " dirent64_1 " " dirent64_3
+ d64_132 = dirent64_1 " " dirent64_3 " " dirent64_2
+ d64_321 = dirent64_3 " " dirent64_2 " " dirent64_1
+ d64_231 = dirent64_2 " " dirent64_3 " " dirent64_1
+ d64_312 = dirent64_3 " " dirent64_1 " " dirent64_2
- d64_123 = dirent64_1 " " dirent64_2 " " dirent64_3
- d64_213 = dirent64_2 " " dirent64_1 " " dirent64_3
- d64_132 = dirent64_1 " " dirent64_3 " " dirent64_2
- d64_321 = dirent64_3 " " dirent64_2 " " dirent64_1
- d64_231 = dirent64_2 " " dirent64_3 " " dirent64_1
- d64_312 = dirent64_3 " " dirent64_1 " " dirent64_2
+ dents = "\\{(" d_123 "|" d_213 "|" d_132 "|" d_321 "|" d_231 "|" d_312 ")\\}"
+ dents64 = "\\{(" d64_123 "|" d64_213 "|" d64_132 "|" d64_321 "|" d64_231 "|" d64_312 ")\\}"
- dents = "\\{(" d_123 "|" d_213 "|" d_132 "|" d_321 "|" d_231 "|" d_312 ")\\}"
- dents64 = "\\{(" d64_123 "|" d64_213 "|" d64_132 "|" d64_321 "|" d64_231 "|" d64_312 ")\\}"
+ getdents = "getdents\\(" i ", " dents ", " len "\\)"
+ getdents64 = "getdents64\\(" i ", " dents64 ", " len "\\)"
- getdents = "^getdents\\(" i ", " dents ", " len "\\) += " len "$"
- getdents64 = "^getdents64\\(" i ", " dents64 ", " len "\\) += " len "$"
+ r[1] = "^(" getdents "|" getdents64 ") += " len "$"
+ r[2] = "^getdents(64)?\\([0-9]+, \\{\\}, [1-9][0-9]+\\) += 0$"
+ s[3] = "+++ exited with 0 +++"
+
+ lines = 3
+ fail = 0
}
-NR == 1 {if (match($0, getdents) || match($0, getdents64)) next}
-
-NR == 2 && /^getdents(64)?\([0-9]+, \{\}, [1-9][0-9]+\) += 0$/ {next}
-
-NR == lines && /^\+\+\+ exited with 0 \+\+\+$/ {next}
-
-{
- print "Line " NR " does not match: " $0
- fail=1
-}
-
-END {
- if (NR != lines) {
- print "Expected " lines " lines, found " NR " line(s)."
- print ""
- exit 1
- }
- if (fail) {
- print ""
- exit 1
- }
-}
+@include "match.awk"
diff --git a/tests/getdents.test b/tests/getdents.test
index 5be3e83..3fa1c8d 100755
--- a/tests/getdents.test
+++ b/tests/getdents.test
@@ -4,9 +4,9 @@
. "${srcdir=.}/init.sh"
-check_prog awk
-awk -f "$srcdir"/getdents.awk "$srcdir"/getdents.out ||
- framework_skip_ 'awk does not work properly'
+check_prog gawk
+AWKPATH="$srcdir" gawk -f "$srcdir"/getdents.awk "$srcdir"/getdents.out ||
+ framework_skip_ 'gawk does not work properly'
check_prog ls
check_prog mkdir
diff --git a/tests/getrandom.awk b/tests/getrandom.awk
index 4c5f6fc..09d2a0f 100644
--- a/tests/getrandom.awk
+++ b/tests/getrandom.awk
@@ -2,25 +2,10 @@
r[1] = "^getrandom\\(\"(\\\\x[0-9a-f][0-9a-f]){3}\", 3, 0\\) += 3$"
r[2] = "^getrandom\\(\"(\\\\x[0-9a-f][0-9a-f]){3}\"\\.\\.\\., 4, GRND_NONBLOCK\\) += 4$"
r[3] = "^getrandom\\(0x[[0-9a-f]+, 4, GRND_NONBLOCK\\|GRND_RANDOM\\|0x3000\\) += -1 "
- r[4] = "^\\+\\+\\+ exited with 0 \\+\\+\\+$"
+ s[4] = "+++ exited with 0 +++"
+
lines = 4
fail = 0
}
-NR > lines { exit 1 }
-
-{
- if (match($0, r[NR]))
- next
-
- print "Line " NR " does not match."
- fail = 1
-}
-
-END {
- if (fail == 0 && NR != lines) {
- fail = 1
- print "Expected " lines " lines, found " NR " line(s)."
- }
- exit fail
-}
+@include "match.awk"
diff --git a/tests/init.sh b/tests/init.sh
index a3ccd1f..c976806 100644
--- a/tests/init.sh
+++ b/tests/init.sh
@@ -59,6 +59,18 @@
rm -f -- "$LOG".[0-9]*
}
+check_gawk()
+{
+ check_prog gawk
+ check_prog grep
+
+ local program="$1"; shift
+ if grep '^@include[[:space:]]' < "$program" > /dev/null; then
+ gawk '@include "/dev/null"' < /dev/null ||
+ framework_skip_ 'gawk does not support @include'
+ fi
+}
+
# Usage: [FILE_TO_CHECK [AWK_PROGRAM [ERROR_MESSAGE [EXTRA_AWK_OPTIONS...]]]]
# Check whether all patterns listed in AWK_PROGRAM
# match FILE_TO_CHECK using egrep.
@@ -66,7 +78,7 @@
# dump both files and fail with ERROR_MESSAGE.
match_awk()
{
- local output program error awk
+ local output program error
if [ $# -eq 0 ]; then
output="$LOG"
else
@@ -82,11 +94,10 @@
else
error="$1"; shift
fi
- awk=${AWK:-awk}
- check_prog "$awk"
+ check_gawk "$program"
- "$awk" -f "$program" "$@" < "$output" || {
+ AWKPATH="$srcdir" gawk -f "$program" "$@" < "$output" || {
cat < "$output"
fail_ "$error"
}
diff --git a/tests/match.awk b/tests/match.awk
new file mode 100644
index 0000000..39af47c
--- /dev/null
+++ b/tests/match.awk
@@ -0,0 +1,26 @@
+# s[] is array of match strings
+# r[] is array of match patterns
+
+NR > lines { next }
+
+{
+ if (s[NR]) {
+ if ($0 == s[NR])
+ next
+ print "Line " NR " does not match expected string: " s[NR]
+ } else {
+ if (match($0, r[NR]))
+ next
+ print "Line " NR " does not match expected pattern: " r[NR]
+ }
+
+ fail = 1
+}
+
+END {
+ if (fail == 0 && NR != lines) {
+ fail = 1
+ print "Expected " lines " lines, found " NR " line(s)."
+ }
+ exit fail
+}
diff --git a/tests/mmap.c b/tests/mmap.c
new file mode 100644
index 0000000..d4d3e66
--- /dev/null
+++ b/tests/mmap.c
@@ -0,0 +1,46 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <limits.h>
+#include <sys/mman.h>
+
+int
+main(void)
+{
+ const intmax_t pagesize = sysconf(_SC_PAGESIZE);
+ const unsigned long length = pagesize * 3;
+ const int fd = -1;
+ off_t offset;
+ void *addr, *p;
+
+#if ULONG_MAX > 4294967295UL
+ offset = 0xcafedeadbeef000 & -pagesize;
+ addr = (void *) (uintmax_t) (0xfacefeed000 & -pagesize);
+#else
+ offset = 0xdeadbeef000 & -pagesize;
+ addr = (void *) (unsigned int) (0xfaced000 & -pagesize);
+#endif
+
+ p = mmap(addr, length, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, fd, offset);
+ if (p == MAP_FAILED ||
+ mprotect(p, length, PROT_NONE) ||
+ munmap(p, length))
+ return 77;
+
+ if (sizeof(offset) == sizeof(int))
+ printf("(mmap2?|old_mmap)\\(%p, %lu, PROT_READ\\|PROT_WRITE, "
+ "MAP_PRIVATE\\|MAP_ANONYMOUS, %d, %#x\\) = %p\n",
+ addr, length, fd, (unsigned int) offset, p);
+ else
+ printf("(mmap2?|old_mmap)\\(%p, %lu, PROT_READ\\|PROT_WRITE, "
+ "MAP_PRIVATE\\|MAP_ANONYMOUS, %d, %#jx\\) = %p\n",
+ addr, length, fd, (uintmax_t) offset, p);
+ printf("mprotect\\(%p, %lu, PROT_NONE\\) += 0\n", p, length);
+ printf("munmap\\(%p, %lu\\) += 0\n", p, length);
+ return 0;
+}
diff --git a/tests/mmap.test b/tests/mmap.test
new file mode 100755
index 0000000..e9c9b3a
--- /dev/null
+++ b/tests/mmap.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Check mmap/mprotect/munmap syscalls decoding.
+
+. "${srcdir=.}/init.sh"
+
+syscall=mprotect,munmap
+for n in mmap mmap2 old_mmap; do
+ $STRACE -e$n -h > /dev/null && syscall=$syscall,$n
+done
+
+OUT="$LOG.out"
+
+run_prog > /dev/null
+run_strace -e$syscall $args > "$OUT"
+match_grep "$LOG" "$OUT"
+
+rm -f "$OUT"
+
+exit 0
diff --git a/tests/mmap64.c b/tests/mmap64.c
new file mode 100644
index 0000000..b31ce42
--- /dev/null
+++ b/tests/mmap64.c
@@ -0,0 +1 @@
+#include "mmap.c"
diff --git a/tests/mmap64.test b/tests/mmap64.test
new file mode 100755
index 0000000..51f1896
--- /dev/null
+++ b/tests/mmap64.test
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+# Check mmap/mprotect/munmap syscalls decoding.
+# Target executable was compiled with -D_FILE_OFFSET_BITS=64.
+
+. "${srcdir=.}/mmap.test"
diff --git a/tests/netlink_inet_diag.c b/tests/netlink_inet_diag.c
index 7d41b0b..bacb938 100644
--- a/tests/netlink_inet_diag.c
+++ b/tests/netlink_inet_diag.c
@@ -81,11 +81,10 @@
close(0);
close(1);
- assert(socket(PF_INET, SOCK_STREAM, 0) == 0);
- assert(bind(0, (struct sockaddr *) &addr, len) == 0);
- assert(listen(0, 5) == 0);
-
- if (socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG) != 1)
+ if (socket(PF_INET, SOCK_STREAM, 0) ||
+ bind(0, (struct sockaddr *) &addr, len) ||
+ listen(0, 5) ||
+ socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG) != 1)
return 77;
return (send_query(1, AF_INET, IPPROTO_TCP) &&
diff --git a/tests/netlink_unix_diag.c b/tests/netlink_unix_diag.c
index 979ab88..817bf01 100644
--- a/tests/netlink_unix_diag.c
+++ b/tests/netlink_unix_diag.c
@@ -90,9 +90,11 @@
close(1);
(void) unlink(SUN_PATH);
- assert(socket(PF_LOCAL, SOCK_STREAM, 0) == 0);
- assert(bind(0, (struct sockaddr *) &addr, len) == 0);
- assert(listen(0, 5) == 0);
+ if (socket(PF_LOCAL, SOCK_STREAM, 0) ||
+ bind(0, (struct sockaddr *) &addr, len) ||
+ listen(0, 5))
+ return 77;
+
assert(unlink(SUN_PATH) == 0);
if (socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG) != 1)
diff --git a/tests/pipe.c b/tests/pipe.c
new file mode 100644
index 0000000..6a5306f
--- /dev/null
+++ b/tests/pipe.c
@@ -0,0 +1,27 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+ (void) close(0);
+ (void) close(1);
+ int fds[2];
+ if (pipe(fds) || fds[0] != 0 || fds[1] != 1)
+ return 77;
+
+#ifdef HAVE_PIPE2
+ (void) close(0);
+ (void) close(1);
+ if (pipe2(fds, O_NONBLOCK) || fds[0] != 0 || fds[1] != 1)
+ return 77;
+ return 0;
+#else
+ return 77;
+#endif
+}
diff --git a/tests/pipe.expected b/tests/pipe.expected
new file mode 100644
index 0000000..675cb85
--- /dev/null
+++ b/tests/pipe.expected
@@ -0,0 +1,2 @@
+pipe(\(\[0, 1\]|2\(\[0, 1\], 0)\) += 0
+pipe2\(\[0, 1\], O_NONBLOCK\) += 0
diff --git a/tests/pipe.test b/tests/pipe.test
new file mode 100755
index 0000000..a445f86
--- /dev/null
+++ b/tests/pipe.test
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+# Check pipe/pipe2 syscalls decoding.
+
+. "${srcdir=.}/init.sh"
+
+syscall=pipe2
+for n in pipe; do
+ $STRACE -e$n -h > /dev/null && syscall=$syscall,$n
+done
+
+run_prog
+run_strace -e$syscall $args
+match_grep
+
+exit 0
diff --git a/tests/seccomp.c b/tests/seccomp.c
new file mode 100644
index 0000000..01fe2eb
--- /dev/null
+++ b/tests/seccomp.c
@@ -0,0 +1,113 @@
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stddef.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/syscall.h>
+
+#ifdef HAVE_PRCTL
+# include <sys/prctl.h>
+#endif
+#ifdef HAVE_LINUX_SECCOMP_H
+# include <linux/seccomp.h>
+#endif
+#ifdef HAVE_LINUX_FILTER_H
+# include <linux/filter.h>
+#endif
+
+#if defined HAVE_PRCTL \
+ && defined PR_SET_NO_NEW_PRIVS \
+ && defined PR_SET_SECCOMP \
+ && defined SECCOMP_MODE_FILTER \
+ && defined SECCOMP_RET_ERRNO \
+ && defined BPF_JUMP \
+ && defined BPF_STMT
+
+#define SOCK_FILTER_ALLOW_SYSCALL(nr) \
+ BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, __NR_ ## nr, 0, 1), \
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW)
+
+#define SOCK_FILTER_DENY_SYSCALL(nr, err) \
+ BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, __NR_ ## nr, 0, 1), \
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (SECCOMP_RET_DATA & (err)))
+
+#define SOCK_FILTER_KILL_PROCESS \
+ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL)
+
+#define PRINT_ALLOW_SYSCALL(nr) \
+ printf("BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, %#x, 0, 0x1), " \
+ "BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), ", \
+ __NR_ ## nr)
+
+#define PRINT_DENY_SYSCALL(nr, err) \
+ printf("BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, %#x, 0, 0x1), " \
+ "BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | %#x), ", \
+ __NR_ ## nr, err)
+
+static const struct sock_filter filter[] = {
+ /* load syscall number */
+ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)),
+
+ /* allow syscalls */
+ SOCK_FILTER_ALLOW_SYSCALL(close),
+ SOCK_FILTER_ALLOW_SYSCALL(exit),
+ SOCK_FILTER_ALLOW_SYSCALL(exit_group),
+
+ /* deny syscalls */
+ SOCK_FILTER_DENY_SYSCALL(sync, EBUSY),
+ SOCK_FILTER_DENY_SYSCALL(setsid, EPERM),
+
+ /* kill process */
+ SOCK_FILTER_KILL_PROCESS
+};
+
+static const struct sock_fprog prog = {
+ .len = sizeof(filter) / sizeof(filter[0]),
+ .filter = (struct sock_filter *) filter,
+};
+
+int
+main(void)
+{
+ int fds[2];
+
+ puts("prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0");
+
+ printf("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, [");
+
+ printf("BPF_STMT(BPF_LD | BPF_W | BPF_ABS, %#x), ",
+ (unsigned) offsetof(struct seccomp_data, nr));
+
+ PRINT_ALLOW_SYSCALL(close);
+ PRINT_ALLOW_SYSCALL(exit);
+ PRINT_ALLOW_SYSCALL(exit_group);
+
+ PRINT_DENY_SYSCALL(sync, EBUSY),
+ PRINT_DENY_SYSCALL(setsid, EPERM),
+
+ printf("BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL)");
+
+ puts("]) = 0");
+ puts("+++ exited with 0 +++");
+
+ fflush(stdout);
+ close(0);
+ close(1);
+
+ if (pipe(fds) ||
+ prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) ||
+ prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) ||
+ close(0) || close(1))
+ _exit(77);
+
+ _exit(0);
+}
+
+#else
+
+int main(void) { return 77; }
+
+#endif
diff --git a/tests/seccomp.test b/tests/seccomp.test
new file mode 100755
index 0000000..4101cae
--- /dev/null
+++ b/tests/seccomp.test
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# Check how SECCOMP_MODE_FILTER is decoded.
+
+. "${srcdir=.}/init.sh"
+
+OUT="$LOG.out"
+
+run_prog > /dev/null
+run_strace -veprctl $args > "$OUT"
+match_diff "$LOG" "$OUT"
+
+rm -f "$OUT"
+
+exit 0
diff --git a/tests/select.awk b/tests/select.awk
index 688cefe..996d028 100644
--- a/tests/select.awk
+++ b/tests/select.awk
@@ -2,25 +2,10 @@
r[1] = "^p?select6?\\(2, \\[0 1\\], \\[0 1\\], \\[0 1\\], NULL(, 0)?\\) += 1 \\(\\)$"
r[2] = "^p?select6?\\(-1, NULL, 0x[0-9a-f]+, NULL, NULL(, 0)?\\) += -1 "
r[3] = "^p?select6?\\(1025, \\[0\\], \\[\\], NULL, \\{0, 100(000)?\\}(, 0)?\\) += 0 \\(Timeout\\)$"
- r[4] = "^\\+\\+\\+ exited with 0 \\+\\+\\+$"
+ s[4] = "+++ exited with 0 +++"
+
lines = 4
fail = 0
}
-NR > lines { exit 1 }
-
-{
- if (match($0, r[NR]))
- next
-
- print "Line " NR " does not match."
- fail = 1
-}
-
-END {
- if (fail == 0 && NR != lines) {
- fail = 1
- print "Expected " lines " lines, found " NR " line(s)."
- }
- exit fail
-}
+@include "match.awk"
diff --git a/tests/sigaction.awk b/tests/sigaction.awk
index 01133d2..df96e4b 100644
--- a/tests/sigaction.awk
+++ b/tests/sigaction.awk
@@ -1,55 +1,37 @@
-# rt_sigaction on ALPHA has 5 args: sig, act, oact, sigsetsize, restorer.
-# rt_sigaction on SPARC has 5 args: sig, act, oact, restorer, sigsetsize.
-# rt_sigaction on other architectures has 4 args: sig, act, oact, sigsetsize.
-# Some architectures have SA_RESTORER, some don't;
-# in particular, SPARC has and ALPHA hasn't.
-#
-# There are two regexps for each test:
-# the 1st is for any architecture with SA_RESTORER, including SPARC;
-# the 2nd is for any architecture without SA_RESTORER, including ALPHA;
-# the 3rd is for any architecture without SA_RESTORER and swapped args.
-
BEGIN {
+ n1[1] = "SIG_IGN, \\[HUP INT\\], SA_RESTORER\\|SA_RESTART, 0x[0-9a-f]+"
+ n2[1] = "SIG_IGN, \\[HUP INT\\], SA_RESTART"
+
+ n1[2] = "0x[0-9a-f]+, \\[QUIT TERM\\], SA_RESTORER\\|SA_SIGINFO, 0x[0-9a-f]+"
+ n2[2] = "0x[0-9a-f]+, \\[QUIT TERM\\], SA_SIGINFO"
+
+ n1[3] = "SIG_DFL, \\[\\], SA_RESTORER, 0x[0-9a-f]+"
+ n2[3] = "SIG_DFL, \\[\\], 0"
+
+ n1[4] = "SIG_DFL, ~\\[HUP( ((RT|SIGRT)[^] ]+|[3-9][0-9]|1[0-9][0-9]))*\\], SA_RESTORER, 0x[0-9a-f]+"
+ n2[4] = "SIG_DFL, ~\\[HUP( ((RT|SIGRT)[^] ]+|[3-9][0-9]|1[0-9][0-9]))*\\], 0"
+
+ o1[1] = o2[1] = "SIG_DFL, \\[\\], 0"
+
+ for (i = 2; i < 5; i++) {
+ o1[i] = n1[i - 1]
+ o2[i] = n2[i - 1]
+ }
+
+ a1 = "(0x[0-9a-f]+, )?(4|8|16)"
+ a2 = "(4|8|16)(, 0x[0-9a-f]+)?"
+ a3 = "0x[0-9a-f]+, (4|8|16)"
+
+ for (i = 1; i < 5; i++) {
+ r[i] = "^rt_sigaction\\(SIGUSR2, (" \
+ "\\{" n1[i] "\\}, \\{" o1[i] "\\}, " a1 "|" \
+ "\\{" n2[i] "\\}, \\{" o2[i] "\\}, " a2 "|" \
+ "\\{" n2[i] "\\}, \\{" o2[i] "\\}, " a3 ")\\) = 0$"
+ }
+ s[5] = "+++ exited with 0 +++"
+
lines = 5
fail = 0
}
-# Test 1.
-NR == 1 && /^rt_sigaction\(SIGUSR2, \{SIG_IGN, \[HUP INT\], SA_RESTORER\|SA_RESTART, 0x[0-9a-f]+\}, \{SIG_DFL, \[\], 0\}, (0x[0-9a-f]+, )?(4|8|16)\) = 0$/ {next}
-NR == 1 && /^rt_sigaction\(SIGUSR2, \{SIG_IGN, \[HUP INT\], SA_RESTART\}, \{SIG_DFL, \[\], 0\}, (4|8|16)(, 0x[0-9a-f]+)?\) = 0$/ {next}
-NR == 1 && /^rt_sigaction\(SIGUSR2, \{SIG_IGN, \[HUP INT\], SA_RESTART\}, \{SIG_DFL, \[\], 0\}, 0x[0-9a-f]+, (4|8|16)\) = 0$/ {next}
-
-# Test 2.
-NR == 2 && /^rt_sigaction\(SIGUSR2, \{0x[0-9a-f]+, \[QUIT TERM\], SA_RESTORER\|SA_SIGINFO, 0x[0-9a-f]+\}, \{SIG_IGN, \[HUP INT\], SA_RESTORER\|SA_RESTART, 0x[0-9a-f]+\}, (0x[0-9a-f]+, )?(4|8|16)\) = 0$/ {next}
-NR == 2 && /^rt_sigaction\(SIGUSR2, \{0x[0-9a-f]+, \[QUIT TERM\], SA_SIGINFO\}, \{SIG_IGN, \[HUP INT\], SA_RESTART\}, (4|8|16)(, 0x[0-9a-f]+)?\) = 0$/ {next}
-NR == 2 && /^rt_sigaction\(SIGUSR2, \{0x[0-9a-f]+, \[QUIT TERM\], SA_SIGINFO\}, \{SIG_IGN, \[HUP INT\], SA_RESTART\}, 0x[0-9a-f]+, (4|8|16)\) = 0$/ {next}
-
-# Test 3.
-NR == 3 && /^rt_sigaction\(SIGUSR2, \{SIG_DFL, \[\], SA_RESTORER, 0x[0-9a-f]+\}, \{0x[0-9a-f]+, \[QUIT TERM\], SA_RESTORER\|SA_SIGINFO, 0x[0-9a-f]+\}, (0x[0-9a-f]+, )?(4|8|16)\) = 0$/ {next}
-NR == 3 && /^rt_sigaction\(SIGUSR2, \{SIG_DFL, \[\], 0\}, \{0x[0-9a-f]+, \[QUIT TERM\], SA_SIGINFO\}, (4|8|16)(, 0x[0-9a-f]+)?\) = 0$/ {next}
-NR == 3 && /^rt_sigaction\(SIGUSR2, \{SIG_DFL, \[\], 0\}, \{0x[0-9a-f]+, \[QUIT TERM\], SA_SIGINFO\}, 0x[0-9a-f]+, (4|8|16)\) = 0$/ {next}
-
-# Test 4.
-NR == 4 && /^rt_sigaction\(SIGUSR2, \{SIG_DFL, ~\[HUP( ((RT|SIGRT)[^] ]+|[3-9][0-9]|1[0-9][0-9]))*\], SA_RESTORER, 0x[0-9a-f]+\}, \{SIG_DFL, \[\], SA_RESTORER, 0x[0-9a-f]+\}, (0x[0-9a-f]+, )?(4|8|16)\) = 0$/ {next}
-NR == 4 && /^rt_sigaction\(SIGUSR2, \{SIG_DFL, ~\[HUP( ((RT|SIGRT)[^] ]+|[3-9][0-9]|1[0-9][0-9]))*\], 0\}, \{SIG_DFL, \[\], 0\}, (4|8|16)(, 0x[0-9a-f]+)?\) = 0$/ {next}
-NR == 4 && /^rt_sigaction\(SIGUSR2, \{SIG_DFL, ~\[HUP( ((RT|SIGRT)[^] ]+|[3-9][0-9]|1[0-9][0-9]))*\], 0\}, \{SIG_DFL, \[\], 0\}, 0x[0-9a-f]+, (4|8|16)\) = 0$/ {next}
-
-# The last line.
-NR == lines && /^\+\+\+ exited with 0 \+\+\+$/ {next}
-
-{
- print "Line " NR " does not match: " $0
- fail=1
-}
-
-END {
- if (NR != lines) {
- print "Expected " lines " lines, found " NR " line(s)."
- print ""
- exit 1
- }
- if (fail) {
- print ""
- exit 1
- }
-}
+@include "match.awk"
diff --git a/tests/umovestr.c b/tests/umovestr.c
new file mode 100644
index 0000000..9ad6b94
--- /dev/null
+++ b/tests/umovestr.c
@@ -0,0 +1,26 @@
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int
+main(void)
+{
+ const size_t page_len = sysconf(_SC_PAGESIZE);
+ const size_t tail_len = 257;
+
+ if (tail_len >= page_len)
+ return 77;
+
+ void *p = mmap(NULL, page_len * 2, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED || mprotect(p + page_len, page_len, PROT_NONE))
+ return 77;
+
+ memset(p, 0, page_len);
+ char *addr = p + page_len - tail_len;
+ memset(addr, '/', tail_len - 1);
+ if (chdir(addr))
+ return 77;
+
+ return 0;
+}
diff --git a/tests/umovestr.expected b/tests/umovestr.expected
new file mode 100644
index 0000000..c26d877
--- /dev/null
+++ b/tests/umovestr.expected
@@ -0,0 +1,2 @@
+chdir("////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////") = 0
++++ exited with 0 +++
diff --git a/tests/umovestr.test b/tests/umovestr.test
new file mode 100755
index 0000000..5ae8ffa
--- /dev/null
+++ b/tests/umovestr.test
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+# umovestr short read regression test
+
+. "${srcdir=.}/init.sh"
+
+run_prog
+run_strace -e chdir $args
+match_diff
+
+exit 0
diff --git a/tests/umovestr2.c b/tests/umovestr2.c
new file mode 100644
index 0000000..c7bd42f
--- /dev/null
+++ b/tests/umovestr2.c
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int
+main(void)
+{
+ const size_t page_len = sysconf(_SC_PAGESIZE);
+ const size_t work_len = page_len * 2;
+ const size_t tail_len = work_len - 1;
+
+ void *p = mmap(NULL, page_len * 3, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (p == MAP_FAILED || mprotect(p + work_len, page_len, PROT_NONE))
+ return 77;
+
+ memset(p, 0, work_len);
+ char *addr = p + work_len - tail_len;
+ memset(addr, '0', tail_len - 1);
+
+ char *argv[] = { NULL };
+ char *envp[] = { addr, NULL };
+ execve("", argv, envp);
+
+ printf("execve(\"\", [], [\"%0*u\"]) = -1 ENOENT (No such file or directory)\n",
+ (int) tail_len - 1, 0);
+ puts("+++ exited with 0 +++");
+
+ return 0;
+}
diff --git a/tests/umovestr2.test b/tests/umovestr2.test
new file mode 100755
index 0000000..2e9fee4
--- /dev/null
+++ b/tests/umovestr2.test
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# umovestr short read regression test
+
+. "${srcdir=.}/init.sh"
+
+OUT="$LOG.out"
+EXP="$LOG.exp"
+
+run_prog > /dev/null
+run_strace -veexecve -s262144 $args > "$EXP"
+check_prog sed
+sed 1d < "$LOG" > "$OUT"
+match_diff "$OUT" "$EXP"
+
+rm -f "$EXP" "$OUT"
+
+exit 0
diff --git a/uid.c b/uid.c
index 1f8c365..96b3d38 100644
--- a/uid.c
+++ b/uid.c
@@ -183,7 +183,7 @@
tprints("...");
break;
}
- if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
+ if (umoven(tcp, cur, sizeof(gid), &gid) < 0) {
tprints("?");
failed = 1;
break;
@@ -242,7 +242,7 @@
tprints("...");
break;
}
- if (umoven(tcp, cur, sizeof(gid), (char *) &gid) < 0) {
+ if (umoven(tcp, cur, sizeof(gid), &gid) < 0) {
tprints("?");
failed = 1;
break;
diff --git a/util.c b/util.c
index 02c5b9a..6afafbb 100644
--- a/util.c
+++ b/util.c
@@ -835,7 +835,7 @@
fprintf(stderr, "Out of memory\n");
return;
}
- if (umoven(tcp, addr, size, (char *) iov) >= 0) {
+ if (umoven(tcp, addr, size, iov) >= 0) {
for (i = 0; i < len; i++) {
/* include the buffer number to make it easy to
* match up the trace with the source */
@@ -881,7 +881,7 @@
strsize = len + 16;
}
- if (umoven(tcp, addr, len, (char *) str) < 0)
+ if (umoven(tcp, addr, len, str) < 0)
return;
/* Space-pad to 16 bytes */
@@ -963,14 +963,29 @@
#endif /* end of hack */
-#define PAGMASK (~(PAGSIZ - 1))
+static ssize_t
+vm_read_mem(pid_t pid, void *laddr, long raddr, size_t len)
+{
+ const struct iovec local = {
+ .iov_base = laddr,
+ .iov_len = len
+ };
+ const struct iovec remote = {
+ .iov_base = (void *) raddr,
+ .iov_len = len
+ };
+
+ return process_vm_readv(pid, &local, 1, &remote, 1, 0);
+}
+
/*
* move `len' bytes of data from process `pid'
- * at address `addr' to our space at `laddr'
+ * at address `addr' to our space at `our_addr'
*/
int
-umoven(struct tcb *tcp, long addr, unsigned int len, char *laddr)
+umoven(struct tcb *tcp, long addr, unsigned int len, void *our_addr)
{
+ char *laddr = our_addr;
int pid = tcp->pid;
unsigned int n, m, nread;
union {
@@ -984,13 +999,7 @@
#endif
if (!process_vm_readv_not_supported) {
- struct iovec local[1], remote[1];
- int r;
-
- local[0].iov_base = laddr;
- remote[0].iov_base = (void*)addr;
- local[0].iov_len = remote[0].iov_len = len;
- r = process_vm_readv(pid, local, 1, remote, 1, 0);
+ int r = vm_read_mem(pid, laddr, addr, len);
if ((unsigned int) r == len)
return 0;
if (r >= 0) {
@@ -1002,10 +1011,13 @@
case ENOSYS:
process_vm_readv_not_supported = 1;
break;
+ case EPERM:
+ /* operation not permitted, try PTRACE_PEEKDATA */
+ break;
case ESRCH:
/* the process is gone */
return -1;
- case EFAULT: case EIO: case EPERM:
+ case EFAULT: case EIO:
/* address space is inaccessible */
return -1;
default:
@@ -1116,38 +1128,31 @@
nread = 0;
if (!process_vm_readv_not_supported) {
- struct iovec local[1], remote[1];
-
- local[0].iov_base = laddr;
- remote[0].iov_base = (void*)addr;
+ const size_t page_size = get_pagesize();
+ const size_t page_mask = page_size - 1;
while (len > 0) {
unsigned int chunk_len;
unsigned int end_in_page;
- int r;
- /* Don't read kilobytes: most strings are short */
- chunk_len = len;
- if (chunk_len > 256)
- chunk_len = 256;
- /* Don't cross pages. I guess otherwise we can get EFAULT
+ /*
+ * Don't cross pages, otherwise we can get EFAULT
* and fail to notice that terminating NUL lies
* in the existing (first) page.
- * (I hope there aren't arches with pages < 4K)
*/
- end_in_page = ((addr + chunk_len) & 4095);
+ chunk_len = len > page_size ? page_size : len;
+ end_in_page = (addr + chunk_len) & page_mask;
if (chunk_len > end_in_page) /* crosses to the next page */
chunk_len -= end_in_page;
- local[0].iov_len = remote[0].iov_len = chunk_len;
- r = process_vm_readv(pid, local, 1, remote, 1, 0);
+ int r = vm_read_mem(pid, laddr, addr, chunk_len);
if (r > 0) {
- if (memchr(local[0].iov_base, '\0', r))
+ if (memchr(laddr, '\0', r))
return 1;
- local[0].iov_base += r;
- remote[0].iov_base += r;
- len -= r;
+ addr += r;
+ laddr += r;
nread += r;
+ len -= r;
continue;
}
switch (errno) {
@@ -1157,11 +1162,16 @@
case ESRCH:
/* the process is gone */
return -1;
- case EFAULT: case EIO: case EPERM:
+ case EPERM:
+ /* operation not permitted, try PTRACE_PEEKDATA */
+ if (!nread)
+ goto vm_readv_didnt_work;
+ /* fall through */
+ case EFAULT: case EIO:
/* address space is inaccessible */
if (nread) {
perror_msg("umovestr: short read (%d < %d) @0x%lx",
- nread, nread + len, addr);
+ nread, nread + len, addr - nread);
}
return -1;
default:
diff --git a/utime.c b/utime.c
index 6e396b0..ba25356 100644
--- a/utime.c
+++ b/utime.c
@@ -19,7 +19,7 @@
tprints("NULL");
else if (!verbose(tcp))
tprintf("%#lx", tcp->u_arg[1]);
- else if (umoven(tcp, tcp->u_arg[1], 2 * wordsize, (char *) &u) < 0)
+ else if (umoven(tcp, tcp->u_arg[1], 2 * wordsize, &u) < 0)
tprints("[?, ?]");
else if (wordsize == sizeof u.utl[0]) {
tprintf("[%s,", sprinttime(u.utl[0]));
diff --git a/xlat/sigaltstack_flags.in b/xlat/sigaltstack_flags.in
index c27a931..376ec18 100644
--- a/xlat/sigaltstack_flags.in
+++ b/xlat/sigaltstack_flags.in
@@ -1,2 +1,2 @@
-SS_ONSTACK
-SS_DISABLE
+SS_ONSTACK 1
+SS_DISABLE 2
diff --git a/xlat/sigbus_codes.in b/xlat/sigbus_codes.in
index 8d8a048..1bce25f 100644
--- a/xlat/sigbus_codes.in
+++ b/xlat/sigbus_codes.in
@@ -1,3 +1,5 @@
-BUS_ADRALN
-BUS_ADRERR
-BUS_OBJERR
+BUS_ADRALN 1
+BUS_ADRERR 2
+BUS_OBJERR 3
+BUS_MCEERR_AR 4
+BUS_MCEERR_AO 5
diff --git a/xlat/sigchld_codes.in b/xlat/sigchld_codes.in
index 40c93ce..202bec4 100644
--- a/xlat/sigchld_codes.in
+++ b/xlat/sigchld_codes.in
@@ -1,6 +1,6 @@
-CLD_EXITED
-CLD_KILLED
-CLD_DUMPED
-CLD_TRAPPED
-CLD_STOPPED
-CLD_CONTINUED
+CLD_EXITED 1
+CLD_KILLED 2
+CLD_DUMPED 3
+CLD_TRAPPED 4
+CLD_STOPPED 5
+CLD_CONTINUED 6
diff --git a/xlat/sigemt_codes.in b/xlat/sigemt_codes.in
index 63fe3a3..eb87561 100644
--- a/xlat/sigemt_codes.in
+++ b/xlat/sigemt_codes.in
@@ -1 +1 @@
-EMT_TAGOVF
+EMT_TAGOVF 1
diff --git a/xlat/sigfpe_codes.in b/xlat/sigfpe_codes.in
index ab86b26..4ef0667 100644
--- a/xlat/sigfpe_codes.in
+++ b/xlat/sigfpe_codes.in
@@ -1,8 +1,8 @@
-FPE_INTDIV
-FPE_INTOVF
-FPE_FLTDIV
-FPE_FLTOVF
-FPE_FLTUND
-FPE_FLTRES
-FPE_FLTINV
-FPE_FLTSUB
+FPE_INTDIV 1
+FPE_INTOVF 2
+FPE_FLTDIV 3
+FPE_FLTOVF 4
+FPE_FLTUND 5
+FPE_FLTRES 6
+FPE_FLTINV 7
+FPE_FLTSUB 8
diff --git a/xlat/sigill_codes.in b/xlat/sigill_codes.in
index 6fb994e..ca111ec 100644
--- a/xlat/sigill_codes.in
+++ b/xlat/sigill_codes.in
@@ -1,8 +1,8 @@
-ILL_ILLOPC
-ILL_ILLOPN
-ILL_ILLADR
-ILL_ILLTRP
-ILL_PRVOPC
-ILL_PRVREG
-ILL_COPROC
-ILL_BADSTK
+ILL_ILLOPC 1
+ILL_ILLOPN 2
+ILL_ILLADR 3
+ILL_ILLTRP 4
+ILL_PRVOPC 5
+ILL_PRVREG 6
+ILL_COPROC 7
+ILL_BADSTK 8
diff --git a/xlat/siginfo_codes.in b/xlat/siginfo_codes.in
index 115d3ab..a57c370 100644
--- a/xlat/siginfo_codes.in
+++ b/xlat/siginfo_codes.in
@@ -1,12 +1,12 @@
-SI_KERNEL
-SI_USER
-SI_QUEUE
-SI_TIMER
-SI_MESGQ
-SI_ASYNCIO
-SI_SIGIO
-SI_TKILL
-SI_DETHREAD
-SI_ASYNCNL
+SI_USER 0
+SI_KERNEL 0x80
+SI_QUEUE -1
+SI_TIMER -2
+SI_MESGQ -3
+SI_ASYNCIO -4
+SI_SIGIO -5
+SI_TKILL -6
+SI_DETHREAD -7
+SI_ASYNCNL -60
SI_NOINFO
SI_LWP
diff --git a/xlat/sigpoll_codes.in b/xlat/sigpoll_codes.in
index f778fc6..00c2a1b 100644
--- a/xlat/sigpoll_codes.in
+++ b/xlat/sigpoll_codes.in
@@ -1,6 +1,6 @@
-POLL_IN
-POLL_OUT
-POLL_MSG
-POLL_ERR
-POLL_PRI
-POLL_HUP
+POLL_IN 1
+POLL_OUT 2
+POLL_MSG 3
+POLL_ERR 4
+POLL_PRI 5
+POLL_HUP 6
diff --git a/xlat/sigsegv_codes.in b/xlat/sigsegv_codes.in
index bdf3d7e..9117bc2 100644
--- a/xlat/sigsegv_codes.in
+++ b/xlat/sigsegv_codes.in
@@ -1,2 +1,3 @@
-SEGV_MAPERR
-SEGV_ACCERR
+SEGV_MAPERR 1
+SEGV_ACCERR 2
+SEGV_BNDERR 3
diff --git a/xlat/sigsys_codes.in b/xlat/sigsys_codes.in
index 7eaa40a..a8c4891 100644
--- a/xlat/sigsys_codes.in
+++ b/xlat/sigsys_codes.in
@@ -1 +1 @@
-SYS_SECCOMP
+SYS_SECCOMP 1
diff --git a/xlat/sigtrap_codes.in b/xlat/sigtrap_codes.in
index 41474fe..078aec8 100644
--- a/xlat/sigtrap_codes.in
+++ b/xlat/sigtrap_codes.in
@@ -1,2 +1,4 @@
-TRAP_BRKPT
-TRAP_TRACE
+TRAP_BRKPT 1
+TRAP_TRACE 2
+TRAP_BRANCH 3
+TRAP_HWBKPT 4