From 7b0fdb52cdf40ed4310fd61e10f37e66f17c3bd5 Mon Sep 17 00:00:00 2001 From: comex Date: Sun, 7 Sep 2014 19:10:02 -0400 Subject: [PATCH] Run exception handlers on an alternate stack on Linux. *Completely untested.* Someone please test. --- Source/Core/Core/ArmMemTools.cpp | 3 +++ Source/Core/Core/Core.cpp | 4 ++++ Source/Core/Core/MemTools.h | 1 + Source/Core/Core/x64MemTools.cpp | 20 ++++++++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/Source/Core/Core/ArmMemTools.cpp b/Source/Core/Core/ArmMemTools.cpp index ff7d77e4f4..c9816aba00 100644 --- a/Source/Core/Core/ArmMemTools.cpp +++ b/Source/Core/Core/ArmMemTools.cpp @@ -86,4 +86,7 @@ void InstallExceptionHandler() sigemptyset(&sa.sa_mask); sigaction(SIGSEGV, &sa, nullptr); } + +void UninstallExceptionHandler() {} + } // namespace diff --git a/Source/Core/Core/Core.cpp b/Source/Core/Core/Core.cpp index 3a764a4e63..5b6294d2c7 100644 --- a/Source/Core/Core/Core.cpp +++ b/Source/Core/Core/Core.cpp @@ -277,6 +277,10 @@ static void CpuThread() if (!_CoreParameter.bCPUThread) g_video_backend->Video_Cleanup(); + #if _M_X86_64 || _M_ARM_32 + EMM::UninstallExceptionHandler(); + #endif + return; } diff --git a/Source/Core/Core/MemTools.h b/Source/Core/Core/MemTools.h index 276af3d887..fcc671b799 100644 --- a/Source/Core/Core/MemTools.h +++ b/Source/Core/Core/MemTools.h @@ -11,4 +11,5 @@ namespace EMM { typedef u32 EAddr; void InstallExceptionHandler(); + void UninstallExceptionHandler(); } diff --git a/Source/Core/Core/x64MemTools.cpp b/Source/Core/Core/x64MemTools.cpp index de298363df..057d3a83f0 100644 --- a/Source/Core/Core/x64MemTools.cpp +++ b/Source/Core/Core/x64MemTools.cpp @@ -125,6 +125,8 @@ void InstallExceptionHandler() handlerInstalled = true; } +void UninstallExceptionHandler() {} + #elif defined(__APPLE__) void CheckKR(const char* name, kern_return_t kr) @@ -243,6 +245,8 @@ void InstallExceptionHandler() CheckKR("mach_port_request_notification", mach_port_request_notification(mach_task_self(), port, MACH_NOTIFY_NO_SENDERS, 0, port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &previous)); } +void UninstallExceptionHandler() {} + #elif defined(_POSIX_VERSION) static void sigsegv_handler(int sig, siginfo_t *info, void *raw_context) @@ -273,6 +277,12 @@ static void sigsegv_handler(int sig, siginfo_t *info, void *raw_context) void InstallExceptionHandler() { + stack_t signal_stack; + signal_stack.ss_sp = malloc(SIGSTKSZ); + signal_stack.ss_size = SIGSTKSZ; + signal_stack.ss_flags = 0; + if (sigaltstack(&signal_stack, nullptr)) + PanicAlert("sigaltstack failed"); struct sigaction sa; sa.sa_handler = nullptr; sa.sa_sigaction = &sigsegv_handler; @@ -281,6 +291,16 @@ void InstallExceptionHandler() sigaction(SIGSEGV, &sa, nullptr); } +void UninstallExceptionHandler() +{ + stack_t signal_stack, old_stack; + signal_stack.ss_flags = SS_DISABLE; + if (!sigaltstack(&signal_stack, &old_stack) && + !(old_stack.ss_flags & SS_DISABLE)) + { + free(old_stack.ss_sp); + } +} #else #error Unsupported x86_64 platform! Report this if you support sigaction