mirror of https://github.com/xemu-project/xemu.git
linux-user/sparc: Implement setup_sigtramp
Create and record the two signal trampolines. Use them when the guest does not use SA_RESTORER. Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20210929130553.121567-24-richard.henderson@linaro.org> Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
parent
b9188f9ccc
commit
3f7685eaf9
|
@ -242,6 +242,12 @@ static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
|
|||
}
|
||||
|
||||
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
|
||||
static void install_sigtramp(uint32_t *tramp, int syscall)
|
||||
{
|
||||
__put_user(0x82102000u + syscall, &tramp[0]); /* mov syscall, %g1 */
|
||||
__put_user(0x91d02010u, &tramp[1]); /* t 0x10 */
|
||||
}
|
||||
|
||||
void setup_frame(int sig, struct target_sigaction *ka,
|
||||
target_sigset_t *set, CPUSPARCState *env)
|
||||
{
|
||||
|
@ -291,13 +297,9 @@ void setup_frame(int sig, struct target_sigaction *ka,
|
|||
if (ka->ka_restorer) {
|
||||
env->regwptr[WREG_O7] = ka->ka_restorer;
|
||||
} else {
|
||||
env->regwptr[WREG_O7] = sf_addr +
|
||||
offsetof(struct target_signal_frame, insns) - 2 * 4;
|
||||
|
||||
/* mov __NR_sigreturn, %g1 */
|
||||
__put_user(0x821020d8u, &sf->insns[0]);
|
||||
/* t 0x10 */
|
||||
__put_user(0x91d02010u, &sf->insns[1]);
|
||||
/* Not used, but retain for ABI compatibility. */
|
||||
install_sigtramp(sf->insns, TARGET_NR_sigreturn);
|
||||
env->regwptr[WREG_O7] = default_sigreturn;
|
||||
}
|
||||
unlock_user(sf, sf_addr, sf_size);
|
||||
}
|
||||
|
@ -358,13 +360,9 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
|||
if (ka->ka_restorer) {
|
||||
env->regwptr[WREG_O7] = ka->ka_restorer;
|
||||
} else {
|
||||
env->regwptr[WREG_O7] =
|
||||
sf_addr + offsetof(struct target_rt_signal_frame, insns) - 2 * 4;
|
||||
|
||||
/* mov __NR_rt_sigreturn, %g1 */
|
||||
__put_user(0x82102065u, &sf->insns[0]);
|
||||
/* t 0x10 */
|
||||
__put_user(0x91d02010u, &sf->insns[1]);
|
||||
/* Not used, but retain for ABI compatibility. */
|
||||
install_sigtramp(sf->insns, TARGET_NR_rt_sigreturn);
|
||||
env->regwptr[WREG_O7] = default_rt_sigreturn;
|
||||
}
|
||||
#else
|
||||
env->regwptr[WREG_O7] = ka->ka_restorer;
|
||||
|
@ -775,4 +773,18 @@ do_sigsegv:
|
|||
unlock_user_struct(ucp, ucp_addr, 1);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
}
|
||||
#else
|
||||
void setup_sigtramp(abi_ulong sigtramp_page)
|
||||
{
|
||||
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 2 * 8, 0);
|
||||
assert(tramp != NULL);
|
||||
|
||||
default_sigreturn = sigtramp_page;
|
||||
install_sigtramp(tramp, TARGET_NR_sigreturn);
|
||||
|
||||
default_rt_sigreturn = sigtramp_page + 8;
|
||||
install_sigtramp(tramp + 2, TARGET_NR_rt_sigreturn);
|
||||
|
||||
unlock_user(tramp, sigtramp_page, 2 * 8);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -69,6 +69,10 @@ typedef struct target_sigaltstack {
|
|||
|
||||
#ifdef TARGET_ABI32
|
||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
|
||||
#else
|
||||
/* For sparc64, use of KA_RESTORER is mandatory. */
|
||||
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
|
||||
#endif
|
||||
|
||||
/* bit-flags */
|
||||
|
|
Loading…
Reference in New Issue