Implement executable memory allocation for Subzero on Unix.
Change-Id: I82b6a3f5336ca64dea30a8d9541fcf43c7ead81a
Reviewed-on: https://swiftshader-review.googlesource.com/8373
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/SubzeroReactor.cpp b/src/Reactor/SubzeroReactor.cpp
index aacec93..ab4c109 100644
--- a/src/Reactor/SubzeroReactor.cpp
+++ b/src/Reactor/SubzeroReactor.cpp
@@ -30,9 +30,13 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_os_ostream.h"
+#if defined(_WIN32)
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
+#else
+#include <sys/mman.h>
+#endif
#include <mutex>
#include <limits>
@@ -292,12 +296,20 @@
T *allocate(size_type n)
{
- return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ #if defined(_WIN32)
+ return (T*)VirtualAlloc(NULL, sizeof(T) * n, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
+ #else
+ return (T*)mmap(nullptr, sizeof(T) * n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ #endif
}
void deallocate(T *p, size_type n)
{
- VirtualFree(p, 0, MEM_RELEASE);
+ #if defined(_WIN32)
+ VirtualFree(p, 0, MEM_RELEASE);
+ #else
+ munmap(p, sizeof(T) * n);
+ #endif
}
};
@@ -315,11 +327,13 @@
virtual ~ELFMemoryStreamer()
{
- if(buffer.size() != 0)
- {
- DWORD exeProtection;
- VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
- }
+ #if defined(_WIN32)
+ if(buffer.size() != 0)
+ {
+ DWORD exeProtection;
+ VirtualProtect(&buffer[0], buffer.size(), oldProtection, &exeProtection);
+ }
+ #endif
}
void write8(uint8_t Value) override
@@ -353,8 +367,13 @@
{
if(!entry)
{
- VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READWRITE, &oldProtection);
- position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
+ #if defined(_WIN32)
+ VirtualProtect(&buffer[0], buffer.size(), PAGE_EXECUTE_READWRITE, &oldProtection);
+ #else
+ mprotect(&buffer[0], buffer.size(), PROT_READ | PROT_WRITE | PROT_EXEC);
+ #endif
+
+ position = std::numeric_limits<std::size_t>::max(); // Can't stream more data after this
entry = loadImage(&buffer[0]);
}
@@ -366,7 +385,10 @@
void *entry;
std::vector<uint8_t, ExecutableAllocator<uint8_t>> buffer;
std::size_t position;
+
+ #if defined(_WIN32)
DWORD oldProtection;
+ #endif
};
Nucleus::Nucleus()