aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2008-10-03 16:17:20 +0000
committerJim Grosbach <grosbach@apple.com>2008-10-03 16:17:20 +0000
commitcce6c297c54b4c9c8615c77e97cd64e70812ea60 (patch)
tree2a65c3ce20bd2065ace4af4a03507d11dcbc03a0 /lib
parent48b828fdb467655fa630fed41e49e2a481fb6dab (diff)
downloadexternal_llvm-cce6c297c54b4c9c8615c77e97cd64e70812ea60.zip
external_llvm-cce6c297c54b4c9c8615c77e97cd64e70812ea60.tar.gz
external_llvm-cce6c297c54b4c9c8615c77e97cd64e70812ea60.tar.bz2
On Darwin ARM, memory needs special handling to do JIT. This patch expands
this handling to work properly for modifying stub functions, relocations back to entry points after JIT compilation, etc.. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@57013 91177308-0d34-0410-b5e6-96231b3b80d8
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 ffaeb1c..a90a6a5 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 804e88d..0ffc779 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 2fc6a23..3660bcb 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 cf0157d..646311d 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
+}
+