Skip to content

Commit 3c62b5d

Browse files
rth7680vivier
authored andcommitted
linux-user/riscv: Implement setup_sigtramp
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. Reviewed-by: Alistair Francis <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Richard Henderson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Laurent Vivier <[email protected]>
1 parent c790e4e commit 3c62b5d

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

linux-user/riscv/signal.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ struct target_ucontext {
4747
};
4848

4949
struct target_rt_sigframe {
50-
uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */
5150
struct target_siginfo info;
5251
struct target_ucontext uc;
5352
};
@@ -105,12 +104,6 @@ static void setup_ucontext(struct target_ucontext *uc,
105104
setup_sigcontext(&uc->uc_mcontext, env);
106105
}
107106

108-
static inline void install_sigtramp(uint32_t *tramp)
109-
{
110-
__put_user(0x08b00893, tramp + 0); /* li a7, 139 = __NR_rt_sigreturn */
111-
__put_user(0x00000073, tramp + 1); /* ecall */
112-
}
113-
114107
void setup_rt_frame(int sig, struct target_sigaction *ka,
115108
target_siginfo_t *info,
116109
target_sigset_t *set, CPURISCVState *env)
@@ -127,14 +120,13 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
127120

128121
setup_ucontext(&frame->uc, env, set);
129122
tswap_siginfo(&frame->info, info);
130-
install_sigtramp(frame->tramp);
131123

132124
env->pc = ka->_sa_handler;
133125
env->gpr[xSP] = frame_addr;
134126
env->gpr[xA0] = sig;
135127
env->gpr[xA1] = frame_addr + offsetof(struct target_rt_sigframe, info);
136128
env->gpr[xA2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
137-
env->gpr[xRA] = frame_addr + offsetof(struct target_rt_sigframe, tramp);
129+
env->gpr[xRA] = default_rt_sigreturn;
138130

139131
return;
140132

@@ -203,3 +195,15 @@ long do_rt_sigreturn(CPURISCVState *env)
203195
force_sig(TARGET_SIGSEGV);
204196
return 0;
205197
}
198+
199+
void setup_sigtramp(abi_ulong sigtramp_page)
200+
{
201+
uint32_t *tramp = lock_user(VERIFY_WRITE, sigtramp_page, 8, 0);
202+
assert(tramp != NULL);
203+
204+
__put_user(0x08b00893, tramp + 0); /* li a7, 139 = __NR_rt_sigreturn */
205+
__put_user(0x00000073, tramp + 1); /* ecall */
206+
207+
default_rt_sigreturn = sigtramp_page;
208+
unlock_user(tramp, sigtramp_page, 8);
209+
}

linux-user/riscv/target_signal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@ typedef struct target_sigaltstack {
1515

1616
#include "../generic/signal.h"
1717

18+
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 1
19+
1820
#endif /* RISCV_TARGET_SIGNAL_H */

0 commit comments

Comments
 (0)