[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp
From: |
Alistair Francis |
Subject: |
Re: [PATCH 16/21] linux-user/riscv: Implement setup_sigtramp |
Date: |
Fri, 18 Jun 2021 11:29:46 +1000 |
On Wed, Jun 16, 2021 at 11:22 AM Richard Henderson
<richard.henderson@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-riscv@nongnu.org
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@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
>
>