Skip to content

Commit

Permalink
AllocatorHooks: Mark JIT code memory as EC code on ARM64EC
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bylaws committed Apr 6, 2024
1 parent e8127b9 commit bd5b817
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
3 changes: 3 additions & 0 deletions FEXCore/Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
19 changes: 15 additions & 4 deletions FEXCore/include/FEXCore/Utils/AllocatorHooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#endif

#ifdef _WIN32
#define NTDDI_VERSION 0x0A000005
#include <memoryapi.h>
#else
#include <sys/mman.h>
Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit bd5b817

Please sign in to comment.