diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler.h b/src/dynarmic/src/dynarmic/backend/exception_handler.h index ff116c5775..b73b9fbe34 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler.h +++ b/src/dynarmic/src/dynarmic/backend/exception_handler.h @@ -43,6 +43,7 @@ struct FakeCall { }; #elif defined(ARCHITECTURE_riscv64) struct FakeCall { + u64 call_sepc; }; #else # error "Invalid architecture" diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp index 9f508f72e5..4154fd6db4 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -140,7 +140,15 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { } fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC); #elif defined(ARCHITECTURE_riscv64) - UNREACHABLE(); + { + std::shared_lock guard(sig_handler->code_block_infos_mutex); + if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_SEPC); iter != sig_handler->code_block_infos.end()) { + FakeCall fc = iter->second.cb(CTX_SEPC); + CTX_SEPC = fc.call_sepc; + return; + } + } + fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_SEPC); #else # error "Invalid architecture" #endif diff --git a/src/dynarmic/src/dynarmic/common/context.h b/src/dynarmic/src/dynarmic/common/context.h index 941289cb94..98dc0d8780 100644 --- a/src/dynarmic/src/dynarmic/common/context.h +++ b/src/dynarmic/src/dynarmic/common/context.h @@ -118,6 +118,20 @@ # else # error "Unknown platform" # endif +#elif defined(ARCHITECTURE_riscv64) +# if defined(__FreeBSD__) +# define CTX_SEPC (mctx.mc_gpregs.gp_sepc) +# define CTX_SP (mctx.mc_gpregs.gp_sp) +# elif defined(__linux__) +# define CTX_SEPC (mctx.__gregs[REG_PC]) +# define CTX_SP (mctx.__gregs[REG_SP]) +# elif defined(__NetBSD__) +# define CTX_SEPC (mctx.__gregs[_REG_PC]) +# define CTX_SP (mctx.__gregs[_REG_SP]) +# elif defined(__OpenBSD__) +# define CTX_SEPC (ucontext->sc_sepc) +# define CTX_SP (ucontext->sc_sp) +# endif #else # error "unimplemented" #endif