From 35af4bd42a054aac81f68d63406cc8035f5347ea Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 7 Feb 2023 10:02:48 -0800 Subject: [PATCH] FEXCore: Removes C wrapper interface This has been a long time coming. The C interface has been a thorn in our side for no reason for a long time. The purpose of this step is to remove the C interface without changing behaviour as much as possible. This means that with this commit there are still some bad practices but the remaining issues will be solved with followup PRs. Primarily, we still have a `DestroyContext(CTX)` static function which calls the Context implementation's `DestroyContext` and does a raw C++ delete. Follow up PR will remove that, but I didn't want to touch it yet since it'll require checking to ensure the unique_ptr changes play nice with our allocator hooking. Which this is already a huge PR without trying to change behaviour. --- .../Source/Interface/Config/Config.cpp | 2 +- .../Source/Interface/Context/Context.cpp | 210 +++------ .../Source/Interface/Context/Context.h | 229 ++++++---- .../Core/ArchHelpers/Arm64Emitter.cpp | 2 +- .../Interface/Core/ArchHelpers/Arm64Emitter.h | 4 +- .../Source/Interface/Core/CPUBackend.cpp | 4 +- .../FEXCore/Source/Interface/Core/CPUID.cpp | 2 +- .../FEXCore/Source/Interface/Core/CPUID.h | 6 +- .../FEXCore/Source/Interface/Core/Core.cpp | 161 ++++--- External/FEXCore/Source/Interface/Core/Core.h | 6 +- .../Core/Dispatcher/Arm64Dispatcher.cpp | 8 +- .../Core/Dispatcher/Arm64Dispatcher.h | 6 +- .../Interface/Core/Dispatcher/Dispatcher.cpp | 8 +- .../Interface/Core/Dispatcher/Dispatcher.h | 12 +- .../Core/Dispatcher/X86Dispatcher.cpp | 6 +- .../Interface/Core/Dispatcher/X86Dispatcher.h | 6 +- .../Source/Interface/Core/Frontend.cpp | 2 +- .../FEXCore/Source/Interface/Core/Frontend.h | 6 +- .../Source/Interface/Core/GdbServer.cpp | 4 +- .../FEXCore/Source/Interface/Core/GdbServer.h | 6 +- .../Interface/Core/Interpreter/BranchOps.cpp | 8 +- .../Core/Interpreter/InterpreterClass.h | 2 +- .../Core/Interpreter/InterpreterCore.cpp | 10 +- .../Core/Interpreter/InterpreterCore.h | 6 +- .../Interface/Core/JIT/Arm64/BranchOps.cpp | 2 +- .../Source/Interface/Core/JIT/Arm64/JIT.cpp | 20 +- .../Interface/Core/JIT/Arm64/JITClass.h | 6 +- .../Source/Interface/Core/JIT/JITCore.h | 10 +- .../Interface/Core/JIT/x86_64/BranchOps.cpp | 2 +- .../Source/Interface/Core/JIT/x86_64/JIT.cpp | 16 +- .../Interface/Core/JIT/x86_64/JITClass.h | 6 +- .../Source/Interface/Core/LookupCache.cpp | 2 +- .../Source/Interface/Core/LookupCache.h | 8 +- .../ObjectCache/NamedRegionObjectHandler.cpp | 2 +- .../Core/ObjectCache/ObjectCacheService.cpp | 2 +- .../Core/ObjectCache/ObjectCacheService.h | 6 +- .../Interface/Core/OpcodeDispatcher.cpp | 2 +- .../Source/Interface/Core/OpcodeDispatcher.h | 4 +- .../Source/Interface/HLE/Thunks/Thunks.cpp | 8 +- .../Source/Interface/HLE/Thunks/Thunks.h | 2 +- External/FEXCore/Source/Interface/IR/AOTIR.h | 7 +- .../Source/Interface/IR/PassManager.cpp | 2 +- .../FEXCore/Source/Interface/IR/PassManager.h | 6 +- .../FEXCore/include/FEXCore/Core/Context.h | 425 +++++++++--------- .../include/FEXCore/Debug/ContextDebug.h | 2 +- .../FEXCore/Debug/InternalThreadState.h | 2 +- .../include/FEXCore/HLE/SyscallHandler.h | 2 +- Source/Tests/AOT/AOTGenerator.cpp | 9 +- Source/Tests/ELFCodeLoader2.h | 2 +- Source/Tests/FEXLoader.cpp | 36 +- Source/Tests/IRLoader.cpp | 33 +- .../EmulatedFiles/EmulatedFiles.cpp | 26 +- .../EmulatedFiles/EmulatedFiles.h | 2 +- Source/Tests/LinuxSyscalls/FileManagement.cpp | 4 - Source/Tests/LinuxSyscalls/FileManagement.h | 2 +- Source/Tests/LinuxSyscalls/Syscalls.cpp | 34 +- Source/Tests/LinuxSyscalls/Syscalls.h | 2 +- .../Tests/LinuxSyscalls/Syscalls/Thread.cpp | 18 +- .../LinuxSyscalls/SyscallsSMCTracking.cpp | 26 +- .../LinuxSyscalls/SyscallsVMATracking.cpp | 6 +- Source/Tests/LinuxSyscalls/x32/Syscalls.cpp | 4 - Source/Tests/LinuxSyscalls/x32/Syscalls.h | 2 +- Source/Tests/LinuxSyscalls/x32/Thread.cpp | 2 +- Source/Tests/TestHarnessRunner.cpp | 20 +- Source/Tests/TestHarnessRunner/HostRunner.h | 4 +- 65 files changed, 698 insertions(+), 794 deletions(-) diff --git a/External/FEXCore/Source/Interface/Config/Config.cpp b/External/FEXCore/Source/Interface/Config/Config.cpp index 209d6ead5..9341dfc90 100644 --- a/External/FEXCore/Source/Interface/Config/Config.cpp +++ b/External/FEXCore/Source/Interface/Config/Config.cpp @@ -30,7 +30,7 @@ #include namespace FEXCore::Context { - struct Context; + class Context; } namespace FEXCore::Config { diff --git a/External/FEXCore/Source/Interface/Context/Context.cpp b/External/FEXCore/Source/Interface/Context/Context.cpp index 6433804b6..e1a1c6c4b 100644 --- a/External/FEXCore/Source/Interface/Context/Context.cpp +++ b/External/FEXCore/Source/Interface/Context/Context.cpp @@ -28,208 +28,108 @@ namespace FEXCore::Context { FEXCore::Paths::ShutdownPaths(); } - FEXCore::Context::Context *CreateNewContext() { - return new FEXCore::Context::Context{}; + FEXCore::Context::Context *FEXCore::Context::Context::CreateNewContext() { + return new FEXCore::Context::ContextImpl{}; } - bool InitializeContext(FEXCore::Context::Context *CTX) { - return FEXCore::CPU::CreateCPUCore(CTX); - } - - void DestroyContext(FEXCore::Context::Context *CTX) { - if (CTX->ParentThread) { - CTX->DestroyThread(CTX->ParentThread); - } + void FEXCore::Context::Context::DestroyContext(FEXCore::Context::Context *CTX) { + CTX->DestroyContext(); delete CTX; } - FEXCore::Core::InternalThreadState* InitCore(FEXCore::Context::Context *CTX, uint64_t InitialRIP, uint64_t StackPointer) { - return CTX->InitCore(InitialRIP, StackPointer); + bool FEXCore::Context::ContextImpl::InitializeContext() { + return FEXCore::CPU::CreateCPUCore(this); } - void SetExitHandler(FEXCore::Context::Context *CTX, ExitHandler handler) { - CTX->CustomExitHandler = std::move(handler); + void FEXCore::Context::ContextImpl::DestroyContext() { + if (ParentThread) { + DestroyThread(ParentThread); + } } - ExitHandler GetExitHandler(const FEXCore::Context::Context *CTX) { - return CTX->CustomExitHandler; + void FEXCore::Context::ContextImpl::SetExitHandler(ExitHandler handler) { + CustomExitHandler = std::move(handler); } - void Run(FEXCore::Context::Context *CTX) { - CTX->Run(); + ExitHandler FEXCore::Context::ContextImpl::GetExitHandler() const { + return CustomExitHandler; } - void Step(FEXCore::Context::Context *CTX) { - CTX->Step(); + void FEXCore::Context::ContextImpl::Stop() { + Stop(false); } - void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { - Thread->CTX->CompileBlock(Thread->CurrentFrame, GuestRIP); + void FEXCore::Context::ContextImpl::CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { + CompileBlock(Thread->CurrentFrame, GuestRIP); } - FEXCore::Context::ExitReason RunUntilExit(FEXCore::Context::Context *CTX) { - return CTX->RunUntilExit(); + FEXCore::Context::ExitReason FEXCore::Context::ContextImpl::GetExitReason() { + return ParentThread->ExitReason; } - int GetProgramStatus(const FEXCore::Context::Context *CTX) { - return CTX->GetProgramStatus(); + bool FEXCore::Context::ContextImpl::IsDone() const { + return IsPaused(); } - FEXCore::Context::ExitReason GetExitReason(const FEXCore::Context::Context *CTX) { - return CTX->ParentThread->ExitReason; + void FEXCore::Context::ContextImpl::GetCPUState(FEXCore::Core::CPUState *State) const { + memcpy(State, ParentThread->CurrentFrame, sizeof(FEXCore::Core::CPUState)); } - bool IsDone(const FEXCore::Context::Context *CTX) { - return CTX->IsPaused(); + void FEXCore::Context::ContextImpl::SetCPUState(const FEXCore::Core::CPUState *State) { + memcpy(ParentThread->CurrentFrame, State, sizeof(FEXCore::Core::CPUState)); } - void GetCPUState(const FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *State) { - memcpy(State, CTX->ParentThread->CurrentFrame, sizeof(FEXCore::Core::CPUState)); + void FEXCore::Context::ContextImpl::SetCustomCPUBackendFactory(CustomCPUFactoryType Factory) { + CustomCPUFactory = std::move(Factory); } - void SetCPUState(FEXCore::Context::Context *CTX, const FEXCore::Core::CPUState *State) { - memcpy(CTX->ParentThread->CurrentFrame, State, sizeof(FEXCore::Core::CPUState)); - } - - void Pause(FEXCore::Context::Context *CTX) { - CTX->Pause(); - } - - void Stop(FEXCore::Context::Context *CTX) { - CTX->Stop(false); - } - - void SetCustomCPUBackendFactory(FEXCore::Context::Context *CTX, CustomCPUFactoryType Factory) { - CTX->CustomCPUFactory = std::move(Factory); - } - - bool AddVirtualMemoryMapping([[maybe_unused]] FEXCore::Context::Context *CTX, [[maybe_unused]] uint64_t VirtualAddress, [[maybe_unused]] uint64_t PhysicalAddress, [[maybe_unused]] uint64_t Size) { + bool FEXCore::Context::ContextImpl::AddVirtualMemoryMapping([[maybe_unused]] uint64_t VirtualAddress, [[maybe_unused]] uint64_t PhysicalAddress, [[maybe_unused]] uint64_t Size) { return false; } - void RegisterExternalSyscallVisitor(FEXCore::Context::Context *CTX, [[maybe_unused]] uint64_t Syscall, [[maybe_unused]] FEXCore::HLE::SyscallVisitor *Visitor) { + HostFeatures FEXCore::Context::ContextImpl::GetHostFeatures() const { + return HostFeatures; } - HostFeatures GetHostFeatures(const FEXCore::Context::Context *CTX) { - return CTX->HostFeatures; + void FEXCore::Context::ContextImpl::SetSignalDelegator(FEXCore::SignalDelegator *_SignalDelegation) { + SignalDelegation = _SignalDelegation; } - void HandleCallback(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) { - CTX->HandleCallback(Thread, RIP); - } - void HandleSignalHandlerReturn(FEXCore::Context::Context *CTX, bool RT) { - CTX->HandleSignalHandlerReturn(RT); - } - void RegisterHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required) { - CTX->RegisterHostSignalHandler(Signal, std::move(Func), Required); + void FEXCore::Context::ContextImpl::SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) { + SyscallHandler = Handler; + SourcecodeResolver = Handler->GetSourcecodeResolver(); } - void RegisterFrontendHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required) { - CTX->RegisterFrontendHostSignalHandler(Signal, std::move(Func), Required); + FEXCore::CPUID::FunctionResults FEXCore::Context::ContextImpl::RunCPUIDFunction(uint32_t Function, uint32_t Leaf) { + return CPUID.RunFunction(Function, Leaf); } - FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) { - return CTX->CreateThread(NewThreadState, ParentTID); - } - - void ExecutionThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - return CTX->ExecutionThread(Thread); - } - - void InitializeThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - return CTX->InitializeThread(Thread); - } - - void RunThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->RunThread(Thread); - } - - void StopThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->StopThread(Thread); - } - - void DestroyThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->DestroyThread(Thread); - } - - void CleanupAfterFork(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread) { - CTX->CleanupAfterFork(Thread); - } - - void SetSignalDelegator(FEXCore::Context::Context *CTX, FEXCore::SignalDelegator *SignalDelegation) { - CTX->SignalDelegation = SignalDelegation; - } - - void SetSyscallHandler(FEXCore::Context::Context *CTX, FEXCore::HLE::SyscallHandler *Handler) { - CTX->SyscallHandler = Handler; - CTX->SourcecodeResolver = Handler->GetSourcecodeResolver(); - } - - FEXCore::CPUID::FunctionResults RunCPUIDFunction(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf) { - return CTX->CPUID.RunFunction(Function, Leaf); - } - - FEX_DEFAULT_VISIBILITY FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf, uint32_t CPU) { - return CTX->CPUID.RunFunctionName(Function, Leaf, CPU); - } - - void SetAOTIRLoader(FEXCore::Context::Context *CTX, std::function CacheReader) { - CTX->SetAOTIRLoader(CacheReader); - } - - void SetAOTIRWriter(FEXCore::Context::Context *CTX, std::function(const std::string&)> CacheWriter) { - CTX->SetAOTIRWriter(CacheWriter); - } - - void SetAOTIRRenamer(FEXCore::Context::Context *CTX, std::function CacheRenamer) { - CTX->SetAOTIRRenamer(CacheRenamer); - } - - void FinalizeAOTIRCache(FEXCore::Context::Context *CTX) { - CTX->FinalizeAOTIRCache(); - } - - void WriteFilesWithCode(FEXCore::Context::Context *CTX, std::function Writer) { - CTX->WriteFilesWithCode(Writer); - } - - IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(FEXCore::Context::Context *CTX, const std::string &Name) { - return CTX->LoadAOTIRCacheEntry(Name); - } - void UnloadAOTIRCacheEntry(FEXCore::Context::Context *CTX, IR::AOTIRCacheEntry *Entry) { - return CTX->UnloadAOTIRCacheEntry(Entry); - } - - CustomIRResult AddCustomIREntrypoint(FEXCore::Context::Context *CTX, uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data) { - return CTX->AddCustomIREntrypoint(Entrypoint, Handler, Creator, Data); - } - - void AppendThunkDefinitions(FEXCore::Context::Context *CTX, std::vector const& Definitions) { - CTX->AppendThunkDefinitions(Definitions); + FEXCore::CPUID::FunctionResults FEXCore::Context::ContextImpl::RunCPUIDFunctionName(uint32_t Function, uint32_t Leaf, uint32_t CPU) { + return CPUID.RunFunctionName(Function, Leaf, CPU); } void SetVDSOSigReturn(FEXCore::Context::Context *CTX, const VDSOSigReturn &Pointers) { CTX->SetVDSOSigReturn(Pointers); } namespace Debug { - void CompileRIP(FEXCore::Context::Context *CTX, uint64_t RIP) { - CTX->CompileRIP(CTX->ParentThread, RIP); - } - uint64_t GetThreadCount(FEXCore::Context::Context *CTX) { - return CTX->GetThreadCount(); - } + //void CompileRIP(FEXCore::Context::Context *CTX, uint64_t RIP) { + // CTX->CompileRIP(CTX->ParentThread, RIP); + //} + //uint64_t GetThreadCount(FEXCore::Context::Context *CTX) { + // return CTX->GetThreadCount(); + //} - FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(FEXCore::Context::Context *CTX, uint64_t Thread) { - return CTX->GetRuntimeStatsForThread(Thread); - } + //FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(FEXCore::Context::Context *CTX, uint64_t Thread) { + // return CTX->GetRuntimeStatsForThread(Thread); + //} - bool GetDebugDataForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::Core::DebugData *Data) { - return CTX->GetDebugDataForRIP(RIP, Data); - } + //bool GetDebugDataForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::Core::DebugData *Data) { + // return CTX->GetDebugDataForRIP(RIP, Data); + //} - bool FindHostCodeForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, uint8_t **Code) { - return CTX->FindHostCodeForRIP(RIP, Code); - } + //bool FindHostCodeForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, uint8_t **Code) { + // return CTX->FindHostCodeForRIP(RIP, Code); + //} // XXX: // bool FindIRForRIP(FEXCore::Context::Context *CTX, uint64_t RIP, FEXCore::IR::IntrusiveIRList **ir) { diff --git a/External/FEXCore/Source/Interface/Context/Context.h b/External/FEXCore/Source/Interface/Context/Context.h index 317504749..d4ae72324 100644 --- a/External/FEXCore/Source/Interface/Context/Context.h +++ b/External/FEXCore/Source/Interface/Context/Context.h @@ -70,7 +70,130 @@ namespace FEXCore::Context { MODE_SINGLESTEP = 1, }; - struct Context { + class ContextImpl final : public FEXCore::Context::Context { + public: + // Context base class implementation. + bool InitializeContext() override; + + void DestroyContext() override; + + FEXCore::Core::InternalThreadState* InitCore(uint64_t InitialRIP, uint64_t StackPointer) override; + + void SetExitHandler(ExitHandler handler) override; + ExitHandler GetExitHandler() const override; + + void Pause() override; + void Run() override; + void Stop() override; + void Step() override; + + ExitReason RunUntilExit() override; + + void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) override; + + int GetProgramStatus() const override; + + ExitReason GetExitReason() override; + + bool IsDone() const override; + + void GetCPUState(FEXCore::Core::CPUState *State) const override; + void SetCPUState(const FEXCore::Core::CPUState *State) override; + + void SetCustomCPUBackendFactory(CustomCPUFactoryType Factory) override; + + bool AddVirtualMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) override; + + HostFeatures GetHostFeatures() const override; + + void HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) override; + + void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) override; + [[noreturn]] void HandleSignalHandlerReturn(bool RT) override ; + void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) override; + + /** + * @brief Used to create FEX thread objects in preparation for creating a true OS thread. Does set a TID or PID. + * + * @param NewThreadState The initial thread state to setup for our state + * @param ParentTID The PID that was the parent thread that created this + * + * @return The InternalThreadState object that tracks all of the emulated thread's state + * + * Usecases: + * OS thread Creation: + * - Thread = CreateThread(NewState, PPID); + * - InitializeThread(Thread); + * OS fork (New thread created with a clone of thread state): + * - clone{2, 3} + * - Thread = CreateThread(CopyOfThreadState, PPID); + * - ExecutionThread(Thread); // Starts executing without creating another host thread + * Thunk callback executing guest code from native host thread + * - Thread = CreateThread(NewState, PPID); + * - InitializeThreadTLSData(Thread); + * - HandleCallback(Thread, RIP); + */ + FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) override; + + // Public for threading + void ExecutionThread(FEXCore::Core::InternalThreadState *Thread) override; + /** + * @brief Initializes the OS thread object and prepares to start executing on that new OS thread + * + * @param Thread The internal FEX thread state object + * + * The OS thread will wait until RunThread is executed + */ + void InitializeThread(FEXCore::Core::InternalThreadState *Thread) override; + /** + * @brief Starts the OS thread object to start executing guest code + * + * @param Thread The internal FEX thread state object + */ + void RunThread(FEXCore::Core::InternalThreadState *Thread) override; + void StopThread(FEXCore::Core::InternalThreadState *Thread) override; + /** + * @brief Destroys this FEX thread object and stops tracking it internally + * + * @param Thread The internal FEX thread state object + */ + void DestroyThread(FEXCore::Core::InternalThreadState *Thread) override; + void CleanupAfterFork(FEXCore::Core::InternalThreadState *Thread) override; + void SetSignalDelegator(FEXCore::SignalDelegator *SignalDelegation) override; + void SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) override; + FEXCore::CPUID::FunctionResults RunCPUIDFunction(uint32_t Function, uint32_t Leaf) override; + FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(uint32_t Function, uint32_t Leaf, uint32_t CPU) override; + + FEXCore::IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(const std::string& Name) override; + void UnloadAOTIRCacheEntry(FEXCore::IR::AOTIRCacheEntry *Entry) override; + + void SetAOTIRLoader(std::function CacheReader) override { + IRCaptureCache.SetAOTIRLoader(CacheReader); + } + void SetAOTIRWriter(std::function(const std::string&)> CacheWriter) override { + IRCaptureCache.SetAOTIRWriter(CacheWriter); + } + void SetAOTIRRenamer(std::function CacheRenamer) override { + IRCaptureCache.SetAOTIRRenamer(CacheRenamer); + } + + void FinalizeAOTIRCache() override { + IRCaptureCache.FinalizeAOTIRCache(); + } + void WriteFilesWithCode(std::function Writer) override { + IRCaptureCache.WriteFilesWithCode(Writer); + } + void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length) override; + void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length, std::function callback) override; + void MarkMemoryShared() override; + + void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) override; + // returns false if a handler was already registered + CustomIRResult AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator = nullptr, void *Data = nullptr) override; + + void AppendThunkDefinitions(std::vector const& Definitions) override; + + public: friend class FEXCore::HLE::SyscallHandler; #ifdef JIT_ARM64 friend class FEXCore::CPU::Arm64JITCore; @@ -154,36 +277,25 @@ namespace FEXCore::Context { X86GeneratedCode X86CodeGen; VDSOSigReturn VDSOPointers{}; - Context(); - ~Context(); + ContextImpl(); + ~ContextImpl(); - FEXCore::Core::InternalThreadState* InitCore(uint64_t InitialRIP, uint64_t StackPointer); - FEXCore::Context::ExitReason RunUntilExit(); - int GetProgramStatus() const; bool IsPaused() const { return !Running; } - void Pause(); - void Run(); void WaitForThreadsToRun(); - void Step(); void Stop(bool IgnoreCurrentThread); void WaitForIdle(); - void StopThread(FEXCore::Core::InternalThreadState *Thread); void SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event); bool GetGdbServerStatus() const { return DebugServer != nullptr; } void StartGdbServer(); void StopGdbServer(); - void HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP); - [[noreturn]] void HandleSignalHandlerReturn(bool RT); - void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required); - void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required); static void ThreadRemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP); static void ThreadAddBlockLink(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestDestination, uintptr_t HostLink, const std::function &delinker); template static uint64_t ThreadExitFunctionLink(FEXCore::Core::CpuStateFrame *Frame, uint64_t *record) { - FHU::ScopedSignalMaskWithSharedLock lk(Frame->Thread->CTX->CodeInvalidationMutex); + FHU::ScopedSignalMaskWithSharedLock lk(static_cast(Frame->Thread->CTX)->CodeInvalidationMutex); return Fn(Frame, record); } @@ -192,21 +304,17 @@ namespace FEXCore::Context { // Must be called from owning thread static void ThreadRemoveCodeEntryFromJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { auto Thread = Frame->Thread; - + LogMan::Throw::AFmt(Thread->ThreadManager.GetTID() == FHU::Syscalls::gettid(), "Must be called from owning thread {}, not {}", Thread->ThreadManager.GetTID(), FHU::Syscalls::gettid()); - FHU::ScopedSignalMaskWithUniqueLock lk(Thread->CTX->CodeInvalidationMutex); + FHU::ScopedSignalMaskWithUniqueLock lk(static_cast(Thread->CTX)->CodeInvalidationMutex); ThreadRemoveCodeEntry(Thread, GuestRIP); } - // returns false if a handler was already registered - CustomIRResult AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data); - void RemoveCustomIREntrypoint(uintptr_t Entrypoint); // Debugger interface - void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP); uint64_t GetThreadCount() const; FEXCore::Core::RuntimeStats *GetRuntimeStatsForThread(uint64_t Thread); bool GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data); @@ -238,29 +346,6 @@ namespace FEXCore::Context { void CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP); // Used for thread creation from syscalls - /** - * @brief Used to create FEX thread objects in preparation for creating a true OS thread. Does set a TID or PID. - * - * @param NewThreadState The initial thread state to setup for our state - * @param ParentTID The PID that was the parent thread that created this - * - * @return The InternalThreadState object that tracks all of the emulated thread's state - * - * Usecases: - * OS thread Creation: - * - Thread = CreateThread(NewState, PPID); - * - InitializeThread(Thread); - * OS fork (New thread created with a clone of thread state): - * - clone{2, 3} - * - Thread = CreateThread(CopyOfThreadState, PPID); - * - ExecutionThread(Thread); // Starts executing without creating another host thread - * Thunk callback executing guest code from native host thread - * - Thread = CreateThread(NewState, PPID); - * - InitializeThreadTLSData(Thread); - * - HandleCallback(Thread, RIP); - */ - FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID); - /** * @brief Initializes TID, PID and TLS data for a thread * @@ -268,67 +353,15 @@ namespace FEXCore::Context { */ void InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread); - /** - * @brief Initializes the OS thread object and prepares to start executing on that new OS thread - * - * @param Thread The internal FEX thread state object - * - * The OS thread will wait until RunThread is executed - */ - void InitializeThread(FEXCore::Core::InternalThreadState *Thread); - - /** - * @brief Starts the OS thread object to start executing guest code - * - * @param Thread The internal FEX thread state object - */ - void RunThread(FEXCore::Core::InternalThreadState *Thread); - - /** - * @brief Destroys this FEX thread object and stops tracking it internally - * - * @param Thread The internal FEX thread state object - */ - void DestroyThread(FEXCore::Core::InternalThreadState *Thread); void CopyMemoryMapping(FEXCore::Core::InternalThreadState *ParentThread, FEXCore::Core::InternalThreadState *ChildThread); - void CleanupAfterFork(FEXCore::Core::InternalThreadState *ExceptForThread); - std::vector* GetThreads() { return &Threads; } uint8_t GetGPRSize() const { return Config.Is64BitMode ? 8 : 4; } - IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(const std::string &filename); - void UnloadAOTIRCacheEntry(IR::AOTIRCacheEntry *Entry); - FEXCore::JITSymbols Symbols; - // Public for threading - void ExecutionThread(FEXCore::Core::InternalThreadState *Thread); - - void FinalizeAOTIRCache() { - IRCaptureCache.FinalizeAOTIRCache(); - } - - void WriteFilesWithCode(std::function Writer) { - IRCaptureCache.WriteFilesWithCode(Writer); - } - - void SetAOTIRLoader(std::function CacheReader) { - IRCaptureCache.SetAOTIRLoader(CacheReader); - } - - void SetAOTIRWriter(std::function(const std::string&)> CacheWriter) { - IRCaptureCache.SetAOTIRWriter(CacheWriter); - } - - void SetAOTIRRenamer(std::function CacheRenamer) { - IRCaptureCache.SetAOTIRRenamer(CacheRenamer); - } - - void AppendThunkDefinitions(std::vector const& Definitions); - - void SetVDSOSigReturn(const VDSOSigReturn &Pointers) { + void SetVDSOSigReturn(const VDSOSigReturn &Pointers) override { VDSOPointers = Pointers; if (VDSOPointers.VDSO_kernel_sigreturn == nullptr) { VDSOPointers.VDSO_kernel_sigreturn = reinterpret_cast(X86CodeGen.sigreturn_32); @@ -342,8 +375,6 @@ namespace FEXCore::Context { FEXCore::Utils::PooledAllocatorMMap OpDispatcherAllocator; FEXCore::Utils::PooledAllocatorMMap FrontendAllocator; - void MarkMemoryShared(); - bool IsTSOEnabled() { return (IsMemoryShared || !Config.TSOAutoMigration) && Config.TSOEnabled; } protected: diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp index 5aa24e539..63c210102 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp @@ -20,7 +20,7 @@ namespace FEXCore::CPU { // We want vixl to not allocate a default buffer. Jit and dispatcher will manually create one. -Arm64Emitter::Arm64Emitter(FEXCore::Context::Context *ctx, size_t size) +Arm64Emitter::Arm64Emitter(FEXCore::Context::ContextImpl *ctx, size_t size) : Emitter(size ? (uint8_t*)FEXCore::Allocator::mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0) : nullptr, size) , EmitterCTX {ctx} { CPU.SetUp(); diff --git a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h index 32c8c0eba..ddf2810b0 100644 --- a/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h +++ b/External/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.h @@ -85,10 +85,10 @@ constexpr FEXCore::ARMEmitter::PRegister PRED_TMP_32B = FEXCore::ARMEmitter::PRe // be used by both Arm64 JIT and ARM64 Dispatcher class Arm64Emitter : public FEXCore::ARMEmitter::Emitter { protected: - Arm64Emitter(FEXCore::Context::Context *ctx, size_t size); + Arm64Emitter(FEXCore::Context::ContextImpl *ctx, size_t size); ~Arm64Emitter(); - FEXCore::Context::Context *EmitterCTX; + FEXCore::Context::ContextImpl *EmitterCTX; vixl::aarch64::CPU CPU; void LoadConstant(FEXCore::ARMEmitter::Size s, FEXCore::ARMEmitter::Register Reg, uint64_t Constant, bool NOPPad = false); diff --git a/External/FEXCore/Source/Interface/Core/CPUBackend.cpp b/External/FEXCore/Source/Interface/Core/CPUBackend.cpp index 59cc7e659..2f6bc20ea 100644 --- a/External/FEXCore/Source/Interface/Core/CPUBackend.cpp +++ b/External/FEXCore/Source/Interface/Core/CPUBackend.cpp @@ -60,8 +60,8 @@ auto CPUBackend::AllocateNewCodeBuffer(size_t Size) -> CodeBuffer { FEXCore::Allocator::mmap(nullptr, Buffer.Size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); LOGMAN_THROW_AA_FMT(!!Buffer.Ptr, "Couldn't allocate code buffer"); - if (ThreadState->CTX->Config.GlobalJITNaming()) { - ThreadState->CTX->Symbols.RegisterJITSpace(Buffer.Ptr, Buffer.Size); + if (static_cast(ThreadState->CTX)->Config.GlobalJITNaming()) { + static_cast(ThreadState->CTX)->Symbols.RegisterJITSpace(Buffer.Ptr, Buffer.Size); } return Buffer; } diff --git a/External/FEXCore/Source/Interface/Core/CPUID.cpp b/External/FEXCore/Source/Interface/Core/CPUID.cpp index 01e33a203..f2201acf6 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.cpp +++ b/External/FEXCore/Source/Interface/Core/CPUID.cpp @@ -1210,7 +1210,7 @@ FEXCore::CPUID::FunctionResults CPUIDEmu::Function_Reserved(uint32_t Leaf) { return Res; } -void CPUIDEmu::Init(FEXCore::Context::Context *ctx) { +void CPUIDEmu::Init(FEXCore::Context::ContextImpl *ctx) { CTX = ctx; // Setup some state tracking diff --git a/External/FEXCore/Source/Interface/Core/CPUID.h b/External/FEXCore/Source/Interface/Core/CPUID.h index 6ec72991e..dfa8ca2a5 100644 --- a/External/FEXCore/Source/Interface/Core/CPUID.h +++ b/External/FEXCore/Source/Interface/Core/CPUID.h @@ -10,7 +10,7 @@ namespace FEXCore { namespace Context { - struct Context; + class ContextImpl; } // Debugging define to switch what family of CPU we execute as. @@ -31,7 +31,7 @@ public: // if we report anything differently then applications are likely to break constexpr static uint64_t CACHELINE_SIZE = 64; - void Init(FEXCore::Context::Context *ctx); + void Init(FEXCore::Context::ContextImpl *ctx); FEXCore::CPUID::FunctionResults RunFunction(uint32_t Function, uint32_t Leaf) { if (Function < Primary.size()) { @@ -64,7 +64,7 @@ public: } private: - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; bool Hybrid{}; FEX_CONFIG_OPT(Cores, THREADS); diff --git a/External/FEXCore/Source/Interface/Core/Core.cpp b/External/FEXCore/Source/Interface/Core/Core.cpp index bf1228578..41164f0e7 100644 --- a/External/FEXCore/Source/Interface/Core/Core.cpp +++ b/External/FEXCore/Source/Interface/Core/Core.cpp @@ -79,7 +79,7 @@ $end_info$ namespace FEXCore::CPU { - bool CreateCPUCore(FEXCore::Context::Context *CTX) { + bool CreateCPUCore(Context::ContextImpl *CTX) { // This should be used for generating things that are shared between threads CTX->CPUID.Init(CTX); return true; @@ -147,7 +147,7 @@ std::string_view const& GetGRegName(unsigned Reg) { } // namespace FEXCore::Core namespace FEXCore::Context { - Context::Context() + ContextImpl::ContextImpl() : IRCaptureCache {this} { #ifdef BLOCKSTATS BlockData = std::make_unique(); @@ -172,7 +172,7 @@ namespace FEXCore::Context { } } - Context::~Context() { + ContextImpl::~ContextImpl() { { if (CodeObjectCacheService) { CodeObjectCacheService->Shutdown(); @@ -214,7 +214,7 @@ namespace FEXCore::Context { return NewThreadState; } - FEXCore::Core::InternalThreadState* Context::InitCore(uint64_t InitialRIP, uint64_t StackPointer) { + FEXCore::Core::InternalThreadState* ContextImpl::InitCore(uint64_t InitialRIP, uint64_t StackPointer) { // Initialize the CPU core signal handlers & DispatcherConfig switch (Config.Core) { #ifdef INTERPRETER_ENABLED @@ -255,13 +255,13 @@ namespace FEXCore::Context { // Initialize common signal handlers auto PauseHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSignalPause(Thread, Signal, info, ucontext); + return static_cast(Thread->CTX)->Dispatcher->HandleSignalPause(Thread, Signal, info, ucontext); }; SignalDelegation->RegisterHostSignalHandler(SignalDelegator::SIGNAL_FOR_PAUSE, PauseHandler, true); auto GuestSignalHandler = [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext, GuestSigAction *GuestAction, stack_t *GuestStack) -> bool { - return Thread->CTX->Dispatcher->HandleGuestSignal(Thread, Signal, info, ucontext, GuestAction, GuestStack); + return static_cast(Thread->CTX)->Dispatcher->HandleGuestSignal(Thread, Signal, info, ucontext, GuestAction, GuestStack); }; for (uint32_t Signal = 0; Signal <= SignalDelegator::MAX_SIGNALS; ++Signal) { @@ -295,22 +295,22 @@ namespace FEXCore::Context { return Thread; } - void Context::StartGdbServer() { + void ContextImpl::StartGdbServer() { if (!DebugServer) { DebugServer = std::make_unique(this); StartPaused = true; } } - void Context::StopGdbServer() { + void ContextImpl::StopGdbServer() { DebugServer.reset(); } - void Context::HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) { - Thread->CTX->Dispatcher->ExecuteJITCallback(Thread->CurrentFrame, RIP); + void ContextImpl::HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) { + static_cast(Thread->CTX)->Dispatcher->ExecuteJITCallback(Thread->CurrentFrame, RIP); } - void Context::HandleSignalHandlerReturn(bool RT) { + void ContextImpl::HandleSignalHandlerReturn(bool RT) { using SignalHandlerReturnFunc = void(*)(); SignalHandlerReturnFunc SignalHandlerReturn{}; @@ -325,15 +325,15 @@ namespace FEXCore::Context { FEX_UNREACHABLE; } - void Context::RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { + void ContextImpl::RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { SignalDelegation->RegisterHostSignalHandler(Signal, Func, Required); } - void Context::RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { + void ContextImpl::RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) { SignalDelegation->RegisterFrontendHostSignalHandler(Signal, Func, Required); } - void Context::WaitForIdle() { + void ContextImpl::WaitForIdle() { std::unique_lock lk(IdleWaitMutex); IdleWaitCV.wait(lk, [this] { return IdleWaitRefCount.load() == 0; @@ -342,7 +342,7 @@ namespace FEXCore::Context { Running = false; } - void Context::WaitForIdleWithTimeout() { + void ContextImpl::WaitForIdleWithTimeout() { std::unique_lock lk(IdleWaitMutex); bool WaitResult = IdleWaitCV.wait_for(lk, std::chrono::milliseconds(1500), [this] { @@ -360,7 +360,7 @@ namespace FEXCore::Context { WaitForIdle(); } - void Context::NotifyPause() { + void ContextImpl::NotifyPause() { // Tell all the threads that they should pause std::lock_guard lk(ThreadCreationMutex); @@ -373,7 +373,7 @@ namespace FEXCore::Context { } } - void Context::Pause() { + void ContextImpl::Pause() { // If we aren't running, WaitForIdle will never compete. if (Running) { NotifyPause(); @@ -382,7 +382,7 @@ namespace FEXCore::Context { } } - void Context::Run() { + void ContextImpl::Run() { // Spin up all the threads std::lock_guard lk(ThreadCreationMutex); for (auto &Thread : Threads) { @@ -394,7 +394,7 @@ namespace FEXCore::Context { } } - void Context::WaitForThreadsToRun() { + void ContextImpl::WaitForThreadsToRun() { size_t NumThreads{}; { std::lock_guard lk(ThreadCreationMutex); @@ -410,7 +410,7 @@ namespace FEXCore::Context { Running = true; } - void Context::Step() { + void ContextImpl::Step() { { std::lock_guard lk(ThreadCreationMutex); // Walk the threads and tell them to clear their caches @@ -430,7 +430,7 @@ namespace FEXCore::Context { this->Config.MaxInstPerBlock = PreviousMaxIntPerBlock; } - void Context::Stop(bool IgnoreCurrentThread) { + void ContextImpl::Stop(bool IgnoreCurrentThread) { pid_t tid = FHU::Syscalls::gettid(); FEXCore::Core::InternalThreadState* CurrentThread{}; @@ -468,21 +468,21 @@ namespace FEXCore::Context { } } - void Context::StopThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::StopThread(FEXCore::Core::InternalThreadState *Thread) { if (Thread->RunningEvents.Running.exchange(false)) { Thread->SignalReason.store(FEXCore::Core::SignalEvent::Stop); FHU::Syscalls::tgkill(Thread->ThreadManager.PID, Thread->ThreadManager.TID, SignalDelegator::SIGNAL_FOR_PAUSE); } } - void Context::SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event) { + void ContextImpl::SignalThread(FEXCore::Core::InternalThreadState *Thread, FEXCore::Core::SignalEvent Event) { if (Thread->RunningEvents.Running.load()) { Thread->SignalReason.store(Event); FHU::Syscalls::tgkill(Thread->ThreadManager.PID, Thread->ThreadManager.TID, SignalDelegator::SIGNAL_FOR_PAUSE); } } - FEXCore::Context::ExitReason Context::RunUntilExit() { + FEXCore::Context::ExitReason ContextImpl::RunUntilExit() { if(!StartPaused) { // We will only have one thread at this point, but just in case run notify everything std::lock_guard lk(ThreadCreationMutex); @@ -503,16 +503,16 @@ namespace FEXCore::Context { } } - int Context::GetProgramStatus() const { + int ContextImpl::GetProgramStatus() const { return ParentThread->StatusCode; } - void Context::InitializeThreadData(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::InitializeThreadData(FEXCore::Core::InternalThreadState *Thread) { Thread->CPUBackend->Initialize(); } struct ExecutionThreadHandler { - FEXCore::Context::Context *This; + ContextImpl *This; FEXCore::Core::InternalThreadState *Thread; }; @@ -523,7 +523,7 @@ namespace FEXCore::Context { return nullptr; } - void Context::InitializeThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::InitializeThread(FEXCore::Core::InternalThreadState *Thread) { // This will create the execution thread but it won't actually start executing ExecutionThreadHandler *Arg = reinterpret_cast(FEXCore::Allocator::malloc(sizeof(ExecutionThreadHandler))); Arg->This = this; @@ -545,7 +545,7 @@ namespace FEXCore::Context { } } - void Context::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::InitializeThreadTLSData(FEXCore::Core::InternalThreadState *Thread) { // Let's do some initial bookkeeping here Thread->ThreadManager.TID = FHU::Syscalls::gettid(); Thread->ThreadManager.PID = ::getpid(); @@ -553,12 +553,12 @@ namespace FEXCore::Context { ThunkHandler->RegisterTLSState(Thread); } - void Context::RunThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::RunThread(FEXCore::Core::InternalThreadState *Thread) { // Tell the thread to start executing Thread->StartRunning.NotifyAll(); } - void Context::InitializeCompiler(FEXCore::Core::InternalThreadState* Thread) { + void ContextImpl::InitializeCompiler(FEXCore::Core::InternalThreadState* Thread) { Thread->OpDispatcher = std::make_unique(this); Thread->OpDispatcher->SetMultiblock(Config.Multiblock); Thread->LookupCache = std::make_unique(this); @@ -610,7 +610,7 @@ namespace FEXCore::Context { } } - FEXCore::Core::InternalThreadState* Context::CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) { + FEXCore::Core::InternalThreadState* ContextImpl::CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) { FEXCore::Core::InternalThreadState *Thread = new FEXCore::Core::InternalThreadState{}; // Copy over the new thread state to the new object @@ -632,7 +632,7 @@ namespace FEXCore::Context { return Thread; } - void Context::DestroyThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::DestroyThread(FEXCore::Core::InternalThreadState *Thread) { // remove new thread object { std::lock_guard lk(ThreadCreationMutex); @@ -651,7 +651,7 @@ namespace FEXCore::Context { delete Thread; } - void Context::CleanupAfterFork(FEXCore::Core::InternalThreadState *LiveThread) { + void ContextImpl::CleanupAfterFork(FEXCore::Core::InternalThreadState *LiveThread) { // This function is called after fork // We need to cleanup some of the thread data that is dead for (auto &DeadThread : Threads) { @@ -690,11 +690,11 @@ namespace FEXCore::Context { FEXCore::Threads::Thread::CleanupAfterFork(); } - void Context::AddBlockMapping(FEXCore::Core::InternalThreadState *Thread, uint64_t Address, void *Ptr) { + void ContextImpl::AddBlockMapping(FEXCore::Core::InternalThreadState *Thread, uint64_t Address, void *Ptr) { Thread->LookupCache->AddBlockMapping(Address, Ptr); } - void Context::ClearCodeCache(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::ClearCodeCache(FEXCore::Core::InternalThreadState *Thread) { FEXCORE_PROFILE_INSTANT("ClearCodeCache"); { @@ -712,7 +712,7 @@ namespace FEXCore::Context { static void IRDumper(FEXCore::Core::InternalThreadState *Thread, IR::IREmitter *IREmitter, uint64_t GuestRIP, IR::RegisterAllocationData* RA) { FILE* f = nullptr; bool CloseAfter = false; - const auto DumpIRStr = Thread->CTX->Config.DumpIR(); + const auto DumpIRStr = static_cast(Thread->CTX)->Config.DumpIR(); // DumpIRStr might be no if not dumping but ShouldDump is set in OpDisp if (DumpIRStr =="stderr" || DumpIRStr =="no") { @@ -739,7 +739,7 @@ namespace FEXCore::Context { } }; - static void ValidateIR(FEXCore::Context::Context *ctx, IR::IREmitter *IREmitter) { + static void ValidateIR(ContextImpl *ctx, IR::IREmitter *IREmitter) { // Convert to text, Parse, Convert to text again and make sure the texts match std::stringstream out; static auto compaction = IR::CreateIRCompaction(ctx->OpDispatcherAllocator); @@ -763,7 +763,7 @@ namespace FEXCore::Context { } } - Context::GenerateIRResult Context::GenerateIR(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP, bool ExtendedDebugInfo) { + ContextImpl::GenerateIRResult ContextImpl::GenerateIR(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP, bool ExtendedDebugInfo) { FEXCORE_PROFILE_SCOPED("GenerateIR"); Thread->OpDispatcher->ReownOrClaimBuffer(); @@ -790,7 +790,7 @@ namespace FEXCore::Context { Thread->FrontendDecoder->DecodeInstructionsAtEntry(GuestCode, GuestRIP, [Thread](uint64_t BlockEntry, uint64_t Start, uint64_t Length) { if (Thread->LookupCache->AddBlockExecutableRange(BlockEntry, Start, Length)) { - Thread->CTX->SyscallHandler->MarkGuestExecutableRange(Start, Length); + static_cast(Thread->CTX)->SyscallHandler->MarkGuestExecutableRange(Start, Length); } }); @@ -908,14 +908,14 @@ namespace FEXCore::Context { IR::IREmitter *IREmitter = Thread->OpDispatcher.get(); - auto ShouldDump = Thread->CTX->Config.DumpIR() != "no" || Thread->OpDispatcher->ShouldDump; + auto ShouldDump = static_cast(Thread->CTX)->Config.DumpIR() != "no" || Thread->OpDispatcher->ShouldDump; // Debug { if (ShouldDump) { IRDumper(Thread, IREmitter, GuestRIP, nullptr); } - if (Thread->CTX->Config.ValidateIRarser) { + if (static_cast(Thread->CTX)->Config.ValidateIRarser) { ValidateIR(this, IREmitter); } } @@ -945,7 +945,7 @@ namespace FEXCore::Context { }; } - Context::CompileCodeResult Context::CompileCode(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { + ContextImpl::CompileCodeResult ContextImpl::CompileCode(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { FEXCore::IR::IRListView *IRList {}; FEXCore::Core::DebugData *DebugData {}; FEXCore::IR::RegisterAllocationData::UniquePtr RAData {}; @@ -1030,7 +1030,7 @@ namespace FEXCore::Context { }; } - void Context::CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { + void ContextImpl::CompileBlockJit(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { auto NewBlock = CompileBlock(Frame, GuestRIP); if (NewBlock == 0) { @@ -1041,7 +1041,7 @@ namespace FEXCore::Context { } } - uintptr_t Context::CompileBlock(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { + uintptr_t ContextImpl::CompileBlock(FEXCore::Core::CpuStateFrame *Frame, uint64_t GuestRIP) { FEXCORE_PROFILE_SCOPED("CompileBlock"); auto Thread = Frame->Thread; @@ -1141,7 +1141,7 @@ namespace FEXCore::Context { return (uintptr_t)CodePtr; } - void Context::ExecutionThread(FEXCore::Core::InternalThreadState *Thread) { + void ContextImpl::ExecutionThread(FEXCore::Core::InternalThreadState *Thread) { Core::ThreadData.Thread = Thread; Thread->ExitReason = FEXCore::Context::ExitReason::EXIT_WAITING; @@ -1152,7 +1152,7 @@ namespace FEXCore::Context { // Now notify the thread that we are initialized Thread->ThreadWaiting.NotifyAll(); - if (Thread != Thread->CTX->ParentThread || StartPaused || Thread->StartPaused) { + if (Thread != static_cast(Thread->CTX)->ParentThread || StartPaused || Thread->StartPaused) { // Parent thread doesn't need to wait to run Thread->StartRunning.Wait(); } @@ -1164,7 +1164,7 @@ namespace FEXCore::Context { Thread->RunningEvents.Running = true; - Thread->CTX->Dispatcher->ExecuteDispatch(Thread->CurrentFrame); + static_cast(Thread->CTX)->Dispatcher->ExecuteDispatch(Thread->CurrentFrame); Thread->RunningEvents.Running = false; } @@ -1193,7 +1193,7 @@ namespace FEXCore::Context { SignalDelegation->UninstallTLSState(Thread); // If the parent thread is waiting to join, then we can't destroy our thread object - if (!Thread->DestroyedByParent && Thread != Thread->CTX->ParentThread) { + if (!Thread->DestroyedByParent && Thread != static_cast(Thread->CTX)->ParentThread) { Thread->CTX->DestroyThread(Thread); } } @@ -1206,34 +1206,34 @@ namespace FEXCore::Context { for (auto it = lower; it != upper; it++) { for (auto Address: it->second) { - Context::ThreadRemoveCodeEntry(Thread, Address); + ContextImpl::ThreadRemoveCodeEntry(Thread, Address); } it->second.clear(); } } - static void InvalidateGuestCodeRangeInternal(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length) { - std::lock_guard lk(CTX->ThreadCreationMutex); + static void InvalidateGuestCodeRangeInternal(ContextImpl *CTX, uint64_t Start, uint64_t Length) { + std::lock_guard lk(static_cast(CTX)->ThreadCreationMutex); - for (auto &Thread : CTX->Threads) { + for (auto &Thread : static_cast(CTX)->Threads) { InvalidateGuestThreadCodeRange(Thread, Start, Length); } } - void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length) { - FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CTX->CodeInvalidationMutex); + void ContextImpl::InvalidateGuestCodeRange(uint64_t Start, uint64_t Length) { + FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CodeInvalidationMutex); - InvalidateGuestCodeRangeInternal(CTX, Start, Length); + InvalidateGuestCodeRangeInternal(this, Start, Length); } - void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length, std::function CallAfter) { - FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CTX->CodeInvalidationMutex); + void ContextImpl::InvalidateGuestCodeRange(uint64_t Start, uint64_t Length, std::function CallAfter) { + FHU::ScopedSignalMaskWithUniqueLock CodeInvalidationLock(CodeInvalidationMutex); - InvalidateGuestCodeRangeInternal(CTX, Start, Length); + InvalidateGuestCodeRangeInternal(this, Start, Length); CallAfter(Start, Length); } - void Context::MarkMemoryShared() { + void ContextImpl::MarkMemoryShared() { if (!IsMemoryShared) { IsMemoryShared = true; @@ -1253,18 +1253,14 @@ namespace FEXCore::Context { } } - void MarkMemoryShared(FEXCore::Context::Context *CTX) { - CTX->MarkMemoryShared(); - } - - void Context::ThreadAddBlockLink(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestDestination, uintptr_t HostLink, const std::function &delinker) { - std::shared_lock lk(Thread->CTX->CodeInvalidationMutex); + void ContextImpl::ThreadAddBlockLink(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestDestination, uintptr_t HostLink, const std::function &delinker) { + std::shared_lock lk(static_cast(Thread->CTX)->CodeInvalidationMutex); Thread->LookupCache->AddBlockLink(GuestDestination, HostLink, delinker); } - void Context::ThreadRemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { - LogMan::Throw::AFmt(Thread->CTX->CodeInvalidationMutex.try_lock() == false, "CodeInvalidationMutex needs to be unique_locked here"); + void ContextImpl::ThreadRemoveCodeEntry(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) { + LogMan::Throw::AFmt(static_cast(Thread->CTX)->CodeInvalidationMutex.try_lock() == false, "CodeInvalidationMutex needs to be unique_locked here"); std::lock_guard lk(Thread->LookupCache->WriteLock); @@ -1272,7 +1268,7 @@ namespace FEXCore::Context { Thread->LookupCache->Erase(GuestRIP); } - CustomIRResult Context::AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data) { + CustomIRResult ContextImpl::AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator, void *Data) { LOGMAN_THROW_A_FMT(Config.Is64BitMode || !(Entrypoint >> 32), "64-bit Entrypoint in 32-bit mode {:x}", Entrypoint); std::unique_lock lk(CustomIRMutex); @@ -1288,12 +1284,12 @@ namespace FEXCore::Context { } } - void Context::RemoveCustomIREntrypoint(uintptr_t Entrypoint) { + void ContextImpl::RemoveCustomIREntrypoint(uintptr_t Entrypoint) { LOGMAN_THROW_A_FMT(Config.Is64BitMode || !(Entrypoint >> 32), "64-bit Entrypoint in 32-bit mode {:x}", Entrypoint); std::scoped_lock lk(CustomIRMutex); - InvalidateGuestCodeRange(this, Entrypoint, 1, [this](uint64_t Entrypoint, uint64_t) { + InvalidateGuestCodeRange(Entrypoint, 1, [this](uint64_t Entrypoint, uint64_t) { CustomIRHandlers.erase(Entrypoint); }); } @@ -1303,24 +1299,26 @@ namespace FEXCore::Context { uint64_t RIPBackup = Thread->CurrentFrame->State.rip; Thread->CurrentFrame->State.rip = RIP; + auto CTX = static_cast(Thread->CTX); + // Erase the RIP from all the storage backings if it exists - ThreadRemoveCodeEntry(Thread, RIP); + CTX->ThreadRemoveCodeEntry(Thread, RIP); // We don't care if compilation passes or not - CompileBlock(Thread->CurrentFrame, RIP); + CTX->CompileBlock(Thread->CurrentFrame, RIP); Thread->CurrentFrame->State.rip = RIPBackup; } - uint64_t Context::GetThreadCount() const { + uint64_t ContextImpl::GetThreadCount() const { return Threads.size(); } - FEXCore::Core::RuntimeStats *Context::GetRuntimeStatsForThread(uint64_t Thread) { + FEXCore::Core::RuntimeStats *ContextImpl::GetRuntimeStatsForThread(uint64_t Thread) { return &Threads[Thread]->Stats; } - bool Context::GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data) { + bool ContextImpl::GetDebugDataForRIP(uint64_t RIP, FEXCore::Core::DebugData *Data) { std::lock_guard lk(ParentThread->LookupCache->WriteLock); auto it = ParentThread->DebugStore.find(RIP); if (it == ParentThread->DebugStore.end()) { @@ -1331,7 +1329,7 @@ namespace FEXCore::Context { return true; } - bool Context::FindHostCodeForRIP(uint64_t RIP, uint8_t **Code) { + bool ContextImpl::FindHostCodeForRIP(uint64_t RIP, uint8_t **Code) { uintptr_t HostCode = ParentThread->LookupCache->FindBlock(RIP); if (!HostCode) { return false; @@ -1347,7 +1345,7 @@ namespace FEXCore::Context { return Result; } - IR::AOTIRCacheEntry *Context::LoadAOTIRCacheEntry(const std::string &filename) { + IR::AOTIRCacheEntry *ContextImpl::LoadAOTIRCacheEntry(const std::string &filename) { auto rv = IRCaptureCache.LoadAOTIRCacheEntry(filename); if (DebugServer) { DebugServer->AlertLibrariesChanged(); @@ -1355,19 +1353,18 @@ namespace FEXCore::Context { return rv; } - void Context::UnloadAOTIRCacheEntry(IR::AOTIRCacheEntry *Entry) { + void ContextImpl::UnloadAOTIRCacheEntry(IR::AOTIRCacheEntry *Entry) { IRCaptureCache.UnloadAOTIRCacheEntry(Entry); if (DebugServer) { DebugServer->AlertLibrariesChanged(); } } - - void Context::AppendThunkDefinitions(std::vector const& Definitions) { + void ContextImpl::AppendThunkDefinitions(std::vector const& Definitions) { ThunkHandler->AppendThunkDefinitions(Definitions); } - void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) { + void ContextImpl::ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) { Thread->FrontendDecoder->SetExternalBranches(ExternalBranches); Thread->FrontendDecoder->SetSectionMaxAddress(SectionMaxAddress); } diff --git a/External/FEXCore/Source/Interface/Core/Core.h b/External/FEXCore/Source/Interface/Core/Core.h index 3279042b8..64c3d4b37 100644 --- a/External/FEXCore/Source/Interface/Core/Core.h +++ b/External/FEXCore/Source/Interface/Core/Core.h @@ -5,7 +5,7 @@ namespace FEXCore { } namespace FEXCore::Context { - struct Context; + class ContextImpl; } namespace FEXCore::CPU { @@ -17,7 +17,7 @@ namespace FEXCore::CPU { * * @return true if core was able to be create */ - bool CreateCPUCore(FEXCore::Context::Context *CTX); + bool CreateCPUCore(FEXCore::Context::ContextImpl *CTX); - bool LoadCode(FEXCore::Context::Context *CTX, FEXCore::CodeLoader *Loader); + bool LoadCode(FEXCore::Context::ContextImpl *CTX, FEXCore::CodeLoader *Loader); } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp index 025198559..057d1c2a3 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.cpp @@ -35,7 +35,7 @@ namespace FEXCore::CPU { constexpr size_t MAX_DISPATCHER_CODE_SIZE = 4096; -Arm64Dispatcher::Arm64Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config) +Arm64Dispatcher::Arm64Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config) : FEXCore::CPU::Dispatcher(ctx, config), Arm64Emitter(ctx, MAX_DISPATCHER_CODE_SIZE) #ifdef VIXL_SIMULATOR , Simulator {&Decoder} @@ -578,10 +578,10 @@ size_t Arm64Dispatcher::GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t Gues // If we have a gdb server running then run in a less efficient mode that checks if we need to exit // This happens when single stepping - static_assert(sizeof(FEXCore::Context::Context::Config.RunningMode) == 4, "This is expected to be size of 4"); + static_assert(sizeof(FEXCore::Context::ContextImpl::Config.RunningMode) == 4, "This is expected to be size of 4"); emit.ldr(ARMEmitter::XReg::x0, STATE_PTR(CpuStateFrame, Thread)); emit.ldr(ARMEmitter::XReg::x0, ARMEmitter::Reg::r0, offsetof(FEXCore::Core::InternalThreadState, CTX)); // Get Context - emit.ldr(ARMEmitter::WReg::w0, ARMEmitter::Reg::r0, offsetof(FEXCore::Context::Context, Config.RunningMode)); + emit.ldr(ARMEmitter::WReg::w0, ARMEmitter::Reg::r0, offsetof(FEXCore::Context::ContextImpl, Config.RunningMode)); // If the value == 0 then we don't need to stop emit.cbz(ARMEmitter::Size::i32Bit, ARMEmitter::Reg::r0, &RunBlock); @@ -672,7 +672,7 @@ void Arm64Dispatcher::InitThreadPointers(FEXCore::Core::InternalThreadState *Thr } } -std::unique_ptr Dispatcher::CreateArm64(FEXCore::Context::Context *CTX, const DispatcherConfig &Config) { +std::unique_ptr Dispatcher::CreateArm64(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config) { return std::make_unique(CTX, Config); } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h index fc52a541c..bb9e00a58 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Arm64Dispatcher.h @@ -7,10 +7,6 @@ #include #endif -namespace FEXCore::Context { -struct Context; -} - namespace FEXCore::Core { struct InternalThreadState; } @@ -22,7 +18,7 @@ namespace FEXCore::CPU { class Arm64Dispatcher final : public Dispatcher, public Arm64Emitter { public: - Arm64Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config); + Arm64Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config); void InitThreadPointers(FEXCore::Core::InternalThreadState *Thread) override; size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) override; size_t GenerateInterpreterTrampoline(uint8_t *CodeBuffer) override; diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp index bcb4563aa..c2a2f8122 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp @@ -22,7 +22,7 @@ namespace FEXCore::CPU { -void Dispatcher::SleepThread(FEXCore::Context::Context *ctx, FEXCore::Core::CpuStateFrame *Frame) { +void Dispatcher::SleepThread(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::CpuStateFrame *Frame) { auto Thread = Frame->Thread; --ctx->IdleWaitRefCount; @@ -1185,7 +1185,7 @@ bool Dispatcher::HandleSignalPause(FEXCore::Core::InternalThreadState *Thread, i if (Thread->RunningEvents.ThreadSleeping) { // If the thread was sleeping then its idle counter was decremented // Reincrement it here to not break logic - ++Thread->CTX->IdleWaitRefCount; + ++static_cast(Thread->CTX)->IdleWaitRefCount; } Thread->SignalReason.store(FEXCore::Core::SignalEvent::Nothing); @@ -1207,14 +1207,14 @@ bool Dispatcher::HandleSignalPause(FEXCore::Core::InternalThreadState *Thread, i } uint64_t Dispatcher::GetCompileBlockPtr() { - using ClassPtrType = void (FEXCore::Context::Context::*)(FEXCore::Core::CpuStateFrame *, uint64_t); + using ClassPtrType = void (FEXCore::Context::ContextImpl::*)(FEXCore::Core::CpuStateFrame *, uint64_t); union PtrCast { ClassPtrType ClassPtr; uintptr_t Data; }; PtrCast CompileBlockPtr; - CompileBlockPtr.ClassPtr = &FEXCore::Context::Context::CompileBlockJit; + CompileBlockPtr.ClassPtr = &FEXCore::Context::ContextImpl::CompileBlockJit; return CompileBlockPtr.Data; } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h index a1724642a..6a8381800 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.h @@ -20,7 +20,7 @@ struct InternalThreadState; } namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::CPU { @@ -74,8 +74,8 @@ public: virtual size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) = 0; virtual size_t GenerateInterpreterTrampoline(uint8_t *CodeBuffer) = 0; - static std::unique_ptr CreateX86(FEXCore::Context::Context *CTX, const DispatcherConfig &Config); - static std::unique_ptr CreateArm64(FEXCore::Context::Context *CTX, const DispatcherConfig &Config); + static std::unique_ptr CreateX86(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config); + static std::unique_ptr CreateArm64(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config); virtual void ExecuteDispatch(FEXCore::Core::CpuStateFrame *Frame) { DispatchPtr(Frame); @@ -86,7 +86,7 @@ public: } protected: - Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &Config) + Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &Config) : CTX {ctx} , config {Config} {} @@ -158,10 +158,10 @@ protected: virtual void SpillSRA(FEXCore::Core::InternalThreadState *Thread, void *ucontext, uint32_t IgnoreMask) {} - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; DispatcherConfig config; - static void SleepThread(FEXCore::Context::Context *ctx, FEXCore::Core::CpuStateFrame *Frame); + static void SleepThread(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::CpuStateFrame *Frame); static uint64_t GetCompileBlockPtr(); diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp index d903265d0..1308a7ea9 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.cpp @@ -27,7 +27,7 @@ namespace FEXCore::CPU { static constexpr size_t MAX_DISPATCHER_CODE_SIZE = 4096; #define STATE r14 -X86Dispatcher::X86Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config) +X86Dispatcher::X86Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config) : Dispatcher(ctx, config) , Xbyak::CodeGenerator(MAX_DISPATCHER_CODE_SIZE, FEXCore::Allocator::mmap(nullptr, MAX_DISPATCHER_CODE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0), @@ -433,7 +433,7 @@ size_t X86Dispatcher::GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestR emit.mov(rax, reinterpret_cast(CTX)); // If the value == 0 then we don't need to stop - emit.cmp(dword [rax + (offsetof(FEXCore::Context::Context, Config.RunningMode))], 0); + emit.cmp(dword [rax + (offsetof(FEXCore::Context::ContextImpl, Config.RunningMode))], 0); emit.je(RunBlock); { // Make sure RIP is syncronized to the context @@ -499,7 +499,7 @@ void X86Dispatcher::InitThreadPointers(FEXCore::Core::InternalThreadState *Threa } } -std::unique_ptr Dispatcher::CreateX86(FEXCore::Context::Context *CTX, const DispatcherConfig &Config) { +std::unique_ptr Dispatcher::CreateX86(FEXCore::Context::ContextImpl *CTX, const DispatcherConfig &Config) { return std::make_unique(CTX, Config); } diff --git a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h index 22a676003..46001fcc9 100644 --- a/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h +++ b/External/FEXCore/Source/Interface/Core/Dispatcher/X86Dispatcher.h @@ -5,10 +5,6 @@ #define XBYAK64 #include -namespace FEXCore::Context { - struct Context; -} - namespace FEXCore::Core { struct InternalThreadState; } @@ -17,7 +13,7 @@ namespace FEXCore::CPU { class X86Dispatcher final : public Dispatcher, public Xbyak::CodeGenerator { public: - X86Dispatcher(FEXCore::Context::Context *ctx, const DispatcherConfig &config); + X86Dispatcher(FEXCore::Context::ContextImpl *ctx, const DispatcherConfig &config); void InitThreadPointers(FEXCore::Core::InternalThreadState *Thread) override; size_t GenerateGDBPauseCheck(uint8_t *CodeBuffer, uint64_t GuestRIP) override; size_t GenerateInterpreterTrampoline(uint8_t *CodeBuffer) override; diff --git a/External/FEXCore/Source/Interface/Core/Frontend.cpp b/External/FEXCore/Source/Interface/Core/Frontend.cpp index c74fec855..c3f372092 100644 --- a/External/FEXCore/Source/Interface/Core/Frontend.cpp +++ b/External/FEXCore/Source/Interface/Core/Frontend.cpp @@ -79,7 +79,7 @@ static uint32_t MapVEXToReg(uint8_t vvvv, bool HasXMM) { } } -Decoder::Decoder(FEXCore::Context::Context *ctx) +Decoder::Decoder(FEXCore::Context::ContextImpl *ctx) : CTX {ctx} , OSABI { ctx->SyscallHandler ? ctx->SyscallHandler->GetOSABI() : FEXCore::HLE::SyscallOSABI::OS_UNKNOWN } , PoolObject {ctx->FrontendAllocator, sizeof(FEXCore::X86Tables::DecodedInst) * DefaultDecodedBufferSize} { diff --git a/External/FEXCore/Source/Interface/Core/Frontend.h b/External/FEXCore/Source/Interface/Core/Frontend.h index 8a1a3c4b2..6e7310ef5 100644 --- a/External/FEXCore/Source/Interface/Core/Frontend.h +++ b/External/FEXCore/Source/Interface/Core/Frontend.h @@ -11,7 +11,7 @@ #include namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::Frontend { @@ -25,7 +25,7 @@ public: bool HasInvalidInstruction{}; }; - Decoder(FEXCore::Context::Context *ctx); + Decoder(FEXCore::Context::ContextImpl *ctx); ~Decoder(); void DecodeInstructionsAtEntry(uint8_t const* InstStream, uint64_t PC, std::function AddContainedCodePage); @@ -52,7 +52,7 @@ private: bool L; // VEX.L bit (if set then 256 bit operation, if unset then scalar or 128-bit operation) }; - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; const FEXCore::HLE::SyscallOSABI OSABI{}; bool DecodeInstruction(uint64_t PC); diff --git a/External/FEXCore/Source/Interface/Core/GdbServer.cpp b/External/FEXCore/Source/Interface/Core/GdbServer.cpp index a884dd684..b50ca0858 100644 --- a/External/FEXCore/Source/Interface/Core/GdbServer.cpp +++ b/External/FEXCore/Source/Interface/Core/GdbServer.cpp @@ -68,11 +68,11 @@ void GdbServer::WaitForThreadWakeup() { ThreadBreakEvent.Wait(); } -GdbServer::GdbServer(FEXCore::Context::Context *ctx) : CTX(ctx) { +GdbServer::GdbServer(FEXCore::Context::ContextImpl *ctx) : CTX(ctx) { // Pass all signals by default std::fill(PassSignals.begin(), PassSignals.end(), true); - Context::SetExitHandler(ctx, [this](uint64_t ThreadId, FEXCore::Context::ExitReason ExitReason) { + ctx->SetExitHandler([this](uint64_t ThreadId, FEXCore::Context::ExitReason ExitReason) { if (ExitReason == FEXCore::Context::ExitReason::EXIT_DEBUG) { this->Break(SIGTRAP); } diff --git a/External/FEXCore/Source/Interface/Core/GdbServer.h b/External/FEXCore/Source/Interface/Core/GdbServer.h index 9ce3c8669..9b6f8dfa0 100644 --- a/External/FEXCore/Source/Interface/Core/GdbServer.h +++ b/External/FEXCore/Source/Interface/Core/GdbServer.h @@ -19,12 +19,12 @@ $end_info$ namespace FEXCore { namespace Context { - struct Context; + class ContextImpl; } class GdbServer { public: - GdbServer(FEXCore::Context::Context *ctx); + GdbServer(FEXCore::Context::ContextImpl *ctx); // Public for threading void GdbServerLoop(); @@ -75,7 +75,7 @@ private: std::string readRegs(); HandledPacketType readReg(const std::string& packet); - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; std::unique_ptr gdbServerThread; std::unique_ptr CommsStream; std::mutex sendMutex; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp index 9b24cb9c4..d84e4fdb3 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/BranchOps.cpp @@ -79,7 +79,7 @@ DEF_OP(Syscall) { Args.Argument[j] = *GetSrc(Data->SSAData, Op->Header.Args[j]); } - uint64_t Res = FEXCore::Context::HandleSyscall(Data->State->CTX->SyscallHandler, Data->State->CurrentFrame, &Args); + uint64_t Res = FEXCore::Context::HandleSyscall(static_cast(Data->State->CTX)->SyscallHandler, Data->State->CurrentFrame, &Args); GD = Res; } @@ -114,7 +114,7 @@ DEF_OP(InlineSyscall) { DEF_OP(Thunk) { auto Op = IROp->C(); - auto thunkFn = Data->State->CTX->ThunkHandler->LookupThunk(Op->ThunkNameHash); + auto thunkFn = static_cast(Data->State->CTX)->ThunkHandler->LookupThunk(Op->ThunkNameHash); thunkFn(*GetSrc(Data->SSAData, Op->ArgPtr)); } @@ -130,7 +130,7 @@ DEF_OP(ValidateCode) { } DEF_OP(ThreadRemoveCodeEntry) { - Data->State->CTX->ThreadRemoveCodeEntryFromJit(Data->State->CurrentFrame, Data->CurrentEntry); + static_cast(Data->State->CTX)->ThreadRemoveCodeEntryFromJit(Data->State->CurrentFrame, Data->CurrentEntry); } DEF_OP(CPUID) { @@ -139,7 +139,7 @@ DEF_OP(CPUID) { const uint64_t Arg = *GetSrc(Data->SSAData, Op->Function); const uint64_t Leaf = *GetSrc(Data->SSAData, Op->Leaf); - auto Results = Data->State->CTX->CPUID.RunFunction(Arg, Leaf); + auto Results = Data->State->CTX->RunCPUIDFunction(Arg, Leaf); memcpy(DstPtr, &Results, sizeof(uint32_t) * 4); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h index 626137b1f..5190d9432 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterClass.h @@ -35,7 +35,7 @@ public: [[nodiscard]] bool NeedsOpDispatch() override { return true; } - static void InitializeSignalHandlers(FEXCore::Context::Context *CTX); + static void InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX); void ClearCache() override; diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp index 9a3472997..0b3d25ca3 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.cpp @@ -49,9 +49,9 @@ InterpreterCore::InterpreterCore(Dispatcher *Dispatcher, FEXCore::Core::Internal ClearCache(); } -void InterpreterCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { +void InterpreterCore::InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX) { CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); + return reinterpret_cast(Thread->CTX)->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); }, true); #ifdef _M_ARM_64 @@ -67,7 +67,7 @@ CPUBackend::CompiledCode InterpreterCore::CompileCode(uint64_t Entry, [[maybe_un const auto MaxSize = IRSize + Dispatcher::MaxInterpreterTrampolineSize + GDBEnabled * Dispatcher::MaxGDBPauseCheckSize; if ((BufferUsed + MaxSize) > CurrentCodeBuffer->Size) { - ThreadState->CTX->ClearCodeCache(ThreadState); + static_cast(ThreadState->CTX)->ClearCodeCache(ThreadState); } CPUBackend::CompiledCode CodeData{}; @@ -103,11 +103,11 @@ void InterpreterCore::ClearCache() { BufferUsed = 0; } -std::unique_ptr CreateInterpreterCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) { +std::unique_ptr CreateInterpreterCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) { return std::make_unique(ctx->Dispatcher.get(), Thread); } -void InitializeInterpreterSignalHandlers(FEXCore::Context::Context *CTX) { +void InitializeInterpreterSignalHandlers(FEXCore::Context::ContextImpl *CTX) { InterpreterCore::InitializeSignalHandlers(CTX); } diff --git a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h index 8cd6d7f33..a59731bd4 100644 --- a/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h +++ b/External/FEXCore/Source/Interface/Core/Interpreter/InterpreterCore.h @@ -3,7 +3,7 @@ #include namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::Core { @@ -14,9 +14,9 @@ namespace FEXCore::CPU { class CPUBackend; struct DispatcherConfig; -[[nodiscard]] std::unique_ptr CreateInterpreterCore(FEXCore::Context::Context *ctx, +[[nodiscard]] std::unique_ptr CreateInterpreterCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); -void InitializeInterpreterSignalHandlers(FEXCore::Context::Context *CTX); +void InitializeInterpreterSignalHandlers(FEXCore::Context::ContextImpl *CTX); CPUBackendFeatures GetInterpreterBackendFeatures(); } // namespace FEXCore::CPU diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp index b71160a79..cc9537cc7 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/BranchOps.cpp @@ -324,7 +324,7 @@ DEF_OP(Thunk) { mov(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r0, GetReg(Op->ArgPtr.ID())); - auto thunkFn = ThreadState->CTX->ThunkHandler->LookupThunk(Op->ThunkNameHash); + auto thunkFn = static_cast(ThreadState->CTX)->ThunkHandler->LookupThunk(Op->ThunkNameHash); LoadConstant(ARMEmitter::Size::i64Bit, ARMEmitter::Reg::r2, (uintptr_t)thunkFn); #ifdef VIXL_SIMULATOR GenerateIndirectRuntimeCall(ARMEmitter::Reg::r2); diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp index 1ac8c87dd..e38d4be5c 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JIT.cpp @@ -484,7 +484,7 @@ static uint64_t Arm64JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Fram FEXCore::ARMEmitter::Emitter::ClearICache((void*)branch, 24); // Add de-linking handler - Context::Context::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [branch, LinkerAddress]{ + Context::ContextImpl::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [branch, LinkerAddress]{ FEXCore::ARMEmitter::Emitter emit((uint8_t*)(branch), 24); FEXCore::ARMEmitter::ForwardLabel l_BranchHost; emit.ldr(FEXCore::ARMEmitter::XReg::x0, &l_BranchHost); @@ -498,7 +498,7 @@ static uint64_t Arm64JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Fram record[0] = HostCode; // Add de-linking handler - Context::Context::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ + Context::ContextImpl::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ record[0] = LinkerAddress; }); } @@ -509,7 +509,7 @@ static uint64_t Arm64JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Fram void Arm64JITCore::Op_NoOp(IR::IROp_Header const *IROp, IR::NodeID Node) { } -Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) +Arm64JITCore::Arm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) : CPUBackend(Thread, INITIAL_CODE_SIZE, MAX_CODE_SIZE) , Arm64Emitter(ctx, 0) , HostSupportsSVE{ctx->HostFeatures.SupportsAVX} @@ -543,7 +543,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern Common.PrintValue = reinterpret_cast(PrintValue); Common.PrintVectorValue = reinterpret_cast(PrintVectorValue); - Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::Context::ThreadRemoveCodeEntryFromJit); + Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::ContextImpl::ThreadRemoveCodeEntryFromJit); Common.CPUIDObj = reinterpret_cast(&CTX->CPUID); { @@ -553,7 +553,7 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern Common.SyscallHandlerObj = reinterpret_cast(CTX->SyscallHandler); Common.SyscallHandlerFunc = reinterpret_cast(FEXCore::Context::HandleSyscall); - Common.ExitFunctionLink = reinterpret_cast(&Context::Context::ThreadExitFunctionLink); + Common.ExitFunctionLink = reinterpret_cast(&Context::ContextImpl::ThreadExitFunctionLink); // Fill in the fallback handlers @@ -572,9 +572,9 @@ Arm64JITCore::Arm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::Intern ClearCache(); } -void Arm64JITCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { +void Arm64JITCore::InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX) { CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); + return reinterpret_cast(Thread->CTX)->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); }, true); #ifdef _M_ARM_64 @@ -584,7 +584,7 @@ void Arm64JITCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { return false; } - return FEXCore::ArchHelpers::Arm64::HandleSIGBUS(Thread->CTX->Config.ParanoidTSO(), Signal, info, ucontext); + return FEXCore::ArchHelpers::Arm64::HandleSIGBUS(static_cast(Thread->CTX)->Config.ParanoidTSO(), Signal, info, ucontext); }, true); #endif } @@ -1081,11 +1081,11 @@ void Arm64JITCore::ResetStack() { } } -std::unique_ptr CreateArm64JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) { +std::unique_ptr CreateArm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) { return std::make_unique(ctx, Thread); } -void InitializeArm64JITSignalHandlers(FEXCore::Context::Context *CTX) { +void InitializeArm64JITSignalHandlers(FEXCore::Context::ContextImpl *CTX) { Arm64JITCore::InitializeSignalHandlers(CTX); } diff --git a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h index 89802422d..f97ddda36 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/Arm64/JITClass.h @@ -31,7 +31,7 @@ namespace FEXCore::Core { namespace FEXCore::CPU { class Arm64JITCore final : public CPUBackend, public Arm64Emitter { public: - explicit Arm64JITCore(FEXCore::Context::Context *ctx, + explicit Arm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); ~Arm64JITCore() override; @@ -48,7 +48,7 @@ public: void ClearCache() override; - static void InitializeSignalHandlers(FEXCore::Context::Context *CTX); + static void InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX); void ClearRelocations() override { Relocations.clear(); } @@ -57,7 +57,7 @@ private: const bool HostSupportsSVE{}; ARMEmitter::BiDirectionalLabel *PendingTargetLabel; - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; FEXCore::IR::IRListView const *IR; uint64_t Entry; CPUBackend::CompiledCode CodeData{}; diff --git a/External/FEXCore/Source/Interface/Core/JIT/JITCore.h b/External/FEXCore/Source/Interface/Core/JIT/JITCore.h index f1a54bb06..0dcf8aa25 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/JITCore.h +++ b/External/FEXCore/Source/Interface/Core/JIT/JITCore.h @@ -3,7 +3,7 @@ #include namespace FEXCore::Context { -struct Context; +class ContextImpl; } namespace FEXCore::Core { @@ -13,14 +13,14 @@ struct InternalThreadState; namespace FEXCore::CPU { class CPUBackend; -[[nodiscard]] std::unique_ptr CreateX86JITCore(FEXCore::Context::Context *ctx, +[[nodiscard]] std::unique_ptr CreateX86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); -void InitializeX86JITSignalHandlers(FEXCore::Context::Context *CTX); +void InitializeX86JITSignalHandlers(FEXCore::Context::ContextImpl *CTX); CPUBackendFeatures GetX86JITBackendFeatures(); -[[nodiscard]] std::unique_ptr CreateArm64JITCore(FEXCore::Context::Context *ctx, +[[nodiscard]] std::unique_ptr CreateArm64JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); -void InitializeArm64JITSignalHandlers(FEXCore::Context::Context *CTX); +void InitializeArm64JITSignalHandlers(FEXCore::Context::ContextImpl *CTX); CPUBackendFeatures GetArm64JITBackendFeatures(); } // namespace FEXCore::CPU diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp index 5a3ef05b0..eed5cf270 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/BranchOps.cpp @@ -202,7 +202,7 @@ DEF_OP(Thunk) { mov(rdi, GetSrc(Op->ArgPtr.ID())); - auto thunkFn = ThreadState->CTX->ThunkHandler->LookupThunk(Op->ThunkNameHash); + auto thunkFn = static_cast(ThreadState->CTX)->ThunkHandler->LookupThunk(Op->ThunkNameHash); mov(rax, reinterpret_cast(thunkFn)); call(rax); diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp index 071309737..527401cc3 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JIT.cpp @@ -330,7 +330,7 @@ static uint64_t X86JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Frame, } auto LinkerAddress = Frame->Pointers.Common.ExitFunctionLinker; - Context::Context::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ + Context::ContextImpl::ThreadAddBlockLink(Thread, GuestRip, (uintptr_t)record, [record, LinkerAddress]{ // undo the link record[0] = LinkerAddress; }); @@ -342,7 +342,7 @@ static uint64_t X86JITCore_ExitFunctionLink(FEXCore::Core::CpuStateFrame *Frame, void X86JITCore::Op_NoOp(IR::IROp_Header *IROp, IR::NodeID Node) { } -X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) +X86JITCore::X86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) : CPUBackend(Thread, INITIAL_CODE_SIZE, MAX_CODE_SIZE) , CodeGenerator(0, this, nullptr) // this is not used here , CTX {ctx} { @@ -379,7 +379,7 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh Common.PrintValue = reinterpret_cast(PrintValue); Common.PrintVectorValue = reinterpret_cast(PrintVectorValue); - Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::Context::ThreadRemoveCodeEntryFromJit); + Common.ThreadRemoveCodeEntryFromJIT = reinterpret_cast(&Context::ContextImpl::ThreadRemoveCodeEntryFromJit); Common.CPUIDObj = reinterpret_cast(&CTX->CPUID); { @@ -389,7 +389,7 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh Common.SyscallHandlerObj = reinterpret_cast(CTX->SyscallHandler); Common.SyscallHandlerFunc = reinterpret_cast(FEXCore::Context::HandleSyscall); - Common.ExitFunctionLink = reinterpret_cast(&Context::Context::ThreadExitFunctionLink); + Common.ExitFunctionLink = reinterpret_cast(&Context::ContextImpl::ThreadExitFunctionLink); // Fill in the fallback handlers InterpreterOps::FillFallbackIndexPointers(Common.FallbackHandlerPointers); @@ -399,9 +399,9 @@ X86JITCore::X86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalTh ClearCache(); } -void X86JITCore::InitializeSignalHandlers(FEXCore::Context::Context *CTX) { +void X86JITCore::InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX) { CTX->SignalDelegation->RegisterHostSignalHandler(SIGILL, [](FEXCore::Core::InternalThreadState *Thread, int Signal, void *info, void *ucontext) -> bool { - return Thread->CTX->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); + return static_cast(Thread->CTX)->Dispatcher->HandleSIGILL(Thread, Signal, info, ucontext); }, true); } @@ -786,7 +786,7 @@ CPUBackend::CompiledCode X86JITCore::CompileCode(uint64_t Entry, [[maybe_unused] return CodeData; } -std::unique_ptr CreateX86JITCore(FEXCore::Context::Context *ctx, FEXCore::Core::InternalThreadState *Thread) { +std::unique_ptr CreateX86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread) { return std::make_unique(ctx, Thread); } @@ -794,7 +794,7 @@ CPUBackendFeatures GetX86JITBackendFeatures() { return CPUBackendFeatures { }; } -void InitializeX86JITSignalHandlers(FEXCore::Context::Context *CTX) { +void InitializeX86JITSignalHandlers(FEXCore::Context::ContextImpl *CTX) { X86JITCore::InitializeSignalHandlers(CTX); } diff --git a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h index f16558868..f694a3988 100644 --- a/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h +++ b/External/FEXCore/Source/Interface/Core/JIT/x86_64/JITClass.h @@ -51,7 +51,7 @@ const std::array RAXMM_x = { xmm1, xmm2, xmm3, xmm4, xmm5, xmm6 class X86JITCore final : public CPUBackend, public Xbyak::CodeGenerator { public: - explicit X86JITCore(FEXCore::Context::Context *ctx, + explicit X86JITCore(FEXCore::Context::ContextImpl *ctx, FEXCore::Core::InternalThreadState *Thread); ~X86JITCore() override; @@ -68,7 +68,7 @@ public: void ClearCache() override; - static void InitializeSignalHandlers(FEXCore::Context::Context *CTX); + static void InitializeSignalHandlers(FEXCore::Context::ContextImpl *CTX); void ClearRelocations() override { Relocations.clear(); } @@ -135,7 +135,7 @@ private: /** @} */ Label* PendingTargetLabel{}; - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; FEXCore::IR::IRListView const *IR; uint64_t Entry; CPUBackend::CompiledCode CodeData{}; diff --git a/External/FEXCore/Source/Interface/Core/LookupCache.cpp b/External/FEXCore/Source/Interface/Core/LookupCache.cpp index 72fe153f4..16b32d65b 100644 --- a/External/FEXCore/Source/Interface/Core/LookupCache.cpp +++ b/External/FEXCore/Source/Interface/Core/LookupCache.cpp @@ -14,7 +14,7 @@ $end_info$ #include namespace FEXCore { -LookupCache::LookupCache(FEXCore::Context::Context *CTX) +LookupCache::LookupCache(FEXCore::Context::ContextImpl *CTX) : ctx {CTX} { TotalCacheSize = ctx->Config.VirtualMemSize / 4096 * 8 + CODE_SIZE + L1_SIZE; diff --git a/External/FEXCore/Source/Interface/Core/LookupCache.h b/External/FEXCore/Source/Interface/Core/LookupCache.h index da011c657..0ecb452c5 100644 --- a/External/FEXCore/Source/Interface/Core/LookupCache.h +++ b/External/FEXCore/Source/Interface/Core/LookupCache.h @@ -1,4 +1,5 @@ #pragma once +#include "Interface/Context/Context.h" #include #include @@ -12,9 +13,6 @@ #include namespace FEXCore { -namespace Context { - struct Context; -} class LookupCache { public: @@ -24,7 +22,7 @@ public: uintptr_t GuestCode; }; - LookupCache(FEXCore::Context::Context *CTX); + LookupCache(FEXCore::Context::ContextImpl *CTX); ~LookupCache(); uintptr_t FindBlock(uint64_t Address) { @@ -260,7 +258,7 @@ private: size_t AllocateOffset {}; - FEXCore::Context::Context *ctx; + FEXCore::Context::ContextImpl *ctx; uint64_t VirtualMemSize{}; }; } diff --git a/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp b/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp index 75fbe0a9e..4df4f56b3 100644 --- a/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp +++ b/External/FEXCore/Source/Interface/Core/ObjectCache/NamedRegionObjectHandler.cpp @@ -4,7 +4,7 @@ #include namespace FEXCore::CodeSerialize { - NamedRegionObjectHandler::NamedRegionObjectHandler(FEXCore::Context::Context *ctx) { + NamedRegionObjectHandler::NamedRegionObjectHandler(FEXCore::Context::ContextImpl *ctx) { DefaultSerializationConfig.Cookie = CODE_COOKIE; // Initialize the Arch from CPUID diff --git a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp index 8443f01a9..55ce8c239 100644 --- a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp +++ b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.cpp @@ -13,7 +13,7 @@ namespace { } namespace FEXCore::CodeSerialize { - CodeObjectSerializeService::CodeObjectSerializeService(FEXCore::Context::Context *ctx) + CodeObjectSerializeService::CodeObjectSerializeService(FEXCore::Context::ContextImpl *ctx) : CTX {ctx} , AsyncHandler { &NamedRegionHandler , this } , NamedRegionHandler { ctx } { diff --git a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h index 6ad4e56bc..58e6cc89d 100644 --- a/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h +++ b/External/FEXCore/Source/Interface/Core/ObjectCache/ObjectCacheService.h @@ -253,7 +253,7 @@ namespace FEXCore::CodeSerialize { class NamedRegionObjectHandler final { public: - NamedRegionObjectHandler(FEXCore::Context::Context *ctx); + NamedRegionObjectHandler(FEXCore::Context::ContextImpl *ctx); void HandleNamedRegionObjectJobs(); @@ -338,7 +338,7 @@ namespace FEXCore::CodeSerialize { */ class CodeObjectSerializeService final { public: - CodeObjectSerializeService(FEXCore::Context::Context *ctx); + CodeObjectSerializeService(FEXCore::Context::ContextImpl *ctx); /** * @brief Initialize the internal interface @@ -440,7 +440,7 @@ namespace FEXCore::CodeSerialize { void NotifyWork() { WorkAvailable.NotifyOne(); } private: - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; Event WorkAvailable{}; std::unique_ptr WorkerThread; diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 0dcd25824..2b62d0f70 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5318,7 +5318,7 @@ void OpDispatchBuilder::StoreResult(FEXCore::IR::RegisterClassType Class, FEXCor StoreResult(Class, Op, Op->Dest, Src, Align, AccessType); } -OpDispatchBuilder::OpDispatchBuilder(FEXCore::Context::Context *ctx) +OpDispatchBuilder::OpDispatchBuilder(FEXCore::Context::ContextImpl *ctx) : IREmitter {ctx->OpDispatcherAllocator} , CTX {ctx} { ResetWorkingList(); diff --git a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 8f1143209..11d2935da 100644 --- a/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/External/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -75,7 +75,7 @@ public: OrderedNode* flagsOpDestSigned{}; OrderedNode* flagsOpSrcSigned{}; - FEXCore::Context::Context *CTX{}; + FEXCore::Context::ContextImpl *CTX{}; // Used during new op bringup bool ShouldDump {false}; @@ -149,7 +149,7 @@ public: return false; } - OpDispatchBuilder(FEXCore::Context::Context *ctx); + OpDispatchBuilder(FEXCore::Context::ContextImpl *ctx); OpDispatchBuilder(FEXCore::Utils::IntrusivePooledAllocator &Allocator); void ResetWorkingList(); diff --git a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp index 0ee4f568a..1b859f624 100644 --- a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp +++ b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.cpp @@ -179,7 +179,7 @@ namespace FEXCore { }; auto args = reinterpret_cast(argsv); - auto CTX = Thread->CTX; + auto CTX = static_cast(Thread->CTX); LOGMAN_THROW_AA_FMT(args->original_callee, "Tried to link null pointer address to guest function"); LOGMAN_THROW_AA_FMT(args->target_addr, "Tried to link address to null pointer guest function"); @@ -264,7 +264,7 @@ namespace FEXCore { } static void LoadLib(void *ArgsV) { - auto CTX = Thread->CTX; + auto CTX = static_cast(Thread->CTX); auto Args = reinterpret_cast(ArgsV); @@ -321,7 +321,7 @@ namespace FEXCore { auto &[Name, rv] = *reinterpret_cast(ArgsRV); - auto CTX = Thread->CTX; + auto CTX = static_cast(Thread->CTX); auto That = reinterpret_cast(CTX->ThunkHandler.get()); { @@ -385,7 +385,7 @@ namespace FEXCore { 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 CTX = Thread->CTX; + const auto CTX = static_cast(Thread->CTX); const auto ThunkHandler = reinterpret_cast(CTX->ThunkHandler.get()); const GuestcallInfo gci = { GuestUnpacker, GuestTarget }; diff --git a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h index 83d0cc1eb..0a3416b67 100644 --- a/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h +++ b/External/FEXCore/Source/Interface/HLE/Thunks/Thunks.h @@ -11,7 +11,7 @@ $end_info$ #include namespace FEXCore::Context { - struct Context; + class ContextImpl; } namespace FEXCore::Core { diff --git a/External/FEXCore/Source/Interface/IR/AOTIR.h b/External/FEXCore/Source/Interface/IR/AOTIR.h index 238c5b4b5..81084ba8d 100644 --- a/External/FEXCore/Source/Interface/IR/AOTIR.h +++ b/External/FEXCore/Source/Interface/IR/AOTIR.h @@ -17,6 +17,9 @@ namespace FEXCore::Core { struct DebugData; } +namespace FEXCore::Context { + class ContextImpl; +} namespace FEXCore::IR { class RegisterAllocationData; @@ -87,7 +90,7 @@ namespace FEXCore::IR { class AOTIRCaptureCache final { public: - AOTIRCaptureCache(FEXCore::Context::Context *ctx) : CTX {ctx} {} + AOTIRCaptureCache(FEXCore::Context::ContextImpl *ctx) : CTX {ctx} {} void FinalizeAOTIRCache(); void AOTIRCaptureCacheWriteoutQueue_Flush(); @@ -131,7 +134,7 @@ namespace FEXCore::IR { } private: - FEXCore::Context::Context *CTX; + FEXCore::Context::ContextImpl *CTX; std::shared_mutex AOTIRCacheLock; std::shared_mutex AOTIRCaptureCacheWriteoutLock; diff --git a/External/FEXCore/Source/Interface/IR/PassManager.cpp b/External/FEXCore/Source/Interface/IR/PassManager.cpp index fdf4ca203..41464f7f4 100644 --- a/External/FEXCore/Source/Interface/IR/PassManager.cpp +++ b/External/FEXCore/Source/Interface/IR/PassManager.cpp @@ -17,7 +17,7 @@ $end_info$ namespace FEXCore::IR { class IREmitter; -void PassManager::AddDefaultPasses(FEXCore::Context::Context *ctx, bool InlineConstants, bool StaticRegisterAllocation) { +void PassManager::AddDefaultPasses(FEXCore::Context::ContextImpl *ctx, bool InlineConstants, bool StaticRegisterAllocation) { FEX_CONFIG_OPT(DisablePasses, O0); if (!DisablePasses()) { diff --git a/External/FEXCore/Source/Interface/IR/PassManager.h b/External/FEXCore/Source/Interface/IR/PassManager.h index 400b52e4f..5c37c985b 100644 --- a/External/FEXCore/Source/Interface/IR/PassManager.h +++ b/External/FEXCore/Source/Interface/IR/PassManager.h @@ -14,6 +14,10 @@ $end_info$ #include #include +namespace FEXCore::Context { + class ContextImpl; +} + namespace FEXCore::HLE { class SyscallHandler; } @@ -40,7 +44,7 @@ protected: class PassManager final { friend class SyscallOptimization; public: - void AddDefaultPasses(FEXCore::Context::Context *ctx, bool InlineConstants, bool StaticRegisterAllocation); + void AddDefaultPasses(FEXCore::Context::ContextImpl *ctx, bool InlineConstants, bool StaticRegisterAllocation); void AddDefaultValidationPasses(); Pass* InsertPass(std::unique_ptr Pass, std::string Name = "") { Pass->RegisterPassManager(this); diff --git a/External/FEXCore/include/FEXCore/Core/Context.h b/External/FEXCore/include/FEXCore/Core/Context.h index 86a4c718a..c8561a6eb 100644 --- a/External/FEXCore/include/FEXCore/Core/Context.h +++ b/External/FEXCore/include/FEXCore/Core/Context.h @@ -41,7 +41,7 @@ namespace FEXCore::IR { } namespace FEXCore::Context { - struct Context; + class Context; enum ExitReason { EXIT_NONE, EXIT_WAITING, @@ -78,224 +78,217 @@ namespace FEXCore::Context { using ExitHandler = std::function; + class Context { + public: + virtual ~Context() = default; + /** + * @brief [[threadsafe]] Create a new FEXCore context object + * + * This is necessary to do when running threaded contexts + * + * @return a new context object + */ + FEX_DEFAULT_VISIBILITY static FEXCore::Context::Context *CreateNewContext(); + + /** + * @brief Post creation context initialization + * Once configurations have been set, do the post-creation initialization with that configuration + * + * @param CTX The context that we created + * + * @return true if we managed to initialize correctly + */ + FEX_DEFAULT_VISIBILITY virtual bool InitializeContext() = 0; + + /** + * @brief Destroy the context object + * + * @param CTX + */ + FEX_DEFAULT_VISIBILITY static void DestroyContext(FEXCore::Context::Context * CTX); + FEX_DEFAULT_VISIBILITY virtual void DestroyContext() = 0; + + /** + * @brief Allows setting up in memory code and other things prior to launchign code execution + * + * @param CTX The context that we created + * @param Loader The loader that will be doing all the code loading + * + * @return true if we loaded code + */ + FEX_DEFAULT_VISIBILITY virtual FEXCore::Core::InternalThreadState* InitCore(uint64_t InitialRIP, uint64_t StackPointer) = 0; + + FEX_DEFAULT_VISIBILITY virtual void SetExitHandler(ExitHandler handler) = 0; + FEX_DEFAULT_VISIBILITY virtual ExitHandler GetExitHandler() const = 0; + + /** + * @brief Pauses execution on the CPU core + * + * Blocks until all threads have paused. + */ + FEX_DEFAULT_VISIBILITY virtual void Pause() = 0; + + /** + * @brief Starts (or continues) the CPU core + * + * This function is async and returns immediately. + * Use RunUntilExit() for synchonous executions + * + */ + FEX_DEFAULT_VISIBILITY virtual void Run() = 0; + + /** + * @brief Tells the core to shutdown + * + * Blocks until shutdown + */ + FEX_DEFAULT_VISIBILITY virtual void Stop() = 0; + + /** + * @brief Executes one instruction + * + * Returns once execution is complete. + */ + FEX_DEFAULT_VISIBILITY virtual void Step() = 0; + + /** + * @brief Runs the CPU core until it exits + * + * If an Exit handler has been registered, this function won't return until the core + * has shutdown. + * + * @param CTX The context that we created + * + * @return The ExitReason for the parentthread. + */ + FEX_DEFAULT_VISIBILITY virtual ExitReason RunUntilExit() = 0; + + FEX_DEFAULT_VISIBILITY virtual void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP) = 0; + + /** + * @brief Gets the program exit status + * + * + * @param CTX The context that we created + * + * @return The program exit status + */ + FEX_DEFAULT_VISIBILITY virtual int GetProgramStatus() const = 0; + + /** + * @brief [[threadsafe]] Returns the ExitReason of the parent thread. Typically used for async result status + * + * @param CTX The context that we created + * + * @return The ExitReason for the parentthread + */ + FEX_DEFAULT_VISIBILITY virtual ExitReason GetExitReason() = 0; + + /** + * @brief [[theadsafe]] Checks if the Context is either done working or paused(in the case of single stepping) + * + * Use this when the context is async running to determine if it is done + * + * @param CTX the context that we created + * + * @return true if the core is done or paused + */ + FEX_DEFAULT_VISIBILITY virtual bool IsDone() const = 0; + + /** + * @brief Gets a copy the CPUState of the parent thread + * + * @param CTX The context that we created + * @param State The state object to populate + */ + FEX_DEFAULT_VISIBILITY virtual void GetCPUState(FEXCore::Core::CPUState *State) const = 0; + + /** + * @brief Copies the CPUState provided to the parent thread + * + * @param CTX The context that we created + * @param State The satate object to copy from + */ + FEX_DEFAULT_VISIBILITY virtual void SetCPUState(const FEXCore::Core::CPUState *State) = 0; + + /** + * @brief Allows the frontend to pass in a custom CPUBackend creation factory + * + * This allows the frontend to have its own frontend. Typically for debugging + * + * @param CTX The context that we created + * @param Factory The factory that the context will call if the DefaultCore config ise set to CUSTOM + */ + FEX_DEFAULT_VISIBILITY virtual void SetCustomCPUBackendFactory(CustomCPUFactoryType Factory) = 0; + + /** + * @brief Sets up memory regions on the guest for mirroring within the guest's VM space + * + * @param VirtualAddress The address we want to set to mirror a physical memory region + * @param PhysicalAddress The physical memory region we are mapping + * @param Size Size of the region to mirror + * + * @return true when successfully mapped. false if there was an error adding + */ + FEX_DEFAULT_VISIBILITY virtual bool AddVirtualMemoryMapping(uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size) = 0; + + /** + * @brief Retrieves a feature struct indicating certain supported aspects from + * the hose. + * + * @param CTX A valid non-null context instance. + */ + FEX_DEFAULT_VISIBILITY virtual HostFeatures GetHostFeatures() const = 0; + + FEX_DEFAULT_VISIBILITY virtual void HandleCallback(FEXCore::Core::InternalThreadState *Thread, uint64_t RIP) = 0; + + FEX_DEFAULT_VISIBILITY virtual void RegisterHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) = 0; + [[noreturn]] FEX_DEFAULT_VISIBILITY virtual void HandleSignalHandlerReturn(bool RT) = 0; + FEX_DEFAULT_VISIBILITY virtual void RegisterFrontendHostSignalHandler(int Signal, HostSignalDelegatorFunction Func, bool Required) = 0; + + FEX_DEFAULT_VISIBILITY virtual FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID) = 0; + FEX_DEFAULT_VISIBILITY virtual void ExecutionThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void InitializeThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void RunThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void StopThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void DestroyThread(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void CleanupAfterFork(FEXCore::Core::InternalThreadState *Thread) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetSignalDelegator(FEXCore::SignalDelegator *SignalDelegation) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetSyscallHandler(FEXCore::HLE::SyscallHandler *Handler) = 0; + FEX_DEFAULT_VISIBILITY virtual FEXCore::CPUID::FunctionResults RunCPUIDFunction(uint32_t Function, uint32_t Leaf) = 0; + FEX_DEFAULT_VISIBILITY virtual FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(uint32_t Function, uint32_t Leaf, uint32_t CPU) = 0; + + FEX_DEFAULT_VISIBILITY virtual FEXCore::IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(const std::string& Name) = 0; + FEX_DEFAULT_VISIBILITY virtual void UnloadAOTIRCacheEntry(FEXCore::IR::AOTIRCacheEntry *Entry) = 0; + + FEX_DEFAULT_VISIBILITY virtual void SetAOTIRLoader(std::function CacheReader) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetAOTIRWriter(std::function(const std::string&)> CacheWriter) = 0; + FEX_DEFAULT_VISIBILITY virtual void SetAOTIRRenamer(std::function CacheRenamer) = 0; + + FEX_DEFAULT_VISIBILITY virtual void FinalizeAOTIRCache() = 0; + FEX_DEFAULT_VISIBILITY virtual void WriteFilesWithCode(std::function Writer) = 0; + FEX_DEFAULT_VISIBILITY virtual void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length) = 0; + FEX_DEFAULT_VISIBILITY virtual void InvalidateGuestCodeRange(uint64_t Start, uint64_t Length, std::function callback) = 0; + FEX_DEFAULT_VISIBILITY virtual void MarkMemoryShared() = 0; + + FEX_DEFAULT_VISIBILITY virtual void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress) = 0; + FEX_DEFAULT_VISIBILITY virtual CustomIRResult AddCustomIREntrypoint(uintptr_t Entrypoint, std::function Handler, void *Creator = nullptr, void *Data = nullptr) = 0; + + /** + * @brief Allows the frontend to register its own thunk handlers independent of what is controlled in the backend. + * + * @param CTX A valid non-null context instance. + * @param Definitions A vector of thunk definitions that the frontend controls + */ + FEX_DEFAULT_VISIBILITY virtual void AppendThunkDefinitions(std::vector const& Definitions) = 0; + + FEX_DEFAULT_VISIBILITY virtual void SetVDSOSigReturn(const VDSOSigReturn &Pointers) = 0; + private: + }; + /** * @brief This initializes internal FEXCore state that is shared between contexts and requires overhead to setup */ FEX_DEFAULT_VISIBILITY void InitializeStaticTables(OperatingMode Mode = MODE_64BIT); FEX_DEFAULT_VISIBILITY void ShutdownStaticTables(); - - /** - * @brief [[threadsafe]] Create a new FEXCore context object - * - * This is necessary to do when running threaded contexts - * - * @return a new context object - */ - FEX_DEFAULT_VISIBILITY FEXCore::Context::Context *CreateNewContext(); - - /** - * @brief Post creation context initialization - * Once configurations have been set, do the post-creation initialization with that configuration - * - * @param CTX The context that we created - * - * @return true if we managed to initialize correctly - */ - FEX_DEFAULT_VISIBILITY bool InitializeContext(FEXCore::Context::Context *CTX); - - /** - * @brief Destroy the context object - * - * @param CTX - */ - FEX_DEFAULT_VISIBILITY void DestroyContext(FEXCore::Context::Context *CTX); - - /** - * @brief Allows setting up in memory code and other things prior to launchign code execution - * - * @param CTX The context that we created - * @param Loader The loader that will be doing all the code loading - * - * @return true if we loaded code - */ - FEX_DEFAULT_VISIBILITY FEXCore::Core::InternalThreadState* InitCore(FEXCore::Context::Context *CTX, uint64_t InitialRIP, uint64_t StackPointer); - - FEX_DEFAULT_VISIBILITY void SetExitHandler(FEXCore::Context::Context *CTX, ExitHandler handler); - FEX_DEFAULT_VISIBILITY ExitHandler GetExitHandler(const FEXCore::Context::Context *CTX); - - /** - * @brief Pauses execution on the CPU core - * - * Blocks until all threads have paused. - */ - FEX_DEFAULT_VISIBILITY void Pause(FEXCore::Context::Context *CTX); - - /** - * @brief Starts (or continues) the CPU core - * - * This function is async and returns immediately. - * Use RunUntilExit() for synchonous executions - * - */ - FEX_DEFAULT_VISIBILITY void Run(FEXCore::Context::Context *CTX); - - /** - * @brief Runs the CPU core until it exits - * - * If an Exit handler has been registered, this function won't return until the core - * has shutdown. - * - * @param CTX The context that we created - * - * @return The ExitReason for the parentthread. - */ - FEX_DEFAULT_VISIBILITY ExitReason RunUntilExit(FEXCore::Context::Context *CTX); - - FEX_DEFAULT_VISIBILITY void CompileRIP(FEXCore::Core::InternalThreadState *Thread, uint64_t GuestRIP); - - /** - * @brief Gets the program exit status - * - * - * @param CTX The context that we created - * - * @return The program exit status - */ - FEX_DEFAULT_VISIBILITY int GetProgramStatus(const FEXCore::Context::Context *CTX); - - /** - * @brief Tells the core to shutdown - * - * Blocks until shutdown - */ - FEX_DEFAULT_VISIBILITY void Stop(FEXCore::Context::Context *CTX); - - /** - * @brief Executes one instruction - * - * Returns once execution is complete. - */ - FEX_DEFAULT_VISIBILITY void Step(FEXCore::Context::Context *CTX); - - /** - * @brief [[threadsafe]] Returns the ExitReason of the parent thread. Typically used for async result status - * - * @param CTX The context that we created - * - * @return The ExitReason for the parentthread - */ - FEX_DEFAULT_VISIBILITY ExitReason GetExitReason(const FEXCore::Context::Context *CTX); - - /** - * @brief [[theadsafe]] Checks if the Context is either done working or paused(in the case of single stepping) - * - * Use this when the context is async running to determine if it is done - * - * @param CTX the context that we created - * - * @return true if the core is done or paused - */ - FEX_DEFAULT_VISIBILITY bool IsDone(const FEXCore::Context::Context *CTX); - - /** - * @brief Gets a copy the CPUState of the parent thread - * - * @param CTX The context that we created - * @param State The state object to populate - */ - FEX_DEFAULT_VISIBILITY void GetCPUState(const FEXCore::Context::Context *CTX, - FEXCore::Core::CPUState *State); - - /** - * @brief Copies the CPUState provided to the parent thread - * - * @param CTX The context that we created - * @param State The satate object to copy from - */ - FEX_DEFAULT_VISIBILITY void SetCPUState(FEXCore::Context::Context *CTX, - const FEXCore::Core::CPUState *State); - - /** - * @brief Allows the frontend to pass in a custom CPUBackend creation factory - * - * This allows the frontend to have its own frontend. Typically for debugging - * - * @param CTX The context that we created - * @param Factory The factory that the context will call if the DefaultCore config ise set to CUSTOM - */ - FEX_DEFAULT_VISIBILITY void SetCustomCPUBackendFactory(FEXCore::Context::Context *CTX, CustomCPUFactoryType Factory); - - /** - * @brief Sets up memory regions on the guest for mirroring within the guest's VM space - * - * @param VirtualAddress The address we want to set to mirror a physical memory region - * @param PhysicalAddress The physical memory region we are mapping - * @param Size Size of the region to mirror - * - * @return true when successfully mapped. false if there was an error adding - */ - FEX_DEFAULT_VISIBILITY bool AddVirtualMemoryMapping(FEXCore::Context::Context *CTX, uint64_t VirtualAddress, uint64_t PhysicalAddress, uint64_t Size); - - /** - * @brief Allows the frontend to set a custom syscall handler - * - * Useful for debugging purposes. May not work if the syscall ID exceeds the maximum number of syscalls in the lookup table - * - * @param Syscall Which syscall ID to install a visitor to - * @param Visitor The Visitor to install - */ - FEX_DEFAULT_VISIBILITY void RegisterExternalSyscallVisitor(FEXCore::Context::Context *CTX, uint64_t Syscall, FEXCore::HLE::SyscallVisitor *Visitor); - - /** - * @brief Retrieves a feature struct indicating certain supported aspects from - * the hose. - * - * @param CTX A valid non-null context instance. - */ - FEX_DEFAULT_VISIBILITY HostFeatures GetHostFeatures(const FEXCore::Context::Context *CTX); - - FEX_DEFAULT_VISIBILITY void HandleCallback(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread, uint64_t RIP); - - FEX_DEFAULT_VISIBILITY void RegisterHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required); - [[noreturn]] FEX_DEFAULT_VISIBILITY void HandleSignalHandlerReturn(FEXCore::Context::Context *CTX, bool RT); - FEX_DEFAULT_VISIBILITY void RegisterFrontendHostSignalHandler(FEXCore::Context::Context *CTX, int Signal, HostSignalDelegatorFunction Func, bool Required); - - FEX_DEFAULT_VISIBILITY FEXCore::Core::InternalThreadState* CreateThread(FEXCore::Context::Context *CTX, FEXCore::Core::CPUState *NewThreadState, uint64_t ParentTID); - FEX_DEFAULT_VISIBILITY void ExecutionThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void InitializeThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void RunThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void StopThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void DestroyThread(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void CleanupAfterFork(FEXCore::Context::Context *CTX, FEXCore::Core::InternalThreadState *Thread); - FEX_DEFAULT_VISIBILITY void SetSignalDelegator(FEXCore::Context::Context *CTX, FEXCore::SignalDelegator *SignalDelegation); - FEX_DEFAULT_VISIBILITY void SetSyscallHandler(FEXCore::Context::Context *CTX, FEXCore::HLE::SyscallHandler *Handler); - FEX_DEFAULT_VISIBILITY FEXCore::CPUID::FunctionResults RunCPUIDFunction(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf); - FEX_DEFAULT_VISIBILITY FEXCore::CPUID::FunctionResults RunCPUIDFunctionName(FEXCore::Context::Context *CTX, uint32_t Function, uint32_t Leaf, uint32_t CPU); - - FEX_DEFAULT_VISIBILITY FEXCore::IR::AOTIRCacheEntry *LoadAOTIRCacheEntry(FEXCore::Context::Context *CTX, const std::string& Name); - FEX_DEFAULT_VISIBILITY void UnloadAOTIRCacheEntry(FEXCore::Context::Context *CTX, FEXCore::IR::AOTIRCacheEntry *Entry); - - FEX_DEFAULT_VISIBILITY void SetAOTIRLoader(FEXCore::Context::Context *CTX, std::function CacheReader); - FEX_DEFAULT_VISIBILITY void SetAOTIRWriter(FEXCore::Context::Context *CTX, std::function(const std::string&)> CacheWriter); - FEX_DEFAULT_VISIBILITY void SetAOTIRRenamer(FEXCore::Context::Context *CTX, std::function CacheRenamer); - - FEX_DEFAULT_VISIBILITY void FinalizeAOTIRCache(FEXCore::Context::Context *CTX); - FEX_DEFAULT_VISIBILITY void WriteFilesWithCode(FEXCore::Context::Context *CTX, std::function Writer); - FEX_DEFAULT_VISIBILITY void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length); - FEX_DEFAULT_VISIBILITY void InvalidateGuestCodeRange(FEXCore::Context::Context *CTX, uint64_t Start, uint64_t Length, std::function callback); - FEX_DEFAULT_VISIBILITY void MarkMemoryShared(FEXCore::Context::Context *CTX); - - FEX_DEFAULT_VISIBILITY void ConfigureAOTGen(FEXCore::Core::InternalThreadState *Thread, std::set *ExternalBranches, uint64_t SectionMaxAddress); - FEX_DEFAULT_VISIBILITY CustomIRResult AddCustomIREntrypoint(FEXCore::Context::Context *CTX, uintptr_t Entrypoint, std::function Handler, void *Creator = nullptr, void *Data = nullptr); - - /** - * @brief Allows the frontend to register its own thunk handlers independent of what is controlled in the backend. - * - * @param CTX A valid non-null context instance. - * @param Definitions A vector of thunk definitions that the frontend controls - */ - FEX_DEFAULT_VISIBILITY void AppendThunkDefinitions(FEXCore::Context::Context *CTX, std::vector const& Definitions); - - FEX_DEFAULT_VISIBILITY void SetVDSOSigReturn(FEXCore::Context::Context *CTX, const VDSOSigReturn &Pointers); - } diff --git a/External/FEXCore/include/FEXCore/Debug/ContextDebug.h b/External/FEXCore/include/FEXCore/Debug/ContextDebug.h index 595005ae3..67cd8cebf 100644 --- a/External/FEXCore/include/FEXCore/Debug/ContextDebug.h +++ b/External/FEXCore/include/FEXCore/Debug/ContextDebug.h @@ -10,7 +10,7 @@ namespace FEXCore::Core { } namespace FEXCore::Context { - struct Context; + class Context; namespace Debug { diff --git a/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h b/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h index 3e8a91dfb..21cc35faf 100644 --- a/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h +++ b/External/FEXCore/include/FEXCore/Debug/InternalThreadState.h @@ -18,7 +18,7 @@ namespace FEXCore { } namespace FEXCore::Context { - struct Context; + class Context; } namespace FEXCore::CPU { diff --git a/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h b/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h index cab09c4b1..cc3042ca3 100644 --- a/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h +++ b/External/FEXCore/include/FEXCore/HLE/SyscallHandler.h @@ -15,7 +15,7 @@ namespace FEXCore::IR { } namespace FEXCore::Context { - struct Context; + class Context; } namespace FEXCore::Core { diff --git a/Source/Tests/AOT/AOTGenerator.cpp b/Source/Tests/AOT/AOTGenerator.cpp index ab9c8db6e..05c3e867a 100644 --- a/Source/Tests/AOT/AOTGenerator.cpp +++ b/Source/Tests/AOT/AOTGenerator.cpp @@ -102,10 +102,9 @@ void AOTGenSection(FEXCore::Context::Context *CTX, ELFCodeLoader2::LoadedSection // Setup thread - Each compilation thread uses its own backing FEX thread FEXCore::Core::CPUState state; - auto Thread = FEXCore::Context::CreateThread(CTX, &state, FHU::Syscalls::gettid()); + auto Thread = CTX->CreateThread(&state, FHU::Syscalls::gettid()); std::set ExternalBranchesLocal; - FEXCore::Context::ConfigureAOTGen(Thread, &ExternalBranchesLocal, SectionMaxAddress); - + CTX->ConfigureAOTGen(Thread, &ExternalBranchesLocal, SectionMaxAddress); for (;;) { uint64_t BranchTarget; @@ -123,7 +122,7 @@ void AOTGenSection(FEXCore::Context::Context *CTX, ELFCodeLoader2::LoadedSection // Compile entrypoint counter++; - FEXCore::Context::CompileRIP(Thread, BranchTarget); + CTX->CompileRIP(Thread, BranchTarget); // Are there more branches? if (ExternalBranchesLocal.size() > 0) { @@ -143,7 +142,7 @@ void AOTGenSection(FEXCore::Context::Context *CTX, ELFCodeLoader2::LoadedSection } // All entryproints processed, cleanup this thread - FEXCore::Context::DestroyThread(CTX, Thread); + CTX->DestroyThread(Thread); }); // Add to the thread pool diff --git a/Source/Tests/ELFCodeLoader2.h b/Source/Tests/ELFCodeLoader2.h index 572202347..22fe7ac81 100644 --- a/Source/Tests/ELFCodeLoader2.h +++ b/Source/Tests/ELFCodeLoader2.h @@ -836,7 +836,7 @@ class ELFCodeLoader2 final : public FEXCore::CodeLoader { void CalculateHWCaps(FEXCore::Context::Context *ctx) { // HWCAP is just CPUID function 0x1, the EDX result - auto res_1 = FEXCore::Context::RunCPUIDFunction(ctx, 1, 0); + auto res_1 = ctx->RunCPUIDFunction(1, 0); HWCap = res_1.edx; // HWCAP2 is as follows: diff --git a/Source/Tests/FEXLoader.cpp b/Source/Tests/FEXLoader.cpp index 9baaad6e1..ffc78669a 100644 --- a/Source/Tests/FEXLoader.cpp +++ b/Source/Tests/FEXLoader.cpp @@ -377,8 +377,8 @@ int main(int argc, char **argv, char **const envp) { // System allocator is now system allocator or FEX FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); - auto CTX = FEXCore::Context::CreateNewContext(); - FEXCore::Context::InitializeContext(CTX); + auto CTX = FEXCore::Context::Context::CreateNewContext(); + CTX->InitializeContext(); auto SignalDelegation = std::make_unique(); @@ -423,22 +423,22 @@ int main(int argc, char **argv, char **const envp) { SyscallHandler->DefaultProgramBreak(BRKInfo.Base, BRKInfo.Size); - FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get()); - FEXCore::Context::SetSyscallHandler(CTX, SyscallHandler.get()); - FEXCore::Context::InitCore(CTX, Loader.DefaultRIP(), Loader.GetStackPointer()); + CTX->SetSignalDelegator(SignalDelegation.get()); + CTX->SetSyscallHandler(SyscallHandler.get()); + CTX->InitCore(Loader.DefaultRIP(), Loader.GetStackPointer()); // Pass in our VDSO thunks - FEXCore::Context::AppendThunkDefinitions(CTX, FEX::VDSO::GetVDSOThunkDefinitions()); - FEXCore::Context::SetVDSOSigReturn(CTX, FEX::VDSO::GetVDSOSymbols()); + CTX->AppendThunkDefinitions(FEX::VDSO::GetVDSOThunkDefinitions()); + CTX->SetVDSOSigReturn(FEX::VDSO::GetVDSOSymbols()); FEXCore::Context::ExitReason ShutdownReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN; // There might already be an exit handler, leave it installed - if(!FEXCore::Context::GetExitHandler(CTX)) { - FEXCore::Context::SetExitHandler(CTX, [&](uint64_t thread, FEXCore::Context::ExitReason reason) { + if(!CTX->GetExitHandler()) { + CTX->SetExitHandler([&](uint64_t thread, FEXCore::Context::ExitReason reason) { if (reason != FEXCore::Context::ExitReason::EXIT_DEBUG) { ShutdownReason = reason; - FEXCore::Context::Stop(CTX); + CTX->Stop(); } }); } @@ -448,13 +448,13 @@ int main(int argc, char **argv, char **const envp) { LogMan::Msg::IFmt("Warning: AOTIR is experimental, and might lead to crashes. " "Capture doesn't work with programs that fork."); - FEXCore::Context::SetAOTIRLoader(CTX, [](const std::string &fileid) -> int { + CTX->SetAOTIRLoader([](const std::string &fileid) -> int { auto filepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir"); return open(filepath.c_str(), O_RDONLY); }); - FEXCore::Context::SetAOTIRWriter(CTX, [](const std::string& fileid) -> std::unique_ptr { + CTX->SetAOTIRWriter([](const std::string& fileid) -> std::unique_ptr { auto filepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir.tmp"); auto AOTWrite = std::make_unique(filepath, std::ios::out | std::ios::binary); if (*AOTWrite) { @@ -467,7 +467,7 @@ int main(int argc, char **argv, char **const envp) { return AOTWrite; }); - FEXCore::Context::SetAOTIRRenamer(CTX, [](const std::string& fileid) -> void { + CTX->SetAOTIRRenamer([](const std::string& fileid) -> void { auto TmpFilepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir.tmp"); auto NewFilepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".aotir"); @@ -481,13 +481,13 @@ int main(int argc, char **argv, char **const envp) { FEX::AOT::AOTGenSection(CTX, Section); } } else { - FEXCore::Context::RunUntilExit(CTX); + CTX->RunUntilExit(); } if (AOTEnabled) { std::filesystem::create_directories(std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir", ec); if (!ec) { - FEXCore::Context::WriteFilesWithCode(CTX, [](const std::string& fileid, const std::string& filename) { + CTX->WriteFilesWithCode([](const std::string& fileid, const std::string& filename) { auto filepath = std::filesystem::path(FEXCore::Config::GetDataDirectory()) / "aotir" / (fileid + ".path"); int fd = open(filepath.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0644); if (fd != -1) { @@ -498,16 +498,16 @@ int main(int argc, char **argv, char **const envp) { } if (AOTIRCapture() || AOTIRGenerate()) { - FEXCore::Context::FinalizeAOTIRCache(CTX); + CTX->FinalizeAOTIRCache(); LogMan::Msg::IFmt("AOTIR Cache Stored"); } } - auto ProgramStatus = FEXCore::Context::GetProgramStatus(CTX); + auto ProgramStatus = CTX->GetProgramStatus(); SyscallHandler.reset(); SignalDelegation.reset(); - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); FEXCore::Context::ShutdownStaticTables(); FEXCore::Threads::Shutdown(); diff --git a/Source/Tests/IRLoader.cpp b/Source/Tests/IRLoader.cpp index 08cb3c628..ceb573ba0 100644 --- a/Source/Tests/IRLoader.cpp +++ b/Source/Tests/IRLoader.cpp @@ -33,7 +33,7 @@ $end_info$ #include "HarnessHelpers.h" namespace FEXCore::Context { - struct Context; + class Context; } void MsgHandler(LogMan::DebugLevels Level, char const *Message) @@ -108,12 +108,12 @@ public: } } - bool LoadIR(FEXCore::Context::Context *CTX) const { + bool LoadIR(FEXCore::Context::Context *CTX) const { if (!ParsedCode) { return false; } - return !!AddCustomIREntrypoint(CTX, EntryRIP, [ParsedCodePtr = ParsedCode.get()](uintptr_t Entrypoint, FEXCore::IR::IREmitter *emit) { + return !!CTX->AddCustomIREntrypoint(EntryRIP, [ParsedCodePtr = ParsedCode.get()](uintptr_t Entrypoint, FEXCore::IR::IREmitter *emit) { emit->CopyData(*ParsedCodePtr); }); } @@ -181,20 +181,20 @@ int main(int argc, char **argv, char **const envp) LOGMAN_THROW_A_FMT(Args.size() > 1, "Not enough arguments"); FEXCore::Context::InitializeStaticTables(); - auto CTX = FEXCore::Context::CreateNewContext(); - FEXCore::Context::InitializeContext(CTX); + auto CTX = FEXCore::Context::Context::CreateNewContext(); + CTX->InitializeContext(); std::unique_ptr SignalDelegation = std::make_unique(); - FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get()); - FEXCore::Context::SetSyscallHandler(CTX, new DummySyscallHandler()); + CTX->SetSignalDelegator(SignalDelegation.get()); + CTX->SetSyscallHandler(new DummySyscallHandler()); IRCodeLoader Loader(Args[0], Args[1]); // Skip tests that require AVX on hosts that don't support it. - const bool SupportsAVX = FEXCore::Context::GetHostFeatures(CTX).SupportsAVX; + const bool SupportsAVX = CTX->GetHostFeatures().SupportsAVX; if (!SupportsAVX && Loader.RequiresAVX()) { - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); return 0; } @@ -202,18 +202,18 @@ int main(int argc, char **argv, char **const envp) if (Loader.LoadIR(CTX)) { - FEXCore::Context::InitCore(CTX, Loader.DefaultRIP(), Loader.GetStackPointer()); + CTX->InitCore(Loader.DefaultRIP(), Loader.GetStackPointer()); auto ShutdownReason = FEXCore::Context::ExitReason::EXIT_SHUTDOWN; // There might already be an exit handler, leave it installed - if (!FEXCore::Context::GetExitHandler(CTX)) + if (!CTX->GetExitHandler()) { - FEXCore::Context::SetExitHandler(CTX, [&](uint64_t thread, FEXCore::Context::ExitReason reason) { + CTX->SetExitHandler([&](uint64_t thread, FEXCore::Context::ExitReason reason) { if (reason != FEXCore::Context::ExitReason::EXIT_DEBUG) { ShutdownReason = reason; - FEXCore::Context::Stop(CTX); + CTX->Stop(); } }); } @@ -228,14 +228,14 @@ int main(int argc, char **argv, char **const envp) LongJumpVal = setjmp(LongJump); if (!LongJumpVal) { - FEXCore::Context::RunUntilExit(CTX); + CTX->RunUntilExit(); } LogMan::Msg::DFmt("Reason we left VM: {}", FEXCore::ToUnderlying(ShutdownReason)); // Just re-use compare state. It also checks against the expected values in config. FEXCore::Core::CPUState State; - FEXCore::Context::GetCPUState(CTX, &State); + CTX->GetCPUState(&State); const bool Passed = Loader.CompareStates(&State, SupportsAVX); @@ -249,7 +249,6 @@ int main(int argc, char **argv, char **const envp) Return = -1; } - FEXCore::Context::DestroyContext(CTX); - + FEXCore::Context::Context::DestroyContext(CTX); return Return; } diff --git a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp index ae6cd9884..939a7e52d 100644 --- a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp +++ b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.cpp @@ -52,17 +52,17 @@ namespace FEX::EmulatedFile { std::string GenerateCPUInfo(FEXCore::Context::Context *ctx, uint32_t CPUCores) { std::ostringstream cpu_stream{}; - auto res_0 = FEXCore::Context::RunCPUIDFunction(ctx, 0, 0); - auto res_1 = FEXCore::Context::RunCPUIDFunction(ctx, 1, 0); - auto res_6 = FEXCore::Context::RunCPUIDFunction(ctx, 6, 0); - auto res_7 = FEXCore::Context::RunCPUIDFunction(ctx, 7, 0); - auto res_10 = FEXCore::Context::RunCPUIDFunction(ctx, 0x10, 0); + auto res_0 = ctx->RunCPUIDFunction(0, 0); + auto res_1 = ctx->RunCPUIDFunction(1, 0); + auto res_6 = ctx->RunCPUIDFunction(6, 0); + auto res_7 = ctx->RunCPUIDFunction(7, 0); + auto res_10 = ctx->RunCPUIDFunction(0x10, 0); - auto res_8000_0001 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0001, 0); - auto res_8000_0007 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0007, 0); - auto res_8000_0008 = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'0008, 0); - auto res_8000_000a = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'000a, 0); - auto res_8000_001f = FEXCore::Context::RunCPUIDFunction(ctx, 0x8000'001f, 0); + auto res_8000_0001 = ctx->RunCPUIDFunction(0x8000'0001, 0); + auto res_8000_0007 = ctx->RunCPUIDFunction(0x8000'0007, 0); + auto res_8000_0008 = ctx->RunCPUIDFunction(0x8000'0008, 0); + auto res_8000_000a = ctx->RunCPUIDFunction(0x8000'000a, 0); + auto res_8000_001f = ctx->RunCPUIDFunction(0x8000'001f, 0); union VendorID { struct { @@ -573,9 +573,9 @@ namespace FEX::EmulatedFile { cpu_stream << "cpu family\t: " << Family << std::endl; cpu_stream << "model\t\t: " << (info.Model + (info.FamilyID >= 6 ? (info.ExModelID << 4) : 0)) << std::endl; ModelName modelname {}; - auto res_8000_0002 = FEXCore::Context::RunCPUIDFunctionName(ctx, 0x8000'0002, 0, i); - auto res_8000_0003 = FEXCore::Context::RunCPUIDFunctionName(ctx, 0x8000'0003, 0, i); - auto res_8000_0004 = FEXCore::Context::RunCPUIDFunctionName(ctx, 0x8000'0004, 0, i); + auto res_8000_0002 = ctx->RunCPUIDFunctionName(0x8000'0002, 0, i); + auto res_8000_0003 = ctx->RunCPUIDFunctionName(0x8000'0003, 0, i); + auto res_8000_0004 = ctx->RunCPUIDFunctionName(0x8000'0004, 0, i); modelname.cpuid_2 = res_8000_0002; modelname.cpuid_3 = res_8000_0003; modelname.cpuid_4 = res_8000_0004; diff --git a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h index af15bd54d..bc776f84f 100644 --- a/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h +++ b/Source/Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h @@ -14,7 +14,7 @@ $end_info$ #include namespace FEXCore::Context { - struct Context; + class Context; } namespace FEX::EmulatedFile { diff --git a/Source/Tests/LinuxSyscalls/FileManagement.cpp b/Source/Tests/LinuxSyscalls/FileManagement.cpp index 8fb458bbe..cd521dc55 100644 --- a/Source/Tests/LinuxSyscalls/FileManagement.cpp +++ b/Source/Tests/LinuxSyscalls/FileManagement.cpp @@ -55,10 +55,6 @@ namespace JSON { } } -namespace FEXCore::Context { - struct Context; -} - namespace FEX::HLE { struct open_how; diff --git a/Source/Tests/LinuxSyscalls/FileManagement.h b/Source/Tests/LinuxSyscalls/FileManagement.h index f28fa24aa..c9e5d38b7 100644 --- a/Source/Tests/LinuxSyscalls/FileManagement.h +++ b/Source/Tests/LinuxSyscalls/FileManagement.h @@ -24,7 +24,7 @@ $end_info$ #include "Tests/LinuxSyscalls/EmulatedFiles/EmulatedFiles.h" namespace FEXCore::Context { -struct Context; +class Context; } namespace FEX::HLE { diff --git a/Source/Tests/LinuxSyscalls/Syscalls.cpp b/Source/Tests/LinuxSyscalls/Syscalls.cpp index a6a71ca0f..52eccef33 100644 --- a/Source/Tests/LinuxSyscalls/Syscalls.cpp +++ b/Source/Tests/LinuxSyscalls/Syscalls.cpp @@ -53,10 +53,6 @@ $end_info$ #include #include -namespace FEXCore::Context { - struct Context; -} - namespace FEX::HLE { class SignalDelegator; SyscallHandler *_SyscallHandler{}; @@ -607,7 +603,7 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::clone3_args }; if (flags & CLONE_VM) { - MarkMemoryShared(Frame->Thread->CTX); + Frame->Thread->CTX->MarkMemoryShared(); } // If there are flags that can't be handled regularly then we need to hand off to the true clone handler @@ -666,14 +662,14 @@ uint64_t CloneHandler(FEXCore::Core::CpuStateFrame *Frame, FEX::HLE::clone3_args } // Actually start the thread - FEXCore::Context::RunThread(Thread->CTX, NewThread); + Thread->CTX->RunThread(NewThread); if (flags & CLONE_VFORK) { // If VFORK is set then the calling process is suspended until the thread exits with execve or exit NewThread->ExecutionThread->join(nullptr); // Normally a thread cleans itself up on exit. But because we need to join, we are now responsible - FEXCore::Context::DestroyThread(Thread->CTX, NewThread); + Thread->CTX->DestroyThread(NewThread); } SYSCALL_ERRNO(); } @@ -708,7 +704,7 @@ uint64_t SyscallHandler::HandleBRK(FEXCore::Core::CpuStateFrame *Frame, void *Ad // We have pages we can unmap auto ok = GuestMunmap(reinterpret_cast(DataSpace + NewSizeAligned), RemainingSize); LOGMAN_THROW_A_FMT(ok != -1, "Munmap failed"); - + DataSpaceMaxSize = NewSizeAligned; } else if (NewSize > DataSpaceMaxSize) { @@ -864,8 +860,8 @@ void SyscallHandler::UnlockAfterFork() { // XXX shared_mutex has issues with locking and forks // VMATracking.Mutex.unlock(); - - FM.GetFDLock()->unlock(); + + FM.GetFDLock()->unlock(); } static bool isHEX(char c) { @@ -880,7 +876,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s LogMan::Msg::DFmt("GenerateMap: '{}' is not an elf file?", GuestBinaryFile); return {}; } - + struct stat GuestBinaryFileStat; if (stat(GuestBinaryFile.data(), &GuestBinaryFileStat)) { @@ -903,7 +899,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s if (stat(GuestSourceFile.data(), &GuestSourceFileStat) != 0 || GuestBinaryFileStat.st_mtime > GuestSourceFileStat.st_mtime) { LogMan::Msg::DFmt("GenerateMap: Generating source for '{}'", GuestBinaryFile); - auto command = fmt::format("x86_64-linux-gnu-objdump -SC \'{}\' > '{}'", GuestBinaryFile, GuestSourceFile); + auto command = fmt::format("x86_64-linux-gnu-objdump -SC \'{}\' > '{}'", GuestBinaryFile, GuestSourceFile); if (system(command.c_str()) != 0) { LogMan::Msg::DFmt("GenerateMap: '{}' failed", command); return {}; @@ -918,7 +914,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s if (!GenerateIndex) { // Index file de-serialization LogMan::Msg::DFmt("GenerateMap: Reading index '{}'", GuestIndexFile); - + std::ifstream Stream(GuestIndexFile); if (!Stream) { @@ -945,7 +941,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedLineMappings.size(); - + Stream.read((char*)&len, sizeof(len)); rv->SortedLineMappings.resize(len); @@ -959,7 +955,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedSymbolMappings.size(); - + Stream.read((char*)&len, sizeof(len)); rv->SortedSymbolMappings.resize(len); @@ -1000,7 +996,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s // objdump parsing std::string Line; int LineNum = 0; - + bool PreviousLineWasEmpty = false; uintptr_t LastSymbolOffset{}; @@ -1143,7 +1139,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedLineMappings.size(); - + IndexStream.write((const char*)&len, sizeof(len)); for (const auto &Mapping: rv->SortedLineMappings) { @@ -1155,7 +1151,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s { auto len = rv->SortedSymbolMappings.size(); - + IndexStream.write((char*)&len, sizeof(len)); for (const auto &Mapping: rv->SortedSymbolMappings) { @@ -1174,7 +1170,7 @@ std::unique_ptr SyscallHandler::GenerateMap(const s return rv; } - + } } diff --git a/Source/Tests/LinuxSyscalls/Syscalls.h b/Source/Tests/LinuxSyscalls/Syscalls.h index 595374444..f80babdf0 100644 --- a/Source/Tests/LinuxSyscalls/Syscalls.h +++ b/Source/Tests/LinuxSyscalls/Syscalls.h @@ -42,7 +42,7 @@ $end_info$ namespace FEXCore { class CodeLoader; namespace Context { - struct Context; + class Context; } namespace Core { struct CpuStateFrame; diff --git a/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp b/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp index be34765b3..2844c729a 100644 --- a/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp +++ b/Source/Tests/LinuxSyscalls/Syscalls/Thread.cpp @@ -55,8 +55,8 @@ namespace FEX::HLE { NewThreadState.gregs[FEXCore::X86State::REG_RSP] = args->args.stack; } - auto NewThread = FEXCore::Context::CreateThread(CTX, &NewThreadState, args->args.parent_tid); - FEXCore::Context::InitializeThread(CTX, NewThread); + auto NewThread = CTX->CreateThread(&NewThreadState, args->args.parent_tid); + CTX->InitializeThread(NewThread); if (FEX::HLE::_SyscallHandler->Is64BitMode()) { if (flags & CLONE_SETTLS) { @@ -128,7 +128,7 @@ namespace FEX::HLE { } // Overwrite thread - NewThread = FEXCore::Context::CreateThread(CTX, &NewThreadState, GuestArgs->parent_tid); + NewThread = CTX->CreateThread(&NewThreadState, GuestArgs->parent_tid); // CLONE_PARENT_SETTID, CLONE_CHILD_SETTID, CLONE_CHILD_CLEARTID, CLONE_PIDFD will be handled by kernel // Call execution thread directly since we already are on the new thread @@ -138,7 +138,7 @@ namespace FEX::HLE { // If we don't have CLONE_THREAD then we are effectively a fork // Clear all the other threads that are being tracked // Frame->Thread is /ONLY/ safe to access when CLONE_THREAD flag is not set - FEXCore::Context::CleanupAfterFork(CTX, Frame->Thread); + CTX->CleanupAfterFork(Frame->Thread); Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RAX] = 0; Thread->CurrentFrame->State.gregs[FEXCore::X86State::REG_RBX] = 0; @@ -177,7 +177,7 @@ namespace FEX::HLE { // Start exuting the thread directly // Our host clone starts in a new stack space, so it can't return back to the JIT space - FEXCore::Context::ExecutionThread(CTX, Thread); + CTX->ExecutionThread(Thread); // The rest of the context remains as is and the thread will continue executing return Thread->StatusCode; @@ -209,7 +209,7 @@ namespace FEX::HLE { Thread->ThreadManager.clear_child_tid = nullptr; // Clear all the other threads that are being tracked - FEXCore::Context::CleanupAfterFork(Thread->CTX, Frame->Thread); + Thread->CTX->CleanupAfterFork(Frame->Thread); // only a single thread running so no need to remove anything from the thread array @@ -264,7 +264,7 @@ namespace FEX::HLE { using namespace FEXCore::IR; REGISTER_SYSCALL_IMPL(rt_sigreturn, [](FEXCore::Core::CpuStateFrame *Frame) -> uint64_t { - FEXCore::Context::HandleSignalHandlerReturn(Frame->Thread->CTX, true); + Frame->Thread->CTX->HandleSignalHandlerReturn(true); FEX_UNREACHABLE; }); @@ -305,7 +305,7 @@ namespace FEX::HLE { } Thread->StatusCode = status; - FEXCore::Context::StopThread(Thread->CTX, Thread); + Thread->CTX->StopThread(Thread); return 0; }); @@ -513,7 +513,7 @@ namespace FEX::HLE { [](FEXCore::Core::CpuStateFrame *Frame, int status) -> uint64_t { auto Thread = Frame->Thread; Thread->StatusCode = status; - FEXCore::Context::Stop(Thread->CTX); + Thread->CTX->Stop(); // This will never be reached std::terminate(); }); diff --git a/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp b/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp index 8aaed027d..cd32a69bd 100644 --- a/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp +++ b/Source/Tests/LinuxSyscalls/SyscallsSMCTracking.cpp @@ -79,17 +79,17 @@ bool SyscallHandler::HandleSegfault(FEXCore::Core::InternalThreadState *Thread, auto FaultBaseMirrored = Offset - VMA->Offset + VMA->Base; if (VMA->Prot.Writable) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, FaultBaseMirrored, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { + CTX->InvalidateGuestCodeRange(FaultBaseMirrored, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { auto rv = mprotect((void *)Start, Length, PROT_READ | PROT_WRITE); LogMan::Throw::AAFmt(rv == 0, "mprotect({}, {}) failed", Start, Length); }); } else { - FEXCore::Context::InvalidateGuestCodeRange(CTX, FaultBaseMirrored, FHU::FEX_PAGE_SIZE); + CTX->InvalidateGuestCodeRange(FaultBaseMirrored, FHU::FEX_PAGE_SIZE); } } } while ((VMA = VMA->ResourceNextVMA)); } else { - FEXCore::Context::InvalidateGuestCodeRange(CTX, FaultBase, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { + CTX->InvalidateGuestCodeRange(FaultBase, FHU::FEX_PAGE_SIZE, [](uintptr_t Start, uintptr_t Length) { auto rv = mprotect((void *)Start, Length, PROT_READ | PROT_WRITE); LogMan::Throw::AAFmt(rv == 0, "mprotect({}, {}) failed", Start, Length); }); @@ -184,7 +184,7 @@ void SyscallHandler::TrackMmap(uintptr_t Base, uintptr_t Size, int Prot, int Fla Size = FEXCore::AlignUp(Size, FHU::FEX_PAGE_SIZE); if (Flags & MAP_SHARED) { - MarkMemoryShared(CTX); + CTX->MarkMemoryShared(); } { @@ -206,7 +206,7 @@ void SyscallHandler::TrackMmap(uintptr_t Base, uintptr_t Size, int Prot, int Fla Resource = &Iter->second; if (Inserted) { - Resource->AOTIRCacheEntry = FEXCore::Context::LoadAOTIRCacheEntry(CTX, filename.value()); + Resource->AOTIRCacheEntry = CTX->LoadAOTIRCacheEntry(filename.value()); Resource->Iterator = Iter; } } @@ -225,7 +225,7 @@ void SyscallHandler::TrackMmap(uintptr_t Base, uintptr_t Size, int Prot, int Fla } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, (uintptr_t)Base, Size); + CTX->InvalidateGuestCodeRange((uintptr_t)Base, Size); } } @@ -239,7 +239,7 @@ void SyscallHandler::TrackMunmap(uintptr_t Base, uintptr_t Size) { } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, (uintptr_t)Base, Size); + CTX->InvalidateGuestCodeRange((uintptr_t)Base, Size); } } @@ -253,7 +253,7 @@ void SyscallHandler::TrackMprotect(uintptr_t Base, uintptr_t Size, int Prot) { } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, Base, Size); + CTX->InvalidateGuestCodeRange(Base, Size); } } @@ -299,19 +299,19 @@ void SyscallHandler::TrackMremap(uintptr_t OldAddress, size_t OldSize, size_t Ne if (OldAddress != NewAddress) { if (OldSize != 0) { // This also handles the MREMAP_DONTUNMAP case - FEXCore::Context::InvalidateGuestCodeRange(CTX, OldAddress, OldSize); + CTX->InvalidateGuestCodeRange(OldAddress, OldSize); } } else { // If mapping shrunk, flush the unmapped region if (OldSize > NewSize) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, OldAddress + NewSize, OldSize - NewSize); + CTX->InvalidateGuestCodeRange(OldAddress + NewSize, OldSize - NewSize); } } } } void SyscallHandler::TrackShmat(int shmid, uintptr_t Base, int shmflg) { - MarkMemoryShared(CTX); + CTX->MarkMemoryShared(); shmid_ds stat; @@ -336,7 +336,7 @@ void SyscallHandler::TrackShmat(int shmid, uintptr_t Base, int shmflg) { ); } if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { - FEXCore::Context::InvalidateGuestCodeRange(CTX, Base, Length); + CTX->InvalidateGuestCodeRange(Base, Length); } } @@ -350,7 +350,7 @@ void SyscallHandler::TrackShmdt(uintptr_t Base) { if (SMCChecks != FEXCore::Config::CONFIG_SMC_NONE) { // This might over flush if the shm has holes in it - FEXCore::Context::InvalidateGuestCodeRange(CTX, Base, Length); + CTX->InvalidateGuestCodeRange(Base, Length); } } diff --git a/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp b/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp index b66db2657..99f88848c 100644 --- a/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp +++ b/Source/Tests/LinuxSyscalls/SyscallsVMATracking.cpp @@ -198,7 +198,7 @@ void SyscallHandler::VMATracking::ClearUnsafe(FEXCore::Context::Context *CTX, ui if (Current->Resource) { if (ListRemove(Current) && Current->Resource != PreservedMappedResource) { if (Current->Resource->AOTIRCacheEntry) { - FEXCore::Context::UnloadAOTIRCacheEntry(CTX, Current->Resource->AOTIRCacheEntry); + CTX->UnloadAOTIRCacheEntry(Current->Resource->AOTIRCacheEntry); } MappedResources.erase(Current->Resource->Iterator); } @@ -351,7 +351,7 @@ uintptr_t SyscallHandler::VMATracking::ClearShmUnsafe(FEXCore::Context::Context if (Entry->second.Resource == Resource) { if (ListRemove(&Entry->second)) { if (Entry->second.Resource->AOTIRCacheEntry) { - FEXCore::Context::UnloadAOTIRCacheEntry(CTX, Entry->second.Resource->AOTIRCacheEntry); + CTX->UnloadAOTIRCacheEntry(Entry->second.Resource->AOTIRCacheEntry); } MappedResources.erase(Entry->second.Resource->Iterator); } @@ -363,4 +363,4 @@ uintptr_t SyscallHandler::VMATracking::ClearShmUnsafe(FEXCore::Context::Context return ShmLength; } -} \ No newline at end of file +} diff --git a/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp b/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp index ff4eb44da..802c2b55d 100644 --- a/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp +++ b/Source/Tests/LinuxSyscalls/x32/Syscalls.cpp @@ -23,10 +23,6 @@ $end_info$ #include #include -namespace FEXCore::Context { - struct Context; -} - namespace FEX::HLE::x32 { void RegisterEpoll(FEX::HLE::SyscallHandler *Handler); void RegisterFD(FEX::HLE::SyscallHandler *Handler); diff --git a/Source/Tests/LinuxSyscalls/x32/Syscalls.h b/Source/Tests/LinuxSyscalls/x32/Syscalls.h index 8e7bdeed9..1bdb88edc 100644 --- a/Source/Tests/LinuxSyscalls/x32/Syscalls.h +++ b/Source/Tests/LinuxSyscalls/x32/Syscalls.h @@ -15,7 +15,7 @@ $end_info$ namespace FEXCore { namespace Context { - struct Context; + class Context; } namespace Core { struct CpuStateFrame; diff --git a/Source/Tests/LinuxSyscalls/x32/Thread.cpp b/Source/Tests/LinuxSyscalls/x32/Thread.cpp index dcaadfe38..0912b0d3a 100644 --- a/Source/Tests/LinuxSyscalls/x32/Thread.cpp +++ b/Source/Tests/LinuxSyscalls/x32/Thread.cpp @@ -100,7 +100,7 @@ namespace FEX::HLE::x32 { void RegisterThread(FEX::HLE::SyscallHandler *Handler) { REGISTER_SYSCALL_IMPL_X32(sigreturn, [](FEXCore::Core::CpuStateFrame *Frame) -> uint64_t { - FEXCore::Context::HandleSignalHandlerReturn(Frame->Thread->CTX, false); + Frame->Thread->CTX->HandleSignalHandlerReturn(false); FEX_UNREACHABLE; }); diff --git a/Source/Tests/TestHarnessRunner.cpp b/Source/Tests/TestHarnessRunner.cpp index f34c7f8be..c972dfe0f 100644 --- a/Source/Tests/TestHarnessRunner.cpp +++ b/Source/Tests/TestHarnessRunner.cpp @@ -162,12 +162,12 @@ int main(int argc, char **argv, char **const envp) { FEXCore::Context::InitializeStaticTables(Loader.Is64BitMode() ? FEXCore::Context::MODE_64BIT : FEXCore::Context::MODE_32BIT); - auto CTX = FEXCore::Context::CreateNewContext(); + auto CTX = FEXCore::Context::Context::CreateNewContext(); - FEXCore::Context::InitializeContext(CTX); + CTX->InitializeContext(); // Skip any tests that the host doesn't support features for - auto HostFeatures = FEXCore::Context::GetHostFeatures(CTX); + auto HostFeatures = CTX->GetHostFeatures(); SupportsAVX = HostFeatures.SupportsAVX; bool TestUnsupported = @@ -182,7 +182,7 @@ int main(int argc, char **argv, char **const envp) { (!HostFeatures.SupportsCLWB && Loader.RequiresCLWB()); if (TestUnsupported) { - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); return 0; } @@ -214,10 +214,10 @@ int main(int argc, char **argv, char **const envp) { return -ENOEXEC; } - FEXCore::Context::SetSignalDelegator(CTX, SignalDelegation.get()); - FEXCore::Context::SetSyscallHandler(CTX, SyscallHandler.get()); + CTX->SetSignalDelegator(SignalDelegation.get()); + CTX->SetSyscallHandler(SyscallHandler.get()); - bool Result1 = FEXCore::Context::InitCore(CTX, Loader.DefaultRIP(), Loader.GetStackPointer()); + bool Result1 = CTX->InitCore(Loader.DefaultRIP(), Loader.GetStackPointer()); if (!Result1) { return 1; @@ -225,11 +225,11 @@ int main(int argc, char **argv, char **const envp) { LongJumpVal = setjmp(LongJump); if (!LongJumpVal) { - FEXCore::Context::RunUntilExit(CTX); + CTX->RunUntilExit(); } // Just re-use compare state. It also checks against the expected values in config. - FEXCore::Context::GetCPUState(CTX, &State); + CTX->GetCPUState(&State); SyscallHandler.reset(); } else { @@ -245,7 +245,7 @@ int main(int argc, char **argv, char **const envp) { RunAsHost(SignalDelegation, Loader.DefaultRIP(), Loader.GetStackPointer(), &State); } - FEXCore::Context::DestroyContext(CTX); + FEXCore::Context::Context::DestroyContext(CTX); FEXCore::Context::ShutdownStaticTables(); bool Passed = !DidFault && Loader.CompareStates(&State, nullptr, SupportsAVX); diff --git a/Source/Tests/TestHarnessRunner/HostRunner.h b/Source/Tests/TestHarnessRunner/HostRunner.h index 784b2d73d..e32c80d8c 100644 --- a/Source/Tests/TestHarnessRunner/HostRunner.h +++ b/Source/Tests/TestHarnessRunner/HostRunner.h @@ -6,7 +6,7 @@ namespace FEXCore::CPU { class CPUBackend; } namespace FEXCore::Context{ - struct Context; + class Context; } namespace FEXCore::Core { struct InternalThreadState; @@ -17,4 +17,4 @@ namespace FEX::HLE { class SignalDelegator; } -void RunAsHost(std::unique_ptr &SignalDelegation, uintptr_t InitialRip, uintptr_t StackPointer, FEXCore::Core::CPUState *OutputState); \ No newline at end of file +void RunAsHost(std::unique_ptr &SignalDelegation, uintptr_t InitialRip, uintptr_t StackPointer, FEXCore::Core::CPUState *OutputState);