All instances of rewind_if_in_safe_syscall are the same, differing only in how the instruction point is fetched from the ucontext and the size of the registers. Use host_signal_pc and new host_signal_set_pc interfaces to fetch the pointer to the PC and adjust if needed. Delete all the old copies of rewind_if_in_safe_syscall.
Signed-off-by: Warner Losh <i...@bsdimp.com> --- linux-user/host/aarch64/hostdep.h | 20 -------------------- linux-user/host/arm/hostdep.h | 20 -------------------- linux-user/host/i386/hostdep.h | 20 -------------------- linux-user/host/ppc64/hostdep.h | 20 -------------------- linux-user/host/riscv/hostdep.h | 20 -------------------- linux-user/host/s390x/hostdep.h | 20 -------------------- linux-user/host/x86_64/hostdep.h | 20 -------------------- linux-user/signal.c | 18 +++++++++++++++++- 8 files changed, 17 insertions(+), 141 deletions(-) diff --git a/linux-user/host/aarch64/hostdep.h b/linux-user/host/aarch64/hostdep.h index a8d41a21ad..39299d798a 100644 --- a/linux-user/host/aarch64/hostdep.h +++ b/linux-user/host/aarch64/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - __u64 *pcreg = &uc->uc_mcontext.pc; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/arm/hostdep.h b/linux-user/host/arm/hostdep.h index 9276fe6ceb..86b137875a 100644 --- a/linux-user/host/arm/hostdep.h +++ b/linux-user/host/arm/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.arm_pc; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/i386/hostdep.h b/linux-user/host/i386/hostdep.h index 073be74d87..ce7136501f 100644 --- a/linux-user/host/i386/hostdep.h +++ b/linux-user/host/i386/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - greg_t *pcreg = &uc->uc_mcontext.gregs[REG_EIP]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/ppc64/hostdep.h b/linux-user/host/ppc64/hostdep.h index 98979ad917..0c290dd904 100644 --- a/linux-user/host/ppc64/hostdep.h +++ b/linux-user/host/ppc64/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.gp_regs[PT_NIP]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/riscv/hostdep.h b/linux-user/host/riscv/hostdep.h index 2ba07456ae..7f67c22868 100644 --- a/linux-user/host/riscv/hostdep.h +++ b/linux-user/host/riscv/hostdep.h @@ -11,24 +11,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.__gregs[REG_PC]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/s390x/hostdep.h b/linux-user/host/s390x/hostdep.h index 4f0171f36f..d801145854 100644 --- a/linux-user/host/s390x/hostdep.h +++ b/linux-user/host/s390x/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - unsigned long *pcreg = &uc->uc_mcontext.psw.addr; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/host/x86_64/hostdep.h b/linux-user/host/x86_64/hostdep.h index a4fefb5114..9c62bd26bd 100644 --- a/linux-user/host/x86_64/hostdep.h +++ b/linux-user/host/x86_64/hostdep.h @@ -15,24 +15,4 @@ /* We have a safe-syscall.inc.S */ #define HAVE_SAFE_SYSCALL -#ifndef __ASSEMBLER__ - -/* These are defined by the safe-syscall.inc.S file */ -extern char safe_syscall_start[]; -extern char safe_syscall_end[]; - -/* 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) -{ - ucontext_t *uc = puc; - greg_t *pcreg = &uc->uc_mcontext.gregs[REG_RIP]; - - if (*pcreg > (uintptr_t)safe_syscall_start - && *pcreg < (uintptr_t)safe_syscall_end) { - *pcreg = (uintptr_t)safe_syscall_start; - } -} - -#endif /* __ASSEMBLER__ */ - #endif diff --git a/linux-user/signal.c b/linux-user/signal.c index 81c45bfce9..dafdf46b93 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -793,7 +793,23 @@ int queue_signal(CPUArchState *env, int sig, int si_type, return 1; /* indicates that the signal was queued */ } -#ifndef HAVE_SAFE_SYSCALL +#ifdef HAVE_SAFE_SYSCALL +/* These are defined by the safe-syscall.inc.S file */ +extern char safe_syscall_start[]; +extern char safe_syscall_end[]; + +/* 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) +{ + ucontext_t *uc = (ucontext_t *)puc; + uintptr_t pcreg = host_signal_pc(uc); + + if (pcreg > (uintptr_t)safe_syscall_start + && pcreg < (uintptr_t)safe_syscall_end) { + host_signal_set_pc(uc, (uintptr_t)safe_syscall_start); + } +} +#else static inline void rewind_if_in_safe_syscall(void *puc) { /* Default version: never rewind */ -- 2.33.0