Index: include/llvm/Support/Memory.h =================================================================== --- include/llvm/Support/Memory.h +++ include/llvm/Support/Memory.h @@ -28,14 +28,16 @@ /// @brief Memory block abstraction. class MemoryBlock { public: - MemoryBlock() : Address(nullptr), Size(0) { } - MemoryBlock(void *addr, size_t size) : Address(addr), Size(size) { } + MemoryBlock() : Address(nullptr), SecondaryAddress(nullptr), Size(0) { } + MemoryBlock(void *addr, size_t size) + : Address(addr), SecondaryAddress(nullptr), Size(size) {} void *base() const { return Address; } size_t size() const { return Size; } private: - void *Address; ///< Address of first byte of memory area - size_t Size; ///< Size, in bytes of the memory area + void *Address; ///< Address of first byte of memory area + void *SecondaryAddress; ///< Secondary address of first byte of memory area + size_t Size; ///< Size, in bytes of the memory area friend class Memory; }; Index: lib/Support/Unix/Memory.inc =================================================================== --- lib/Support/Unix/Memory.inc +++ lib/Support/Unix/Memory.inc @@ -195,6 +195,10 @@ #if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_EXEC, flags, fd, 0); +#elif defined(__NetBSD__) && defined(PROT_MPROTECT) + void *pa = + ::mmap(start, PageSize * NumPages, + PROT_READ | PROT_WRITE | PROT_MPROTECT(PROT_EXEC), flags, fd, 0); #else void *pa = ::mmap(start, PageSize*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC, flags, fd, 0); @@ -223,10 +227,35 @@ MakeErrMsg(ErrMsg, "vm_protect RW failed"); return MemoryBlock(); } +#elif defined(__NetBSD__) && defined(PROT_MPROTECT) + void *codeseg = + ::mremap(pa, PageSize * NumPages, NULL, PageSize * NumPages, + MAP_REMAPDUP); + if (codeseg == MAP_FAILED) { + ::munmap(pa, PageSize * NumPages); + + if (NearBlock) // Try again without a near hint + return AllocateRWX(NumBytes, nullptr); + + MakeErrMsg(ErrMsg, "Can't allocate RWX Memory"); + return MemoryBlock(); + } + if (::mprotect(codeseg, PageSize * NumPages, PROT_READ | PROT_EXEC) == -1) { + ::munmap(pa, PageSize * NumPages); + ::munmap(codeseg, PageSize * NumPages); + if (NearBlock) // Try again without a near hint + return AllocateRWX(NumBytes, nullptr); + + MakeErrMsg(ErrMsg, "Can't allocate RWX Memory"); + return MemoryBlock(); + } #endif MemoryBlock result; result.Address = pa; +#if defined(__NetBSD__) && defined(PROT_MPROTECT) + result.SecondaryAddress = codeseg; +#endif result.Size = NumPages*PageSize; return result; @@ -236,6 +265,9 @@ if (M.Address == nullptr || M.Size == 0) return false; if (0 != ::munmap(M.Address, M.Size)) return MakeErrMsg(ErrMsg, "Can't release RWX Memory"); + if (M.SecondaryAddress) + if (0 != ::munmap(M.SecondaryAddress, M.Size)) + return MakeErrMsg(ErrMsg, "Can't release RWX Memory"); return false; }