Skip to content

Commit

Permalink
Merge pull request #3294 from Sonicadvance1/mov_xid_check
Browse files Browse the repository at this point in the history
FEXCore: Moves XID check to the frontend
  • Loading branch information
Sonicadvance1 committed Dec 7, 2023
2 parents b613576 + afebf73 commit 7524029
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 23 deletions.
1 change: 0 additions & 1 deletion FEXCore/Source/Interface/Context/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ namespace FEXCore::Context {
FEXCore::Core::InternalThreadState* ParentThread{};
fextl::vector<FEXCore::Core::InternalThreadState*> Threads;
std::atomic_bool CoreShuttingDown{false};
bool NeedToCheckXID{true};

std::mutex IdleWaitMutex;
std::condition_variable IdleWaitCV;
Expand Down
11 changes: 0 additions & 11 deletions FEXCore/Source/Interface/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,21 +528,10 @@ namespace FEXCore::Context {
ExecutionThreadHandler *Arg = reinterpret_cast<ExecutionThreadHandler*>(FEXCore::Allocator::malloc(sizeof(ExecutionThreadHandler)));
Arg->This = this;
Arg->Thread = Thread;
Thread->StartPaused = NeedToCheckXID;
Thread->ExecutionThread = FEXCore::Threads::Thread::Create(ThreadHandler, Arg);

// Wait for the thread to have started
Thread->ThreadWaiting.Wait();

if (NeedToCheckXID) {
// The first time an application creates a thread, GLIBC installs their SETXID signal handler.
// FEX needs to capture all signals and defer them to the guest.
// Once FEX creates its first guest thread, overwrite the GLIBC SETXID handler *again* to ensure
// FEX maintains control of the signal handler on this signal.
NeedToCheckXID = false;
SignalDelegation->CheckXIDHandler();
Thread->StartRunning.NotifyAll();
}
}

void ContextImpl::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) {
Expand Down
8 changes: 0 additions & 8 deletions FEXCore/include/FEXCore/Core/SignalDelegator.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,6 @@ namespace Core {
virtual void RegisterTLSState(FEXCore::Core::InternalThreadState *Thread) = 0;
virtual void UninstallTLSState(FEXCore::Core::InternalThreadState *Thread) = 0;

/**
* @brief Check to ensure the XID handler is still set to the FEX handler
*
* On a new thread GLIBC will set the XID handler underneath us.
* After the first thread is created check this.
*/
virtual void CheckXIDHandler() = 0;

struct SignalDelegatorConfig {
bool StaticRegisterAllocation{};
bool SupportsAVX{};
Expand Down
2 changes: 0 additions & 2 deletions Source/Tools/CommonTools/DummyHandlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ class DummySyscallHandler: public FEXCore::HLE::SyscallHandler, public FEXCore::

class DummySignalDelegator final : public FEXCore::SignalDelegator, public FEXCore::Allocator::FEXAllocOperators {
public:
void CheckXIDHandler() override {}

void SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event) override {}

FEXCore::Core::InternalThreadState *GetBackingTLSThread() {
Expand Down
8 changes: 7 additions & 1 deletion Source/Tools/FEXLoader/LinuxSyscalls/SignalDelegator.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,13 @@ namespace FEX::HLE {
uint64_t GuestSignalFD(int fd, const uint64_t *set, size_t sigsetsize , int flags);
/** @} */

void CheckXIDHandler() override;
/**
* @brief Check to ensure the XID handler is still set to the FEX handler
*
* On a new thread GLIBC will set the XID handler underneath us.
* After the first thread is created check this.
*/
void CheckXIDHandler();

void UninstallHostHandler(int Signal);
FEXCore::Context::Context *CTX;
Expand Down
4 changes: 4 additions & 0 deletions Source/Tools/FEXLoader/LinuxSyscalls/Syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,9 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source

SourcecodeResolver *GetSourcecodeResolver() override { return this; }

bool NeedXIDCheck() const { return NeedToCheckXID; }
void DisableXIDCheck() { NeedToCheckXID = false; }

protected:
SyscallHandler(FEXCore::Context::Context *_CTX, FEX::HLE::SignalDelegator *_SignalDelegation);

Expand All @@ -250,6 +253,7 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source
std::mutex FutexMutex;
std::mutex SyscallMutex;
FEXCore::CodeLoader *LocalLoader{};
bool NeedToCheckXID{true};

#ifdef DEBUG_STRACE
void Strace(FEXCore::HLE::SyscallArguments *Args, uint64_t Ret);
Expand Down
11 changes: 11 additions & 0 deletions Source/Tools/FEXLoader/LinuxSyscalls/Syscalls/Thread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,19 @@ namespace FEX::HLE {
}

auto NewThread = CTX->CreateThread(0, 0, &NewThreadState, args->args.parent_tid);
bool NeedsXIDCheck = FEX::HLE::_SyscallHandler->NeedXIDCheck();
NewThread->StartPaused = NeedsXIDCheck;
CTX->InitializeThread(NewThread);

if (NeedsXIDCheck) {
// The first time an application creates a thread, GLIBC installs their SETXID signal handler.
// FEX needs to capture all signals and defer them to the guest.
// Once FEX creates its first guest thread, overwrite the GLIBC SETXID handler *again* to ensure
// FEX maintains control of the signal handler on this signal.
FEX::HLE::_SyscallHandler->GetSignalDelegator()->CheckXIDHandler();
FEX::HLE::_SyscallHandler->DisableXIDCheck();
}

if (FEX::HLE::_SyscallHandler->Is64BitMode()) {
if (flags & CLONE_SETTLS) {
x64::SetThreadArea(NewThread->CurrentFrame, reinterpret_cast<void*>(args->args.tls));
Expand Down

0 comments on commit 7524029

Please sign in to comment.