diff --git a/Source/Tools/LinuxEmulation/CMakeLists.txt b/Source/Tools/LinuxEmulation/CMakeLists.txt index 894a1063b..715a8f132 100644 --- a/Source/Tools/LinuxEmulation/CMakeLists.txt +++ b/Source/Tools/LinuxEmulation/CMakeLists.txt @@ -164,29 +164,3 @@ add_custom_target(struct_verifier WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" USES_TERMINAL COMMAND "ctest" "--output-on-failure" "--timeout" "302" ${TEST_JOB_FLAG} "-R" "Test_verify*") - -include(CheckCSourceCompiles) - -check_c_source_compiles(" -#include -int main(void){ - sigset_t s; - (void)sizeof(s.__val); // glibc - return 0; -}" SIGSET_HAS___VAL) - -check_c_source_compiles(" -#include -int main(void){ - sigset_t s; - (void)sizeof(s.__bits); // musl - return 0; -}" SIGSET_HAS___BITS) - -if(SIGSET_HAS___VAL) - add_compile_definitions("SIGSET_VAL=__val") -elseif(SIGSET_HAS___BITS) - add_compile_definitions("SIGSET_VAL=__bits") -else() - message(FATAL_ERROR "Unknown sigset_t layout!") -endif() diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp index 1a21afb9f..9ba706c7b 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/SignalDelegator.cpp @@ -649,17 +649,19 @@ void SignalDelegator::HandleGuestSignal(FEX::HLE::ThreadStateObject* ThreadObjec "capacity size. This will " "likely crash! Asserting now!"); + // Peek into sigset_t implementation details, extracting the __val member for glibc and __bits for musl + auto& [sigmask_val] = _context->uc_sigmask; + static_assert(sizeof(sigmask_val[0]) == sizeof(uint64_t), "Unknown sigset_t layout"); + ThreadObject->SignalInfo.DeferredSignalFrames.emplace_back(ThreadStateObject::DeferredSignalState { .Info = SigInfo, .Signal = Signal, - .SigMask = _context->uc_sigmask.SIGSET_VAL[0], + .SigMask = sigmask_val[0], }); - uint64_t NewMask = GetNewSigMask(Signal); - // Update our host signal mask so we don't hit race conditions with signals // This allows us to maintain the expected signal mask through the guest signal handling and then all the way back again - memcpy(&_context->uc_sigmask, &NewMask, sizeof(uint64_t)); + sigmask_val[0] = GetNewSigMask(Signal); // Now update the faulting page permissions so it will fault on write. mprotect(reinterpret_cast(&Thread->InterruptFaultPage), sizeof(Thread->InterruptFaultPage), PROT_NONE);