diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp index 9617d242e1..cc7612a412 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp @@ -463,7 +463,7 @@ static void PrintFlags(uint64_t Flags) { static uint64_t Clone2Handler(FEXCore::Core::CpuStateFrame* Frame, FEX::HLE::clone3_args* args) { StackFrameData* Data = (StackFrameData*)FEXCore::Allocator::malloc(sizeof(StackFrameData)); - Data->Thread = static_cast(Frame->Thread->FrontendPtr); + Data->Thread = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame); Data->CTX = Frame->Thread->CTX; Data->GuestArgs = *args; @@ -489,7 +489,7 @@ static uint64_t Clone3Handler(FEXCore::Core::CpuStateFrame* Frame, FEX::HLE::clo constexpr size_t Offset = sizeof(StackFramePlusRet); StackFramePlusRet* Data = (StackFramePlusRet*)(reinterpret_cast(args->NewStack) + args->StackSize - Offset); Data->Ret = (uint64_t)Clone3HandlerRet; - Data->Data.Thread = static_cast(Frame->Thread->FrontendPtr); + Data->Data.Thread = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame); Data->Data.CTX = Frame->Thread->CTX; Data->Data.GuestArgs = *args; diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp index bfa1ea4d15..d2a410dd22 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls/Thread.cpp @@ -385,7 +385,7 @@ void RegisterThread(FEX::HLE::SyscallHandler* Handler) { // TLS/DTV teardown is something FEX can't control. Disable glibc checking when we leave a pthread. // Since this thread is hard stopping, we can't track the TLS/DTV teardown in FEX's thread handling. FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator::HardDisable(); - auto ThreadObject = static_cast(Thread->FrontendPtr); + auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(Frame); if (Thread->ThreadManager.clear_child_tid) { std::atomic* Addr = reinterpret_cast*>(Thread->ThreadManager.clear_child_tid); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.cpp index ca38faf7e3..f8c9bb185b 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.cpp @@ -217,8 +217,8 @@ void ThreadManager::UnlockAfterFork(FEXCore::Core::InternalThreadState* LiveThre // Remove all threads but the live thread from Threads Threads.clear(); - auto LiveThreadData = static_cast(LiveThread->FrontendPtr); - Threads.push_back(LiveThreadData); + auto ThreadObject = FEX::HLE::ThreadManager::GetStateObjectFromCPUState(LiveThread->CurrentFrame); + Threads.push_back(ThreadObject); // Clean up dead stacks FEXCore::Threads::Thread::CleanupAfterFork(); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.h index bc2ae7cb31..0f68dbf5ff 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/ThreadManager.h @@ -30,6 +30,11 @@ class ThreadManager final { ~ThreadManager(); + ///< Returns the ThreadStateObject from a CpuStateFrame object. + static inline FEX::HLE::ThreadStateObject* GetStateObjectFromCPUState(FEXCore::Core::CpuStateFrame* Frame) { + return static_cast(Frame->Thread->FrontendPtr); + } + FEX::HLE::ThreadStateObject* CreateThread(uint64_t InitialRIP, uint64_t StackPointer, FEXCore::Core::CPUState* NewThreadState = nullptr, uint64_t ParentTID = 0); void TrackThread(FEX::HLE::ThreadStateObject* Thread) {