diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp index dea7a0c4b0..f1f208179f 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -7,14 +7,16 @@ */ #include +#include +#include #include +#include #include +#include #include "dynarmic/backend/exception_handler.h" #include "dynarmic/common/assert.h" #include "dynarmic/common/context.h" -#include #include "dynarmic/common/common_types.h" - #if defined(ARCHITECTURE_x86_64) # include "dynarmic/backend/x64/block_of_code.h" #elif defined(ARCHITECTURE_arm64) @@ -111,68 +113,14 @@ void RegisterHandler() { } } -SigHandler::SigHandler() { - const size_t signal_stack_size = std::max(SIGSTKSZ, 2 * 1024 * 1024); - - signal_stack_memory = std::malloc(signal_stack_size); - - stack_t signal_stack; - signal_stack.ss_sp = signal_stack_memory; - signal_stack.ss_size = signal_stack_size; - signal_stack.ss_flags = 0; - if (sigaltstack(&signal_stack, nullptr) != 0) { - fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n"); - supports_fast_mem = false; - return; - } - - struct sigaction sa; - sa.sa_handler = nullptr; - sa.sa_sigaction = &SigHandler::SigAction; - sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART; - sigemptyset(&sa.sa_mask); - if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) { - fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n"); - supports_fast_mem = false; - return; - } -#ifdef __APPLE__ - if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) { - fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n"); - supports_fast_mem = false; - return; - } -#endif -} - -SigHandler::~SigHandler() { - std::free(signal_stack_memory); -} - -void SigHandler::AddCodeBlock(CodeBlockInfo cbi) { - std::lock_guard guard(code_block_infos_mutex); - if (auto const iter = FindCodeBlockInfo(cbi.code_begin); iter != code_block_infos.end()) - code_block_infos.erase(iter); - code_block_infos.push_back(cbi); -} - -void SigHandler::RemoveCodeBlock(u64 host_pc) { - std::lock_guard guard(code_block_infos_mutex); - const auto iter = FindCodeBlockInfo(host_pc); - if (iter != code_block_infos.end()) - code_block_infos.erase(iter); -} - void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { - ASSERT(sig == SIGSEGV || sig == SIGBUS); + DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS); CTX_DECLARE(raw_context); #if defined(ARCHITECTURE_x86_64) { - std::lock_guard guard(sig_handler->code_block_infos_mutex); - - const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP); - if (iter != sig_handler->code_block_infos.end()) { - FakeCall fc = iter->cb(CTX_RIP); + std::shared_lock guard(sig_handler->code_block_infos_mutex); + if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) { + FakeCall fc = iter->second.cb(CTX_RIP); CTX_RSP -= sizeof(u64); *mcl::bit_cast(CTX_RSP) = fc.ret_rip; CTX_RIP = fc.call_rip; @@ -182,10 +130,9 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP); #elif defined(ARCHITECTURE_arm64) { - std::lock_guard guard(sig_handler->code_block_infos_mutex); - const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); - if (iter != sig_handler->code_block_infos.end()) { - FakeCall fc = iter->cb(CTX_PC); + std::shared_lock guard(sig_handler->code_block_infos_mutex); + if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) { + FakeCall fc = iter->second.cb(CTX_PC); CTX_PC = fc.call_pc; return; } @@ -240,15 +187,15 @@ private: ExceptionHandler::ExceptionHandler() = default; ExceptionHandler::~ExceptionHandler() = default; -#if defined(ARCHITECTURE_x86_64) +#if defined(MCL_ARCHITECTURE_X86_64) void ExceptionHandler::Register(X64::BlockOfCode& code) { impl = std::make_unique(mcl::bit_cast(code.getCode()), code.GetTotalCodeSize()); } -#elif defined(ARCHITECTURE_arm64) +#elif defined(MCL_ARCHITECTURE_ARM64) void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) { impl = std::make_unique(mcl::bit_cast(mem.ptr()), size); } -#elif defined(ARCHITECTURE_riscv64) +#elif defined(MCL_ARCHITECTURE_RISCV) void ExceptionHandler::Register(RV64::CodeBlock& mem, std::size_t size) { impl = std::make_unique(mcl::bit_cast(mem.ptr()), size); }