// SPDX-License-Identifier: MIT #pragma once #include #include #include #include #include #include namespace FEXCore::Core { struct InternalThreadState; } namespace FEXCore::Context { class Context; } namespace FEX::Windows { /** * @brief Handles SMC and regular code invalidation */ class InvalidationTracker { public: InvalidationTracker(FEXCore::Context::Context& CTX, const std::unordered_map& Threads); void HandleMemoryProtectionNotification(uint64_t Address, uint64_t Size, ULONG Prot); void HandleImageMap(std::string_view Name, uint64_t Address); struct InvalidateContainingSectionResult { uint64_t SectionStart; uint64_t SectionSize; }; InvalidateContainingSectionResult InvalidateContainingSection(uint64_t Address, bool Free); void InvalidateAlignedInterval(uint64_t Address, uint64_t Size, bool Free); void ReprotectRWXIntervals(uint64_t Address, uint64_t Size); bool HandleRWXAccessViolation(FEXCore::Core::InternalThreadState* Thread, uint64_t HostPC, uint64_t FaultAddress); FEXCore::HLE::ExecutableRangeInfo QueryExecutableRange(uint64_t Address); private: void DetectMonoBackpatcherBlock(FEXCore::Core::InternalThreadState* Thread, uint64_t HostPC); void DisableSMCDetection(); void InvalidateIntervalInternal(uint64_t Address, uint64_t Size); FEXCore::IntervalList XIntervals; FEXCore::IntervalList RWXIntervals; std::shared_mutex IntervalsLock; FEXCore::Context::Context& CTX; const std::unordered_map& Threads; bool SMCDetectionDisabled {false}; // Protected by IntervalsLock bool MonoBackpatcherDetectionPending {false}; uint64_t MonoBase {0}; uint64_t MonoEnd {0}; }; } // namespace FEX::Windows