mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-07-27 04:13:53 -06:00
linux-user: Add cpu_loop_exit_sigsegv
This is a new interface to be provided by the os emulator for raising SIGSEGV on fault. Use the new record_sigsegv target hook. Reviewed by: Warner Losh <imp@bsdimp.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
09e94676ad
commit
72d2bbf9ff
3 changed files with 55 additions and 23 deletions
|
@ -688,9 +688,27 @@ void force_sigsegv(int oldsig)
|
|||
}
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void cpu_loop_exit_sigsegv(CPUState *cpu, target_ulong addr,
|
||||
MMUAccessType access_type, bool maperr, uintptr_t ra)
|
||||
{
|
||||
const struct TCGCPUOps *tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
|
||||
|
||||
if (tcg_ops->record_sigsegv) {
|
||||
tcg_ops->record_sigsegv(cpu, addr, access_type, maperr, ra);
|
||||
} else if (tcg_ops->tlb_fill) {
|
||||
tcg_ops->tlb_fill(cpu, addr, 0, access_type, MMU_USER_IDX, false, ra);
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
force_sig_fault(TARGET_SIGSEGV,
|
||||
maperr ? TARGET_SEGV_MAPERR : TARGET_SEGV_ACCERR,
|
||||
addr);
|
||||
cpu->exception_index = EXCP_INTERRUPT;
|
||||
cpu_loop_exit_restore(cpu, ra);
|
||||
}
|
||||
|
||||
/* abort execution with signal */
|
||||
static void QEMU_NORETURN dump_core_and_abort(int target_sig)
|
||||
{
|
||||
|
@ -806,7 +824,7 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|||
access_type = adjust_signal_pc(&pc, is_write);
|
||||
|
||||
if (host_sig == SIGSEGV) {
|
||||
const struct TCGCPUOps *tcg_ops;
|
||||
bool maperr = true;
|
||||
|
||||
if (info->si_code == SEGV_ACCERR && h2g_valid(host_addr)) {
|
||||
/* If this was a write to a TB protected page, restart. */
|
||||
|
@ -821,18 +839,14 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|||
* which means that we may get ACCERR when we want MAPERR.
|
||||
*/
|
||||
if (page_get_flags(guest_addr) & PAGE_VALID) {
|
||||
/* maperr = false; */
|
||||
maperr = false;
|
||||
} else {
|
||||
info->si_code = SEGV_MAPERR;
|
||||
}
|
||||
}
|
||||
|
||||
sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
|
||||
|
||||
tcg_ops = CPU_GET_CLASS(cpu)->tcg_ops;
|
||||
tcg_ops->tlb_fill(cpu, guest_addr, 0, access_type,
|
||||
MMU_USER_IDX, false, pc);
|
||||
g_assert_not_reached();
|
||||
cpu_loop_exit_sigsegv(cpu, guest_addr, access_type, maperr, pc);
|
||||
} else {
|
||||
sigprocmask(SIG_SETMASK, &uc->uc_sigmask, NULL);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue