diff --git a/Source/Windows/WOW64/Module.cpp b/Source/Windows/WOW64/Module.cpp index c27d4bb7a..beec33731 100644 --- a/Source/Windows/WOW64/Module.cpp +++ b/Source/Windows/WOW64/Module.cpp @@ -251,6 +251,34 @@ namespace Context { } } +namespace Invalidation { + void HandleMemoryProtectionNotification(uint64_t Address, uint64_t Size, ULONG Prot) { + const auto AlignedBase = Address & FHU::FEX_PAGE_MASK; + const auto AlignedSize = (Address - AlignedBase + Size + FHU::FEX_PAGE_SIZE - 1) & FHU::FEX_PAGE_MASK; + + if (Prot & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE)) { + CTX->InvalidateGuestCodeRange(GetTLS().ThreadState(), AlignedBase, AlignedSize); + } + } + + void InvalidateContainingSection(uint64_t Address, bool Free) { + MEMORY_BASIC_INFORMATION Info; + if (NtQueryVirtualMemory(NtCurrentProcess(), reinterpret_cast(Address), MemoryBasicInformation, &Info, sizeof(Info), nullptr)) + return; + + const auto SectionBase = reinterpret_cast(Info.AllocationBase); + const auto SectionSize = reinterpret_cast(Info.BaseAddress) + Info.RegionSize + - reinterpret_cast(Info.AllocationBase); + CTX->InvalidateGuestCodeRange(GetTLS().ThreadState(), SectionBase, SectionSize); + } + + void InvalidateAlignedInterval(uint64_t Address, uint64_t Size, bool Free) { + const auto AlignedBase = Address & FHU::FEX_PAGE_MASK; + const auto AlignedSize = (Address - AlignedBase + Size + FHU::FEX_PAGE_SIZE - 1) & FHU::FEX_PAGE_MASK; + CTX->InvalidateGuestCodeRange(GetTLS().ThreadState(), AlignedBase, AlignedSize); + } +} + namespace Logging { void MsgHandler(LogMan::DebugLevels Level, char const *Message) { const auto Output = fextl::fmt::format("[{}][{:X}] {}\n", LogMan::DebugLevelStr(Level), GetCurrentThreadId(), Message); @@ -494,6 +522,31 @@ NTSTATUS BTCpuResetToConsistentState(EXCEPTION_POINTERS *Ptrs) { return STATUS_SUCCESS; } +void BTCpuFlushInstructionCache2(const void *Address, SIZE_T Size) { + Invalidation::InvalidateAlignedInterval(reinterpret_cast(Address), static_cast(Size), false); +} + +void BTCpuNotifyMemoryAlloc(void *Address, SIZE_T Size, ULONG Type, ULONG Prot) { + Invalidation::HandleMemoryProtectionNotification(reinterpret_cast(Address), Size, Prot); +} + +void BTCpuNotifyMemoryProtect(void *Address, SIZE_T Size, ULONG NewProt, ULONG *OldProt) { + const auto AddressInt = reinterpret_cast(Address); + Invalidation::HandleMemoryProtectionNotification(AddressInt, static_cast(Size), NewProt); +} + +void BTCpuNotifyMemoryFree(void *Address, SIZE_T Size, ULONG FreeType) { + if (!Size) { + Invalidation::InvalidateContainingSection(reinterpret_cast(Address), true); + } else if (FreeType & MEM_DECOMMIT) { + Invalidation::InvalidateAlignedInterval(reinterpret_cast(Address), static_cast(Size), true); + } +} + +void BTCpuNotifyUnmapViewOfSection(void *Address, ULONG Flags) { + Invalidation::InvalidateContainingSection(reinterpret_cast(Address), true); +} + BOOLEAN WINAPI BTCpuIsProcessorFeaturePresent(UINT Feature) { switch (Feature) { case PF_FLOATING_POINT_PRECISION_ERRATA: