aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLiam <[email protected]>2023-10-05 15:01:41 -0400
committermerry <[email protected]>2023-10-08 16:24:10 +0100
commit0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378 (patch)
tree23e4119d7b2f00ea3d24e8fd8ac046af5aef1e7e
parentac643f1bee75953a0a3e07be60a1fa60aded4b6e (diff)
downloaddynarmic-0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378.tar.gz
dynarmic-0df09e2f6b61c2d7ad2f2053d4f020a5c33e0378.zip
exception_handler: connect installation to instance lifetime
-rw-r--r--src/dynarmic/backend/exception_handler_macos.cpp21
-rw-r--r--src/dynarmic/backend/exception_handler_posix.cpp35
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) {