diff options
Diffstat (limited to 'llvm/lib/Support')
-rw-r--r-- | llvm/lib/Support/Unix/Memory.inc | 127 | ||||
-rw-r--r-- | llvm/lib/Support/Windows/Memory.inc | 80 |
2 files changed, 4 insertions, 203 deletions
diff --git a/llvm/lib/Support/Unix/Memory.inc b/llvm/lib/Support/Unix/Memory.inc index cf812d008d3..31480162c87 100644 --- a/llvm/lib/Support/Unix/Memory.inc +++ b/llvm/lib/Support/Unix/Memory.inc @@ -102,6 +102,10 @@ Memory::allocateMappedMemory(size_t NumBytes, int Protect = getPosixProtectionFlags(PFlags); +#if defined(__NetBSD__) && defined(PROT_MPROTECT) + Protect |= PROT_MPROTECT(PROT_READ | PROT_WRITE | PROT_EXEC); +#endif + // Use any near hint and the page size to set a page-aligned starting address uintptr_t Start = NearBlock ? reinterpret_cast<uintptr_t>(NearBlock->base()) + NearBlock->size() : 0; @@ -166,129 +170,6 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { return std::error_code(); } -/// AllocateRWX - Allocate a slab of memory with read/write/execute -/// permissions. This is typically used for JIT applications where we want -/// to emit code to the memory then jump to it. Getting this type of memory -/// is very OS specific. -/// -MemoryBlock -Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock, - std::string *ErrMsg) { - if (NumBytes == 0) return MemoryBlock(); - - static const size_t PageSize = Process::getPageSize(); - size_t NumPages = (NumBytes+PageSize-1)/PageSize; - - int fd = -1; - - int flags = MAP_PRIVATE | -#ifdef MAP_ANONYMOUS - MAP_ANONYMOUS -#else - MAP_ANON -#endif - ; - - void* start = NearBlock ? (unsigned char*)NearBlock->base() + - NearBlock->size() : nullptr; - -#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); -#endif - if (pa == MAP_FAILED) { - if (NearBlock) //Try again without a near hint - return AllocateRWX(NumBytes, nullptr); - - MakeErrMsg(ErrMsg, "Can't allocate RWX Memory"); - return MemoryBlock(); - } - -#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)pa, - (vm_size_t)(PageSize*NumPages), 0, - VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); - if (KERN_SUCCESS != kr) { - MakeErrMsg(ErrMsg, "vm_protect max RX failed"); - return MemoryBlock(); - } - - kr = vm_protect(mach_task_self(), (vm_address_t)pa, - (vm_size_t)(PageSize*NumPages), 0, - VM_PROT_READ | VM_PROT_WRITE); - if (KERN_SUCCESS != kr) { - MakeErrMsg(ErrMsg, "vm_protect RW failed"); - return MemoryBlock(); - } -#endif - - MemoryBlock result; - result.Address = pa; - result.Size = NumPages*PageSize; - - return result; -} - -bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { - if (M.Address == nullptr || M.Size == 0) return false; - if (0 != ::munmap(M.Address, M.Size)) - return MakeErrMsg(ErrMsg, "Can't release RWX Memory"); - return false; -} - -bool Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) { -#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) - if (M.Address == 0 || M.Size == 0) return false; - Memory::InvalidateInstructionCache(M.Address, M.Size); - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, - (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_WRITE); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} - -bool Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) { - if (M.Address == nullptr || M.Size == 0) return false; - Memory::InvalidateInstructionCache(M.Address, M.Size); -#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)M.Address, - (vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} - -bool Memory::setRangeWritable(const void *Addr, size_t Size) { -#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr, - (vm_size_t)Size, 0, - VM_PROT_READ | VM_PROT_WRITE); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} - -bool Memory::setRangeExecutable(const void *Addr, size_t Size) { -#if defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) - kern_return_t kr = vm_protect(mach_task_self(), (vm_address_t)Addr, - (vm_size_t)Size, 0, - VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); - return KERN_SUCCESS == kr; -#else - return true; -#endif -} - /// InvalidateInstructionCache - Before the JIT can run a block of code /// that has been emitted it must invalidate the instruction cache on some /// platforms. diff --git a/llvm/lib/Support/Windows/Memory.inc b/llvm/lib/Support/Windows/Memory.inc index 7eab9ff3afd..318e65aaa9e 100644 --- a/llvm/lib/Support/Windows/Memory.inc +++ b/llvm/lib/Support/Windows/Memory.inc @@ -160,85 +160,5 @@ void Memory::InvalidateInstructionCache( FlushInstructionCache(GetCurrentProcess(), Addr, Len); } - -MemoryBlock Memory::AllocateRWX(size_t NumBytes, - const MemoryBlock *NearBlock, - std::string *ErrMsg) { - MemoryBlock MB; - std::error_code EC; - MB = allocateMappedMemory(NumBytes, NearBlock, - MF_READ|MF_WRITE|MF_EXEC, EC); - if (EC != std::error_code() && ErrMsg) { - MakeErrMsg(ErrMsg, EC.message()); - } - return MB; -} - -bool Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { - std::error_code EC = releaseMappedMemory(M); - if (EC == std::error_code()) - return false; - MakeErrMsg(ErrMsg, EC.message()); - return true; -} - -static DWORD getProtection(const void *addr) { - MEMORY_BASIC_INFORMATION info; - if (sizeof(info) == ::VirtualQuery(addr, &info, sizeof(info))) { - return info.Protect; - } - return 0; -} - -bool Memory::setWritable(MemoryBlock &M, std::string *ErrMsg) { - if (!setRangeWritable(M.Address, M.Size)) { - return MakeErrMsg(ErrMsg, "Cannot set memory to writeable"); - } - return true; -} - -bool Memory::setExecutable(MemoryBlock &M, std::string *ErrMsg) { - if (!setRangeExecutable(M.Address, M.Size)) { - return MakeErrMsg(ErrMsg, "Cannot set memory to executable"); - } - return true; -} - -bool Memory::setRangeWritable(const void *Addr, size_t Size) { - DWORD prot = getProtection(Addr); - if (!prot) - return false; - - if (prot == PAGE_EXECUTE || prot == PAGE_EXECUTE_READ) { - prot = PAGE_EXECUTE_READWRITE; - } else if (prot == PAGE_NOACCESS || prot == PAGE_READONLY) { - prot = PAGE_READWRITE; - } - - DWORD oldProt; - Memory::InvalidateInstructionCache(Addr, Size); - return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt) - == TRUE; -} - -bool Memory::setRangeExecutable(const void *Addr, size_t Size) { - DWORD prot = getProtection(Addr); - if (!prot) - return false; - - if (prot == PAGE_NOACCESS) { - prot = PAGE_EXECUTE; - } else if (prot == PAGE_READONLY) { - prot = PAGE_EXECUTE_READ; - } else if (prot == PAGE_READWRITE) { - prot = PAGE_EXECUTE_READWRITE; - } - - DWORD oldProt; - Memory::InvalidateInstructionCache(Addr, Size); - return ::VirtualProtect(const_cast<LPVOID>(Addr), Size, prot, &oldProt) - == TRUE; -} - } // namespace sys } // namespace llvm |