Message ID | 20210706234932.356913-20-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | linux-user: Signal trampolines and vdsos | expand |
> -----Original Message----- > From: Richard Henderson <richard.henderson@linaro.org> > Sent: Tuesday, July 6, 2021 5:49 PM > To: qemu-devel@nongnu.org > Cc: laurent@vivier.eu; alex.bennee@linaro.org; Taylor Simpson > <tsimpson@quicinc.com>; Philippe Mathieu-Daudé <f4bug@amsat.org> > Subject: [PATCH v2 19/36] linux-user/hexagon: Implement setup_sigtramp > > Continue to initialize the words on the stack, as documented. > However, use the off-stack trampoline. > > Cc: Taylor Simpson <tsimpson@quicinc.com> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> > Signed-off-by: Richard Henderson <richard.henderson@linaro.org> > --- > linux-user/hexagon/target_signal.h | 2 ++ > linux-user/hexagon/signal.c | 19 +++++++++++++++++-- > 2 files changed, 19 insertions(+), 2 deletions(-) Reviewed-by: Taylor Simpson <tsimpson@quicinc.com> Tested-by: Taylor Simpson <tsimpson@quicinc.com>
diff --git a/linux-user/hexagon/target_signal.h b/linux-user/hexagon/target_signal.h index 345cf1cbb8..9e0223d322 100644 --- a/linux-user/hexagon/target_signal.h +++ b/linux-user/hexagon/target_signal.h @@ -31,4 +31,6 @@ typedef struct target_sigaltstack { #include "../generic/signal.h" +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1 + #endif /* TARGET_SIGNAL_H */ diff --git a/linux-user/hexagon/signal.c b/linux-user/hexagon/signal.c index 85eab5e943..bd0f9b1c85 100644 --- a/linux-user/hexagon/signal.c +++ b/linux-user/hexagon/signal.c @@ -161,6 +161,11 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, setup_ucontext(&frame->uc, env, set); tswap_siginfo(&frame->info, info); + /* + * The on-stack signal trampoline is no longer executed; + * however, the libgcc signal frame unwinding code checks + * for the presence of these two numeric magic values. + */ install_sigtramp(frame->tramp); env->gpr[HEX_REG_PC] = ka->_sa_handler; @@ -170,8 +175,7 @@ void setup_rt_frame(int sig, struct target_sigaction *ka, frame_addr + offsetof(struct target_rt_sigframe, info); env->gpr[HEX_REG_R02] = frame_addr + offsetof(struct target_rt_sigframe, uc); - env->gpr[HEX_REG_LR] = - frame_addr + offsetof(struct target_rt_sigframe, tramp); + env->gpr[HEX_REG_LR] = default_rt_sigreturn; return; @@ -270,3 +274,14 @@ badframe: force_sig(TARGET_SIGSEGV); return 0; } + +void setup_sigtramp(abi_ulong sigtramp_page) +{ + uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 4 * 2, 0); + assert(tramp != NULL); + + default_rt_sigreturn = sigtramp_page; + install_sigtramp(tramp); + + unlock_user(tramp, sigtramp_page, 4 * 2); +}