aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS3
-rw-r--r--bsd-user/errno_defs.h6
-rw-r--r--bsd-user/meson.build6
-rw-r--r--bsd-user/special-errno.h24
-rw-r--r--common-user/host/aarch64/safe-syscall.inc.S88
-rw-r--r--common-user/host/arm/safe-syscall.inc.S108
-rw-r--r--common-user/host/i386/safe-syscall.inc.S126
-rw-r--r--common-user/host/mips/safe-syscall.inc.S148
-rw-r--r--common-user/host/ppc64/safe-syscall.inc.S94
-rw-r--r--common-user/host/riscv/safe-syscall.inc.S79
-rw-r--r--common-user/host/s390x/safe-syscall.inc.S98
-rw-r--r--common-user/host/sparc64/safe-syscall.inc.S89
-rw-r--r--common-user/host/x86_64/safe-syscall.inc.S (renamed from linux-user/host/x86_64/safe-syscall.inc.S)42
-rw-r--r--common-user/meson.build6
-rw-r--r--common-user/safe-syscall-error.c25
-rw-r--r--common-user/safe-syscall.S (renamed from linux-user/safe-syscall.S)5
-rw-r--r--include/user/safe-syscall.h (renamed from linux-user/safe-syscall.h)37
-rw-r--r--linux-user/aarch64/cpu_loop.c4
-rw-r--r--linux-user/aarch64/signal.c4
-rw-r--r--linux-user/alpha/cpu_loop.c4
-rw-r--r--linux-user/alpha/signal.c8
-rw-r--r--linux-user/arm/cpu_loop.c4
-rw-r--r--linux-user/arm/signal.c8
-rw-r--r--linux-user/cpu_loop-common.h1
-rw-r--r--linux-user/cris/cpu_loop.c4
-rw-r--r--linux-user/cris/signal.c4
-rw-r--r--linux-user/generic/target_errno_defs.h17
-rw-r--r--linux-user/hexagon/cpu_loop.c4
-rw-r--r--linux-user/hexagon/signal.c2
-rw-r--r--linux-user/host/aarch64/hostdep.h18
-rw-r--r--linux-user/host/aarch64/safe-syscall.inc.S75
-rw-r--r--linux-user/host/arm/hostdep.h18
-rw-r--r--linux-user/host/arm/safe-syscall.inc.S90
-rw-r--r--linux-user/host/i386/hostdep.h18
-rw-r--r--linux-user/host/i386/safe-syscall.inc.S100
-rw-r--r--linux-user/host/ia64/hostdep.h15
-rw-r--r--linux-user/host/mips/hostdep.h15
-rw-r--r--linux-user/host/ppc/hostdep.h15
-rw-r--r--linux-user/host/ppc64/hostdep.h18
-rw-r--r--linux-user/host/ppc64/safe-syscall.inc.S96
-rw-r--r--linux-user/host/riscv/hostdep.h14
-rw-r--r--linux-user/host/riscv/safe-syscall.inc.S77
-rw-r--r--linux-user/host/s390/hostdep.h15
-rw-r--r--linux-user/host/s390x/hostdep.h18
-rw-r--r--linux-user/host/s390x/safe-syscall.inc.S90
-rw-r--r--linux-user/host/sparc/hostdep.h15
-rw-r--r--linux-user/host/sparc64/hostdep.h15
-rw-r--r--linux-user/host/x32/hostdep.h15
-rw-r--r--linux-user/host/x86_64/hostdep.h18
-rw-r--r--linux-user/hppa/cpu_loop.c4
-rw-r--r--linux-user/hppa/signal.c4
-rw-r--r--linux-user/i386/cpu_loop.c12
-rw-r--r--linux-user/i386/signal.c8
-rw-r--r--linux-user/m68k/cpu_loop.c4
-rw-r--r--linux-user/m68k/signal.c8
-rw-r--r--linux-user/meson.build9
-rw-r--r--linux-user/microblaze/cpu_loop.c4
-rw-r--r--linux-user/microblaze/signal.c4
-rw-r--r--linux-user/mips/cpu_loop.c4
-rw-r--r--linux-user/mips/signal.c8
-rw-r--r--linux-user/openrisc/cpu_loop.c4
-rw-r--r--linux-user/ppc/cpu_loop.c4
-rw-r--r--linux-user/ppc/signal.c10
-rw-r--r--linux-user/riscv/cpu_loop.c4
-rw-r--r--linux-user/riscv/signal.c2
-rw-r--r--linux-user/s390x/cpu_loop.c4
-rw-r--r--linux-user/s390x/signal.c8
-rw-r--r--linux-user/sh4/cpu_loop.c4
-rw-r--r--linux-user/sh4/signal.c8
-rw-r--r--linux-user/signal-common.h4
-rw-r--r--linux-user/signal.c10
-rw-r--r--linux-user/sparc/cpu_loop.c2
-rw-r--r--linux-user/sparc/signal.c8
-rw-r--r--linux-user/special-errno.h32
-rw-r--r--linux-user/syscall.c21
-rw-r--r--linux-user/thunk.c (renamed from thunk.c)0
-rw-r--r--linux-user/user-internals.h1
-rw-r--r--linux-user/xtensa/cpu_loop.c4
-rw-r--r--linux-user/xtensa/signal.c4
-rw-r--r--meson.build21
80 files changed, 1097 insertions, 930 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 9a8d1bdf72..1de6ce6e44 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3077,8 +3077,9 @@ Usermode Emulation
Overall usermode emulation
M: Riku Voipio <riku.voipio@iki.fi>
S: Maintained
-F: thunk.c
F: accel/tcg/user-exec*.c
+F: include/user/
+F: common-user/
BSD user
M: Warner Losh <imp@bsdimp.com>
diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h
index 832671354f..73cfa24b7f 100644
--- a/bsd-user/errno_defs.h
+++ b/bsd-user/errno_defs.h
@@ -151,6 +151,10 @@
/* Internal errors: */
#define TARGET_EJUSTRETURN 254 /* Just return without modifing regs */
#define TARGET_ERESTART 255 /* Restart syscall */
-#define TARGET_ERESTARTSYS TARGET_ERESTART /* Linux compat */
+
+#include "special-errno.h"
+
+_Static_assert(TARGET_ERESTART == QEMU_ERESTARTSYS,
+ "TARGET_ERESTART and QEMU_ERESTARTSYS expected to match");
#endif /* ! _ERRNO_DEFS_H_ */
diff --git a/bsd-user/meson.build b/bsd-user/meson.build
index 87885d91ed..9fcb80c3fa 100644
--- a/bsd-user/meson.build
+++ b/bsd-user/meson.build
@@ -2,6 +2,10 @@ if not have_bsd_user
subdir_done()
endif
+bsd_user_ss = ss.source_set()
+
+common_user_inc += include_directories('.')
+
bsd_user_ss.add(files(
'bsdload.c',
'elfload.c',
@@ -15,3 +19,5 @@ bsd_user_ss.add(files(
# Pull in the OS-specific build glue, if any
subdir(targetos)
+
+specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
diff --git a/bsd-user/special-errno.h b/bsd-user/special-errno.h
new file mode 100644
index 0000000000..03599d9b5a
--- /dev/null
+++ b/bsd-user/special-errno.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * QEMU internal errno values for implementing user-only POSIX.
+ *
+ * Copyright (c) 2021 Linaro, Ltd.
+ */
+
+#ifndef SPECIAL_ERRNO_H
+#define SPECIAL_ERRNO_H
+
+/*
+ * All of these are QEMU internal, not visible to the guest.
+ * They should be chosen so as to not overlap with any host
+ * or guest errno.
+ */
+
+/*
+ * This is returned when a system call should be restarted, to tell the
+ * main loop that it should wind the guest PC backwards so it will
+ * re-execute the syscall after handling any pending signals.
+ */
+#define QEMU_ERESTARTSYS 255
+
+#endif /* SPECIAL_ERRNO_H */
diff --git a/common-user/host/aarch64/safe-syscall.inc.S b/common-user/host/aarch64/safe-syscall.inc.S
new file mode 100644
index 0000000000..b8fd5b553e
--- /dev/null
+++ b/common-user/host/aarch64/safe-syscall.inc.S
@@ -0,0 +1,88 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, #function
+ .type safe_syscall_start, #function
+ .type safe_syscall_end, #function
+
+ /* This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+ .cfi_startproc
+ /* The syscall calling convention isn't the same as the
+ * C one:
+ * we enter with x0 == &signal_pending
+ * x1 == syscall number
+ * x2 ... x7, (stack) == syscall arguments
+ * and return the result in x0
+ * and the syscall instruction needs
+ * x8 == syscall number
+ * x0 ... x6 == syscall arguments
+ * and returns the result in x0
+ * Shuffle everything around appropriately.
+ */
+ mov x9, x0 /* signal_pending pointer */
+ mov x8, x1 /* syscall number */
+ mov x0, x2 /* syscall arguments */
+ mov x1, x3
+ mov x2, x4
+ mov x3, x5
+ mov x4, x6
+ mov x5, x7
+ ldr x6, [sp]
+
+ /* This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* if signal_pending is non-zero, don't do the call */
+ ldr w10, [x9]
+ cbnz w10, 2f
+ svc 0x0
+safe_syscall_end:
+
+ /* code path for having successfully executed the syscall */
+#if defined(__linux__)
+ /* Linux kernel returns (small) negative errno. */
+ cmp x0, #-4096
+ b.hi 0f
+#elif defined(__FreeBSD__)
+ /* FreeBSD kernel returns positive errno and C bit set. */
+ b.cs 1f
+#else
+#error "unsupported os"
+#endif
+ ret
+
+#if defined(__linux__)
+ /* code path setting errno */
+0: neg w0, w0
+ b safe_syscall_set_errno_tail
+#endif
+
+ /* code path when we didn't execute the syscall */
+2: mov w0, #QEMU_ERESTARTSYS
+1: b safe_syscall_set_errno_tail
+
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
diff --git a/common-user/host/arm/safe-syscall.inc.S b/common-user/host/arm/safe-syscall.inc.S
new file mode 100644
index 0000000000..bbfb89634e
--- /dev/null
+++ b/common-user/host/arm/safe-syscall.inc.S
@@ -0,0 +1,108 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, %function
+
+ .cfi_sections .debug_frame
+
+ .text
+ .syntax unified
+ .arm
+ .align 2
+
+ /* This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+ .fnstart
+ .cfi_startproc
+ mov r12, sp /* save entry stack */
+ push { r4, r5, r6, r7, r8, lr }
+ .save { r4, r5, r6, r7, r8, lr }
+ .cfi_adjust_cfa_offset 24
+ .cfi_rel_offset r4, 0
+ .cfi_rel_offset r5, 4
+ .cfi_rel_offset r6, 8
+ .cfi_rel_offset r7, 12
+ .cfi_rel_offset r8, 16
+ .cfi_rel_offset lr, 20
+
+ /* The syscall calling convention isn't the same as the C one:
+ * we enter with r0 == &signal_pending
+ * r1 == syscall number
+ * r2, r3, [sp+0] ... [sp+12] == syscall arguments
+ * and return the result in r0
+ * and the syscall instruction needs
+ * r7 == syscall number
+ * r0 ... r6 == syscall arguments
+ * and returns the result in r0
+ * Shuffle everything around appropriately.
+ * Note the 16 bytes that we pushed to save registers.
+ */
+ mov r8, r0 /* copy signal_pending */
+ mov r7, r1 /* syscall number */
+ mov r0, r2 /* syscall args */
+ mov r1, r3
+ ldm r12, { r2, r3, r4, r5, r6 }
+
+ /* This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* if signal_pending is non-zero, don't do the call */
+ ldr r12, [r8] /* signal_pending */
+ tst r12, r12
+ bne 2f
+ swi 0
+safe_syscall_end:
+
+ /* code path for having successfully executed the syscall */
+#if defined(__linux__)
+ /* Linux kernel returns (small) negative errno. */
+ cmp r0, #-4096
+ neghi r0, r0
+ bhi 1f
+#elif defined(__FreeBSD__)
+ /* FreeBSD kernel returns positive errno and C bit set. */
+ bcs 1f
+#else
+#error "unsupported os"
+#endif
+ pop { r4, r5, r6, r7, r8, pc }
+
+ /* code path when we didn't execute the syscall */
+2: mov r0, #QEMU_ERESTARTSYS
+
+ /* code path setting errno */
+1: pop { r4, r5, r6, r7, r8, lr }
+ .cfi_adjust_cfa_offset -24
+ .cfi_restore r4
+ .cfi_restore r5
+ .cfi_restore r6
+ .cfi_restore r7
+ .cfi_restore r8
+ .cfi_restore lr
+ b safe_syscall_set_errno_tail
+
+ .fnend
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
diff --git a/common-user/host/i386/safe-syscall.inc.S b/common-user/host/i386/safe-syscall.inc.S
new file mode 100644
index 0000000000..baf5400a29
--- /dev/null
+++ b/common-user/host/i386/safe-syscall.inc.S
@@ -0,0 +1,126 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, @function
+
+ /* This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+ .cfi_startproc
+ push %ebp
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset ebp, 0
+ push %esi
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset esi, 0
+ push %edi
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset edi, 0
+ push %ebx
+ .cfi_adjust_cfa_offset 4
+ .cfi_rel_offset ebx, 0
+
+ /* The syscall calling convention isn't the same as the C one:
+ * we enter with 0(%esp) == return address
+ * 4(%esp) == &signal_pending
+ * 8(%esp) == syscall number
+ * 12(%esp) ... 32(%esp) == syscall arguments
+ * and return the result in eax
+ * and the syscall instruction needs
+ * eax == syscall number
+ * ebx, ecx, edx, esi, edi, ebp == syscall arguments
+ * and returns the result in eax
+ * Shuffle everything around appropriately.
+ * Note the 16 bytes that we pushed to save registers.
+ */
+ mov 12+16(%esp), %ebx /* the syscall arguments */
+ mov 16+16(%esp), %ecx
+ mov 20+16(%esp), %edx
+ mov 24+16(%esp), %esi
+ mov 28+16(%esp), %edi
+ mov 32+16(%esp), %ebp
+
+ /* This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* if signal_pending is non-zero, don't do the call */
+ mov 4+16(%esp), %eax /* signal_pending */
+ cmpl $0, (%eax)
+ jnz 2f
+ mov 8+16(%esp), %eax /* syscall number */
+ int $0x80
+safe_syscall_end:
+
+ /* code path for having successfully executed the syscall */
+#if defined(__linux__)
+ /* Linux kernel returns (small) negative errno. */
+ cmp $-4095, %eax
+ jae 0f
+#elif defined(__FreeBSD__)
+ /* FreeBSD kernel returns positive errno and C bit set. */
+ jc 1f
+#else
+#error "unsupported os"
+#endif
+ pop %ebx
+ .cfi_remember_state
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore ebx
+ pop %edi
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore edi
+ pop %esi
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore esi
+ pop %ebp
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore ebp
+ ret
+ .cfi_restore_state
+
+#if defined(__linux__)
+0: neg %eax
+ jmp 1f
+#endif
+
+ /* code path when we didn't execute the syscall */
+2: mov $QEMU_ERESTARTSYS, %eax
+
+ /* code path setting errno */
+1: pop %ebx
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore ebx
+ pop %edi
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore edi
+ pop %esi
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore esi
+ pop %ebp
+ .cfi_adjust_cfa_offset -4
+ .cfi_restore ebp
+ jmp safe_syscall_set_errno_tail
+
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
diff --git a/common-user/host/mips/safe-syscall.inc.S b/common-user/host/mips/safe-syscall.inc.S
new file mode 100644
index 0000000000..fc75a337d1
--- /dev/null
+++ b/common-user/host/mips/safe-syscall.inc.S
@@ -0,0 +1,148 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <richard.henderson@linaro.org>
+ * Copyright (C) 2021 Linaro, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "sys/regdef.h"
+#include "sys/asm.h"
+
+ .text
+ .set nomips16
+ .set reorder
+
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_start, @function
+ .type safe_syscall_end, @function
+
+ /*
+ * This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+
+#if _MIPS_SIM == _ABIO32
+/* 8 * 4 = 32 for outgoing parameters; 1 * 4 for s0 save; 1 * 4 for align. */
+#define FRAME 40
+#define OFS_S0 32
+#else
+/* 1 * 8 for s0 save; 1 * 8 for align. */
+#define FRAME 16
+#define OFS_S0 0
+#endif
+
+
+NESTED(safe_syscall_base, FRAME, ra)
+ .cfi_startproc
+ PTR_ADDIU sp, sp, -FRAME
+ .cfi_adjust_cfa_offset FRAME
+ REG_S s0, OFS_S0(sp)
+ .cfi_rel_offset s0, OFS_S0
+#if _MIPS_SIM == _ABIO32
+ /*
+ * The syscall calling convention is nearly the same as C:
+ * we enter with a0 == &signal_pending
+ * a1 == syscall number
+ * a2, a3, stack == syscall arguments
+ * and return the result in a0
+ * and the syscall instruction needs
+ * v0 == syscall number
+ * a0 ... a3, stack == syscall arguments
+ * and returns the result in v0
+ * Shuffle everything around appropriately.
+ */
+ move s0, a0 /* signal_pending pointer */
+ move v0, a1 /* syscall number */
+ move a0, a2 /* syscall arguments */
+ move a1, a3
+ lw a2, FRAME+16(sp)
+ lw a3, FRAME+20(sp)
+ lw t4, FRAME+24(sp)
+ lw t5, FRAME+28(sp)
+ lw t6, FRAME+32(sp)
+ lw t7, FRAME+40(sp)
+ sw t4, 16(sp)
+ sw t5, 20(sp)
+ sw t6, 24(sp)
+ sw t7, 28(sp)
+#else
+ /*
+ * The syscall calling convention is nearly the same as C:
+ * we enter with a0 == &signal_pending
+ * a1 == syscall number
+ * a2 ... a7 == syscall arguments
+ * and return the result in a0
+ * and the syscall instruction needs
+ * v0 == syscall number
+ * a0 ... a5 == syscall arguments
+ * and returns the result in v0
+ * Shuffle everything around appropriately.
+ */
+ move s0, a0 /* signal_pending pointer */
+ move v0, a1 /* syscall number */
+ move a0, a2 /* syscall arguments */
+ move a1, a3
+ move a2, a4
+ move a3, a5
+ move a4, a6
+ move a5, a7
+#endif
+
+ /*
+ * This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* If signal_pending is non-zero, don't do the call */
+ lw t1, 0(s0)
+ bnez t1, 2f
+ syscall
+safe_syscall_end:
+
+ /* code path for having successfully executed the syscall */
+ REG_L s0, OFS_S0(sp)
+ PTR_ADDIU sp, sp, FRAME
+ .cfi_remember_state
+ .cfi_adjust_cfa_offset -FRAME
+ .cfi_restore s0
+ bnez a3, 1f
+ jr ra
+ .cfi_restore_state
+
+ /* code path when we didn't execute the syscall */
+2: REG_L s0, OFS_S0(sp)
+ PTR_ADDIU sp, sp, FRAME
+ .cfi_adjust_cfa_offset -FRAME
+ .cfi_restore s0
+ li v0, QEMU_ERESTARTSYS
+
+ /* code path setting errno */
+ /*
+ * We didn't setup GP on entry, optimistic of the syscall success.
+ * We must do so now to load the address of the helper, as required
+ * by the ABI, into t9.
+ *
+ * Note that SETUP_GPX and SETUP_GPX64 are themselves conditional,
+ * so we can simply let the one that's not empty succeed.
+ */
+1: USE_ALT_CP(t0)
+ SETUP_GPX(t1)
+ SETUP_GPX64(t0, t1)
+ PTR_LA t9, safe_syscall_set_errno_tail
+ jr t9
+
+ .cfi_endproc
+END(safe_syscall_base)
diff --git a/common-user/host/ppc64/safe-syscall.inc.S b/common-user/host/ppc64/safe-syscall.inc.S
new file mode 100644
index 0000000000..947a850dfd
--- /dev/null
+++ b/common-user/host/ppc64/safe-syscall.inc.S
@@ -0,0 +1,94 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, @function
+
+ .text
+
+ /* This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+#if _CALL_ELF == 2
+safe_syscall_base:
+ .cfi_startproc
+ .localentry safe_syscall_base,0
+#else
+ .section ".opd","aw"
+ .align 3
+safe_syscall_base:
+ .quad .L.safe_syscall_base,.TOC.@tocbase,0
+ .previous
+.L.safe_syscall_base:
+ .cfi_startproc
+#endif
+ /* We enter with r3 == &signal_pending
+ * r4 == syscall number
+ * r5 ... r10 == syscall arguments
+ * and return the result in r3
+ * and the syscall instruction needs
+ * r0 == syscall number
+ * r3 ... r8 == syscall arguments
+ * and returns the result in r3
+ * Shuffle everything around appropriately.
+ */
+ std 14, 16(1) /* Preserve r14 in SP+16 */
+ .cfi_offset 14, 16
+ mr 14, 3 /* signal_pending */
+ mr 0, 4 /* syscall number */
+ mr 3, 5 /* syscall arguments */
+ mr 4, 6
+ mr 5, 7
+ mr 6, 8
+ mr 7, 9
+ mr 8, 10
+
+ /* This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* if signal_pending is non-zero, don't do the call */
+ lwz 12, 0(14)
+ cmpwi 0, 12, 0
+ bne- 2f
+ sc
+safe_syscall_end:
+ /* code path when we did execute the syscall */
+ ld 14, 16(1) /* restore r14 */
+ bso- 1f
+ blr
+
+ /* code path when we didn't execute the syscall */
+2: ld 14, 16(1) /* restore r14 */
+ addi 3, 0, QEMU_ERESTARTSYS
+
+ /* code path setting errno */
+1: b safe_syscall_set_errno_tail
+ nop /* per abi, for the linker to modify */
+
+ .cfi_endproc
+
+#if _CALL_ELF == 2
+ .size safe_syscall_base, .-safe_syscall_base
+#else
+ .size safe_syscall_base, .-.L.safe_syscall_base
+ .size .L.safe_syscall_base, .-.L.safe_syscall_base
+#endif
diff --git a/common-user/host/riscv/safe-syscall.inc.S b/common-user/host/riscv/safe-syscall.inc.S
new file mode 100644
index 0000000000..dfe83c300e
--- /dev/null
+++ b/common-user/host/riscv/safe-syscall.inc.S
@@ -0,0 +1,79 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2018 Linaro, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, @function
+ .type safe_syscall_start, @function
+ .type safe_syscall_end, @function
+
+ /*
+ * This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+ .cfi_startproc
+ /*
+ * The syscall calling convention is nearly the same as C:
+ * we enter with a0 == &signal_pending
+ * a1 == syscall number
+ * a2 ... a7 == syscall arguments
+ * and return the result in a0
+ * and the syscall instruction needs
+ * a7 == syscall number
+ * a0 ... a5 == syscall arguments
+ * and returns the result in a0
+ * Shuffle everything around appropriately.
+ */
+ mv t0, a0 /* signal_pending pointer */
+ mv t1, a1 /* syscall number */
+ mv a0, a2 /* syscall arguments */
+ mv a1, a3
+ mv a2, a4
+ mv a3, a5
+ mv a4, a6
+ mv a5, a7
+ mv a7, t1
+
+ /*
+ * This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* If signal_pending is non-zero, don't do the call */
+ lw t1, 0(t0)
+ bnez t1, 2f
+ scall
+safe_syscall_end:
+ /* code path for having successfully executed the syscall */
+ li t2, -4096
+ bgtu a0, t2, 0f
+ ret
+
+ /* code path setting errno */
+0: neg a0, a0
+ j safe_syscall_set_errno_tail
+
+ /* code path when we didn't execute the syscall */
+2: li a0, QEMU_ERESTARTSYS
+ j safe_syscall_set_errno_tail
+
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
diff --git a/common-user/host/s390x/safe-syscall.inc.S b/common-user/host/s390x/safe-syscall.inc.S
new file mode 100644
index 0000000000..2ccbaa2402
--- /dev/null
+++ b/common-user/host/s390x/safe-syscall.inc.S
@@ -0,0 +1,98 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2016 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, @function
+
+ /* This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+ .cfi_startproc
+ stmg %r6,%r15,48(%r15) /* save all call-saved registers */
+ .cfi_offset %r15,-40
+ .cfi_offset %r14,-48
+ .cfi_offset %r13,-56
+ .cfi_offset %r12,-64
+ .cfi_offset %r11,-72
+ .cfi_offset %r10,-80
+ .cfi_offset %r9,-88
+ .cfi_offset %r8,-96
+ .cfi_offset %r7,-104
+ .cfi_offset %r6,-112
+ lgr %r1,%r15
+ lg %r0,8(%r15) /* load eos */
+ aghi %r15,-160
+ .cfi_adjust_cfa_offset 160
+ stg %r1,0(%r15) /* store back chain */
+ stg %r0,8(%r15) /* store eos */
+
+ /*
+ * The syscall calling convention isn't the same as the C one:
+ * we enter with r2 == &signal_pending
+ * r3 == syscall number
+ * r4, r5, r6, (stack) == syscall arguments
+ * and return the result in r2
+ * and the syscall instruction needs
+ * r1 == syscall number
+ * r2 ... r7 == syscall arguments
+ * and returns the result in r2
+ * Shuffle everything around appropriately.
+ */
+ lgr %r8,%r2 /* signal_pending pointer */
+ lgr %r1,%r3 /* syscall number */
+ lgr %r2,%r4 /* syscall args */
+ lgr %r3,%r5
+ lgr %r4,%r6
+ lmg %r5,%r7,320(%r15)
+
+ /* This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* if signal_pending is non-zero, don't do the call */
+ icm %r0,15,0(%r8)
+ jne 2f
+ svc 0
+safe_syscall_end:
+
+ /* code path for having successfully executed the syscall */
+ lg %r15,0(%r15) /* load back chain */
+ .cfi_remember_state
+ .cfi_adjust_cfa_offset -160
+ lmg %r6,%r15,48(%r15) /* load saved registers */
+
+ lghi %r0, -4095 /* check for syscall error */
+ clgr %r2, %r0
+ blr %r14 /* return on success */
+ lcr %r2, %r2 /* create positive errno */
+ jg safe_syscall_set_errno_tail
+ .cfi_restore_state
+
+ /* code path when we didn't execute the syscall */
+2: lg %r15,0(%r15) /* load back chain */
+ .cfi_adjust_cfa_offset -160
+ lmg %r6,%r15,48(%r15) /* load saved registers */
+ lghi %r2, QEMU_ERESTARTSYS
+ jg safe_syscall_set_errno_tail
+
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
diff --git a/common-user/host/sparc64/safe-syscall.inc.S b/common-user/host/sparc64/safe-syscall.inc.S
new file mode 100644
index 0000000000..a2f2b9c967
--- /dev/null
+++ b/common-user/host/sparc64/safe-syscall.inc.S
@@ -0,0 +1,89 @@
+/*
+ * safe-syscall.inc.S : host-specific assembly fragment
+ * to handle signals occurring at the same time as system calls.
+ * This is intended to be included by common-user/safe-syscall.S
+ *
+ * Written by Richard Henderson <richard.henderson@linaro.org>
+ * Copyright (C) 2021 Linaro, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+ .text
+ .balign 4
+
+ .register %g2, #scratch
+ .register %g3, #scratch
+
+ .global safe_syscall_base
+ .global safe_syscall_start
+ .global safe_syscall_end
+ .type safe_syscall_base, @function
+ .type safe_syscall_start, @function
+ .type safe_syscall_end, @function
+
+#define STACK_BIAS 2047
+#define PARAM(N) STACK_BIAS + N*8
+
+ /*
+ * This is the entry point for making a system call. The calling
+ * convention here is that of a C varargs function with the
+ * first argument an 'int *' to the signal_pending flag, the
+ * second one the system call number (as a 'long'), and all further
+ * arguments being syscall arguments (also 'long').
+ */
+safe_syscall_base:
+ .cfi_startproc
+ /*
+ * The syscall calling convention isn't the same as the C one:
+ * we enter with o0 == &signal_pending
+ * o1 == syscall number
+ * o2 ... o5, (stack) == syscall arguments
+ * and return the result in x0
+ * and the syscall instruction needs
+ * g1 == syscall number
+ * o0 ... o5 == syscall arguments
+ * and returns the result in o0
+ * Shuffle everything around appropriately.
+ */
+ mov %o0, %g2 /* signal_pending pointer */
+ mov %o1, %g1 /* syscall number */
+ mov %o2, %o0 /* syscall arguments */
+ mov %o3, %o1
+ mov %o4, %o2
+ mov %o5, %o3
+ ldx [%sp + PARAM(6)], %o4
+ ldx [%sp + PARAM(7)], %o5
+
+ /*
+ * This next sequence of code works in conjunction with the
+ * rewind_if_safe_syscall_function(). If a signal is taken
+ * and the interrupted PC is anywhere between 'safe_syscall_start'
+ * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
+ * The code sequence must therefore be able to cope with this, and
+ * the syscall instruction must be the final one in the sequence.
+ */
+safe_syscall_start:
+ /* if signal_pending is non-zero, don't do the call */
+ lduw [%g2], %g3
+ brnz,pn %g3, 2f
+ nop
+ ta 0x6d
+safe_syscall_end:
+ /* code path for having successfully executed the syscall */
+ bcs,pn %xcc, 1f
+ nop
+ ret
+ nop
+
+ /* code path when we didn't execute the syscall */
+2: set QEMU_ERESTARTSYS, %o0
+
+ /* code path setting errno */
+1: mov %o7, %g1
+ call safe_syscall_set_errno_tail
+ mov %g1, %o7
+
+ .cfi_endproc
+ .size safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/x86_64/safe-syscall.inc.S b/common-user/host/x86_64/safe-syscall.inc.S
index f36992daa3..a20927a783 100644
--- a/linux-user/host/x86_64/safe-syscall.inc.S
+++ b/common-user/host/x86_64/safe-syscall.inc.S
@@ -1,7 +1,7 @@
/*
* safe-syscall.inc.S : host-specific assembly fragment
* to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
+ * This is intended to be included by common-user/safe-syscall.S
*
* Copyright (C) 2015 Timothy Edward Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
*
@@ -19,9 +19,6 @@
* first argument an 'int *' to the signal_pending flag, the
* second one the system call number (as a 'long'), and all further
* arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
*/
safe_syscall_base:
.cfi_startproc
@@ -35,9 +32,9 @@ safe_syscall_base:
.cfi_adjust_cfa_offset 8
.cfi_rel_offset rbp, 0
- /* The syscall calling convention isn't the same as the
- * C one:
- * we enter with rdi == *signal_pending
+ /*
+ * The syscall calling convention isn't the same as the C one:
+ * we enter with rdi == &signal_pending
* rsi == syscall number
* rdx, rcx, r8, r9, (stack), (stack) == syscall arguments
* and return the result in rax
@@ -67,25 +64,42 @@ safe_syscall_base:
*/
safe_syscall_start:
/* if signal_pending is non-zero, don't do the call */
- cmpl $0, (%rbp)
- jnz 1f
+ cmpl $0, (%rbp)
+ jnz 2f
syscall
safe_syscall_end:
+
/* code path for having successfully executed the syscall */
+#if defined(__linux__)
+ /* Linux kernel returns (small) negative errno. */
+ cmp $-4095, %rax
+ jae 0f
+#elif defined(__FreeBSD__)
+ /* FreeBSD kernel returns positive errno and C bit set. */
+ jc 1f
+#else
+#error "unsupported os"
+#endif
pop %rbp
.cfi_remember_state
.cfi_def_cfa_offset 8
.cfi_restore rbp
ret
+ .cfi_restore_state
+
+#if defined(__linux__)
+0: neg %eax
+ jmp 1f
+#endif
-1:
/* code path when we didn't execute the syscall */
- .cfi_restore_state
- mov $-TARGET_ERESTARTSYS, %rax
- pop %rbp
+2: mov $QEMU_ERESTARTSYS, %eax
+
+ /* code path setting errno */
+1: pop %rbp
.cfi_def_cfa_offset 8
.cfi_restore rbp
- ret
+ jmp safe_syscall_set_errno_tail
.cfi_endproc
.size safe_syscall_base, .-safe_syscall_base
diff --git a/common-user/meson.build b/common-user/meson.build
new file mode 100644
index 0000000000..5cb42bc664
--- /dev/null
+++ b/common-user/meson.build
@@ -0,0 +1,6 @@
+common_user_inc += include_directories('host/' / host_arch)
+
+common_user_ss.add(files(
+ 'safe-syscall.S',
+ 'safe-syscall-error.c',
+))
diff --git a/common-user/safe-syscall-error.c b/common-user/safe-syscall-error.c
new file mode 100644
index 0000000000..cf74b504f8
--- /dev/null
+++ b/common-user/safe-syscall-error.c
@@ -0,0 +1,25 @@
+/*
+ * safe-syscall-error.c: errno setting fragment
+ * This is intended to be invoked by safe-syscall.S
+ *
+ * Written by Richard Henderson <rth@twiddle.net>
+ * Copyright (C) 2021 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "user/safe-syscall.h"
+
+/*
+ * This is intended to be invoked via tail-call on the error path
+ * from the assembly in host/arch/safe-syscall.inc.S. This takes
+ * care of the host specific addressing of errno.
+ * Return -1 to finalize the return value for safe_syscall_base.
+ */
+long safe_syscall_set_errno_tail(int value)
+{
+ errno = value;
+ return -1;
+}
diff --git a/linux-user/safe-syscall.S b/common-user/safe-syscall.S
index 42ea7c40ba..74f7e35694 100644
--- a/linux-user/safe-syscall.S
+++ b/common-user/safe-syscall.S
@@ -10,15 +10,12 @@
* See the COPYING file in the top-level directory.
*/
-#include "hostdep.h"
-#include "target_errno_defs.h"
+#include "special-errno.h"
/* We have the correct host directory on our include path
* so that this will pull in the right fragment for the architecture.
*/
-#ifdef HAVE_SAFE_SYSCALL
#include "safe-syscall.inc.S"
-#endif
/* We must specifically say that we're happy for the stack to not be
* executable, otherwise the toolchain will default to assuming our
diff --git a/linux-user/safe-syscall.h b/include/user/safe-syscall.h
index aaa9ffc0e2..61a04e2b5a 100644
--- a/linux-user/safe-syscall.h
+++ b/include/user/safe-syscall.h
@@ -25,10 +25,10 @@
*
* Call a system call if guest signal not pending.
* This has the same API as the libc syscall() function, except that it
- * may return -1 with errno == TARGET_ERESTARTSYS if a signal was pending.
+ * may return -1 with errno == QEMU_ERESTARTSYS if a signal was pending.
*
* Returns: the system call result, or -1 with an error code in errno
- * (Errnos are host errnos; we rely on TARGET_ERESTARTSYS not clashing
+ * (Errnos are host errnos; we rely on QEMU_ERESTARTSYS not clashing
* with any of the host errno values.)
*/
@@ -81,7 +81,7 @@
* which are only technically blocking (ie which we know in practice won't
* stay in the host kernel indefinitely) it's OK to use libc if necessary.
* You must be able to cope with backing out correctly if some safe_syscall
- * you make in the implementation returns either -TARGET_ERESTARTSYS or
+ * you make in the implementation returns either -QEMU_ERESTARTSYS or
* EINTR though.)
*
* block_signals() cannot be used for interruptible syscalls.
@@ -94,7 +94,7 @@
* handler checks the interrupted host PC against the addresse of that
* known section. If the PC is before or at the address of the syscall
* instruction then we change the PC to point at a "return
- * -TARGET_ERESTARTSYS" code path instead, and then exit the signal handler
+ * -QEMU_ERESTARTSYS" code path instead, and then exit the signal handler
* (causing the safe_syscall() call to immediately return that value).
* Then in the main.c loop if we see this magic return value we adjust
* the guest PC to wind it back to before the system call, and invoke
@@ -124,34 +124,17 @@
* need to check SA_RESTART flags in QEMU or distinguish the various
* kinds of restartability.
*/
-#ifdef HAVE_SAFE_SYSCALL
+
/* The core part of this function is implemented in assembly */
extern long safe_syscall_base(int *pending, long number, ...);
+extern long safe_syscall_set_errno_tail(int value);
+
/* These are defined by the safe-syscall.inc.S file */
extern char safe_syscall_start[];
extern char safe_syscall_end[];
-#define safe_syscall(...) \
- ({ \
- long ret_; \
- int *psp_ = &((TaskState *)thread_cpu->opaque)->signal_pending; \
- ret_ = safe_syscall_base(psp_, __VA_ARGS__); \
- if (is_error(ret_)) { \
- errno = -ret_; \
- ret_ = -1; \
- } \
- ret_; \
- })
-
-#else
-
-/*
- * Fallback for architectures which don't yet provide a safe-syscall assembly
- * fragment; note that this is racy!
- * This should go away when all host architectures have been updated.
- */
-#define safe_syscall syscall
-
-#endif
+#define safe_syscall(...) \
+ safe_syscall_base(&((TaskState *)thread_cpu->opaque)->signal_pending, \
+ __VA_ARGS__)
#endif
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index f9f3473288..1737e2ea65 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -99,9 +99,9 @@ void cpu_loop(CPUARMState *env)
env->xregs[4],
env->xregs[5],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 4;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->xregs[0] = ret;
}
break;
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
index 29c52db3f1..df9e39a4ba 100644
--- a/linux-user/aarch64/signal.c
+++ b/linux-user/aarch64/signal.c
@@ -556,12 +556,12 @@ long do_rt_sigreturn(CPUARMState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_sigreturn(CPUARMState *env)
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 4029849d5c..37c33f0ccd 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -98,11 +98,11 @@ void cpu_loop(CPUAlphaState *env)
env->ir[IR_A2], env->ir[IR_A3],
env->ir[IR_A4], env->ir[IR_A5],
0, 0);
- if (sysret == -TARGET_ERESTARTSYS) {
+ if (sysret == -QEMU_ERESTARTSYS) {
env->pc -= 4;
break;
}
- if (sysret == -TARGET_QEMU_ESIGRETURN) {
+ if (sysret == -QEMU_ESIGRETURN) {
break;
}
/* Syscall writes 0 to V0 to bypass error check, similar
diff --git a/linux-user/alpha/signal.c b/linux-user/alpha/signal.c
index bbe3dd175a..4ec42994d4 100644
--- a/linux-user/alpha/signal.c
+++ b/linux-user/alpha/signal.c
@@ -225,11 +225,11 @@ long do_sigreturn(CPUAlphaState *env)
restore_sigcontext(env, sc);
unlock_user_struct(sc, sc_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUAlphaState *env)
@@ -249,13 +249,13 @@ long do_rt_sigreturn(CPUAlphaState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 01cb6eb534..f153ab503a 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -407,9 +407,9 @@ void cpu_loop(CPUARMState *env)
env->regs[4],
env->regs[5],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->regs[15] -= env->thumb ? 2 : 4;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->regs[0] = ret;
}
}
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index df9f8e8eb2..cf99fd7b8a 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -511,12 +511,12 @@ long do_sigreturn(CPUARMState *env)
}
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUARMState *env)
@@ -546,12 +546,12 @@ long do_rt_sigreturn(CPUARMState *env)
}
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
/*
diff --git a/linux-user/cpu_loop-common.h b/linux-user/cpu_loop-common.h
index 8828af28a4..dc0042e4de 100644
--- a/linux-user/cpu_loop-common.h
+++ b/linux-user/cpu_loop-common.h
@@ -21,6 +21,7 @@
#define CPU_LOOP_COMMON_H
#include "exec/log.h"
+#include "special-errno.h"
#define EXCP_DUMP(env, fmt, ...) \
do { \
diff --git a/linux-user/cris/cpu_loop.c b/linux-user/cris/cpu_loop.c
index 0d5d268609..5213aebf55 100644
--- a/linux-user/cris/cpu_loop.c
+++ b/linux-user/cris/cpu_loop.c
@@ -50,9 +50,9 @@ void cpu_loop(CPUCRISState *env)
env->pregs[7],
env->pregs[11],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 2;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->regs[10] = ret;
}
break;
diff --git a/linux-user/cris/signal.c b/linux-user/cris/signal.c
index 7f6aca934e..4f532b2903 100644
--- a/linux-user/cris/signal.c
+++ b/linux-user/cris/signal.c
@@ -177,10 +177,10 @@ long do_sigreturn(CPUCRISState *env)
restore_sigcontext(&frame->sc, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUCRISState *env)
diff --git a/linux-user/generic/target_errno_defs.h b/linux-user/generic/target_errno_defs.h
index 17d85e0b61..c2f9d403e7 100644
--- a/linux-user/generic/target_errno_defs.h
+++ b/linux-user/generic/target_errno_defs.h
@@ -147,21 +147,4 @@
#define TARGET_ERFKILL 132 /* Operation not possible due to RF-kill */
#define TARGET_EHWPOISON 133 /* Memory page has hardware error */
-/* QEMU internal, not visible to the guest. This is returned when a
- * system call should be restarted, to tell the main loop that it
- * should wind the guest PC backwards so it will re-execute the syscall
- * after handling any pending signals. They match with the ones the guest
- * kernel uses for the same purpose.
- */
-#define TARGET_ERESTARTSYS 512 /* Restart system call (if SA_RESTART) */
-
-/* QEMU internal, not visible to the guest. This is returned by the
- * do_sigreturn() code after a successful sigreturn syscall, to indicate
- * that it has correctly set the guest registers and so the main loop
- * should not touch them. We use the value the guest would use for
- * ERESTART_NOINTR (which is kernel internal) to guarantee that we won't
- * clash with a valid guest errno now or in the future.
- */
-#define TARGET_QEMU_ESIGRETURN 513 /* Return from signal */
-
#endif
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index e47f8348d5..0d73934d31 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -55,9 +55,9 @@ void cpu_loop(CPUHexagonState *env)
env->gpr[4],
env->gpr[5],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->gpr[HEX_REG_PC] -= 4;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->gpr[0] = ret;
}
break;
diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c
index 74e61739a0..ad4e3822d5 100644
--- a/linux-user/hexagon/signal.c
+++ b/linux-user/hexagon/signal.c
@@ -268,7 +268,7 @@ long do_rt_sigreturn(CPUHexagonState *env)
target_restore_altstack(&frame->uc.uc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
diff --git a/linux-user/host/aarch64/hostdep.h b/linux-user/host/aarch64/hostdep.h
deleted file mode 100644
index 39299d798a..0000000000
--- a/linux-user/host/aarch64/hostdep.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef AARCH64_HOSTDEP_H
-#define AARCH64_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/host/aarch64/safe-syscall.inc.S b/linux-user/host/aarch64/safe-syscall.inc.S
deleted file mode 100644
index bc1f5a9792..0000000000
--- a/linux-user/host/aarch64/safe-syscall.inc.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
- .global safe_syscall_base
- .global safe_syscall_start
- .global safe_syscall_end
- .type safe_syscall_base, #function
- .type safe_syscall_start, #function
- .type safe_syscall_end, #function
-
- /* This is the entry point for making a system call. The calling
- * convention here is that of a C varargs function with the
- * first argument an 'int *' to the signal_pending flag, the
- * second one the system call number (as a 'long'), and all further
- * arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
- */
-safe_syscall_base:
- .cfi_startproc
- /* The syscall calling convention isn't the same as the
- * C one:
- * we enter with x0 == *signal_pending
- * x1 == syscall number
- * x2 ... x7, (stack) == syscall arguments
- * and return the result in x0
- * and the syscall instruction needs
- * x8 == syscall number
- * x0 ... x6 == syscall arguments
- * and returns the result in x0
- * Shuffle everything around appropriately.
- */
- mov x9, x0 /* signal_pending pointer */
- mov x8, x1 /* syscall number */
- mov x0, x2 /* syscall arguments */
- mov x1, x3
- mov x2, x4
- mov x3, x5
- mov x4, x6
- mov x5, x7
- ldr x6, [sp]
-
- /* This next sequence of code works in conjunction with the
- * rewind_if_safe_syscall_function(). If a signal is taken
- * and the interrupted PC is anywhere between 'safe_syscall_start'
- * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
- * The code sequence must therefore be able to cope with this, and
- * the syscall instruction must be the final one in the sequence.
- */
-safe_syscall_start:
- /* if signal_pending is non-zero, don't do the call */
- ldr w10, [x9]
- cbnz w10, 0f
- svc 0x0
-safe_syscall_end:
- /* code path for having successfully executed the syscall */
- ret
-
-0:
- /* code path when we didn't execute the syscall */
- mov x0, #-TARGET_ERESTARTSYS
- ret
- .cfi_endproc
-
- .size safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/arm/hostdep.h b/linux-user/host/arm/hostdep.h
deleted file mode 100644
index 86b137875a..0000000000
--- a/linux-user/host/arm/hostdep.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef ARM_HOSTDEP_H
-#define ARM_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/host/arm/safe-syscall.inc.S b/linux-user/host/arm/safe-syscall.inc.S
deleted file mode 100644
index 88c4958504..0000000000
--- a/linux-user/host/arm/safe-syscall.inc.S
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
- .global safe_syscall_base
- .global safe_syscall_start
- .global safe_syscall_end
- .type safe_syscall_base, %function
-
- .cfi_sections .debug_frame
-
- .text
- .syntax unified
- .arm
- .align 2
-
- /* This is the entry point for making a system call. The calling
- * convention here is that of a C varargs function with the
- * first argument an 'int *' to the signal_pending flag, the
- * second one the system call number (as a 'long'), and all further
- * arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
- */
-safe_syscall_base:
- .fnstart
- .cfi_startproc
- mov r12, sp /* save entry stack */
- push { r4, r5, r6, r7, r8, lr }
- .save { r4, r5, r6, r7, r8, lr }
- .cfi_adjust_cfa_offset 24
- .cfi_rel_offset r4, 0
- .cfi_rel_offset r5, 4
- .cfi_rel_offset r6, 8
- .cfi_rel_offset r7, 12
- .cfi_rel_offset r8, 16
- .cfi_rel_offset lr, 20
-
- /* The syscall calling convention isn't the same as the C one:
- * we enter with r0 == *signal_pending
- * r1 == syscall number
- * r2, r3, [sp+0] ... [sp+12] == syscall arguments
- * and return the result in r0
- * and the syscall instruction needs
- * r7 == syscall number
- * r0 ... r6 == syscall arguments
- * and returns the result in r0
- * Shuffle everything around appropriately.
- * Note the 16 bytes that we pushed to save registers.
- */
- mov r8, r0 /* copy signal_pending */
- mov r7, r1 /* syscall number */
- mov r0, r2 /* syscall args */
- mov r1, r3
- ldm r12, { r2, r3, r4, r5, r6 }
-
- /* This next sequence of code works in conjunction with the
- * rewind_if_safe_syscall_function(). If a signal is taken
- * and the interrupted PC is anywhere between 'safe_syscall_start'
- * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
- * The code sequence must therefore be able to cope with this, and
- * the syscall instruction must be the final one in the sequence.
- */
-safe_syscall_start:
- /* if signal_pending is non-zero, don't do the call */
- ldr r12, [r8] /* signal_pending */
- tst r12, r12
- bne 1f
- swi 0
-safe_syscall_end:
- /* code path for having successfully executed the syscall */
- pop { r4, r5, r6, r7, r8, pc }
-
-1:
- /* code path when we didn't execute the syscall */
- ldr r0, =-TARGET_ERESTARTSYS
- pop { r4, r5, r6, r7, r8, pc }
- .fnend
- .cfi_endproc
-
- .size safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/i386/hostdep.h b/linux-user/host/i386/hostdep.h
deleted file mode 100644
index ce7136501f..0000000000
--- a/linux-user/host/i386/hostdep.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef I386_HOSTDEP_H
-#define I386_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/host/i386/safe-syscall.inc.S b/linux-user/host/i386/safe-syscall.inc.S
deleted file mode 100644
index 9e58fc6504..0000000000
--- a/linux-user/host/i386/safe-syscall.inc.S
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
- .global safe_syscall_base
- .global safe_syscall_start
- .global safe_syscall_end
- .type safe_syscall_base, @function
-
- /* This is the entry point for making a system call. The calling
- * convention here is that of a C varargs function with the
- * first argument an 'int *' to the signal_pending flag, the
- * second one the system call number (as a 'long'), and all further
- * arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
- */
-safe_syscall_base:
- .cfi_startproc
- push %ebp
- .cfi_adjust_cfa_offset 4
- .cfi_rel_offset ebp, 0
- push %esi
- .cfi_adjust_cfa_offset 4
- .cfi_rel_offset esi, 0
- push %edi
- .cfi_adjust_cfa_offset 4
- .cfi_rel_offset edi, 0
- push %ebx
- .cfi_adjust_cfa_offset 4
- .cfi_rel_offset ebx, 0
-
- /* The syscall calling convention isn't the same as the C one:
- * we enter with 0(%esp) == return address
- * 4(%esp) == *signal_pending
- * 8(%esp) == syscall number
- * 12(%esp) ... 32(%esp) == syscall arguments
- * and return the result in eax
- * and the syscall instruction needs
- * eax == syscall number
- * ebx, ecx, edx, esi, edi, ebp == syscall arguments
- * and returns the result in eax
- * Shuffle everything around appropriately.
- * Note the 16 bytes that we pushed to save registers.
- */
- mov 12+16(%esp), %ebx /* the syscall arguments */
- mov 16+16(%esp), %ecx
- mov 20+16(%esp), %edx
- mov 24+16(%esp), %esi
- mov 28+16(%esp), %edi
- mov 32+16(%esp), %ebp
-
- /* This next sequence of code works in conjunction with the
- * rewind_if_safe_syscall_function(). If a signal is taken
- * and the interrupted PC is anywhere between 'safe_syscall_start'
- * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
- * The code sequence must therefore be able to cope with this, and
- * the syscall instruction must be the final one in the sequence.
- */
-safe_syscall_start:
- /* if signal_pending is non-zero, don't do the call */
- mov 4+16(%esp), %eax /* signal_pending */
- cmpl $0, (%eax)
- jnz 1f
- mov 8+16(%esp), %eax /* syscall number */
- int $0x80
-safe_syscall_end:
- /* code path for having successfully executed the syscall */
- pop %ebx
- .cfi_remember_state
- .cfi_adjust_cfa_offset -4
- .cfi_restore ebx
- pop %edi
- .cfi_adjust_cfa_offset -4
- .cfi_restore edi
- pop %esi
- .cfi_adjust_cfa_offset -4
- .cfi_restore esi
- pop %ebp
- .cfi_adjust_cfa_offset -4
- .cfi_restore ebp
- ret
-
-1:
- /* code path when we didn't execute the syscall */
- .cfi_restore_state
- mov $-TARGET_ERESTARTSYS, %eax
- jmp safe_syscall_end
- .cfi_endproc
-
- .size safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/ia64/hostdep.h b/linux-user/host/ia64/hostdep.h
deleted file mode 100644
index 263bf7658e..0000000000
--- a/linux-user/host/ia64/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef IA64_HOSTDEP_H
-#define IA64_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/mips/hostdep.h b/linux-user/host/mips/hostdep.h
deleted file mode 100644
index ba111d75c3..0000000000
--- a/linux-user/host/mips/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef MIPS_HOSTDEP_H
-#define MIPS_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/ppc/hostdep.h b/linux-user/host/ppc/hostdep.h
deleted file mode 100644
index 23d8bd9d47..0000000000
--- a/linux-user/host/ppc/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef PPC_HOSTDEP_H
-#define PPC_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/ppc64/hostdep.h b/linux-user/host/ppc64/hostdep.h
deleted file mode 100644
index 0c290dd904..0000000000
--- a/linux-user/host/ppc64/hostdep.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef PPC64_HOSTDEP_H
-#define PPC64_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/host/ppc64/safe-syscall.inc.S b/linux-user/host/ppc64/safe-syscall.inc.S
deleted file mode 100644
index 875133173b..0000000000
--- a/linux-user/host/ppc64/safe-syscall.inc.S
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
- .global safe_syscall_base
- .global safe_syscall_start
- .global safe_syscall_end
- .type safe_syscall_base, @function
-
- .text
-
- /* This is the entry point for making a system call. The calling
- * convention here is that of a C varargs function with the
- * first argument an 'int *' to the signal_pending flag, the
- * second one the system call number (as a 'long'), and all further
- * arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
- */
-#if _CALL_ELF == 2
-safe_syscall_base:
- .cfi_startproc
- .localentry safe_syscall_base,0
-#else
- .section ".opd","aw"
- .align 3
-safe_syscall_base:
- .quad .L.safe_syscall_base,.TOC.@tocbase,0
- .previous
-.L.safe_syscall_base:
- .cfi_startproc
-#endif
- /* We enter with r3 == *signal_pending
- * r4 == syscall number
- * r5 ... r10 == syscall arguments
- * and return the result in r3
- * and the syscall instruction needs
- * r0 == syscall number
- * r3 ... r8 == syscall arguments
- * and returns the result in r3
- * Shuffle everything around appropriately.
- */
- std 14, 16(1) /* Preserve r14 in SP+16 */
- .cfi_offset 14, 16
- mr 14, 3 /* signal_pending */
- mr 0, 4 /* syscall number */
- mr 3, 5 /* syscall arguments */
- mr 4, 6
- mr 5, 7
- mr 6, 8
- mr 7, 9
- mr 8, 10
-
- /* This next sequence of code works in conjunction with the
- * rewind_if_safe_syscall_function(). If a signal is taken
- * and the interrupted PC is anywhere between 'safe_syscall_start'
- * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
- * The code sequence must therefore be able to cope with this, and
- * the syscall instruction must be the final one in the sequence.
- */
-safe_syscall_start:
- /* if signal_pending is non-zero, don't do the call */
- lwz 12, 0(14)
- cmpwi 0, 12, 0
- bne- 0f
- sc
-safe_syscall_end:
- /* code path when we did execute the syscall */
- ld 14, 16(1) /* restore r14 to its original value */
- bnslr+
-
- /* syscall failed; return negative errno */
- neg 3, 3
- blr
-
- /* code path when we didn't execute the syscall */
-0: addi 3, 0, -TARGET_ERESTARTSYS
- ld 14, 16(1) /* restore r14 to its original value */
- blr
- .cfi_endproc
-
-#if _CALL_ELF == 2
- .size safe_syscall_base, .-safe_syscall_base
-#else
- .size safe_syscall_base, .-.L.safe_syscall_base
- .size .L.safe_syscall_base, .-.L.safe_syscall_base
-#endif
diff --git a/linux-user/host/riscv/hostdep.h b/linux-user/host/riscv/hostdep.h
deleted file mode 100644
index 7f67c22868..0000000000
--- a/linux-user/host/riscv/hostdep.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef RISCV_HOSTDEP_H
-#define RISCV_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/host/riscv/safe-syscall.inc.S b/linux-user/host/riscv/safe-syscall.inc.S
deleted file mode 100644
index 9ca3fbfd1e..0000000000
--- a/linux-user/host/riscv/safe-syscall.inc.S
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2018 Linaro, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
- .global safe_syscall_base
- .global safe_syscall_start
- .global safe_syscall_end
- .type safe_syscall_base, @function
- .type safe_syscall_start, @function
- .type safe_syscall_end, @function
-
- /*
- * This is the entry point for making a system call. The calling
- * convention here is that of a C varargs function with the
- * first argument an 'int *' to the signal_pending flag, the
- * second one the system call number (as a 'long'), and all further
- * arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
- */
-safe_syscall_base:
- .cfi_startproc
- /*
- * The syscall calling convention is nearly the same as C:
- * we enter with a0 == *signal_pending
- * a1 == syscall number
- * a2 ... a7 == syscall arguments
- * and return the result in a0
- * and the syscall instruction needs
- * a7 == syscall number
- * a0 ... a5 == syscall arguments
- * and returns the result in a0
- * Shuffle everything around appropriately.
- */
- mv t0, a0 /* signal_pending pointer */
- mv t1, a1 /* syscall number */
- mv a0, a2 /* syscall arguments */
- mv a1, a3
- mv a2, a4
- mv a3, a5
- mv a4, a6
- mv a5, a7
- mv a7, t1
-
- /*
- * This next sequence of code works in conjunction with the
- * rewind_if_safe_syscall_function(). If a signal is taken
- * and the interrupted PC is anywhere between 'safe_syscall_start'
- * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
- * The code sequence must therefore be able to cope with this, and
- * the syscall instruction must be the final one in the sequence.
- */
-safe_syscall_start:
- /* If signal_pending is non-zero, don't do the call */
- lw t1, 0(t0)
- bnez t1, 0f
- scall
-safe_syscall_end:
- /* code path for having successfully executed the syscall */
- ret
-
-0:
- /* code path when we didn't execute the syscall */
- li a0, -TARGET_ERESTARTSYS
- ret
- .cfi_endproc
-
- .size safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/s390/hostdep.h b/linux-user/host/s390/hostdep.h
deleted file mode 100644
index afcba5a16a..0000000000
--- a/linux-user/host/s390/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef S390_HOSTDEP_H
-#define S390_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/s390x/hostdep.h b/linux-user/host/s390x/hostdep.h
deleted file mode 100644
index d801145854..0000000000
--- a/linux-user/host/s390x/hostdep.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef S390X_HOSTDEP_H
-#define S390X_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/host/s390x/safe-syscall.inc.S b/linux-user/host/s390x/safe-syscall.inc.S
deleted file mode 100644
index 414b44ad38..0000000000
--- a/linux-user/host/s390x/safe-syscall.inc.S
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * safe-syscall.inc.S : host-specific assembly fragment
- * to handle signals occurring at the same time as system calls.
- * This is intended to be included by linux-user/safe-syscall.S
- *
- * Written by Richard Henderson <rth@twiddle.net>
- * Copyright (C) 2016 Red Hat, Inc.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
- .global safe_syscall_base
- .global safe_syscall_start
- .global safe_syscall_end
- .type safe_syscall_base, @function
-
- /* This is the entry point for making a system call. The calling
- * convention here is that of a C varargs function with the
- * first argument an 'int *' to the signal_pending flag, the
- * second one the system call number (as a 'long'), and all further
- * arguments being syscall arguments (also 'long').
- * We return a long which is the syscall's return value, which
- * may be negative-errno on failure. Conversion to the
- * -1-and-errno-set convention is done by the calling wrapper.
- */
-safe_syscall_base:
- .cfi_startproc
- stmg %r6,%r15,48(%r15) /* save all call-saved registers */
- .cfi_offset %r15,-40
- .cfi_offset %r14,-48
- .cfi_offset %r13,-56
- .cfi_offset %r12,-64
- .cfi_offset %r11,-72
- .cfi_offset %r10,-80
- .cfi_offset %r9,-88
- .cfi_offset %r8,-96
- .cfi_offset %r7,-104
- .cfi_offset %r6,-112
- lgr %r1,%r15
- lg %r0,8(%r15) /* load eos */
- aghi %r15,-160
- .cfi_adjust_cfa_offset 160
- stg %r1,0(%r15) /* store back chain */
- stg %r0,8(%r15) /* store eos */
-
- /* The syscall calling convention isn't the same as the
- * C one:
- * we enter with r2 == *signal_pending
- * r3 == syscall number
- * r4, r5, r6, (stack) == syscall arguments
- * and return the result in r2
- * and the syscall instruction needs
- * r1 == syscall number
- * r2 ... r7 == syscall arguments
- * and returns the result in r2
- * Shuffle everything around appropriately.
- */
- lgr %r8,%r2 /* signal_pending pointer */
- lgr %r1,%r3 /* syscall number */
- lgr %r2,%r4 /* syscall args */
- lgr %r3,%r5
- lgr %r4,%r6
- lmg %r5,%r7,320(%r15)
-
- /* This next sequence of code works in conjunction with the
- * rewind_if_safe_syscall_function(). If a signal is taken
- * and the interrupted PC is anywhere between 'safe_syscall_start'
- * and 'safe_syscall_end' then we rewind it to 'safe_syscall_start'.
- * The code sequence must therefore be able to cope with this, and
- * the syscall instruction must be the final one in the sequence.
- */
-safe_syscall_start:
- /* if signal_pending is non-zero, don't do the call */
- icm %r0,15,0(%r8)
- jne 2f
- svc 0
-safe_syscall_end:
-
-1: lg %r15,0(%r15) /* load back chain */
- .cfi_remember_state
- .cfi_adjust_cfa_offset -160
- lmg %r6,%r15,48(%r15) /* load saved registers */
- br %r14
- .cfi_restore_state
-2: lghi %r2, -TARGET_ERESTARTSYS
- j 1b
- .cfi_endproc
-
- .size safe_syscall_base, .-safe_syscall_base
diff --git a/linux-user/host/sparc/hostdep.h b/linux-user/host/sparc/hostdep.h
deleted file mode 100644
index 391ad923cf..0000000000
--- a/linux-user/host/sparc/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef SPARC_HOSTDEP_H
-#define SPARC_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/sparc64/hostdep.h b/linux-user/host/sparc64/hostdep.h
deleted file mode 100644
index ce3968fca0..0000000000
--- a/linux-user/host/sparc64/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef SPARC64_HOSTDEP_H
-#define SPARC64_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/x32/hostdep.h b/linux-user/host/x32/hostdep.h
deleted file mode 100644
index 2c2d6d37da..0000000000
--- a/linux-user/host/x32/hostdep.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef X32_HOSTDEP_H
-#define X32_HOSTDEP_H
-
-#endif
diff --git a/linux-user/host/x86_64/hostdep.h b/linux-user/host/x86_64/hostdep.h
deleted file mode 100644
index 9c62bd26bd..0000000000
--- a/linux-user/host/x86_64/hostdep.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * hostdep.h : things which are dependent on the host architecture
- *
- * * Written by Peter Maydell <peter.maydell@linaro.org>
- *
- * Copyright (C) 2016 Linaro Limited
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-
-#ifndef X86_64_HOSTDEP_H
-#define X86_64_HOSTDEP_H
-
-/* We have a safe-syscall.inc.S */
-#define HAVE_SAFE_SYSCALL
-
-#endif
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 375576c8f0..a47a63176b 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -133,8 +133,8 @@ void cpu_loop(CPUHPPAState *env)
env->iaoq_f = env->gr[31];
env->iaoq_b = env->gr[31] + 4;
break;
- case -TARGET_ERESTARTSYS:
- case -TARGET_QEMU_ESIGRETURN:
+ case -QEMU_ERESTARTSYS:
+ case -QEMU_ESIGRETURN:
break;
}
break;
diff --git a/linux-user/hppa/signal.c b/linux-user/hppa/signal.c
index c2fbc26ebb..962f551c04 100644
--- a/linux-user/hppa/signal.c
+++ b/linux-user/hppa/signal.c
@@ -191,9 +191,9 @@ long do_rt_sigreturn(CPUArchState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index f6a1cc632b..9aaae93e2f 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -180,8 +180,8 @@ static void emulate_vsyscall(CPUX86State *env)
ret = do_syscall(env, syscall, env->regs[R_EDI], env->regs[R_ESI],
env->regs[R_EDX], env->regs[10], env->regs[8],
env->regs[9], 0, 0);
- g_assert(ret != -TARGET_ERESTARTSYS);
- g_assert(ret != -TARGET_QEMU_ESIGRETURN);
+ g_assert(ret != -QEMU_ERESTARTSYS);
+ g_assert(ret != -QEMU_ESIGRETURN);
if (ret == -TARGET_EFAULT) {
goto sigsegv;
}
@@ -223,9 +223,9 @@ void cpu_loop(CPUX86State *env)
env->regs[R_EDI],
env->regs[R_EBP],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->eip -= 2;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->regs[R_EAX] = ret;
}
break;
@@ -241,9 +241,9 @@ void cpu_loop(CPUX86State *env)
env->regs[8],
env->regs[9],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->eip -= 2;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->regs[R_EAX] = ret;
}
break;
diff --git a/linux-user/i386/signal.c b/linux-user/i386/signal.c
index 433efa3d69..4372621a4d 100644
--- a/linux-user/i386/signal.c
+++ b/linux-user/i386/signal.c
@@ -559,12 +559,12 @@ long do_sigreturn(CPUX86State *env)
if (restore_sigcontext(env, &frame->sc))
goto badframe;
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
#endif
@@ -588,12 +588,12 @@ long do_rt_sigreturn(CPUX86State *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
#ifndef TARGET_X86_64
diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index 790bd558c3..3181594414 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -80,9 +80,9 @@ void cpu_loop(CPUM68KState *env)
env->dregs[5],
env->aregs[0],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 2;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->dregs[0] = ret;
}
}
diff --git a/linux-user/m68k/signal.c b/linux-user/m68k/signal.c
index ec33482e14..5f35354487 100644
--- a/linux-user/m68k/signal.c
+++ b/linux-user/m68k/signal.c
@@ -353,11 +353,11 @@ long do_sigreturn(CPUM68KState *env)
restore_sigcontext(env, &frame->sc);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUM68KState *env)
@@ -381,12 +381,12 @@ long do_rt_sigreturn(CPUM68KState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/linux-user/meson.build b/linux-user/meson.build
index bf62c13e37..b2f4afd5e7 100644
--- a/linux-user/meson.build
+++ b/linux-user/meson.build
@@ -2,6 +2,11 @@ if not have_linux_user
subdir_done()
endif
+linux_user_ss = ss.source_set()
+
+common_user_inc += include_directories('host/' / host_arch)
+common_user_inc += include_directories('.')
+
linux_user_ss.add(files(
'elfload.c',
'exit.c',
@@ -9,10 +14,10 @@ linux_user_ss.add(files(
'linuxload.c',
'main.c',
'mmap.c',
- 'safe-syscall.S',
'signal.c',
'strace.c',
'syscall.c',
+ 'thunk.c',
'uaccess.c',
'uname.c',
))
@@ -39,3 +44,5 @@ subdir('sh4')
subdir('sparc')
subdir('x86_64')
subdir('xtensa')
+
+specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index a94467dd2d..ff1fb26c8b 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -53,10 +53,10 @@ void cpu_loop(CPUMBState *env)
env->regs[9],
env->regs[10],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
/* Wind back to before the syscall. */
env->pc -= 4;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->regs[3] = ret;
}
/* All syscall exits result in guest r14 being equal to the
diff --git a/linux-user/microblaze/signal.c b/linux-user/microblaze/signal.c
index 8ebb6a1b7d..5188d74025 100644
--- a/linux-user/microblaze/signal.c
+++ b/linux-user/microblaze/signal.c
@@ -207,12 +207,12 @@ long do_rt_sigreturn(CPUMBState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index b735c99a24..32f9fc1c1c 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -141,11 +141,11 @@ done_syscall:
env->active_tc.gpr[8], env->active_tc.gpr[9],
env->active_tc.gpr[10], env->active_tc.gpr[11]);
# endif /* O32 */
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->active_tc.PC -= 4;
break;
}
- if (ret == -TARGET_QEMU_ESIGRETURN) {
+ if (ret == -QEMU_ESIGRETURN) {
/* Returning from a successful sigreturn syscall.
Avoid clobbering register state. */
break;
diff --git a/linux-user/mips/signal.c b/linux-user/mips/signal.c
index 8f79e405ec..58a9d7a8a3 100644
--- a/linux-user/mips/signal.c
+++ b/linux-user/mips/signal.c
@@ -281,11 +281,11 @@ long do_sigreturn(CPUMIPSState *regs)
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
regs->CP0_EPC = 0;
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
# endif /* O32 */
@@ -371,11 +371,11 @@ long do_rt_sigreturn(CPUMIPSState *env)
/* I am not sure this is right, but it seems to work
* maybe a problem with nested signals ? */
env->CP0_EPC = 0;
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index 3cfdbbf037..592901a68b 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -48,9 +48,9 @@ void cpu_loop(CPUOpenRISCState *env)
cpu_get_gpr(env, 6),
cpu_get_gpr(env, 7),
cpu_get_gpr(env, 8), 0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 4;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
cpu_set_gpr(env, 11, ret);
}
break;
diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 483e669300..30c82f2354 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -428,11 +428,11 @@ void cpu_loop(CPUPPCState *env)
ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
env->gpr[5], env->gpr[6], env->gpr[7],
env->gpr[8], 0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->nip -= 4;
break;
}
- if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {
+ if (ret == (target_ulong)(-QEMU_ESIGRETURN)) {
/* Returning from a successful sigreturn syscall.
Avoid corrupting register state. */
break;
diff --git a/linux-user/ppc/signal.c b/linux-user/ppc/signal.c
index 90a0369632..176c9d8503 100644
--- a/linux-user/ppc/signal.c
+++ b/linux-user/ppc/signal.c
@@ -591,13 +591,13 @@ long do_sigreturn(CPUPPCState *env)
unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
sigsegv:
unlock_user_struct(sr, sr_addr, 1);
unlock_user_struct(sc, sc_addr, 1);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
#endif /* !defined(TARGET_PPC64) */
@@ -646,12 +646,12 @@ long do_rt_sigreturn(CPUPPCState *env)
target_restore_altstack(&rt_sf->uc.tuc_stack, env);
unlock_user_struct(rt_sf, rt_sf_addr, 1);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
sigsegv:
unlock_user_struct(rt_sf, rt_sf_addr, 1);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
/* This syscall implements {get,set,swap}context for userland. */
@@ -704,7 +704,7 @@ abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
/* We cannot return to a partially updated context. */
force_sig(TARGET_SIGSEGV);
}
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
return 0;
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index b301dac802..0cd8985cb8 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -69,9 +69,9 @@ void cpu_loop(CPURISCVState *env)
env->gpr[xA5],
0, 0);
}
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 4;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->gpr[xA0] = ret;
}
if (cs->singlestep_enabled) {
diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index a0f9542ce3..296e39fbf0 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -188,7 +188,7 @@ long do_rt_sigreturn(CPURISCVState *env)
target_restore_altstack(&frame->uc.uc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index d089c8417e..ad0c3cd263 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -83,9 +83,9 @@ void cpu_loop(CPUS390XState *env)
ret = do_syscall(env, n, env->regs[2], env->regs[3],
env->regs[4], env->regs[5],
env->regs[6], env->regs[7], 0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->psw.addr -= env->int_svc_ilen;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->regs[2] = ret;
}
break;
diff --git a/linux-user/s390x/signal.c b/linux-user/s390x/signal.c
index 676b948147..f47713e04a 100644
--- a/linux-user/s390x/signal.c
+++ b/linux-user/s390x/signal.c
@@ -359,7 +359,7 @@ long do_sigreturn(CPUS390XState *env)
trace_user_do_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
/* Make sure that we're initializing all of target_set. */
@@ -373,7 +373,7 @@ long do_sigreturn(CPUS390XState *env)
restore_sigregs_ext(env, &frame->sregs_ext);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUS390XState *env)
@@ -385,7 +385,7 @@ long do_rt_sigreturn(CPUS390XState *env)
trace_user_do_rt_sigreturn(env, frame_addr);
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
@@ -397,7 +397,7 @@ long do_rt_sigreturn(CPUS390XState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index ac9b01840c..3290f6445c 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -50,9 +50,9 @@ void cpu_loop(CPUSH4State *env)
env->gregs[0],
env->gregs[1],
0, 0);
- if (ret == -TARGET_ERESTARTSYS) {
+ if (ret == -QEMU_ERESTARTSYS) {
env->pc -= 2;
- } else if (ret != -TARGET_QEMU_ESIGRETURN) {
+ } else if (ret != -QEMU_ESIGRETURN) {
env->gregs[0] = ret;
}
break;
diff --git a/linux-user/sh4/signal.c b/linux-user/sh4/signal.c
index faa869fb19..f6a18bc6b5 100644
--- a/linux-user/sh4/signal.c
+++ b/linux-user/sh4/signal.c
@@ -286,12 +286,12 @@ long do_sigreturn(CPUSH4State *regs)
restore_sigcontext(regs, &frame->sc);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
long do_rt_sigreturn(CPUSH4State *regs)
@@ -313,12 +313,12 @@ long do_rt_sigreturn(CPUSH4State *regs)
target_restore_altstack(&frame->uc.tuc_stack, regs);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/linux-user/signal-common.h b/linux-user/signal-common.h
index 7457f8025c..42aa479080 100644
--- a/linux-user/signal-common.h
+++ b/linux-user/signal-common.h
@@ -20,6 +20,8 @@
#ifndef SIGNAL_COMMON_H
#define SIGNAL_COMMON_H
+#include "special-errno.h"
+
/* Fallback addresses into sigtramp page. */
extern abi_ulong default_sigreturn;
extern abi_ulong default_rt_sigreturn;
@@ -76,7 +78,7 @@ abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
* Block all signals, and arrange that the signal mask is returned to
* its correct value for the guest before we resume execution of guest code.
* If this function returns non-zero, then the caller should immediately
- * return -TARGET_ERESTARTSYS to the main loop, which will take the pending
+ * return -QEMU_ERESTARTSYS to the main loop, which will take the pending
* signal and restart execution of the syscall.
* If block_signals() returns zero, then the caller can continue with
* emulation of the system call knowing that no signals can be taken
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 6d5e5b698c..510db73c34 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -31,7 +31,7 @@
#include "trace.h"
#include "signal-common.h"
#include "host-signal.h"
-#include "safe-syscall.h"
+#include "user/safe-syscall.h"
static struct target_sigaction sigact_table[TARGET_NSIG];
@@ -213,7 +213,7 @@ int block_signals(void)
/* Wrapper for sigprocmask function
* Emulates a sigprocmask in a safe way for the guest. Note that set and oldset
- * are host signal set, not guest ones. Returns -TARGET_ERESTARTSYS if
+ * are host signal set, not guest ones. Returns -QEMU_ERESTARTSYS if
* a signal was already pending and the syscall must be restarted, or
* 0 on success.
* If set is NULL, this is guaranteed not to fail.
@@ -230,7 +230,7 @@ int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
int i;
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
switch (how) {
@@ -798,7 +798,6 @@ int queue_signal(CPUArchState *env, int sig, int si_type,
/* Adjust the signal context to rewind out of safe-syscall if we're in it */
static inline void rewind_if_in_safe_syscall(void *puc)
{
-#ifdef HAVE_SAFE_SYSCALL
ucontext_t *uc = (ucontext_t *)puc;
uintptr_t pcreg = host_signal_pc(uc);
@@ -806,7 +805,6 @@ static inline void rewind_if_in_safe_syscall(void *puc)
&& pcreg < (uintptr_t)safe_syscall_end) {
host_signal_set_pc(uc, (uintptr_t)safe_syscall_start);
}
-#endif
}
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
@@ -987,7 +985,7 @@ int do_sigaction(int sig, const struct target_sigaction *act,
}
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
k = &sigact_table[sig - 1];
diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 0ba65e431c..8765ab6020 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -181,7 +181,7 @@ void cpu_loop (CPUSPARCState *env)
env->regwptr[2], env->regwptr[3],
env->regwptr[4], env->regwptr[5],
0, 0);
- if (ret == -TARGET_ERESTARTSYS || ret == -TARGET_QEMU_ESIGRETURN) {
+ if (ret == -QEMU_ERESTARTSYS || ret == -QEMU_ESIGRETURN) {
break;
}
if ((abi_ulong)ret >= (abi_ulong)(-515)) {
diff --git a/linux-user/sparc/signal.c b/linux-user/sparc/signal.c
index 23e1e761de..b501750fe0 100644
--- a/linux-user/sparc/signal.c
+++ b/linux-user/sparc/signal.c
@@ -431,12 +431,12 @@ long do_sigreturn(CPUSPARCState *env)
set_sigmask(&host_set);
unlock_user_struct(sf, sf_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
segv_and_exit:
unlock_user_struct(sf, sf_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
#else
return -TARGET_ENOSYS;
#endif
@@ -495,12 +495,12 @@ long do_rt_sigreturn(CPUSPARCState *env)
env->npc = tnpc;
unlock_user_struct(sf, sf_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
segv_and_exit:
unlock_user_struct(sf, sf_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
diff --git a/linux-user/special-errno.h b/linux-user/special-errno.h
new file mode 100644
index 0000000000..4120455baa
--- /dev/null
+++ b/linux-user/special-errno.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * QEMU internal errno values for implementing user-only POSIX.
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ * Copyright (c) 2021 Linaro, Ltd.
+ */
+
+#ifndef SPECIAL_ERRNO_H
+#define SPECIAL_ERRNO_H
+
+/*
+ * All of these are QEMU internal, not visible to the guest.
+ * They should be chosen so as to not overlap with any host
+ * or guest errno.
+ */
+
+/*
+ * This is returned when a system call should be restarted, to tell the
+ * main loop that it should wind the guest PC backwards so it will
+ * re-execute the syscall after handling any pending signals.
+ */
+#define QEMU_ERESTARTSYS 512
+
+/*
+ * This is returned after a successful sigreturn syscall, to indicate
+ * that it has correctly set the guest registers and so the main loop
+ * should not touch them.
+ */
+#define QEMU_ESIGRETURN 513
+
+#endif /* SPECIAL_ERRNO_H */
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index f1cfcc8104..56a3e17183 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -132,10 +132,11 @@
#include "signal-common.h"
#include "loader.h"
#include "user-mmap.h"
-#include "safe-syscall.h"
+#include "user/safe-syscall.h"
#include "qemu/guest-random.h"
#include "qemu/selfmap.h"
#include "user/syscall-trace.h"
+#include "special-errno.h"
#include "qapi/error.h"
#include "fd-trans.h"
#include "tcg/tcg.h"
@@ -547,10 +548,10 @@ static inline abi_long get_errno(abi_long ret)
const char *target_strerror(int err)
{
- if (err == TARGET_ERESTARTSYS) {
+ if (err == QEMU_ERESTARTSYS) {
return "To be restarted";
}
- if (err == TARGET_QEMU_ESIGRETURN) {
+ if (err == QEMU_ESIGRETURN) {
return "Successful exit from sigreturn";
}
@@ -6458,7 +6459,7 @@ static int do_fork(CPUArchState *env, unsigned int flags, abi_ulong newsp,
}
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
fork_start();
@@ -8328,7 +8329,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
Do thread termination if we have more then one thread. */
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
pthread_mutex_lock(&clone_lock);
@@ -9317,7 +9318,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
#endif
ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
SIGSET_T_SIZE));
- if (ret != -TARGET_ERESTARTSYS) {
+ if (ret != -QEMU_ERESTARTSYS) {
ts->in_sigsuspend = 1;
}
}
@@ -9336,7 +9337,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
unlock_user(p, arg1, 0);
ret = get_errno(safe_rt_sigsuspend(&ts->sigsuspend_mask,
SIGSET_T_SIZE));
- if (ret != -TARGET_ERESTARTSYS) {
+ if (ret != -QEMU_ERESTARTSYS) {
ts->in_sigsuspend = 1;
}
}
@@ -9452,13 +9453,13 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
#ifdef TARGET_NR_sigreturn
case TARGET_NR_sigreturn:
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
return do_sigreturn(cpu_env);
#endif
case TARGET_NR_rt_sigreturn:
if (block_signals()) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
return do_rt_sigreturn(cpu_env);
case TARGET_NR_sethostname:
@@ -13145,7 +13146,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
static bool flag;
flag = !flag;
if (flag) {
- return -TARGET_ERESTARTSYS;
+ return -QEMU_ERESTARTSYS;
}
}
#endif
diff --git a/thunk.c b/linux-user/thunk.c
index dac4bf11c6..dac4bf11c6 100644
--- a/thunk.c
+++ b/linux-user/thunk.c
diff --git a/linux-user/user-internals.h b/linux-user/user-internals.h
index 661612a088..f71f372829 100644
--- a/linux-user/user-internals.h
+++ b/linux-user/user-internals.h
@@ -18,7 +18,6 @@
#ifndef LINUX_USER_USER_INTERNALS_H
#define LINUX_USER_USER_INTERNALS_H
-#include "hostdep.h"
#include "exec/user/thunk.h"
#include "exec/exec-all.h"
#include "qemu/log.h"
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index a83490ab35..6bc6d6dee6 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -184,11 +184,11 @@ void cpu_loop(CPUXtensaState *env)
env->regs[2] = ret;
break;
- case -TARGET_ERESTARTSYS:
+ case -QEMU_ERESTARTSYS:
env->pc -= 3;
break;
- case -TARGET_QEMU_ESIGRETURN:
+ case -QEMU_ESIGRETURN:
break;
}
break;
diff --git a/linux-user/xtensa/signal.c b/linux-user/xtensa/signal.c
index 81572a5fc7..06d91a37ec 100644
--- a/linux-user/xtensa/signal.c
+++ b/linux-user/xtensa/signal.c
@@ -263,12 +263,12 @@ long do_rt_sigreturn(CPUXtensaState *env)
target_restore_altstack(&frame->uc.tuc_stack, env);
unlock_user_struct(frame, frame_addr, 0);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
badframe:
unlock_user_struct(frame, frame_addr, 0);
force_sig(TARGET_SIGSEGV);
- return -TARGET_QEMU_ESIGRETURN;
+ return -QEMU_ESIGRETURN;
}
void setup_sigtramp(abi_ulong sigtramp_page)
diff --git a/meson.build b/meson.build
index 2495360fd0..f45ecf31bd 100644
--- a/meson.build
+++ b/meson.build
@@ -2375,13 +2375,12 @@ genh += hxdep
authz_ss = ss.source_set()
blockdev_ss = ss.source_set()
block_ss = ss.source_set()
-bsd_user_ss = ss.source_set()
chardev_ss = ss.source_set()
common_ss = ss.source_set()
+common_user_ss = ss.source_set()
crypto_ss = ss.source_set()
hwcore_ss = ss.source_set()
io_ss = ss.source_set()
-linux_user_ss = ss.source_set()
qmp_ss = ss.source_set()
qom_ss = ss.source_set()
softmmu_ss = ss.source_set()
@@ -2622,14 +2621,24 @@ subdir('tcg')
subdir('fpu')
subdir('accel')
subdir('plugins')
+subdir('ebpf')
+
+common_user_inc = []
+
+subdir('common-user')
subdir('bsd-user')
subdir('linux-user')
-subdir('ebpf')
-specific_ss.add_all(when: 'CONFIG_BSD_USER', if_true: bsd_user_ss)
+common_user_ss = common_user_ss.apply(config_all, strict: false)
+common_user = static_library('common-user',
+ sources: common_user_ss.sources(),
+ dependencies: common_user_ss.dependencies(),
+ include_directories: common_user_inc,
+ name_suffix: 'fa',
+ build_by_default: false)
+common_user = declare_dependency(link_with: common_user)
-linux_user_ss.add(files('thunk.c'))
-specific_ss.add_all(when: 'CONFIG_LINUX_USER', if_true: linux_user_ss)
+user_ss.add(common_user)
# needed for fuzzing binaries
subdir('tests/qtest/libqos')