diff options
author | Liam <[email protected]> | 2023-10-05 15:01:41 -0400 |
---|---|---|
committer | merry <[email protected]> | 2023-10-08 16:24:10 +0100 |
commit | 0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378 (patch) | |
tree | 23e4119d7b2f00ea3d24e8fd8ac046af5aef1e7e | |
parent | ac643f1bee75953a0a3e07be60a1fa60aded4b6e (diff) | |
download | dynarmic-0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378.tar.gz dynarmic-0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378.zip |
exception_handler: connect installation to instance lifetime
-rw-r--r-- | src/dynarmic/backend/exception_handler_macos.cpp | 21 | ||||
-rw-r--r-- | src/dynarmic/backend/exception_handler_posix.cpp | 35 |
2 files changed, 39 insertions, 17 deletions
diff --git a/src/dynarmic/backend/exception_handler_macos.cpp b/src/dynarmic/backend/exception_handler_macos.cpp index 04144593..bac8d9c9 100644 --- a/src/dynarmic/backend/exception_handler_macos.cpp +++ b/src/dynarmic/backend/exception_handler_macos.cpp @@ -10,6 +10,7 @@ #include <functional> #include <memory> #include <mutex> +#include <optional> #include <thread> #include <vector> @@ -183,7 +184,15 @@ void MachHandler::RemoveCodeBlock(u64 rip) { code_block_infos.erase(iter); } -MachHandler mach_handler; +std::mutex handler_lock; +std::optional<MachHandler> mach_handler; + +void RegisterHandler() { + std::lock_guard<std::mutex> guard(handler_lock); + if (!mach_handler) { + mach_handler.emplace(); + } +} } // anonymous namespace @@ -224,7 +233,7 @@ mig_external kern_return_t catch_mach_exception_raise_state( dynarmic_thread_state_t ts; std::memcpy(&ts, old_state, sizeof(ts)); - kern_return_t ret = mach_handler.HandleRequest(&ts); + kern_return_t ret = mach_handler->HandleRequest(&ts); std::memcpy(new_state, &ts, sizeof(ts)); *new_stateCnt = THREAD_STATE_COUNT; @@ -234,18 +243,20 @@ mig_external kern_return_t catch_mach_exception_raise_state( struct ExceptionHandler::Impl final { Impl(u64 code_begin_, u64 code_end_) : code_begin(code_begin_) - , code_end(code_end_) {} + , code_end(code_end_) { + RegisterHandler(); + } void SetCallback(std::function<FakeCall(u64)> cb) { CodeBlockInfo cbi; cbi.code_begin = code_begin; cbi.code_end = code_end; cbi.cb = cb; - mach_handler.AddCodeBlock(cbi); + mach_handler->AddCodeBlock(cbi); } ~Impl() { - mach_handler.RemoveCodeBlock(code_begin); + mach_handler->RemoveCodeBlock(code_begin); } private: diff --git a/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/backend/exception_handler_posix.cpp index ec0b0cff..0a1c270b 100644 --- a/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/backend/exception_handler_posix.cpp @@ -19,6 +19,7 @@ #include <functional> #include <memory> #include <mutex> +#include <optional> #include <vector> #include <mcl/assert.hpp> @@ -72,7 +73,15 @@ private: static void SigAction(int sig, siginfo_t* info, void* raw_context); }; -SigHandler sig_handler; +std::mutex handler_lock; +std::optional<SigHandler> sig_handler; + +void RegisterHandler() { + std::lock_guard<std::mutex> guard(handler_lock); + if (!sig_handler) { + sig_handler.emplace(); + } +} SigHandler::SigHandler() { const size_t signal_stack_size = std::max<size_t>(SIGSTKSZ, 2 * 1024 * 1024); @@ -159,10 +168,10 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { # endif { - std::lock_guard<std::mutex> guard(sig_handler.code_block_infos_mutex); + std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex); - const auto iter = sig_handler.FindCodeBlockInfo(CTX_RIP); - if (iter != sig_handler.code_block_infos.end()) { + const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP); + if (iter != sig_handler->code_block_infos.end()) { FakeCall fc = iter->cb(CTX_RIP); CTX_RSP -= sizeof(u64); @@ -220,10 +229,10 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { # endif { - std::lock_guard<std::mutex> guard(sig_handler.code_block_infos_mutex); + std::lock_guard<std::mutex> guard(sig_handler->code_block_infos_mutex); - const auto iter = sig_handler.FindCodeBlockInfo(CTX_PC); - if (iter != sig_handler.code_block_infos.end()) { + const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); + if (iter != sig_handler->code_block_infos.end()) { FakeCall fc = iter->cb(CTX_PC); CTX_PC = fc.call_pc; @@ -240,7 +249,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { #endif - struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler.old_sa_segv : &sig_handler.old_sa_bus; + struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus; if (retry_sa->sa_flags & SA_SIGINFO) { retry_sa->sa_sigaction(sig, info, raw_context); return; @@ -260,18 +269,20 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { struct ExceptionHandler::Impl final { Impl(u64 code_begin_, u64 code_end_) : code_begin(code_begin_) - , code_end(code_end_) {} + , code_end(code_end_) { + RegisterHandler(); + } void SetCallback(std::function<FakeCall(u64)> cb) { CodeBlockInfo cbi; cbi.code_begin = code_begin; cbi.code_end = code_end; cbi.cb = cb; - sig_handler.AddCodeBlock(cbi); + sig_handler->AddCodeBlock(cbi); } ~Impl() { - sig_handler.RemoveCodeBlock(code_begin); + sig_handler->RemoveCodeBlock(code_begin); } private: @@ -298,7 +309,7 @@ void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) { #endif bool ExceptionHandler::SupportsFastmem() const noexcept { - return static_cast<bool>(impl) && sig_handler.SupportsFastmem(); + return static_cast<bool>(impl) && sig_handler->SupportsFastmem(); } void ExceptionHandler::SetFastmemCallback(std::function<FakeCall(u64)> cb) { |