};
struct target_rt_sigframe {
- uint32_t tramp[2]; /* not in kernel, which uses VDSO instead */
struct target_siginfo info;
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)
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;
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);
+}