]> granicus.if.org Git - strace/commitdiff
Implement arch specific methods of changing syscall number and error code
authorDmitry V. Levin <ldv@altlinux.org>
Tue, 15 Nov 2016 17:38:21 +0000 (17:38 +0000)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 16 Nov 2016 02:33:13 +0000 (02:33 +0000)
This introduces arch_set_error and arch_set_scno functions for each
supported architecture, needed to implement syscall fault injection.

* linux/aarch64/set_error.c: New file.
* linux/aarch64/set_scno.c: Likewise.
* linux/alpha/set_error.c: Likewise.
* linux/alpha/set_scno.c: Likewise.
* linux/arc/set_error.c: Likewise.
* linux/arc/set_scno.c: Likewise.
* linux/arm/set_error.c: Likewise.
* linux/arm/set_scno.c: Likewise.
* linux/avr32/set_error.c: Likewise.
* linux/avr32/set_scno.c: Likewise.
* linux/bfin/set_error.c: Likewise.
* linux/bfin/set_scno.c: Likewise.
* linux/crisv10/set_error.c: Likewise.
* linux/crisv10/set_scno.c: Likewise.
* linux/crisv32/set_error.c: Likewise.
* linux/crisv32/set_scno.c: Likewise.
* linux/hppa/set_error.c: Likewise.
* linux/hppa/set_scno.c: Likewise.
* linux/i386/set_error.c: Likewise.
* linux/i386/set_scno.c: Likewise.
* linux/ia64/set_error.c: Likewise.
* linux/ia64/set_scno.c: Likewise.
* linux/m68k/set_error.c: Likewise.
* linux/m68k/set_scno.c: Likewise.
* linux/metag/set_error.c: Likewise.
* linux/metag/set_scno.c: Likewise.
* linux/microblaze/set_error.c: Likewise.
* linux/microblaze/set_scno.c: Likewise.
* linux/mips/set_error.c: Likewise.
* linux/mips/set_scno.c: Likewise.
* linux/nios2/set_error.c: Likewise.
* linux/nios2/set_scno.c: Likewise.
* linux/or1k/set_error.c: Likewise.
* linux/or1k/set_scno.c: Likewise.
* linux/powerpc/set_error.c: Likewise.
* linux/powerpc/set_scno.c: Likewise.
* linux/powerpc64/set_error.c: Likewise.
* linux/powerpc64/set_scno.c: Likewise.
* linux/riscv/set_error.c: Likewise.
* linux/riscv/set_scno.c: Likewise.
* linux/s390/set_error.c: Likewise.
* linux/s390/set_scno.c: Likewise.
* linux/s390x/set_error.c: Likewise.
* linux/s390x/set_scno.c: Likewise.
* linux/sh/set_error.c: Likewise.
* linux/sh/set_scno.c: Likewise.
* linux/sh64/set_error.c: Likewise.
* linux/sh64/set_scno.c: Likewise.
* linux/sparc/set_error.c: Likewise.
* linux/sparc/set_scno.c: Likewise.
* linux/sparc64/set_error.c: Likewise.
* linux/sparc64/set_scno.c: Likewise.
* linux/tile/set_error.c: Likewise.
* linux/tile/set_scno.c: Likewise.
* linux/x32/set_error.c: Likewise.
* linux/x32/set_scno.c: Likewise.
* linux/x86_64/set_error.c: Likewise.
* linux/x86_64/set_scno.c: Likewise.
* linux/xtensa/set_error.c: Likewise.
* linux/xtensa/set_scno.c: Likewise.
* Makefile.am (EXTRA_DIST): Add them.

