Adds support for guest sigprocmask

This was causing our SIGBUS handling to fail in FTL
This commit is contained in:
Ryan Houdek committed 2020-08-18 21:00:33 +01:00
1 parent 1db1a42576
commit 7700a4d24b
3 files changed
+35 -4

No files matched your search

@@ -21,6 +21,7 @@ namespace FEXCore {
// Guest signal sa_mask is per thread!
SignalDelegator::GuestSAMask Guest_sa_mask[SignalDelegator::MAX_SIGNALS]{};
uint32_t CurrentSignal{};
uint64_t GuestProcMask{};
};
thread_local ThreadState ThreadData{};
@@ -94,11 +95,18 @@ namespace FEXCore {
}
}
// Signal specific mask check
if (SigIsMember(&ThreadData.Guest_sa_mask[ThreadData.CurrentSignal], Signal)) {
// If we are in a signal and our signal mask is blocking this signal then ignore it
return;
}
// Thread specific mask check
if (ThreadData.GuestProcMask & (Signal - 1)) {
// If the thread specific mask masks the signal then it is hidden from the guest
return;
}
ThreadData.CurrentSignal = Signal;
// We have an emulation thread pointer, we can now modify its state
@@ -396,4 +404,27 @@ namespace FEXCore {
return 0;
}
uint64_t SignalDelegator::GuestSigProcMask(int how, const uint64_t *set, uint64_t *oldset) {
if (!!oldset) {
*oldset = ThreadData.GuestProcMask;
}
if (!!set) {
uint64_t IgnoredSignalsMask = ~((1ULL << (SIGKILL - 1)) | (1ULL << (SIGSTOP - 1)));
if (how == SIG_BLOCK) {
ThreadData.GuestProcMask |= *set & IgnoredSignalsMask;
}
else if (how == SIG_UNBLOCK) {
ThreadData.GuestProcMask &= *set & IgnoredSignalsMask;
}
else if (how == SIG_SETMASK) {
ThreadData.GuestProcMask = *set & IgnoredSignalsMask;
}
else {
return -EINVAL;
}
}
return 0;
}
}
@@ -82,6 +82,8 @@ 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);
// Called from the thunk handler to handle the signal
void HandleSignal(int Signal, void *Info, void *UContext);
+2 -4
View File
@@ -14,10 +14,8 @@ namespace FEXCore::HLE {
return Thread->CTX->SignalDelegation.RegisterGuestSignalHandler(signum, act, oldact);
});
REGISTER_SYSCALL_IMPL(rt_sigprocmask, [](FEXCore::Core::InternalThreadState *Thread, int how, const sigset_t *set, sigset_t *oldset) -> uint64_t {
// XXX: Pass through SignalDelegator
uint64_t Result = ::sigprocmask(how, set, oldset);
SYSCALL_ERRNO();
REGISTER_SYSCALL_IMPL(rt_sigprocmask, [](FEXCore::Core::InternalThreadState *Thread, int how, const uint64_t *set, uint64_t *oldset) -> uint64_t {
return Thread->CTX->SignalDelegation.GuestSigProcMask(how, set, oldset);
});
REGISTER_SYSCALL_IMPL(sigaltstack, [](FEXCore::Core::InternalThreadState *Thread, const stack_t *ss, stack_t *old_ss) -> uint64_t {