summaryrefslogtreecommitdiff
path: root/Source/Core/Common/MemoryUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/Common/MemoryUtil.cpp')
-rw-r--r--Source/Core/Common/MemoryUtil.cpp37
1 files changed, 35 insertions, 2 deletions
diff --git a/Source/Core/Common/MemoryUtil.cpp b/Source/Core/Common/MemoryUtil.cpp
index 44a6015027..b91faeeb91 100644
--- a/Source/Core/Common/MemoryUtil.cpp
+++ b/Source/Core/Common/MemoryUtil.cpp
@@ -16,6 +16,7 @@
#include <windows.h>
#include "Common/StringUtil.h"
#else
+#include <pthread.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>
@@ -38,9 +39,12 @@ void* AllocateExecutableMemory(size_t size)
#if defined(_WIN32)
void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
+ int map_flags =MAP_ANON | MAP_PRIVATE;
+#if defined(_M_ARM_64) && defined(__APPLE__)
+ map_flags |= MAP_JIT;
+#endif
void* ptr =
- mmap(nullptr, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
-
+ mmap(nullptr, size, PROT_READ | PROT_WRITE |PROT_EXEC , map_flags, -1, 0);
if (ptr == MAP_FAILED)
ptr = nullptr;
#endif
@@ -50,6 +54,35 @@ void* AllocateExecutableMemory(size_t size)
return ptr;
}
+// Certain platforms (Mac OS X on ARM) enforce that a single thread can only have write or
+// execute permissions to pages at any given point of time. The two below functions
+// are used to toggle between having write permissions or execute permissions.
+//
+// The default state of these allocations in Dolphin is for them to be executable,
+// but not writeable. So, functions that are updating these pages should wrap their
+// writes like below:
+
+// JITPageWriteEnableExecuteDisable();
+// PrepareInstructionStreamForJIT();
+// JITPageWriteDisableExecuteEnable();
+
+//Allows a thread to write to executable memory, but not execute the data.
+void JITPageWriteEnableExecuteDisable(){
+#if defined(_M_ARM_64) && defined(__APPLE__)
+ if (__builtin_available(macOS 11.0, *)) {
+ pthread_jit_write_protect_np(0);
+ }
+#endif
+
+}
+//Allows a thread to execute memory allocated for execution, but not write to it.
+void JITPageWriteDisableExecuteEnable(){
+#if defined(_M_ARM_64) && defined(__APPLE__)
+ if (__builtin_available(macOS 11.0, *)) {
+ pthread_jit_write_protect_np(1);
+ }
+#endif
+}
void* AllocateMemoryPages(size_t size)
{