Create common rewind_if_in_safe_syscall function.
Resolves pointer type issues with uc_mcontext.pc on aarch64 between glibc and musl. -----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmGcqosdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV84JAgAjk5PmFv5ARYa6GD1 oXX+s5Z8YcBa/p7vflDQkZuStRFN8uddkp76LKhqZdaYmFQLFKvw/TIoHPrESvOW 083FSRxvOjJLvoV+X+Lb2LrzwlYhSmTVoL8oQY7dCuo/lSIZR23TEFcfkPmOb3Qd Ill+7VpYY5YYwTEBWXB4DQKwuoZ2kBb9a9T1Dyo2fakCMghlv2ZYPC+8V/TiAdhT pH8Cxcj5KOHG6CBd/0qrlGGYPaSiSxeCNZBRGj2TCwlZlW2UIBQ88ee4rqFhwfnh QS5T+LJtcTAbL7D/8DRxi2ekdBRtVK0WXpwcurwizV4Kw7wzdepXp3Ls77IMk7PU nLO/jg== =J1Ha -----END PGP SIGNATURE----- Merge tag 'pull-lu-20211123' of https://gitlab.com/rth7680/qemu into staging Create common rewind_if_in_safe_syscall function. Resolves pointer type issues with uc_mcontext.pc on aarch64 between glibc and musl. # gpg: Signature made Tue 23 Nov 2021 09:47:07 AM CET # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * tag 'pull-lu-20211123' of https://gitlab.com/rth7680/qemu: linux-user/signal.c: Create a common rewind_if_in_safe_syscall linux-user: Add host_signal_set_pc to set pc in mcontext Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
73e0f70e09
@ -35,6 +35,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.pc;
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.pc = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
struct _aarch64_ctx *hdr;
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.sc_pc;
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.sc_pc = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
uint32_t *pc = (uint32_t *)host_signal_pc(uc);
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.arm_pc;
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.arm_pc = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.gregs[REG_EIP];
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.gregs[REG_EIP] = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.pc;
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.pc = pc;
|
||||
}
|
||||
|
||||
#if defined(__misp16) || defined(__mips_micromips)
|
||||
#error "Unsupported encoding"
|
||||
#endif
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.regs->nip;
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.regs->nip = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
return uc->uc_mcontext.regs->trap != 0x400
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.__gregs[REG_PC];
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.__gregs[REG_PC] = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
/*
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.psw.addr;
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.psw.addr = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
uint16_t *pinsn = (uint16_t *)host_signal_pc(uc);
|
||||
|
@ -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
|
||||
|
@ -20,6 +20,15 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
#ifdef __arch64__
|
||||
uc->uc_mcontext.mc_gregs[MC_PC] = pc;
|
||||
#else
|
||||
uc->uc_mcontext.gregs[REG_PC] = pc;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
uint32_t insn = *(uint32_t *)host_signal_pc(uc);
|
||||
|
@ -15,6 +15,11 @@ static inline uintptr_t host_signal_pc(ucontext_t *uc)
|
||||
return uc->uc_mcontext.gregs[REG_RIP];
|
||||
}
|
||||
|
||||
static inline void host_signal_set_pc(ucontext_t *uc, uintptr_t pc)
|
||||
{
|
||||
uc->uc_mcontext.gregs[REG_RIP] = pc;
|
||||
}
|
||||
|
||||
static inline bool host_signal_write(siginfo_t *info, ucontext_t *uc)
|
||||
{
|
||||
return uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe
|
||||
|
@ -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
|
||||
|
@ -127,6 +127,9 @@
|
||||
#ifdef HAVE_SAFE_SYSCALL
|
||||
/* The core part of this function is implemented in assembly */
|
||||
extern long safe_syscall_base(int *pending, long number, ...);
|
||||
/* These are defined by the safe-syscall.inc.S file */
|
||||
extern char safe_syscall_start[];
|
||||
extern char safe_syscall_end[];
|
||||
|
||||
#define safe_syscall(...) \
|
||||
({ \
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "trace.h"
|
||||
#include "signal-common.h"
|
||||
#include "host-signal.h"
|
||||
#include "safe-syscall.h"
|
||||
|
||||
static struct target_sigaction sigact_table[TARGET_NSIG];
|
||||
|
||||
@ -793,12 +794,20 @@ int queue_signal(CPUArchState *env, int sig, int si_type,
|
||||
return 1; /* indicates that the signal was queued */
|
||||
}
|
||||
|
||||
#ifndef HAVE_SAFE_SYSCALL
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* Default version: never rewind */
|
||||
}
|
||||
#ifdef HAVE_SAFE_SYSCALL
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user