summaryrefslogtreecommitdiff
path: root/erts/emulator/asmjit/core/virtmem.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/asmjit/core/virtmem.cpp')
-rw-r--r--erts/emulator/asmjit/core/virtmem.cpp339
1 files changed, 160 insertions, 179 deletions
diff --git a/erts/emulator/asmjit/core/virtmem.cpp b/erts/emulator/asmjit/core/virtmem.cpp
index ba02fa7a78..43766ef2cd 100644
--- a/erts/emulator/asmjit/core/virtmem.cpp
+++ b/erts/emulator/asmjit/core/virtmem.cpp
@@ -1,25 +1,7 @@
-// AsmJit - Machine code generation for C++
+// This file is part of AsmJit project <https://asmjit.com>
//
-// * Official AsmJit Home Page: https://asmjit.com
-// * Official Github Repository: https://github.com/asmjit/asmjit
-//
-// Copyright (c) 2008-2020 The AsmJit Authors
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-// 3. This notice may not be removed or altered from any source distribution.
+// See asmjit.h or LICENSE.md for license and copyright information
+// SPDX-License-Identifier: Zlib
#include "../core/api-build_p.h"
#ifndef ASMJIT_NO_JIT
@@ -48,8 +30,7 @@
#include <TargetConditionals.h>
#if TARGET_OS_OSX
#include <sys/utsname.h>
- // We also need this for sys_icache_invalidate().
- #include <libkern/OSCacheControl.h>
+ #include <libkern/OSCacheControl.h> // sys_icache_invalidate().
#endif
// Older SDK doesn't define `MAP_JIT`.
#ifndef MAP_JIT
@@ -65,30 +46,35 @@
#include <atomic>
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(__BIONIC__)
#define ASMJIT_VM_SHM_DETECT 0
#else
#define ASMJIT_VM_SHM_DETECT 1
#endif
+// Android NDK doesn't provide `shm_open()` and `shm_unlink()`.
+#if defined(__BIONIC__)
+ #define ASMJIT_VM_SHM_AVAILABLE 0
+#else
+ #define ASMJIT_VM_SHM_AVAILABLE 1
+#endif
+
#if defined(__APPLE__) && ASMJIT_ARCH_ARM >= 64
#define ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP
#endif
-ASMJIT_BEGIN_NAMESPACE
+ASMJIT_BEGIN_SUB_NAMESPACE(VirtMem)
-// ============================================================================
-// [asmjit::VirtMem - Utilities]
-// ============================================================================
+// Virtual Memory Utilities
+// ========================
-static const uint32_t VirtMem_dualMappingFilter[2] = {
- VirtMem::kAccessWrite | VirtMem::kMMapMaxAccessWrite,
- VirtMem::kAccessExecute | VirtMem::kMMapMaxAccessExecute
+static const MemoryFlags dualMappingFilter[2] = {
+ MemoryFlags::kAccessWrite | MemoryFlags::kMMapMaxAccessWrite,
+ MemoryFlags::kAccessExecute | MemoryFlags::kMMapMaxAccessExecute
};
-// ============================================================================
-// [asmjit::VirtMem - Virtual Memory Management [Windows]]
-// ============================================================================
+// Virtual Memory [Windows]
+// ========================
#if defined(_WIN32)
@@ -104,7 +90,7 @@ struct ScopedHandle {
HANDLE value;
};
-static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
+static void getVMInfo(Info& vmInfo) noexcept {
SYSTEM_INFO systemInfo;
::GetSystemInfo(&systemInfo);
@@ -112,15 +98,15 @@ static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
vmInfo.pageGranularity = systemInfo.dwAllocationGranularity;
}
-// Returns windows-specific protectFlags from \ref VirtMem::Flags.
-static DWORD VirtMem_winProtectFlagsFromFlags(uint32_t flags) noexcept {
+// Returns windows-specific protectFlags from \ref MemoryFlags.
+static DWORD protectFlagsFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
DWORD protectFlags;
// READ|WRITE|EXECUTE.
- if (flags & VirtMem::kAccessExecute)
- protectFlags = (flags & VirtMem::kAccessWrite) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
- else if (flags & VirtMem::kAccessRW)
- protectFlags = (flags & VirtMem::kAccessWrite) ? PAGE_READWRITE : PAGE_READONLY;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute))
+ protectFlags = Support::test(memoryFlags, MemoryFlags::kAccessWrite) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+ else if (Support::test(memoryFlags, MemoryFlags::kAccessRW))
+ protectFlags = Support::test(memoryFlags, MemoryFlags::kAccessWrite) ? PAGE_READWRITE : PAGE_READONLY;
else
protectFlags = PAGE_NOACCESS;
@@ -128,23 +114,23 @@ static DWORD VirtMem_winProtectFlagsFromFlags(uint32_t flags) noexcept {
return protectFlags;
}
-static DWORD VirtMem_winDesiredAccessFromFlags(uint32_t flags) noexcept {
- DWORD access = (flags & VirtMem::kAccessWrite) ? FILE_MAP_WRITE : FILE_MAP_READ;
- if (flags & VirtMem::kAccessExecute)
+static DWORD desiredAccessFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
+ DWORD access = Support::test(memoryFlags, MemoryFlags::kAccessWrite) ? FILE_MAP_WRITE : FILE_MAP_READ;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute))
access |= FILE_MAP_EXECUTE;
return access;
}
-static uint32_t VirtMem_hardenedRuntimeFlags() noexcept {
- return 0;
+static HardenedRuntimeFlags getHardenedRuntimeFlags() noexcept {
+ return HardenedRuntimeFlags::kNone;
}
-Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
+Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
*p = nullptr;
if (size == 0)
return DebugUtils::errored(kErrorInvalidArgument);
- DWORD protectFlags = VirtMem_winProtectFlagsFromFlags(flags);
+ DWORD protectFlags = protectFlagsFromMemoryFlags(memoryFlags);
void* result = ::VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, protectFlags);
if (!result)
@@ -154,15 +140,15 @@ Error VirtMem::alloc(void** p, size_t size, uint32_t flags) noexcept {
return kErrorOk;
}
-Error VirtMem::release(void* p, size_t size) noexcept {
+Error release(void* p, size_t size) noexcept {
DebugUtils::unused(size);
if (ASMJIT_UNLIKELY(!::VirtualFree(p, 0, MEM_RELEASE)))
return DebugUtils::errored(kErrorInvalidArgument);
return kErrorOk;
}
-Error VirtMem::protect(void* p, size_t size, uint32_t flags) noexcept {
- DWORD protectFlags = VirtMem_winProtectFlagsFromFlags(flags);
+Error protect(void* p, size_t size, MemoryFlags memoryFlags) noexcept {
+ DWORD protectFlags = protectFlagsFromMemoryFlags(memoryFlags);
DWORD oldFlags;
if (::VirtualProtect(p, size, protectFlags, &oldFlags))
@@ -171,11 +157,7 @@ Error VirtMem::protect(void* p, size_t size, uint32_t flags) noexcept {
return DebugUtils::errored(kErrorInvalidArgument);
}
-// ============================================================================
-// [asmjit::VirtMem - Dual Mapping [Windows]]
-// ============================================================================
-
-Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) noexcept {
+Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
dm->rx = nullptr;
dm->rw = nullptr;
@@ -196,8 +178,8 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
- uint32_t accessFlags = flags & ~VirtMem_dualMappingFilter[i];
- DWORD desiredAccess = VirtMem_winDesiredAccessFromFlags(accessFlags);
+ MemoryFlags accessFlags = memoryFlags & ~dualMappingFilter[i];
+ DWORD desiredAccess = desiredAccessFromMemoryFlags(accessFlags);
ptr[i] = ::MapViewOfFile(handle.value, desiredAccess, 0, 0, size);
if (ptr[i] == nullptr) {
@@ -212,7 +194,7 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t flags) no
return kErrorOk;
}
-Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
+Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
DebugUtils::unused(size);
bool failed = false;
@@ -232,13 +214,12 @@ Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
#endif
-// ============================================================================
-// [asmjit::VirtMem - Virtual Memory Management [Posix]]
-// ============================================================================
+// Virtual Memory [Posix]
+// ======================
#if !defined(_WIN32)
-static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
+static void getVMInfo(Info& vmInfo) noexcept {
uint32_t pageSize = uint32_t(::getpagesize());
vmInfo.pageSize = pageSize;
@@ -246,14 +227,14 @@ static void VirtMem_getInfo(VirtMem::Info& vmInfo) noexcept {
}
#if !defined(SHM_ANON)
-static const char* VirtMem_getTmpDir() noexcept {
+static const char* getTmpDir() noexcept {
const char* tmpDir = getenv("TMPDIR");
return tmpDir ? tmpDir : "/tmp";
}
#endif
// Translates libc errors specific to VirtualMemory mapping to `asmjit::Error`.
-static Error VirtMem_asmjitErrorFromErrno(int e) noexcept {
+static Error asmjitErrorFromErrno(int e) noexcept {
switch (e) {
case EACCES:
case EAGAIN:
@@ -275,16 +256,14 @@ static Error VirtMem_asmjitErrorFromErrno(int e) noexcept {
}
}
-// Some operating systems don't allow /dev/shm to be executable. On Linux this
-// happens when /dev/shm is mounted with 'noexec', which is enforced by systemd.
-// Other operating systems like MacOS also restrict executable permissions regarding
-// /dev/shm, so we use a runtime detection before attempting to allocate executable
-// memory. Sometimes we don't need the detection as we know it would always result
-// in `kShmStrategyTmpDir`.
-enum ShmStrategy : uint32_t {
- kShmStrategyUnknown = 0,
- kShmStrategyDevShm = 1,
- kShmStrategyTmpDir = 2
+// Some operating systems don't allow /dev/shm to be executable. On Linux this happens when /dev/shm is mounted with
+// 'noexec', which is enforced by systemd. Other operating systems like MacOS also restrict executable permissions
+// regarding /dev/shm, so we use a runtime detection before attempting to allocate executable memory. Sometimes we
+// don't need the detection as we know it would always result in `ShmStrategy::kTmpDir`.
+enum class ShmStrategy : uint32_t {
+ kUnknown = 0,
+ kDevShm = 1,
+ kTmpDir = 2
};
class AnonymousMemory {
@@ -299,17 +278,17 @@ public:
FileType _fileType;
StringTmp<128> _tmpName;
- ASMJIT_INLINE AnonymousMemory() noexcept
+ inline AnonymousMemory() noexcept
: _fd(-1),
_fileType(kFileTypeNone),
_tmpName() {}
- ASMJIT_INLINE ~AnonymousMemory() noexcept {
+ inline ~AnonymousMemory() noexcept {
unlink();
close();
}
- ASMJIT_INLINE int fd() const noexcept { return _fd; }
+ inline int fd() const noexcept { return _fd; }
Error open(bool preferTmpOverDevShm) noexcept {
#if defined(__linux__) && defined(__NR_memfd_create)
@@ -329,7 +308,7 @@ public:
if (e == ENOSYS)
memfd_create_not_supported = 1;
else
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
#endif
@@ -341,13 +320,12 @@ public:
if (ASMJIT_LIKELY(_fd >= 0))
return kErrorOk;
else
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(errno));
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
#else
- // POSIX API. We have to generate somehow a unique name. This is nothing
- // cryptographic, just using a bit from the stack address to always have
- // a different base for different threads (as threads have their own stack)
- // and retries for avoiding collisions. We use `shm_open()` with flags that
- // require creation of the file so we never open an existing shared memory.
+ // POSIX API. We have to generate somehow a unique name. This is nothing cryptographic, just using a bit from
+ // the stack address to always have a different base for different threads (as threads have their own stack)
+ // and retries for avoiding collisions. We use `shm_open()` with flags that require creation of the file so we
+ // never open an existing shared memory.
static std::atomic<uint32_t> internalCounter;
const char* kShmFormat = "/shm-id-%016llX";
@@ -358,8 +336,10 @@ public:
bits -= uint64_t(OSUtils::getTickCount()) * 773703683;
bits = ((bits >> 14) ^ (bits << 6)) + uint64_t(++internalCounter) * 10619863;
- if (!ASMJIT_VM_SHM_DETECT || preferTmpOverDevShm) {
- _tmpName.assign(VirtMem_getTmpDir());
+ bool useTmp = !ASMJIT_VM_SHM_DETECT || preferTmpOverDevShm;
+
+ if (useTmp) {
+ _tmpName.assign(getTmpDir());
_tmpName.appendFormat(kShmFormat, (unsigned long long)bits);
_fd = ::open(_tmpName.data(), O_RDWR | O_CREAT | O_EXCL, 0);
if (ASMJIT_LIKELY(_fd >= 0)) {
@@ -367,6 +347,7 @@ public:
return kErrorOk;
}
}
+#if ASMJIT_VM_SHM_AVAILABLE
else {
_tmpName.assignFormat(kShmFormat, (unsigned long long)bits);
_fd = ::shm_open(_tmpName.data(), O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
@@ -375,10 +356,11 @@ public:
return kErrorOk;
}
}
+#endif
int e = errno;
if (e != EEXIST)
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
return DebugUtils::errored(kErrorFailedToOpenAnonymousMemory);
@@ -389,10 +371,17 @@ public:
FileType type = _fileType;
_fileType = kFileTypeNone;
- if (type == kFileTypeShm)
+#if ASMJIT_VM_SHM_AVAILABLE
+ if (type == kFileTypeShm) {
::shm_unlink(_tmpName.data());
- else if (type == kFileTypeTmp)
+ return;
+ }
+#endif
+
+ if (type == kFileTypeTmp) {
::unlink(_tmpName.data());
+ return;
+ }
}
void close() noexcept {
@@ -405,23 +394,25 @@ public:
Error allocate(size_t size) noexcept {
// TODO: Improve this by using `posix_fallocate()` when available.
if (ftruncate(_fd, off_t(size)) != 0)
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(errno));
+ return DebugUtils::errored(asmjitErrorFromErrno(errno));
return kErrorOk;
}
};
-// Returns `mmap()` protection flags from \ref VirtMem::Flags.
-static int VirtMem_mmProtFromFlags(uint32_t flags) noexcept {
+// Returns `mmap()` protection flags from \ref MemoryFlags.
+static int mmProtFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
int protection = 0;
- if (flags & VirtMem::kAccessRead) protection |= PROT_READ;
- if (flags & VirtMem::kAccessWrite) protection |= PROT_READ | PROT_WRITE;
- if (flags & VirtMem::kAccessExecute) protection |= PROT_READ | PROT_EXEC;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessRead)) protection |= PROT_READ;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessWrite)) protection |= PROT_READ | PROT_WRITE;
+ if (Support::test(memoryFlags, MemoryFlags::kAccessExecute)) protection |= PROT_READ | PROT_EXEC;
return protection;
}
#if defined(__APPLE__)
-static ASMJIT_INLINE bool VirtMem_hasHardenedRuntimeMacOS() noexcept {
+// Detects whether the current process is hardened, which means that pages that have WRITE and EXECUTABLE flags cannot
+// be allocated without MAP_JIT flag.
+static inline bool hasHardenedRuntimeMacOS() noexcept {
#if TARGET_OS_OSX && ASMJIT_ARCH_ARM >= 64
// MacOS on AArch64 has always hardened runtime enabled.
return true;
@@ -453,7 +444,7 @@ static ASMJIT_INLINE bool VirtMem_hasHardenedRuntimeMacOS() noexcept {
#endif
}
-static ASMJIT_INLINE bool VirtMem_hasMapJitSupportMacOS() noexcept {
+static inline bool hasMapJitSupportMacOS() noexcept {
#if TARGET_OS_OSX && ASMJIT_ARCH_ARM >= 64
// MacOS for 64-bit AArch architecture always uses hardened runtime. Some documentation can be found here:
// - https://developer.apple.com/documentation/apple_silicon/porting_just-in-time_compilers_to_apple_silicon
@@ -477,62 +468,61 @@ static ASMJIT_INLINE bool VirtMem_hasMapJitSupportMacOS() noexcept {
}
#endif // __APPLE__
-// Detects whether the current process is hardened, which means that pages that
-// have WRITE and EXECUTABLE flags cannot be normally allocated. On MacOS such
-// allocation requires MAP_JIT flag.
-static ASMJIT_INLINE bool VirtMem_hasHardenedRuntime() noexcept {
+// Detects whether the current process is hardened, which means that pages that have WRITE and EXECUTABLE flags
+// cannot be normally allocated. On MacOS such allocation requires MAP_JIT flag.
+static inline bool hasHardenedRuntime() noexcept {
#if defined(__APPLE__)
- return VirtMem_hasHardenedRuntimeMacOS();
+ return hasHardenedRuntimeMacOS();
#else
return false;
#endif
}
// Detects whether MAP_JIT is available.
-static ASMJIT_INLINE bool VirtMem_hasMapJitSupport() noexcept {
+static inline bool hasMapJitSupport() noexcept {
#if defined(__APPLE__)
- return VirtMem_hasMapJitSupportMacOS();
+ return hasMapJitSupportMacOS();
#else
return false;
#endif
}
// Returns either MAP_JIT or 0 based on `flags` and the host operating system.
-static ASMJIT_INLINE int VirtMem_mmMapJitFromFlags(uint32_t flags) noexcept {
+static inline int mmMapJitFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
#if defined(__APPLE__)
- // Always use MAP_JIT flag if user asked for it (could be used for testing
- // on non-hardened processes) and detect whether it must be used when the
- // process is actually hardened (in that case it doesn't make sense to rely
- // on user `flags`).
- bool useMapJit = (flags & VirtMem::kMMapEnableMapJit) != 0 || VirtMem_hasHardenedRuntime();
+ // Always use MAP_JIT flag if user asked for it (could be used for testing on non-hardened processes) and detect
+ // whether it must be used when the process is actually hardened (in that case it doesn't make sense to rely on
+ // user `memoryFlags`).
+ bool useMapJit = Support::test(memoryFlags, MemoryFlags::kMMapEnableMapJit) || hasHardenedRuntime();
if (useMapJit)
- return VirtMem_hasMapJitSupport() ? int(MAP_JIT) : 0;
+ return hasMapJitSupport() ? int(MAP_JIT) : 0;
else
return 0;
#else
- DebugUtils::unused(flags);
+ DebugUtils::unused(memoryFlags);
return 0;
#endif
}
// Returns BSD-specific `PROT_MAX()` flags.
-static ASMJIT_INLINE int VirtMem_mmMaxProtFromFlags(uint32_t flags) noexcept {
+static inline int mmMaxProtFromMemoryFlags(MemoryFlags memoryFlags) noexcept {
#if defined(PROT_MAX)
- static constexpr uint32_t kMaxProtShift = Support::constCtz(VirtMem::kMMapMaxAccessRead);
- if (flags & (VirtMem::kMMapMaxAccessReadWrite | VirtMem::kMMapMaxAccessExecute))
- return PROT_MAX(VirtMem_mmProtFromFlags(flags >> kMaxProtShift));
+ static constexpr uint32_t kMaxProtShift = Support::ConstCTZ<uint32_t(MemoryFlags::kMMapMaxAccessRead)>::value;
+
+ if (Support::test(memoryFlags, MemoryFlags::kMMapMaxAccessReadWrite | MemoryFlags::kMMapMaxAccessExecute))
+ return PROT_MAX(mmProtFromMemoryFlags((MemoryFlags)(uint32_t(memoryFlags) >> kMaxProtShift)));
else
return 0;
#else
- DebugUtils::unused(flags);
+ DebugUtils::unused(memoryFlags);
return 0;
#endif
}
#if ASMJIT_VM_SHM_DETECT
-static Error VirtMem_detectShmStrategy(uint32_t* strategyOut) noexcept {
+static Error detectShmStrategy(ShmStrategy* strategyOut) noexcept {
AnonymousMemory anonMem;
- VirtMem::Info vmInfo = VirtMem::info();
+ Info vmInfo = info();
ASMJIT_PROPAGATE(anonMem.open(false));
ASMJIT_PROPAGATE(anonMem.allocate(vmInfo.pageSize));
@@ -541,58 +531,57 @@ static Error VirtMem_detectShmStrategy(uint32_t* strategyOut) noexcept {
if (ptr == MAP_FAILED) {
int e = errno;
if (e == EINVAL) {
- *strategyOut = kShmStrategyTmpDir;
+ *strategyOut = ShmStrategy::kTmpDir;
return kErrorOk;
}
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
else {
munmap(ptr, vmInfo.pageSize);
- *strategyOut = kShmStrategyDevShm;
+ *strategyOut = ShmStrategy::kDevShm;
return kErrorOk;
}
}
#endif
-static Error VirtMem_getShmStrategy(uint32_t* strategyOut) noexcept {
+static Error getShmStrategy(ShmStrategy* strategyOut) noexcept {
#if ASMJIT_VM_SHM_DETECT
- // Initially don't assume anything. It has to be tested whether
- // '/dev/shm' was mounted with 'noexec' flag or not.
+ // Initially don't assume anything. It has to be tested whether '/dev/shm' was mounted with 'noexec' flag or not.
static std::atomic<uint32_t> globalShmStrategy;
- uint32_t strategy = globalShmStrategy.load();
- if (strategy == kShmStrategyUnknown) {
- ASMJIT_PROPAGATE(VirtMem_detectShmStrategy(&strategy));
- globalShmStrategy.store(strategy);
+ ShmStrategy strategy = static_cast<ShmStrategy>(globalShmStrategy.load());
+ if (strategy == ShmStrategy::kUnknown) {
+ ASMJIT_PROPAGATE(detectShmStrategy(&strategy));
+ globalShmStrategy.store(static_cast<uint32_t>(strategy));
}
*strategyOut = strategy;
return kErrorOk;
#else
- *strategyOut = kShmStrategyTmpDir;
+ *strategyOut = ShmStrategy::kTmpDir;
return kErrorOk;
#endif
}
-static uint32_t VirtMem_hardenedRuntimeFlags() noexcept {
- uint32_t flags = 0;
+static HardenedRuntimeFlags getHardenedRuntimeFlags() noexcept {
+ HardenedRuntimeFlags hrFlags = HardenedRuntimeFlags::kNone;
- if (VirtMem_hasHardenedRuntime())
- flags |= VirtMem::kHardenedRuntimeEnabled;
+ if (hasHardenedRuntime())
+ hrFlags |= HardenedRuntimeFlags::kEnabled;
- if (VirtMem_hasMapJitSupport())
- flags |= VirtMem::kHardenedRuntimeMapJit;
+ if (hasMapJitSupport())
+ hrFlags |= HardenedRuntimeFlags::kMapJit;
- return flags;
+ return hrFlags;
}
-Error VirtMem::alloc(void** p, size_t size, uint32_t memoryFlags) noexcept {
+Error alloc(void** p, size_t size, MemoryFlags memoryFlags) noexcept {
*p = nullptr;
if (size == 0)
return DebugUtils::errored(kErrorInvalidArgument);
- int protection = VirtMem_mmProtFromFlags(memoryFlags) | VirtMem_mmMaxProtFromFlags(memoryFlags);
- int mmFlags = MAP_PRIVATE | MAP_ANONYMOUS | VirtMem_mmMapJitFromFlags(memoryFlags);
+ int protection = mmProtFromMemoryFlags(memoryFlags) | mmMaxProtFromMemoryFlags(memoryFlags);
+ int mmFlags = MAP_PRIVATE | MAP_ANONYMOUS | mmMapJitFromMemoryFlags(memoryFlags);
void* ptr = mmap(nullptr, size, protection, mmFlags, -1, 0);
if (ptr == MAP_FAILED)
@@ -602,7 +591,7 @@ Error VirtMem::alloc(void** p, size_t size, uint32_t memoryFlags) noexcept {
return kErrorOk;
}
-Error VirtMem::release(void* p, size_t size) noexcept {
+Error release(void* p, size_t size) noexcept {
if (ASMJIT_UNLIKELY(munmap(p, size) != 0))
return DebugUtils::errored(kErrorInvalidArgument);
@@ -610,30 +599,26 @@ Error VirtMem::release(void* p, size_t size) noexcept {
}
-Error VirtMem::protect(void* p, size_t size, uint32_t memoryFlags) noexcept {
- int protection = VirtMem_mmProtFromFlags(memoryFlags);
+Error protect(void* p, size_t size, MemoryFlags memoryFlags) noexcept {
+ int protection = mmProtFromMemoryFlags(memoryFlags);
if (mprotect(p, size, protection) == 0)
return kErrorOk;
return DebugUtils::errored(kErrorInvalidArgument);
}
-// ============================================================================
-// [asmjit::VirtMem - Dual Mapping [Posix]]
-// ============================================================================
-
-Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t memoryFlags) noexcept {
+Error allocDualMapping(DualMapping* dm, size_t size, MemoryFlags memoryFlags) noexcept {
dm->rx = nullptr;
dm->rw = nullptr;
if (off_t(size) <= 0)
return DebugUtils::errored(size == 0 ? kErrorInvalidArgument : kErrorTooLarge);
- bool preferTmpOverDevShm = (memoryFlags & kMappingPreferTmp) != 0;
+ bool preferTmpOverDevShm = Support::test(memoryFlags, MemoryFlags::kMappingPreferTmp);
if (!preferTmpOverDevShm) {
- uint32_t strategy;
- ASMJIT_PROPAGATE(VirtMem_getShmStrategy(&strategy));
- preferTmpOverDevShm = (strategy == kShmStrategyTmpDir);
+ ShmStrategy strategy;
+ ASMJIT_PROPAGATE(getShmStrategy(&strategy));
+ preferTmpOverDevShm = (strategy == ShmStrategy::kTmpDir);
}
AnonymousMemory anonMem;
@@ -642,8 +627,8 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t memoryFla
void* ptr[2];
for (uint32_t i = 0; i < 2; i++) {
- uint32_t accessFlags = memoryFlags & ~VirtMem_dualMappingFilter[i];
- int protection = VirtMem_mmProtFromFlags(accessFlags) | VirtMem_mmMaxProtFromFlags(accessFlags);
+ MemoryFlags accessFlags = memoryFlags & ~dualMappingFilter[i];
+ int protection = mmProtFromMemoryFlags(accessFlags) | mmMaxProtFromMemoryFlags(accessFlags);
ptr[i] = mmap(nullptr, size, protection, MAP_SHARED, anonMem.fd(), 0);
if (ptr[i] == MAP_FAILED) {
@@ -651,7 +636,7 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t memoryFla
int e = errno;
if (i == 1)
munmap(ptr[0], size);
- return DebugUtils::errored(VirtMem_asmjitErrorFromErrno(e));
+ return DebugUtils::errored(asmjitErrorFromErrno(e));
}
}
@@ -660,7 +645,7 @@ Error VirtMem::allocDualMapping(DualMapping* dm, size_t size, uint32_t memoryFla
return kErrorOk;
}
-Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
+Error releaseDualMapping(DualMapping* dm, size_t size) noexcept {
Error err = release(dm->rx, size);
if (dm->rx != dm->rw)
err |= release(dm->rw, size);
@@ -674,13 +659,12 @@ Error VirtMem::releaseDualMapping(DualMapping* dm, size_t size) noexcept {
}
#endif
-// ============================================================================
-// [asmjit::VirtMem - Instruction Cache]
-// ============================================================================
+// Virtual Memory - Flush Instruction Cache
+// ========================================
-void VirtMem::flushInstructionCache(void* p, size_t size) noexcept {
+void flushInstructionCache(void* p, size_t size) noexcept {
#if ASMJIT_ARCH_X86
- // X86 architecture doesn't require to do anything to flush instruction cache.
+ // X86/X86_64 architecture doesn't require to do anything to flush instruction cache.
DebugUtils::unused(p, size);
#elif defined(__APPLE__)
sys_icache_invalidate(p, size);
@@ -697,17 +681,16 @@ void VirtMem::flushInstructionCache(void* p, size_t size) noexcept {
#endif
}
-// ============================================================================
-// [asmjit::VirtMem - Page Info]
-// ============================================================================
+// Virtual Memory - Memory Info
+// ============================
-VirtMem::Info VirtMem::info() noexcept {
+Info info() noexcept {
static std::atomic<uint32_t> vmInfoInitialized;
- static VirtMem::Info vmInfo;
+ static Info vmInfo;
if (!vmInfoInitialized.load()) {
- VirtMem::Info localMemInfo;
- VirtMem_getInfo(localMemInfo);
+ Info localMemInfo;
+ getVMInfo(localMemInfo);
vmInfo = localMemInfo;
vmInfoInitialized.store(1u);
@@ -716,19 +699,17 @@ VirtMem::Info VirtMem::info() noexcept {
return vmInfo;
}
-// ============================================================================
-// [asmjit::VirtMem - Hardened Runtime Info]
-// ============================================================================
+// Virtual Memory - Hardened Runtime Info
+// ======================================
-VirtMem::HardenedRuntimeInfo VirtMem::hardenedRuntimeInfo() noexcept {
- return VirtMem::HardenedRuntimeInfo { VirtMem_hardenedRuntimeFlags() };
+HardenedRuntimeInfo hardenedRuntimeInfo() noexcept {
+ return HardenedRuntimeInfo { getHardenedRuntimeFlags() };
}
-// ============================================================================
-// [asmjit::VirtMem - JIT Memory Protection]
-// ============================================================================
+// Virtual Memory - Project JIT Memory
+// ===================================
-void VirtMem::protectJitMemory(VirtMem::ProtectJitAccess access) noexcept {
+void protectJitMemory(ProtectJitAccess access) noexcept {
#if defined(ASMJIT_HAS_PTHREAD_JIT_WRITE_PROTECT_NP)
pthread_jit_write_protect_np(static_cast<uint32_t>(access));
#else
@@ -736,6 +717,6 @@ void VirtMem::protectJitMemory(VirtMem::ProtectJitAccess access) noexcept {
#endif
}
-ASMJIT_END_NAMESPACE
+ASMJIT_END_SUB_NAMESPACE
#endif