diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ExecutionEngine/JIT/JITEmitter.cpp | 12 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JITMemoryManager.cpp | 15 | ||||
-rw-r--r-- | lib/System/Memory.cpp | 11 | ||||
-rw-r--r-- | lib/System/Unix/Memory.inc | 26 |
4 files changed, 51 insertions, 13 deletions
diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index ffaeb1c4ea..a90a6a52fa 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -560,6 +560,10 @@ namespace { if (ExceptionHandling) DE->setModuleInfo(Info); } + void setMemoryExecutable(void) { + MemMgr->setMemoryExecutable(); + } + private: void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference, @@ -791,6 +795,8 @@ unsigned JITEmitter::GetSizeOfGlobalsInBytes(MachineFunction &MF) { void JITEmitter::startFunction(MachineFunction &F) { uintptr_t ActualSize = 0; + // Set the memory writable, if it's not already + MemMgr->setMemoryWritable(); if (MemMgr->NeedsExactSize()) { DOUT << "ExactSize\n"; const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); @@ -938,7 +944,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) { Relocations.clear(); // Mark code region readable and executable if it's not so already. - sys::Memory::SetRXPrivilege(FnStart, FnEnd-FnStart); + MemMgr->setMemoryExecutable(); #ifndef NDEBUG { @@ -1086,6 +1092,10 @@ void JITEmitter::startFunctionStub(const GlobalValue* F, unsigned StubSize, void *JITEmitter::finishFunctionStub(const GlobalValue* F) { NumBytes += getCurrentPCOffset(); + + // Invalidate the icache if necessary. + sys::Memory::InvalidateInstructionCache(BufferBegin, NumBytes); + std::swap(SavedBufferBegin, BufferBegin); BufferEnd = SavedBufferEnd; CurBufferPtr = SavedCurBufferPtr; diff --git a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp index 804e88df4c..0ffc779901 100644 --- a/lib/ExecutionEngine/JIT/JITMemoryManager.cpp +++ b/lib/ExecutionEngine/JIT/JITMemoryManager.cpp @@ -365,6 +365,21 @@ namespace { // Finally, remove this entry from TableBlocks. TableBlocks.erase(I); } + + /// setMemoryWritable - When code generation is in progress, + /// the code pages may need permissions changed. + void setMemoryWritable(void) + { + for (unsigned i = 0, e = Blocks.size(); i != e; ++i) + sys::Memory::setWritable(Blocks[i]); + } + /// setMemoryExecutable - When code generation is done and we're ready to + /// start execution, the code pages may need permissions changed. + void setMemoryExecutable(void) + { + for (unsigned i = 0, e = Blocks.size(); i != e; ++i) + sys::Memory::setExecutable(Blocks[i]); + } }; } diff --git a/lib/System/Memory.cpp b/lib/System/Memory.cpp index 2fc6a23a3a..3660bcb1a4 100644 --- a/lib/System/Memory.cpp +++ b/lib/System/Memory.cpp @@ -58,14 +58,3 @@ void llvm::sys::Memory::InvalidateInstructionCache(const void *Addr, #endif // end PPC } - -bool llvm::sys::Memory::SetRXPrivilege(const void *Addr, size_t Size) { -#if defined(__APPLE__) && defined(__arm__) - 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 -} diff --git a/lib/System/Unix/Memory.inc b/lib/System/Unix/Memory.inc index cf0157d577..646311d8cd 100644 --- a/lib/System/Unix/Memory.inc +++ b/lib/System/Unix/Memory.inc @@ -76,7 +76,7 @@ llvm::sys::Memory::AllocateRWX(unsigned NumBytes, const MemoryBlock* NearBlock, (vm_size_t)(pageSize*NumPages), 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY); if (KERN_SUCCESS != kr) { - MakeErrMsg(ErrMsg, "vm_protect max RWX failed\n"); + MakeErrMsg(ErrMsg, "vm_protect max RX failed\n"); return sys::MemoryBlock(); } @@ -103,3 +103,27 @@ bool llvm::sys::Memory::ReleaseRWX(MemoryBlock &M, std::string *ErrMsg) { return false; } +bool llvm::sys::Memory::setWritable (MemoryBlock &M, std::string *ErrMsg) { +#if defined(__APPLE__) && defined(__arm__) + if (M.Address == 0 || M.Size == 0) return false; + sys::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 llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) { +#if defined(__APPLE__) && defined(__arm__) + if (M.Address == 0 || M.Size == 0) return false; + sys::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_EXECUTE | VM_PROT_COPY); + return KERN_SUCCESS == kr; +#else + return false; +#endif +} + |