diff --git a/Source/Windows/ARM64EC/Module.cpp b/Source/Windows/ARM64EC/Module.cpp index c2c9be484..ab07af93f 100644 --- a/Source/Windows/ARM64EC/Module.cpp +++ b/Source/Windows/ARM64EC/Module.cpp @@ -126,6 +126,10 @@ struct ThreadCPUArea { } }; +struct FrontendThreadData { + bool InLockedRWXRead {}; +}; + namespace { fextl::unique_ptr CTX; fextl::unique_ptr SignalDelegator; @@ -150,6 +154,10 @@ ThreadCPUArea GetCPUArea() { return ThreadCPUArea(NtCurrentTeb()); } +FrontendThreadData* GetFrontendThreadData(FEXCore::Core::InternalThreadState* Thread) { + return static_cast(Thread->FrontendPtr); +} + bool IsEmulatorStackAddress(const ThreadCPUArea CPUArea, uint64_t Address) { return Address <= CPUArea.EmulatorStackBase() && Address >= CPUArea.EmulatorStackLimit(); } @@ -928,6 +936,8 @@ NTSTATUS ThreadInit() { .AMD64_ControlWord = 0x27f}; Exception::LoadStateFromECContext(Thread, CPUArea.ContextAmd64().AMD64_Context); + Thread->FrontendPtr = new FrontendThreadData(); + { auto ThreadTID = GetCurrentThreadId(); Threads.emplace(ThreadTID, Thread); @@ -983,6 +993,8 @@ NTSTATUS ThreadTerm(HANDLE Thread, LONG ExitCode) { } auto ThreadState = CPUArea.ThreadState(); + delete GetFrontendThreadData(ThreadState); + // GDT and LDT are mirrored, only free one. delete[] ThreadState->CurrentFrame->State.segment_arrays[FEXCore::Core::CPUState::SEGMENT_ARRAY_INDEX_GDT]; diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index 23dbf679b..39800fa51 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -107,6 +107,10 @@ struct TLS { } }; +struct FrontendThreadData { + bool InLockedRWXRead {}; +}; + class WowSyscallHandler; namespace { @@ -142,6 +146,10 @@ TLS GetTLS() { return TLS {NtCurrentTeb()}; } +FrontendThreadData* GetFrontendThreadData(FEXCore::Core::InternalThreadState* Thread) { + return static_cast(Thread->FrontendPtr); +} + uint64_t GetWowTEB(void* TEB) { static constexpr size_t WowTEBOffsetMemberOffset {0x180c}; return static_cast( @@ -595,6 +603,8 @@ void BTCpuThreadInit() { TLS.ThreadState() = Thread; TLS.ControlWord().fetch_or(ControlBits::WOW_CPU_AREA_DIRTY, std::memory_order::relaxed); + Thread->FrontendPtr = new FrontendThreadData(); + auto ThreadTID = GetCurrentThreadId(); Threads.emplace(ThreadTID, Thread); if (StatAllocHandler) { @@ -641,6 +651,8 @@ void BTCpuThreadTerm(HANDLE Thread, LONG ExitCode) { } auto ThreadState = TLS.ThreadState(); + delete GetFrontendThreadData(ThreadState); + // GDT and LDT are mirrored, only free one. delete[] ThreadState->CurrentFrame->State.segment_arrays[FEXCore::Core::CPUState::SEGMENT_ARRAY_INDEX_GDT];