61 files changed:
Makefile.am
linux/aarch64/set_error.c [new file with mode: 0644]
linux/aarch64/set_scno.c [new file with mode: 0644]
linux/alpha/set_error.c [new file with mode: 0644]
linux/alpha/set_scno.c [new file with mode: 0644]
linux/arc/set_error.c [new file with mode: 0644]
linux/arc/set_scno.c [new file with mode: 0644]
linux/arm/set_error.c [new file with mode: 0644]
linux/arm/set_scno.c [new file with mode: 0644]
linux/avr32/set_error.c [new file with mode: 0644]
linux/avr32/set_scno.c [new file with mode: 0644]
linux/bfin/set_error.c [new file with mode: 0644]
linux/bfin/set_scno.c [new file with mode: 0644]
linux/crisv10/set_error.c [new file with mode: 0644]
linux/crisv10/set_scno.c [new file with mode: 0644]
linux/crisv32/set_error.c [new file with mode: 0644]
linux/crisv32/set_scno.c [new file with mode: 0644]
linux/hppa/set_error.c [new file with mode: 0644]
linux/hppa/set_scno.c [new file with mode: 0644]
linux/i386/set_error.c [new file with mode: 0644]
linux/i386/set_scno.c [new file with mode: 0644]
linux/ia64/set_error.c [new file with mode: 0644]
linux/ia64/set_scno.c [new file with mode: 0644]
linux/m68k/set_error.c [new file with mode: 0644]
linux/m68k/set_scno.c [new file with mode: 0644]
linux/metag/set_error.c [new file with mode: 0644]
linux/metag/set_scno.c [new file with mode: 0644]
linux/microblaze/set_error.c [new file with mode: 0644]
linux/microblaze/set_scno.c [new file with mode: 0644]
linux/mips/set_error.c [new file with mode: 0644]
linux/mips/set_scno.c [new file with mode: 0644]
linux/nios2/set_error.c [new file with mode: 0644]
linux/nios2/set_scno.c [new file with mode: 0644]
linux/or1k/set_error.c [new file with mode: 0644]
linux/or1k/set_scno.c [new file with mode: 0644]
linux/powerpc/set_error.c [new file with mode: 0644]
linux/powerpc/set_scno.c [new file with mode: 0644]
linux/powerpc64/set_error.c [new file with mode: 0644]
linux/powerpc64/set_scno.c [new file with mode: 0644]
linux/riscv/set_error.c [new file with mode: 0644]
linux/riscv/set_scno.c [new file with mode: 0644]
linux/s390/set_error.c [new file with mode: 0644]
linux/s390/set_scno.c [new file with mode: 0644]
linux/s390x/set_error.c [new file with mode: 0644]
linux/s390x/set_scno.c [new file with mode: 0644]
linux/sh/set_error.c [new file with mode: 0644]
linux/sh/set_scno.c [new file with mode: 0644]
linux/sh64/set_error.c [new file with mode: 0644]
linux/sh64/set_scno.c [new file with mode: 0644]
linux/sparc/set_error.c [new file with mode: 0644]
linux/sparc/set_scno.c [new file with mode: 0644]
linux/sparc64/set_error.c [new file with mode: 0644]
linux/sparc64/set_scno.c [new file with mode: 0644]
linux/tile/set_error.c [new file with mode: 0644]
linux/tile/set_scno.c [new file with mode: 0644]
linux/x32/set_error.c [new file with mode: 0644]
linux/x32/set_scno.c [new file with mode: 0644]
linux/x86_64/set_error.c [new file with mode: 0644]
linux/x86_64/set_scno.c [new file with mode: 0644]
linux/xtensa/set_error.c [new file with mode: 0644]
linux/xtensa/set_scno.c [new file with mode: 0644]

index ecc35b35a3acb7c4abaf2d1ecb884f81af98c5d8..f801ab27fa8ce556a7f71339eff79f9cc6e481c1 100644 (file)
@@ -311,6 +311,8 @@ EXTRA_DIST =                                \
        linux/aarch64/ioctls_arch1.h    \
        linux/aarch64/ioctls_inc0.h     \
        linux/aarch64/ioctls_inc1.h     \
+       linux/aarch64/set_error.c       \
+       linux/aarch64/set_scno.c        \
        linux/aarch64/signalent1.h      \
        linux/aarch64/syscallent.h      \
        linux/aarch64/syscallent1.h     \
@@ -325,6 +327,8 @@ EXTRA_DIST =                                \
        linux/alpha/get_syscall_result.c\
        linux/alpha/ioctls_arch0.h      \
        linux/alpha/ioctls_inc0.h       \
+       linux/alpha/set_error.c         \
+       linux/alpha/set_scno.c          \
        linux/alpha/signalent.h         \
        linux/alpha/syscallent.h        \
        linux/alpha/userent.h           \
@@ -334,6 +338,8 @@ EXTRA_DIST =                                \
        linux/arc/get_syscall_args.c    \
        linux/arc/ioctls_arch0.h        \
        linux/arc/ioctls_inc0.h         \
+       linux/arc/set_error.c           \
+       linux/arc/set_scno.c            \
        linux/arc/syscallent.h          \
        linux/arch_regs.h               \
        linux/arch_sigreturn.c          \
@@ -345,6 +351,8 @@ EXTRA_DIST =                                \
        linux/arm/get_syscall_args.c    \
        linux/arm/ioctls_arch0.h        \
        linux/arm/ioctls_inc0.h         \
+       linux/arm/set_error.c           \
+       linux/arm/set_scno.c            \
        linux/arm/syscallent.h          \
        linux/arm/userent.h             \
        linux/avr32/arch_regs.c         \
@@ -353,6 +361,8 @@ EXTRA_DIST =                                \
        linux/avr32/get_syscall_args.c  \
        linux/avr32/ioctls_arch0.h      \
        linux/avr32/ioctls_inc0.h       \
