On Wed, Jun 16, 2021 at 11:22 AM Richard Henderson <richard.hender...@linaro.org> wrote: > > Create and record the rt signal trampoline. > > This fixes a bug wrt libgcc fallback unwinding. It expects > the stack pointer to point to the siginfo_t, whereas we had > inexplicably placed our private signal trampoline at the start > of the signal frame instead of the end. Now moot because we > have removed it from the stack frame entirely. > > Cc: qemu-ri...@nongnu.org > Signed-off-by: Richard Henderson <richard.hender...@linaro.org>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > linux-user/riscv/target_signal.h | 2 ++ > linux-user/riscv/signal.c | 22 +++++++++++++--------- > 2 files changed, 15 insertions(+), 9 deletions(-) > > diff --git a/linux-user/riscv/target_signal.h > b/linux-user/riscv/target_signal.h > index f113ba9a55..3e36fddc9d 100644 > --- a/linux-user/riscv/target_signal.h > +++ b/linux-user/riscv/target_signal.h > @@ -15,4 +15,6 @@ typedef struct target_sigaltstack { > > #include "../generic/signal.h" > > +#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1 > + > #endif /* RISCV_TARGET_SIGNAL_H */ > diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c > index 9405c7fd9a..4086dfa5d5 100644 > --- a/linux-user/riscv/signal.c > +++ b/linux-user/riscv/signal.c > @@ -46,7 +46,6 @@ struct target_ucontext { > }; > > struct target_rt_sigframe { > - uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */ > struct target_siginfo info; > struct target_ucontext uc; > }; > @@ -104,12 +103,6 @@ static void setup_ucontext(struct target_ucontext *uc, > setup_sigcontext(&uc->uc_mcontext, env); > } > > -static inline void install_sigtramp(uint32_t *tramp) > -{ > - __put_user(0x08b00893, tramp + 0); /* li a7, 139 = __NR_rt_sigreturn */ > - __put_user(0x00000073, tramp + 1); /* ecall */ > -} > - > void setup_rt_frame(int sig, struct target_sigaction *ka, > target_siginfo_t *info, > target_sigset_t *set, CPURISCVState *env) > @@ -126,14 +119,13 @@ void setup_rt_frame(int sig, struct target_sigaction > *ka, > > setup_ucontext(&frame->uc, env, set); > tswap_siginfo(&frame->info, info); > - install_sigtramp(frame->tramp); > > env->pc = ka->_sa_handler; > env->gpr[xSP] = frame_addr; > env->gpr[xA0] = sig; > env->gpr[xA1] = frame_addr + offsetof(struct target_rt_sigframe, info); > env->gpr[xA2] = frame_addr + offsetof(struct target_rt_sigframe, uc); > - env->gpr[xRA] = frame_addr + offsetof(struct target_rt_sigframe, tramp); > + env->gpr[xRA] = default_rt_sigreturn; > > return; > > @@ -202,3 +194,15 @@ badframe: > force_sig(TARGET_SIGSEGV); > return 0; > } > + > +void setup_sigtramp(abi_ulong sigtramp_page) > +{ > + uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0); > + assert(tramp != NULL); > + > + __put_user(0x08b00893, tramp + 0); /* li a7, 139 = __NR_rt_sigreturn */ > + __put_user(0x00000073, tramp + 1); /* ecall */ > + > + default_rt_sigreturn = sigtramp_page; > + unlock_user(tramp, sigtramp_page, 8); > +} > -- > 2.25.1 > >