summaryrefslogtreecommitdiff
path: root/Source/Core/Common/MemoryUtil.cpp
diff options
context:
space:
mode:
authorSkyler Saleh <skylersaleh@gmail.com>2021-02-03 07:11:30 -0800
committerSkyler Saleh <skylersaleh@gmail.com>2021-05-22 15:25:18 -0700
commit4ff429266a75d8cfdb71fd37d818baa9a75264a3 (patch)
treec1369fe130d55cd9633435bf18c5cf95f8bc638b /Source/Core/Common/MemoryUtil.cpp
parent8cb86e7ae01211efb540999f4fbe44c4f42e001a (diff)
Apple M1: MacOS 11.2 mprotect restrictions
In MacOS 11.2 mprotect can no longer change the access protection settings of pages that were previously marked as executable to anything but PROT_NONE. This commit works around this new restriction by bypassing the mprotect based write protection and instead relying on the write protection provided by MAP_JIT.
Diffstat (limited to 'Source/Core/Common/MemoryUtil.cpp')
-rw-r--r--Source/Core/Common/MemoryUtil.cpp14
1 files changed, 11 insertions, 3 deletions
diff --git a/Source/Core/Common/MemoryUtil.cpp b/Source/Core/Common/MemoryUtil.cpp
index e81637912e..7aec9df40f 100644
--- a/Source/Core/Common/MemoryUtil.cpp
+++ b/Source/Core/Common/MemoryUtil.cpp
@@ -41,7 +41,9 @@ void* AllocateExecutableMemory(size_t size)
#else
int map_flags = MAP_ANON | MAP_PRIVATE;
#if defined(_M_ARM_64) && defined(__APPLE__)
- // This check is in place to prepare for x86_64 MAP_JIT support.
+ // This check is in place to prepare for x86_64 MAP_JIT support. While MAP_JIT did exist
+ // prior to 10.14, it had restrictions on the number of JIT allocations that were removed
+ // in 10.14.
if (__builtin_available(macOS 10.14, *))
map_flags |= MAP_JIT;
#endif
@@ -206,7 +208,10 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute)
DWORD oldValue;
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
PanicAlertFmt("WriteProtectMemory failed!\nVirtualProtect: {}", GetLastErrorString());
-#else
+#elif !(defined(_M_ARM_64) && defined(__APPLE__))
+ // MacOS 11.2 on ARM does not allow for changing the access permissions of pages
+ // that were marked executable, instead it uses the protections offered by MAP_JIT
+ // for write protection.
if (mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_EXEC) : PROT_READ) != 0)
PanicAlertFmt("WriteProtectMemory failed!\nmprotect: {}", LastStrerrorString());
#endif
@@ -218,7 +223,10 @@ void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute)
DWORD oldValue;
if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue))
PanicAlertFmt("UnWriteProtectMemory failed!\nVirtualProtect: {}", GetLastErrorString());
-#else
+#elif !(defined(_M_ARM_64) && defined(__APPLE__))
+ // MacOS 11.2 on ARM does not allow for changing the access permissions of pages
+ // that were marked executable, instead it uses the protections offered by MAP_JIT
+ // for write protection.
if (mprotect(ptr, size,
allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ) != 0)
{