+       linux/avr32/set_error.c         \
+       linux/avr32/set_scno.c          \
        linux/avr32/syscallent.h        \
        linux/avr32/userent.h           \
        linux/bfin/arch_regs.c          \
@@ -362,6 +372,8 @@ EXTRA_DIST =                                \
        linux/bfin/get_syscall_result.c \
        linux/bfin/ioctls_arch0.h       \
        linux/bfin/ioctls_inc0.h        \
+       linux/bfin/set_error.c          \
+       linux/bfin/set_scno.c           \
        linux/bfin/syscallent.h         \
        linux/bfin/userent.h            \
        linux/crisv10/arch_regs.c       \
@@ -370,6 +382,8 @@ EXTRA_DIST =                                \
        linux/crisv10/get_scno.c        \
        linux/crisv10/get_syscall_args.c        \
        linux/crisv10/get_syscall_result.c      \
+       linux/crisv10/set_error.c       \
+       linux/crisv10/set_scno.c        \
        linux/crisv10/syscallent.h      \
        linux/crisv10/userent.h         \
        linux/crisv32/arch_regs.c       \
@@ -378,6 +392,8 @@ EXTRA_DIST =                                \
        linux/crisv32/get_scno.c        \
        linux/crisv32/get_syscall_args.c        \
        linux/crisv32/get_syscall_result.c      \
+       linux/crisv32/set_error.c       \
+       linux/crisv32/set_scno.c        \
        linux/crisv32/syscallent.h      \
        linux/crisv32/userent.h         \
        linux/dummy.h                   \
@@ -392,6 +408,8 @@ EXTRA_DIST =                                \
        linux/hppa/get_syscall_result.c \
        linux/hppa/ioctls_arch0.h       \
        linux/hppa/ioctls_inc0.h        \
+       linux/hppa/set_error.c          \
+       linux/hppa/set_scno.c           \
        linux/hppa/signalent.h          \
        linux/hppa/syscallent.h         \
        linux/i386/arch_regs.c          \
@@ -402,6 +420,8 @@ EXTRA_DIST =                                \
        linux/i386/get_syscall_args.c   \
        linux/i386/ioctls_arch0.h       \
        linux/i386/ioctls_inc0.h        \
+       linux/i386/set_error.c          \
+       linux/i386/set_scno.c           \
        linux/i386/syscallent.h         \
        linux/i386/userent.h            \
        linux/i386/userent0.h           \
@@ -414,6 +434,8 @@ EXTRA_DIST =                                \
        linux/ia64/get_syscall_args.c   \
        linux/ia64/ioctls_arch0.h       \
        linux/ia64/ioctls_inc0.h        \
+       linux/ia64/set_error.c          \
+       linux/ia64/set_scno.c           \
        linux/ia64/syscallent.h         \
        linux/ia64/userent.h            \
        linux/inet_diag.h               \
@@ -425,6 +447,8 @@ EXTRA_DIST =                                \
        linux/m68k/get_syscall_args.c   \
        linux/m68k/ioctls_arch0.h       \
        linux/m68k/ioctls_inc0.h        \
+       linux/m68k/set_error.c          \
+       linux/m68k/set_scno.c           \
        linux/m68k/syscallent.h         \
        linux/m68k/userent.h            \
        linux/metag/arch_regs.c         \
@@ -433,6 +457,8 @@ EXTRA_DIST =                                \
        linux/metag/get_syscall_args.c  \
        linux/metag/ioctls_arch0.h      \
        linux/metag/ioctls_inc0.h       \
+       linux/metag/set_error.c         \
+       linux/metag/set_scno.c          \
        linux/metag/syscallent.h        \
        linux/microblaze/arch_regs.c    \
        linux/microblaze/arch_sigreturn.c       \
@@ -442,6 +468,8 @@ EXTRA_DIST =                                \
        linux/microblaze/get_syscall_result.c   \
        linux/microblaze/ioctls_arch0.h \
        linux/microblaze/ioctls_inc0.h  \
+       linux/microblaze/set_error.c    \
+       linux/microblaze/set_scno.c     \
        linux/microblaze/syscallent.h   \
        linux/microblaze/userent.h      \
        linux/mips/arch_getrval2.c      \
@@ -455,6 +483,8 @@ EXTRA_DIST =                                \
        linux/mips/get_syscall_args.c   \
        linux/mips/ioctls_arch0.h       \
        linux/mips/ioctls_inc0.h        \
+       linux/mips/set_error.c          \
+       linux/mips/set_scno.c           \
        linux/mips/signalent.h          \
        linux/mips/syscallent-compat.h  \
        linux/mips/syscallent-n32.h     \
