Use allocateExecutable() in LLVMReactor
LLVMReactor was using default memory mapper when creating
SectionMemoryManager. The default memory mapper calls mmap() to allocate
memory on all platforms except Windows. It doesn't specify MAP_JIT flag
that is required to create executable memory on Mac and Fuchsia. As
result the allocated memory is not executable, which leads to crashes
when trying to run the generated code. Update LLVMRector to use a custom
MemoryMapper implementation.
Bug: chromium:1032622, b/145348318
Change-Id: Id188af269d80371b709e625c29b92ff546e9ba28
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39408
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Tested-by: Sergey Ulanov <sergeyu@chromium.org>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index 8683862..4b09748 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -43,11 +43,6 @@
#define NOMINMAX
#endif // !NOMINMAX
#include <Windows.h>
-#else
-#include <sys/mman.h>
-#if !defined(MAP_ANONYMOUS)
-#define MAP_ANONYMOUS MAP_ANON
-#endif
#endif
#include <mutex>
@@ -474,12 +469,13 @@
T *allocate(size_type n)
{
- return (T*)allocateExecutable(sizeof(T) * n);
+ return (T*)allocateMemoryPages(
+ sizeof(T) * n, PERMISSION_READ | PERMISSION_WRITE, true);
}
void deallocate(T *p, size_type n)
{
- deallocateExecutable(p, sizeof(T) * n);
+ deallocateMemoryPages(p, sizeof(T) * n);
}
};
@@ -497,13 +493,6 @@
~ELFMemoryStreamer() override
{
- #if defined(_WIN32)
- if(buffer.size() != 0)
- {
- DWORD exeProtection;
- VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
- }
- #endif
}
void write8(uint8_t Value) override
@@ -540,11 +529,10 @@
size_t codeSize = 0;
const void *entry = loadImage(&buffer[0], codeSize);
+ protectMemoryPages(&buffer[0], buffer.size(), PERMISSION_READ | PERMISSION_EXECUTE);
#if defined(_WIN32)
- VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READ, &oldProtection);
FlushInstructionCache(GetCurrentProcess(), NULL, 0);
#else
- mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_EXEC);
__builtin___clear_cache((char*)entry, (char*)entry + codeSize);
#endif
return entry;
@@ -576,10 +564,6 @@
std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
std::size_t position;
std::vector<std::unique_ptr<uint8_t[]>> constantData;
-
- #if defined(_WIN32)
- DWORD oldProtection;
- #endif
};
Nucleus::Nucleus()