From d5b9c4a4bbb03fe50334ef076911e6c269f26e79 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Thu, 23 Aug 2018 20:52:50 +0100
Subject: [PATCH] block_of_code: Hide NX support behind compiler flag

Systems that require W^X can use the DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT cmake option.
---
 CMakeLists.txt                    | 3 ++-
 src/CMakeLists.txt                | 3 +++
 src/backend/x64/block_of_code.cpp | 8 ++++++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e52a6fee..f5a26d50 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,9 +10,10 @@ endif()
 
 # Dynarmic project options
 option(DYNARMIC_ENABLE_CPU_FEATURE_DETECTION "Turning this off causes dynarmic to assume the host CPU doesn't support anything later than SSE3" ON)
-option(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF)
+option(DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT "Enables support for systems that require W^X" OFF)
 option(DYNARMIC_TESTS "Build tests" ${MASTER_PROJECT})
 option(DYNARMIC_TESTS_USE_UNICORN "Enable fuzzing tests against unicorn" OFF)
+option(DYNARMIC_USE_LLVM "Support disassembly of jitted x86_64 code using LLVM" OFF)
 option(DYNARMIC_WARNINGS_AS_ERRORS "Warnings as errors" ${MASTER_PROJECT})
 
 # Default to a Release build
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index be0c4a27..d5347f46 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -277,6 +277,9 @@ target_link_libraries(dynarmic
 if (DYNARMIC_ENABLE_CPU_FEATURE_DETECTION)
     target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_CPU_FEATURE_DETECTION=1)
 endif()
+if (DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
+    target_compile_definitions(dynarmic PRIVATE DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=1)
+endif()
 if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
     target_compile_definitions(dynarmic PRIVATE FMT_USE_WINDOWS_H=0)
 endif()
diff --git a/src/backend/x64/block_of_code.cpp b/src/backend/x64/block_of_code.cpp
index b49d9392..73ebb3a3 100644
--- a/src/backend/x64/block_of_code.cpp
+++ b/src/backend/x64/block_of_code.cpp
@@ -51,12 +51,15 @@ constexpr size_t CONSTANT_POOL_SIZE = 2 * 1024 * 1024;
 
 class CustomXbyakAllocator : public Xbyak::Allocator {
 public:
+#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
     bool useProtect() const override { return false; }
+#endif
 };
 
 // This is threadsafe as Xbyak::Allocator does not contain any state; it is a pure interface.
 CustomXbyakAllocator s_allocator;
 
+#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
 void ProtectMemory(const void* base, size_t size, bool is_executable) {
 #ifdef _WIN32
     DWORD oldProtect = 0;
@@ -69,6 +72,7 @@ void ProtectMemory(const void* base, size_t size, bool is_executable) {
     mprotect(reinterpret_cast<void*>(roundAddr), size + (iaddr - roundAddr), mode);
 #endif
 }
+#endif
 
 } // anonymous namespace
 
@@ -92,11 +96,15 @@ void BlockOfCode::PreludeComplete() {
 }
 
 void BlockOfCode::EnableWriting() {
+#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
     ProtectMemory(getCode(), maxSize_, false);
+#endif
 }
 
 void BlockOfCode::DisableWriting() {
+#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
     ProtectMemory(getCode(), maxSize_, true);
+#endif
 }
 
 void BlockOfCode::ClearCache() {