@@ -470,6 +500,8 @@ EXTRA_DIST =                                \
        linux/nios2/get_syscall_args.c  \
        linux/nios2/ioctls_arch0.h      \
        linux/nios2/ioctls_inc0.h       \
+       linux/nios2/set_error.c         \
+       linux/nios2/set_scno.c          \
        linux/nios2/syscallent.h        \
        linux/or1k/arch_regs.c          \
        linux/or1k/get_error.c          \
@@ -477,6 +509,8 @@ EXTRA_DIST =                                \
        linux/or1k/get_syscall_args.c   \
        linux/or1k/ioctls_arch0.h       \
        linux/or1k/ioctls_inc0.h        \
+       linux/or1k/set_error.c          \
+       linux/or1k/set_scno.c           \
        linux/or1k/syscallent.h         \
        linux/or1k/userent.h            \
        linux/personality.h             \
@@ -491,6 +525,8 @@ EXTRA_DIST =                                \
        linux/powerpc/getregs_old.h     \
        linux/powerpc/ioctls_arch0.h    \
        linux/powerpc/ioctls_inc0.h     \
+       linux/powerpc/set_error.c       \
+       linux/powerpc/set_scno.c        \
        linux/powerpc/syscallent.h      \
        linux/powerpc/userent.h         \
        linux/powerpc64/arch_regs.c     \
@@ -507,6 +543,8 @@ EXTRA_DIST =                                \
        linux/powerpc64/ioctls_arch1.h  \
        linux/powerpc64/ioctls_inc0.h   \
        linux/powerpc64/ioctls_inc1.h   \
+       linux/powerpc64/set_error.c     \
+       linux/powerpc64/set_scno.c      \
        linux/powerpc64/signalent1.h    \
        linux/powerpc64/syscallent.h    \
        linux/powerpc64/syscallent1.h   \
@@ -521,6 +559,8 @@ EXTRA_DIST =                                \
        linux/riscv/ioctls_arch1.h      \
        linux/riscv/ioctls_inc0.h       \
        linux/riscv/ioctls_inc1.h       \
+       linux/riscv/set_error.c         \
+       linux/riscv/set_scno.c          \
        linux/riscv/signalent1.h        \
        linux/riscv/syscallent.h        \
        linux/riscv/syscallent1.h       \
@@ -532,6 +572,8 @@ EXTRA_DIST =                                \
        linux/s390/get_syscall_args.c   \
        linux/s390/ioctls_arch0.h       \
        linux/s390/ioctls_inc0.h        \
+       linux/s390/set_error.c          \
+       linux/s390/set_scno.c           \
        linux/s390/syscallent.h         \
        linux/s390/userent.h            \
        linux/s390/userent0.h           \
@@ -544,6 +586,8 @@ EXTRA_DIST =                                \
        linux/s390x/get_syscall_args.c  \
        linux/s390x/ioctls_arch0.h      \
        linux/s390x/ioctls_inc0.h       \
+       linux/s390x/set_error.c         \
+       linux/s390x/set_scno.c          \
        linux/s390x/syscallent.h        \
        linux/s390x/userent.h           \
        linux/sh/arch_getrval2.c        \
@@ -554,6 +598,8 @@ EXTRA_DIST =                                \
        linux/sh/get_syscall_result.c   \
        linux/sh/ioctls_arch0.h         \
        linux/sh/ioctls_inc0.h          \
+       linux/sh/set_error.c            \
+       linux/sh/set_scno.c             \
        linux/sh/syscallent.h           \
        linux/sh/userent.h              \
        linux/sh/userent0.h             \
@@ -565,6 +611,8 @@ EXTRA_DIST =                                \
        linux/sh64/get_syscall_result.c \
        linux/sh64/ioctls_arch0.h       \
        linux/sh64/ioctls_inc0.h        \
+       linux/sh64/set_error.c          \
+       linux/sh64/set_scno.c           \
        linux/sh64/syscallent.h         \
        linux/sh64/userent.h            \
        linux/signalent.h               \
@@ -580,6 +628,8 @@ EXTRA_DIST =                                \
        linux/sparc/get_syscall_args.c  \
        linux/sparc/ioctls_arch0.h      \
        linux/sparc/ioctls_inc0.h       \
+       linux/sparc/set_error.c         \
+       linux/sparc/set_scno.c          \
        linux/sparc/signalent.h         \
        linux/sparc/syscallent.h        \
        linux/sparc/userent.h           \
@@ -596,6 +646,8 @@ EXTRA_DIST =                                \
        linux/sparc64/ioctls_arch1.h    \
        linux/sparc64/ioctls_inc0.h     \
        linux/sparc64/ioctls_inc1.h     \
+       linux/sparc64/set_error.c       \
+       linux/sparc64/set_scno.c        \
        linux/sparc64/signalent.h       \
        linux/sparc64/signalent1.h      \
        linux/sparc64/syscallent.h      \
