From bd5b817c3a01b6881b7f2ba5be70cd391806bbaf Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Wed, 24 Jan 2024 00:37:25 +0000 Subject: [PATCH] AllocatorHooks: Mark JIT code memory as EC code on ARM64EC Executable mapped memory is treated as x86 code by default when running under EC, VirtualAlloc2 needs to be used together with a special flag to map JIT arm64 code. --- FEXCore/Source/CMakeLists.txt | 3 +++ .../include/FEXCore/Utils/AllocatorHooks.h | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/FEXCore/Source/CMakeLists.txt b/FEXCore/Source/CMakeLists.txt index 1dbf0165e5..b569e9af75 100644 --- a/FEXCore/Source/CMakeLists.txt +++ b/FEXCore/Source/CMakeLists.txt @@ -200,6 +200,9 @@ if (NOT MINGW_BUILD) list (APPEND LIBS dl) else() list (APPEND LIBS synchronization) + if (_M_ARM_64EC) + list (APPEND LIBS kernelbase) + endif() endif() if (ENABLE_JEMALLOC) diff --git a/FEXCore/include/FEXCore/Utils/AllocatorHooks.h b/FEXCore/include/FEXCore/Utils/AllocatorHooks.h index 85d2d914d1..0d0c246317 100644 --- a/FEXCore/include/FEXCore/Utils/AllocatorHooks.h +++ b/FEXCore/include/FEXCore/Utils/AllocatorHooks.h @@ -8,6 +8,7 @@ #endif #ifdef _WIN32 +#define NTDDI_VERSION 0x0A000005 #include #else #include @@ -38,12 +39,22 @@ extern "C" { namespace FEXCore::Allocator { #ifdef _WIN32 - inline void *VirtualAlloc(size_t Size, bool Execute = false) { - return ::VirtualAlloc(nullptr, Size, MEM_COMMIT, Execute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); + inline void *VirtualAlloc(void* Base, size_t Size, bool Execute = false) { +#ifdef _M_ARM_64EC + MEM_EXTENDED_PARAMETER Parameter{}; + if (Execute) { + Parameter.Type = MemExtendedParameterAttributeFlags; + Parameter.ULong64 = MEM_EXTENDED_PARAMETER_EC_CODE; + }; + return ::VirtualAlloc2(nullptr, Base, Size, MEM_COMMIT | (Base ? MEM_RESERVE : 0), Execute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, + &Parameter, Execute ? 1 : 0); +#else + return ::VirtualAlloc(Base, Size, MEM_COMMIT | (Base ? MEM_RESERVE : 0), Execute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); +#endif } - inline void *VirtualAlloc(void* Base, size_t Size, bool Execute = false) { - return ::VirtualAlloc(Base, Size, MEM_COMMIT | MEM_RESERVE, Execute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE); + inline void *VirtualAlloc(size_t Size, bool Execute = false) { + return VirtualAlloc(nullptr, Size, Execute); } inline void VirtualFree(void *Ptr, size_t Size) {