From 8c1740f5926694f1e973e77687d2fa2044f53b0b Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 20 Sep 2024 00:23:05 -0700 Subject: [PATCH] Thunks: Remove the temporary TLS variables From prep commit 511103ee5dcc9474b0b7468c05f61ce10fea4393. Now that the frontend is setup, we can remove the temporary TLS variables and use the ThreadObject directly. --- Source/Tools/FEXLoader/FEXLoader.cpp | 2 +- .../LinuxEmulation/LinuxSyscalls/Syscalls.cpp | 2 +- .../LinuxEmulation/LinuxSyscalls/Syscalls.h | 4 ++ Source/Tools/LinuxEmulation/Thunks.cpp | 62 +++++++++---------- Source/Tools/LinuxEmulation/Thunks.h | 2 +- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Source/Tools/FEXLoader/FEXLoader.cpp b/Source/Tools/FEXLoader/FEXLoader.cpp index bd61bbb8db..ea5188c85c 100644 --- a/Source/Tools/FEXLoader/FEXLoader.cpp +++ b/Source/Tools/FEXLoader/FEXLoader.cpp @@ -563,7 +563,7 @@ int main(int argc, char** argv, char** const envp) { auto ParentThread = SyscallHandler->TM.CreateThread(Loader.DefaultRIP(), Loader.GetStackPointer()); SyscallHandler->TM.TrackThread(ParentThread); SignalDelegation->RegisterTLSState(ParentThread); - ThunkHandler->RegisterTLSState(CTX.get(), ParentThread); + ThunkHandler->RegisterTLSState(ParentThread); // Pass in our VDSO thunks ThunkHandler->AppendThunkDefinitions(FEX::VDSO::GetVDSOThunkDefinitions()); diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp index b44100c80c..9b2e280a75 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.cpp @@ -876,7 +876,7 @@ void SyscallHandler::UnlockAfterFork(FEXCore::Core::InternalThreadState* LiveThr void SyscallHandler::RegisterTLSState(FEX::HLE::ThreadStateObject* Thread) { SignalDelegation->RegisterTLSState(Thread); - ThunkHandler->RegisterTLSState(CTX, Thread); + ThunkHandler->RegisterTLSState(Thread); } void SyscallHandler::UninstallTLSState(FEX::HLE::ThreadStateObject* Thread) { diff --git a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h index f210bba598..5417a3c6ec 100644 --- a/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h +++ b/Source/Tools/LinuxEmulation/LinuxSyscalls/Syscalls.h @@ -192,6 +192,10 @@ class SyscallHandler : public FEXCore::HLE::SyscallHandler, FEXCore::HLE::Source return SignalDelegation; } + FEX::HLE::ThunkHandler* GetThunkHandler() { + return ThunkHandler; + } + FEX_CONFIG_OPT(IsInterpreter, IS_INTERPRETER); FEX_CONFIG_OPT(IsInterpreterInstalled, INTERPRETER_INSTALLED); FEX_CONFIG_OPT(Filename, APP_FILENAME); diff --git a/Source/Tools/LinuxEmulation/Thunks.cpp b/Source/Tools/LinuxEmulation/Thunks.cpp index d74a7dcac5..fa8f487c77 100644 --- a/Source/Tools/LinuxEmulation/Thunks.cpp +++ b/Source/Tools/LinuxEmulation/Thunks.cpp @@ -7,6 +7,7 @@ tags: glue|thunks */ #include "Thunks.h" +#include "LinuxSyscalls/Syscalls.h" #include "LinuxSyscalls/ThreadManager.h" #include @@ -73,15 +74,7 @@ struct LoadlibArgs { const char* Name; }; -struct ThunkHandler_impl; - -struct TEMP_TLS_DATA { - FEXCore::Core::InternalThreadState* Thread {}; - ThunkHandler_impl* ThunkHandler {}; - FEXCore::Context::Context* CTX {}; -}; - -static thread_local TEMP_TLS_DATA ThreadData {}; +static thread_local FEX::HLE::ThreadStateObject* ThreadObject {}; struct ExportEntry { uint8_t* sha256; @@ -177,22 +170,25 @@ struct ThunkHandler_impl final : public FEX::HLE::ThunkHandler { Set arg0/1 to arg regs, use CTX::HandleCallback to handle the callback */ static void CallCallback(void* callback, void* arg0, void* arg1) { - if (!ThreadData.Thread) { + if (!ThreadObject) { ERROR_AND_DIE_FMT("Thunked library attempted to invoke guest callback asynchronously"); } - if (ThreadData.ThunkHandler->Is64BitMode()) { - ThreadData.Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0; - ThreadData.Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1; + auto CTX = static_cast(ThreadObject->Thread->CTX); + auto ThunkHandler = reinterpret_cast(FEX::HLE::_SyscallHandler->GetThunkHandler()); + + if (ThunkHandler->Is64BitMode()) { + ThreadObject->Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDI] = (uintptr_t)arg0; + ThreadObject->Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSI] = (uintptr_t)arg1; } else { if ((reinterpret_cast(arg1) >> 32) != 0) { ERROR_AND_DIE_FMT("Tried to call guest function with arguments packed to a 64-bit address"); } - ThreadData.Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RCX] = (uintptr_t)arg0; - ThreadData.Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDX] = (uintptr_t)arg1; + ThreadObject->Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RCX] = (uintptr_t)arg0; + ThreadObject->Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RDX] = (uintptr_t)arg1; } - ThreadData.CTX->HandleCallback(ThreadData.Thread, (uintptr_t)callback); + CTX->HandleCallback(ThreadObject->Thread, (uintptr_t)callback); } FEXCore::ThunkedFunction* LookupThunk(const FEXCore::IR::SHA256Sum& sha256) override { @@ -208,10 +204,8 @@ struct ThunkHandler_impl final : public FEX::HLE::ThunkHandler { } } - void RegisterTLSState(FEXCore::Context::Context* CTX, FEX::HLE::ThreadStateObject* ThreadObject) override { - ThreadData.Thread = ThreadObject->Thread; - ThreadData.ThunkHandler = this; - ThreadData.CTX = CTX; + void RegisterTLSState(FEX::HLE::ThreadStateObject* _ThreadObject) override { + ThreadObject = _ThreadObject; } void AppendThunkDefinitions(std::span Definitions) override { @@ -230,10 +224,10 @@ namespace ThunkFunctions { auto Args = reinterpret_cast(ArgsV); std::string_view Name = Args->Name; + auto ThunkHandler = reinterpret_cast(FEX::HLE::_SyscallHandler->GetThunkHandler()); auto SOName = - (ThreadData.ThunkHandler->Is64BitMode() ? ThreadData.ThunkHandler->ThunkHostLibsPath() : ThreadData.ThunkHandler->ThunkHostLibsPath32()) + - "/" + Name.data() + "-host.so"; + (ThunkHandler->Is64BitMode() ? ThunkHandler->ThunkHostLibsPath() : ThunkHandler->ThunkHostLibsPath32()) + "/" + Name.data() + "-host.so"; LogMan::Msg::DFmt("LoadLib: {} -> {}", Name, SOName); @@ -262,13 +256,13 @@ namespace ThunkFunctions { } { - std::lock_guard lk(ThreadData.ThunkHandler->ThunksMutex); + std::lock_guard lk(ThunkHandler->ThunksMutex); - ThreadData.ThunkHandler->Libs.insert(fextl::string {Name}); + ThunkHandler->Libs.insert(fextl::string {Name}); int i; for (i = 0; Exports[i].sha256; i++) { - ThreadData.ThunkHandler->Thunks[*reinterpret_cast(Exports[i].sha256)] = Exports[i].Fn; + ThunkHandler->Thunks[*reinterpret_cast(Exports[i].sha256)] = Exports[i].Fn; } LogMan::Msg::DFmt("Loaded {} syms", i); @@ -282,10 +276,11 @@ namespace ThunkFunctions { }; auto& [Name, rv] = *reinterpret_cast(ArgsRV); + auto ThunkHandler = reinterpret_cast(FEX::HLE::_SyscallHandler->GetThunkHandler()); { - std::shared_lock lk(ThreadData.ThunkHandler->ThunksMutex); - rv = ThreadData.ThunkHandler->Libs.contains(Name); + std::shared_lock lk(ThunkHandler->ThunksMutex); + rv = ThunkHandler->Libs.contains(Name); } } @@ -326,7 +321,8 @@ namespace ThunkFunctions { }; auto args = reinterpret_cast(argsv); - ThreadData.CTX->AddThunkTrampolineIRHandler(args->original_callee, args->target_addr); + auto CTX = static_cast(ThreadObject->Thread->CTX); + CTX->AddThunkTrampolineIRHandler(args->original_callee, args->target_addr); } /** @@ -378,7 +374,7 @@ FEX_DEFAULT_VISIBILITY HostToGuestTrampolinePtr* MakeHostTrampolineForGuestFunction(void* HostPacker, uintptr_t GuestTarget, uintptr_t GuestUnpacker) { LOGMAN_THROW_AA_FMT(GuestTarget, "Tried to create host-trampoline to null pointer guest function"); - const auto ThunkHandler = reinterpret_cast(ThreadData.ThunkHandler); + const auto ThunkHandler = reinterpret_cast(FEX::HLE::_SyscallHandler->GetThunkHandler()); const GuestcallInfo gci = {GuestUnpacker, GuestTarget}; @@ -444,15 +440,15 @@ FEX_DEFAULT_VISIBILITY void FinalizeHostTrampolineForGuestFunction(HostToGuestTr } FEX_DEFAULT_VISIBILITY void* GetGuestStack() { - if (!ThreadData.Thread) { + if (!ThreadObject) { ERROR_AND_DIE_FMT("Thunked library attempted to query guest stack pointer asynchronously"); } - return (void*)(uintptr_t)((ThreadData.Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSP])); + return (void*)(uintptr_t)((ThreadObject->Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSP])); } FEX_DEFAULT_VISIBILITY void MoveGuestStack(uintptr_t NewAddress) { - if (!ThreadData.Thread) { + if (!ThreadObject) { ERROR_AND_DIE_FMT("Thunked library attempted to query guest stack pointer asynchronously"); } @@ -460,7 +456,7 @@ FEX_DEFAULT_VISIBILITY void MoveGuestStack(uintptr_t NewAddress) { ERROR_AND_DIE_FMT("Tried to set stack pointer for 32-bit guest to a 64-bit address"); } - ThreadData.Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSP] = NewAddress; + ThreadObject->Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RSP] = NewAddress; } fextl::unique_ptr CreateThunkHandler() { diff --git a/Source/Tools/LinuxEmulation/Thunks.h b/Source/Tools/LinuxEmulation/Thunks.h index 5a3a9b2801..b0b28787cd 100644 --- a/Source/Tools/LinuxEmulation/Thunks.h +++ b/Source/Tools/LinuxEmulation/Thunks.h @@ -7,7 +7,7 @@ struct ThreadStateObject; class ThunkHandler : public FEXCore::ThunkHandler { public: - virtual void RegisterTLSState(FEXCore::Context::Context* CTX, FEX::HLE::ThreadStateObject* ThreadObject) = 0; + virtual void RegisterTLSState(FEX::HLE::ThreadStateObject* ThreadObject) = 0; /** * @brief Allows the frontend to register its own thunk handlers independent of what is controlled in the backend. *