From 758de4deaaddfecd99db29730d53f7fdf224bcbf Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Thu, 20 Aug 2020 13:47:03 -0700 Subject: [PATCH] Implements rt_sigpending Any time a guest signal is blocked, add it to the guest signal mask. This doesn't use a signal queue so repeat signals can end up being lost. This is expected behaviour This doesn't help with implementing the problem of unblocking signals causing the masked signal to be resent --- .../Source/Interface/Core/SignalDelegator.cpp | 12 ++++++++++++ .../FEXCore/Source/Interface/Core/SignalDelegator.h | 1 + .../Source/Interface/HLE/Syscalls/Signals.cpp | 4 ++++ .../FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp | 4 ---- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp b/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp index e49f93c7a..70b3182d0 100644 --- a/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp +++ b/External/FEXCore/Source/Interface/Core/SignalDelegator.cpp @@ -22,6 +22,7 @@ namespace FEXCore { SignalDelegator::GuestSAMask Guest_sa_mask[SignalDelegator::MAX_SIGNALS]{}; uint32_t CurrentSignal{}; uint64_t GuestProcMask{}; + uint64_t PendingSignals{}; }; thread_local ThreadState ThreadData{}; @@ -104,6 +105,8 @@ namespace FEXCore { // Thread specific mask check if (ThreadData.GuestProcMask & (Signal - 1)) { // If the thread specific mask masks the signal then it is hidden from the guest + // It gets put in to the pending signals mask + ThreadData.PendingSignals |= 1ULL << (Signal - 1); return; } @@ -427,4 +430,13 @@ namespace FEXCore { return 0; } + + uint64_t SignalDelegator::GuestSigPending(uint64_t *set, size_t sigsetsize) { + if (sigsetsize > sizeof(uint64_t)) { + return -EINVAL; + } + + *set = ThreadData.PendingSignals; + return 0; + } } diff --git a/External/FEXCore/Source/Interface/Core/SignalDelegator.h b/External/FEXCore/Source/Interface/Core/SignalDelegator.h index d6f7cb2cb..fa691e5b2 100644 --- a/External/FEXCore/Source/Interface/Core/SignalDelegator.h +++ b/External/FEXCore/Source/Interface/Core/SignalDelegator.h @@ -83,6 +83,7 @@ namespace Core { uint64_t RegisterGuestSigAltStack(const stack_t *ss, stack_t *old_ss); uint64_t GuestSigProcMask(int how, const uint64_t *set, uint64_t *oldset); + uint64_t GuestSigPending(uint64_t *set, size_t sigsetsize); // Called from the thunk handler to handle the signal void HandleSignal(int Signal, void *Info, void *UContext); diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls/Signals.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls/Signals.cpp index e62c36b2d..a9edcac93 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls/Signals.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls/Signals.cpp @@ -21,5 +21,9 @@ namespace FEXCore::HLE { REGISTER_SYSCALL_IMPL(sigaltstack, [](FEXCore::Core::InternalThreadState *Thread, const stack_t *ss, stack_t *old_ss) -> uint64_t { return Thread->CTX->SignalDelegation.RegisterGuestSigAltStack(ss, old_ss); }); + + REGISTER_SYSCALL_IMPL(rt_sigpending, [](FEXCore::Core::InternalThreadState *Thread, uint64_t *set, size_t sigsetsize) -> uint64_t { + return Thread->CTX->SignalDelegation.GuestSigPending(set, sigsetsize); + }); } } diff --git a/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp b/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp index 6ef4aa9c9..0a227b064 100644 --- a/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp +++ b/External/FEXCore/Source/Interface/HLE/Syscalls/Stubs.cpp @@ -92,10 +92,6 @@ namespace FEXCore::HLE { SYSCALL_STUB(capset); }); - REGISTER_SYSCALL_IMPL(rt_sigpending, [](FEXCore::Core::InternalThreadState *Thread, sigset_t *set, size_t sigsetsize) -> uint64_t { - SYSCALL_STUB(rt_sigpending); - }); - REGISTER_SYSCALL_IMPL(rt_sigtimedwait, [](FEXCore::Core::InternalThreadState *Thread, sigset_t *set, const struct timespec*, size_t sigsetsize) -> uint64_t { SYSCALL_STUB(rt_sigtimedwait); });