@@ -614,6 +666,8 @@ EXTRA_DIST =                                \
        linux/tile/ioctls_arch1.h       \
        linux/tile/ioctls_inc0.h        \
        linux/tile/ioctls_inc1.h        \
+       linux/tile/set_error.c          \
+       linux/tile/set_scno.c           \
        linux/tile/signalent1.h         \
        linux/tile/syscallent.h         \
        linux/tile/syscallent1.h        \
@@ -633,6 +687,8 @@ EXTRA_DIST =                                \
        linux/x32/ioctls_arch1.h        \
        linux/x32/ioctls_inc0.h         \
        linux/x32/ioctls_inc1.h         \
+       linux/x32/set_error.c           \
+       linux/x32/set_scno.c            \
        linux/x32/signalent1.h          \
        linux/x32/syscallent.h          \
        linux/x32/syscallent1.h         \
@@ -654,6 +710,8 @@ EXTRA_DIST =                                \
        linux/x86_64/ioctls_inc0.h      \
        linux/x86_64/ioctls_inc1.h      \
        linux/x86_64/ioctls_inc2.h      \
+       linux/x86_64/set_error.c        \
+       linux/x86_64/set_scno.c         \
        linux/x86_64/signalent1.h       \
        linux/x86_64/signalent2.h       \
        linux/x86_64/syscallent.h       \
@@ -667,6 +725,8 @@ EXTRA_DIST =                                \
        linux/xtensa/get_syscall_result.c       \
        linux/xtensa/ioctls_arch0.h     \
        linux/xtensa/ioctls_inc0.h      \
+       linux/xtensa/set_error.c        \
+       linux/xtensa/set_scno.c         \
        linux/xtensa/syscallent.h       \
        linux/xtensa/userent.h          \
        maint/ioctls_gen.sh             \
