aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/ExecutionEngine/JIT/JITEmitter.cpp12
-rw-r--r--lib/ExecutionEngine/JIT/JITMemoryManager.cpp15
-rw-r--r--lib/System/Memory.cpp11
-rw-r--r--lib/System/Unix/Memory.inc26
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
+}
+