diff --git a/linux/aarch64/set_error.c b/linux/aarch64/set_error.c
new file mode 100644 (file)
index 0000000..f1d3aca
--- /dev/null
@@ -0,0 +1,13 @@
+#define arch_set_error arm_set_error
+#include "arm/set_error.c"
+#undef arch_set_error
+
+static int
+arch_set_error(struct tcb *tcp)
+{
+       if (aarch64_io.iov_len == sizeof(arm_regs))
+               return arm_set_error(tcp);
+
+       aarch64_regs.regs[0] = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/aarch64/set_scno.c b/linux/aarch64/set_scno.c
new file mode 100644 (file)
index 0000000..70e0a17
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef NT_ARM_SYSTEM_CALL
+# define NT_ARM_SYSTEM_CALL 0x404
+#endif
+
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       unsigned int n = (uint16_t) scno;
+       const struct iovec io = {
+               .iov_base = &n,
+               .iov_len = sizeof(n)
+       };
+       int rc = ptrace(PTRACE_SETREGSET, tcp->pid, NT_ARM_SYSTEM_CALL, &io);
+       if (rc && errno != ESRCH)
+               perror_msg("arch_set_scno: NT_ARM_SYSTEM_CALL pid:%d scno:%#x",
+                          tcp->pid, n);
+       return rc;
+}
diff --git a/linux/alpha/set_error.c b/linux/alpha/set_error.c
new file mode 100644 (file)
index 0000000..e4e38de
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       alpha_r0 = tcp->u_error;
+       return upoke(tcp->pid, REG_R0, alpha_r0);
+}
diff --git a/linux/alpha/set_scno.c b/linux/alpha/set_scno.c
new file mode 100644 (file)
index 0000000..21c603a
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, REG_R0, scno);
+}
diff --git a/linux/arc/set_error.c b/linux/arc/set_error.c
new file mode 100644 (file)
index 0000000..3cb0a6b
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       arc_regs.scratch.r0 = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/arc/set_scno.c b/linux/arc/set_scno.c
new file mode 100644 (file)
index 0000000..afac740
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       arc_regs.scratch.r8 = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/arm/set_error.c b/linux/arm/set_error.c
new file mode 100644 (file)
index 0000000..9653d76
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       arm_regs.ARM_r0 = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/arm/set_scno.c b/linux/arm/set_scno.c
new file mode 100644 (file)
index 0000000..f99a7fb
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef PTRACE_SET_SYSCALL
+# define PTRACE_SET_SYSCALL 23
+#endif
+
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       unsigned int n = (uint16_t) scno;
+       int rc = ptrace(PTRACE_SET_SYSCALL, tcp->pid, NULL, (unsigned long) n);
+       if (rc && errno != ESRCH)
+               perror_msg("arch_set_scno: PTRACE_SET_SYSCALL pid:%d scno:%#x",
+                          tcp->pid, n);
+       return rc;
+}
diff --git a/linux/avr32/set_error.c b/linux/avr32/set_error.c
new file mode 100644 (file)
index 0000000..aeb474a
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       avr32_regs.r12 = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/avr32/set_scno.c b/linux/avr32/set_scno.c
new file mode 100644 (file)
index 0000000..1090d2f
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       avr32_regs.r8 = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/bfin/set_error.c b/linux/bfin/set_error.c
new file mode 100644 (file)
index 0000000..daa3526
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       bfin_r0 = -tcp->u_error;
+       return upoke(tcp->pid, PT_R0, bfin_r0);
+}
diff --git a/linux/bfin/set_scno.c b/linux/bfin/set_scno.c
new file mode 100644 (file)
index 0000000..235dbb3
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, PT_ORIG_P0, scno);
+}
diff --git a/linux/crisv10/set_error.c b/linux/crisv10/set_error.c
new file mode 100644 (file)
index 0000000..d99ee5f
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       cris_r10 = -tcp->u_error;
+       return upoke(tcp->pid, 4 * PT_R10, cris_r10);
+}
diff --git a/linux/crisv10/set_scno.c b/linux/crisv10/set_scno.c
new file mode 100644 (file)
index 0000000..4ccba5a
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, 4 * PT_R9, scno);
+}
diff --git a/linux/crisv32/set_error.c b/linux/crisv32/set_error.c
new file mode 100644 (file)
index 0000000..18a5ee8
--- /dev/null
@@ -0,0 +1 @@
+#include "crisv10/set_error.c"
diff --git a/linux/crisv32/set_scno.c b/linux/crisv32/set_scno.c
new file mode 100644 (file)
index 0000000..b021adf
--- /dev/null
@@ -0,0 +1 @@
+#include "crisv10/set_scno.c"
diff --git a/linux/hppa/set_error.c b/linux/hppa/set_error.c
new file mode 100644 (file)
index 0000000..6d19695
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       hppa_r28 = -tcp->u_error;
+       return upoke(tcp->pid, PT_GR28, hppa_r28);
+}
diff --git a/linux/hppa/set_scno.c b/linux/hppa/set_scno.c
new file mode 100644 (file)
index 0000000..21321a0
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, PT_GR20, scno);
+}
diff --git a/linux/i386/set_error.c b/linux/i386/set_error.c
new file mode 100644 (file)
index 0000000..fb567d8
--- /dev/null
@@ -0,0 +1,10 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       i386_regs.eax = -tcp->u_error;
+#ifdef HAVE_GETREGS_OLD
+       return upoke(tcp->pid, 4 * EAX, i386_regs.eax);
+#else
+       return set_regs(tcp->pid);
+#endif
+}
diff --git a/linux/i386/set_scno.c b/linux/i386/set_scno.c
new file mode 100644 (file)
index 0000000..1affa3a
--- /dev/null
@@ -0,0 +1,10 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+#ifdef HAVE_GETREGS_OLD
+       return upoke(tcp->pid, 4 * ORIG_EAX, scno);
+#else
+       i386_regs.orig_eax = scno;
+       return set_regs(tcp->pid);
+#endif
+}
diff --git a/linux/ia64/set_error.c b/linux/ia64/set_error.c
new file mode 100644 (file)
index 0000000..4ce79f3
--- /dev/null
@@ -0,0 +1,11 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       if (ia64_ia32mode) {
+               ia64_regs.gr[8] = -tcp->u_error;
+       } else {
+               ia64_regs.gr[8] = tcp->u_error;
+               ia64_regs.gr[10] = -1;
+       }
+       return set_regs(tcp->pid);
+}
diff --git a/linux/ia64/set_scno.c b/linux/ia64/set_scno.c
new file mode 100644 (file)
index 0000000..3450f1c
--- /dev/null
@@ -0,0 +1,10 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       if (ia64_ia32mode)
+               ia64_regs.gr[0] = scno;
+       else
+               ia64_regs.gr[15] = scno;
+
+       return set_regs(tcp->pid);
+}
diff --git a/linux/m68k/set_error.c b/linux/m68k/set_error.c
new file mode 100644 (file)
index 0000000..7e49bce
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       m68k_regs.d0 = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/m68k/set_scno.c b/linux/m68k/set_scno.c
new file mode 100644 (file)
index 0000000..f8753b3
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       m68k_regs.orig_d0 = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/metag/set_error.c b/linux/metag/set_error.c
new file mode 100644 (file)
index 0000000..9787596
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       metag_regs.dx[0][0] = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/metag/set_scno.c b/linux/metag/set_scno.c
new file mode 100644 (file)
index 0000000..72198d6
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       metag_regs.dx[0][1] = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/microblaze/set_error.c b/linux/microblaze/set_error.c
new file mode 100644 (file)
index 0000000..98c5419
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       microblaze_r3 = -tcp->u_error;
+       return upoke(tcp->pid, 3 * 4, microblaze_r3);
+}
diff --git a/linux/microblaze/set_scno.c b/linux/microblaze/set_scno.c
new file mode 100644 (file)
index 0000000..0f7ce9e
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, 0, scno);
+}
diff --git a/linux/mips/set_error.c b/linux/mips/set_error.c
new file mode 100644 (file)
index 0000000..8c8845f
--- /dev/null
@@ -0,0 +1,7 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       mips_REG_V0 = tcp->u_error;
+       mips_REG_A3 = -1;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/mips/set_scno.c b/linux/mips/set_scno.c
new file mode 100644 (file)
index 0000000..fc7a63b
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       mips_REG_V0 = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/nios2/set_error.c b/linux/nios2/set_error.c
new file mode 100644 (file)
index 0000000..e09b255
--- /dev/null
@@ -0,0 +1,7 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       nios2_regs.regs[7] = 1;
+       nios2_regs.regs[2] = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/nios2/set_scno.c b/linux/nios2/set_scno.c
new file mode 100644 (file)
index 0000000..e8e06be
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       nios2_regs.regs[2] = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/or1k/set_error.c b/linux/or1k/set_error.c
new file mode 100644 (file)
index 0000000..d532679
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       or1k_regs.gpr[11] = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/or1k/set_scno.c b/linux/or1k/set_scno.c
new file mode 100644 (file)
index 0000000..5cf7672
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       or1k_regs.gpr[11] = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/powerpc/set_error.c b/linux/powerpc/set_error.c
new file mode 100644 (file)
index 0000000..fb18f17
--- /dev/null
@@ -0,0 +1,10 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       ppc_regs.gpr[3] = tcp->u_error;
+#ifdef HAVE_GETREGS_OLD
+       return upoke(tcp->pid, sizeof(long) * (PT_R0 + 3), ppc_regs.gpr[3]);
+#else
+       return set_regs(tcp->pid);
+#endif
+}
diff --git a/linux/powerpc/set_scno.c b/linux/powerpc/set_scno.c
new file mode 100644 (file)
index 0000000..9c1acd0
--- /dev/null
@@ -0,0 +1,10 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+#ifdef HAVE_GETREGS_OLD
+       return upoke(tcp->pid, sizeof(long) * PT_R0, scno);
+#else
+       ppc_regs.gpr[0] = scno;
+       return set_regs(tcp->pid);
+#endif
+}
diff --git a/linux/powerpc64/set_error.c b/linux/powerpc64/set_error.c
new file mode 100644 (file)
index 0000000..b8dc768
--- /dev/null
@@ -0,0 +1 @@
+#include "powerpc/set_error.c"
diff --git a/linux/powerpc64/set_scno.c b/linux/powerpc64/set_scno.c
new file mode 100644 (file)
index 0000000..c23bb83
--- /dev/null
@@ -0,0 +1 @@
+#include "powerpc/set_scno.c"
diff --git a/linux/riscv/set_error.c b/linux/riscv/set_error.c
new file mode 100644 (file)
index 0000000..54fd925
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       riscv_regs.a0 = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/riscv/set_scno.c b/linux/riscv/set_scno.c
new file mode 100644 (file)
index 0000000..4ef3d6e
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       riscv_regs.a7 = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/s390/set_error.c b/linux/s390/set_error.c
new file mode 100644 (file)
index 0000000..d691c9a
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       s390_regset.gprs[2] = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/s390/set_scno.c b/linux/s390/set_scno.c
new file mode 100644 (file)
index 0000000..e21c540
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       s390_regset.gprs[2] = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/s390x/set_error.c b/linux/s390x/set_error.c
new file mode 100644 (file)
index 0000000..737ddef
--- /dev/null
@@ -0,0 +1 @@
+#include "s390/set_error.c"
diff --git a/linux/s390x/set_scno.c b/linux/s390x/set_scno.c
new file mode 100644 (file)
index 0000000..9cea4d1
--- /dev/null
@@ -0,0 +1 @@
+#include "s390/set_scno.c"
diff --git a/linux/sh/set_error.c b/linux/sh/set_error.c
new file mode 100644 (file)
index 0000000..cd646f5
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       sh_r0 = -tcp->u_error;
+       return upoke(tcp->pid, 4 * REG_REG0, sh_r0);
+}
diff --git a/linux/sh/set_scno.c b/linux/sh/set_scno.c
new file mode 100644 (file)
index 0000000..83d603e
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, 4 * (REG_REG0 + 3), scno);
+}
diff --git a/linux/sh64/set_error.c b/linux/sh64/set_error.c
new file mode 100644 (file)
index 0000000..79c4229
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       sh64_r9 = -tcp->u_error;
+       return upoke(tcp->pid, REG_GENERAL(9), sh64_r9);
+}
diff --git a/linux/sh64/set_scno.c b/linux/sh64/set_scno.c
new file mode 100644 (file)
index 0000000..212ce2e
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, REG_SYSCALL, scno);
+}
diff --git a/linux/sparc/set_error.c b/linux/sparc/set_error.c
new file mode 100644 (file)
index 0000000..3d757a9
--- /dev/null
@@ -0,0 +1,7 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       sparc_regs.psr |= PSR_C;
+       sparc_regs.u_regs[U_REG_O0] = tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/sparc/set_scno.c b/linux/sparc/set_scno.c
new file mode 100644 (file)
index 0000000..0f8c4ac
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       sparc_regs.u_regs[U_REG_G1] = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/sparc64/set_error.c b/linux/sparc64/set_error.c
new file mode 100644 (file)
index 0000000..54a8b62
--- /dev/null
@@ -0,0 +1,7 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       sparc_regs.tstate |= 0x1100000000UL;
+       sparc_regs.u_regs[U_REG_O0] = tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/sparc64/set_scno.c b/linux/sparc64/set_scno.c
new file mode 100644 (file)
index 0000000..ae57cdf
--- /dev/null
@@ -0,0 +1 @@
+#include "sparc/set_scno.c"
diff --git a/linux/tile/set_error.c b/linux/tile/set_error.c
new file mode 100644 (file)
index 0000000..ceb9d3a
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       tile_regs.regs[0] = -tcp->u_error;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/tile/set_scno.c b/linux/tile/set_scno.c
new file mode 100644 (file)
index 0000000..5ba1963
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       tile_regs.regs[10] = scno;
+       return set_regs(tcp->pid);
+}
diff --git a/linux/x32/set_error.c b/linux/x32/set_error.c
new file mode 100644 (file)
index 0000000..66a7327
--- /dev/null
@@ -0,0 +1 @@
+#include "x86_64/set_error.c"
diff --git a/linux/x32/set_scno.c b/linux/x32/set_scno.c
new file mode 100644 (file)
index 0000000..5f7cdb4
--- /dev/null
@@ -0,0 +1 @@
+#include "x86_64/set_scno.c"
diff --git a/linux/x86_64/set_error.c b/linux/x86_64/set_error.c
new file mode 100644 (file)
index 0000000..1e2d23c
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef HAVE_GETREGS_OLD
+# define arch_set_error i386_set_error
+# include "i386/set_error.c"
+# undef arch_set_error
+#endif /* !HAVE_GETREGS_OLD */
+
+static int
+arch_set_error(struct tcb *tcp)
+{
+#ifdef HAVE_GETREGS_OLD
+       x86_64_regs.rax = - (long long) tcp->u_error;
+       return upoke(tcp->pid, 8 * RAX, x86_64_regs.rax);
+#else
+       if (x86_io.iov_len == sizeof(i386_regs))
+               return i386_set_error(tcp);
+
+       x86_64_regs.rax = - (long long) tcp->u_error;
+       return set_regs(tcp->pid);
+#endif
+}
diff --git a/linux/x86_64/set_scno.c b/linux/x86_64/set_scno.c
new file mode 100644 (file)
index 0000000..af1910b
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef HAVE_GETREGS_OLD
+# define arch_set_scno i386_set_scno
+# include "i386/set_scno.c"
+# undef arch_set_scno
+#endif /* !HAVE_GETREGS_OLD */
+
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+#ifdef HAVE_GETREGS_OLD
+       return upoke(tcp->pid, 8 * ORIG_RAX, scno);
+#else
+       if (x86_io.iov_len == sizeof(i386_regs))
+               return i386_set_scno(tcp, scno);
+
+       x86_64_regs.orig_rax = scno;
+       return set_regs(tcp->pid);
+#endif
+}
diff --git a/linux/xtensa/set_error.c b/linux/xtensa/set_error.c
new file mode 100644 (file)
index 0000000..d61b04e
--- /dev/null
@@ -0,0 +1,6 @@
+static int
+arch_set_error(struct tcb *tcp)
+{
+       xtensa_a2 = -tcp->u_error;
+       return upoke(tcp->pid, REG_A_BASE + 2, xtensa_a2);
+}
diff --git a/linux/xtensa/set_scno.c b/linux/xtensa/set_scno.c
new file mode 100644 (file)
index 0000000..532814f
--- /dev/null
@@ -0,0 +1,5 @@
+static int
+arch_set_scno(struct tcb *tcp, long scno)
+{
+       return upoke(tcp->pid, SYSCALL_NR, scno);
+}