[llvm-commits] [llvm] r168114 - in /llvm/trunk: include/llvm/ExecutionEngine/RuntimeDyld.h lib/ExecutionEngine/JIT/JITMemoryManager.cpp lib/ExecutionEngine/MCJIT/MCJIT.cpp lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp tools/lli/RecordingMemoryManager.cpp tools/lli/RecordingMemoryManager.h tools/lli/lli.cpp tools/llvm-rtdyld/llvm-rtdyld.cpp unittests/ExecutionEngine/JIT/JITTest.cpp unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
Andrew Kaylor
andrew.kaylor at intel.com
Thu Nov 15 15:50:01 PST 2012
Author: akaylor
Date: Thu Nov 15 17:50:01 2012
New Revision: 168114
URL: http://llvm.org/viewvc/llvm-project?rev=168114&view=rev
Log:
Interface changes to allow RuntimeDyld memory managers to set memory permissions after an object has been loaded.
Modified:
llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
llvm/trunk/tools/lli/RecordingMemoryManager.cpp
llvm/trunk/tools/lli/RecordingMemoryManager.h
llvm/trunk/tools/lli/lli.cpp
llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
Modified: llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/RuntimeDyld.h Thu Nov 15 17:50:01 2012
@@ -48,7 +48,7 @@
/// assigned by the JIT engine, and optionally recorded by the memory manager
/// to access a loaded section.
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) = 0;
+ unsigned SectionID, bool IsReadOnly) = 0;
/// getPointerToNamedFunction - This method returns the address of the
/// specified function. As such it is only useful for resolving library
@@ -59,6 +59,15 @@
/// message to stderr and aborts.
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) = 0;
+
+ /// applyPermissions - This method is called when object loading is
+ /// complete and section page permissions can be applied. It is up to
+ /// the memory manager implementation to decide whether or not to act
+ /// on this method. The memory manager will typically allocate all
+ /// sections as read-write and then apply specific permissions when
+ /// this method is called. Returns true if an error occurred, false
+ /// otherwise.
+ virtual bool applyPermissions(std::string *ErrMsg = 0) = 0;
};
class RuntimeDyld {
Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITMemoryManager.cpp Thu Nov 15 17:50:01 2012
@@ -501,10 +501,14 @@
/// allocateDataSection - Allocate memory for a data section.
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) {
+ unsigned SectionID, bool IsReadOnly) {
return (uint8_t*)DataAllocator.Allocate(Size, Alignment);
}
+ bool applyPermissions(std::string *ErrMsg) {
+ return false;
+ }
+
/// startExceptionTable - Use startFunctionBody to allocate memory for the
/// function's exception table.
uint8_t* startExceptionTable(const Function* F, uintptr_t &ActualSize) {
Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Thu Nov 15 17:50:01 2012
@@ -118,17 +118,26 @@
// FIXME: Add a parameter to identify which object is being finalized when
// MCJIT supports multiple modules.
+// FIXME: Provide a way to separate code emission, relocations and page
+// protection in the interface.
void MCJIT::finalizeObject() {
// If the module hasn't been compiled, just do that.
if (!isCompiled) {
// If the call to Dyld.resolveRelocations() is removed from emitObject()
// we'll need to do that here.
emitObject(M);
+
+ // Set page permissions.
+ MemMgr->applyPermissions();
+
return;
}
// Resolve any relocations.
Dyld.resolveRelocations();
+
+ // Set page permissions.
+ MemMgr->applyPermissions();
}
void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) {
Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp Thu Nov 15 17:50:01 2012
@@ -182,7 +182,7 @@
// Allocate memory for the section
unsigned SectionID = Sections.size();
uint8_t *Addr = MemMgr->allocateDataSection(TotalSize, sizeof(void*),
- SectionID);
+ SectionID, false);
if (!Addr)
report_fatal_error("Unable to allocate memory for common symbols!");
uint64_t Offset = 0;
@@ -237,11 +237,13 @@
bool IsRequired;
bool IsVirtual;
bool IsZeroInit;
+ bool IsReadOnly;
uint64_t DataSize;
StringRef Name;
Check(Section.isRequiredForExecution(IsRequired));
Check(Section.isVirtual(IsVirtual));
Check(Section.isZeroInit(IsZeroInit));
+ Check(Section.isReadOnlyData(IsReadOnly));
Check(Section.getSize(DataSize));
Check(Section.getName(Name));
@@ -256,7 +258,7 @@
Allocate = DataSize + StubBufSize;
Addr = IsCode
? MemMgr->allocateCodeSection(Allocate, Alignment, SectionID)
- : MemMgr->allocateDataSection(Allocate, Alignment, SectionID);
+ : MemMgr->allocateDataSection(Allocate, Alignment, SectionID, IsReadOnly);
if (!Addr)
report_fatal_error("Unable to allocate section memory!");
@@ -451,6 +453,12 @@
//===----------------------------------------------------------------------===//
// RuntimeDyld class implementation
RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) {
+ // FIXME: There's a potential issue lurking here if a single instance of
+ // RuntimeDyld is used to load multiple objects. The current implementation
+ // associates a single memory manager with a RuntimeDyld instance. Even
+ // though the public class spawns a new 'impl' instance for each load,
+ // they share a single memory manager. This can become a problem when page
+ // permissions are applied.
Dyld = 0;
MM = mm;
}
Modified: llvm/trunk/tools/lli/RecordingMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/tools/lli/RecordingMemoryManager.cpp (original)
+++ llvm/trunk/tools/lli/RecordingMemoryManager.cpp Thu Nov 15 17:50:01 2012
@@ -28,7 +28,8 @@
}
uint8_t *RecordingMemoryManager::
-allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
+allocateDataSection(uintptr_t Size, unsigned Alignment,
+ unsigned SectionID, bool IsReadOnly) {
// The recording memory manager is just a local copy of the remote target.
// The alignment requirement is just stored here for later use. Regular
// heap storage is sufficient here.
Modified: llvm/trunk/tools/lli/RecordingMemoryManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.h?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/tools/lli/RecordingMemoryManager.h (original)
+++ llvm/trunk/tools/lli/RecordingMemoryManager.h Thu Nov 15 17:50:01 2012
@@ -47,10 +47,13 @@
unsigned SectionID);
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
+
+ bool applyPermissions(std::string *ErrMsg) { return false; }
+
// The following obsolete JITMemoryManager calls are stubbed out for
// this model.
void setMemoryWritable();
Modified: llvm/trunk/tools/lli/lli.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/tools/lli/lli.cpp (original)
+++ llvm/trunk/tools/lli/lli.cpp Thu Nov 15 17:50:01 2012
@@ -231,11 +231,13 @@
unsigned SectionID);
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
+ virtual bool applyPermissions(std::string *ErrMsg) { return false; }
+
// Invalidate instruction cache for code sections. Some platforms with
// separate data cache and instruction cache require explicit cache flush,
// otherwise JIT code manipulations (like resolved relocations) will get to
@@ -301,7 +303,8 @@
uint8_t *LLIMCJITMemoryManager::allocateDataSection(uintptr_t Size,
unsigned Alignment,
- unsigned SectionID) {
+ unsigned SectionID,
+ bool IsReadOnly) {
if (!Alignment)
Alignment = 16;
// Ensure that enough memory is requested to allow aligning.
Modified: llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp (original)
+++ llvm/trunk/tools/llvm-rtdyld/llvm-rtdyld.cpp Thu Nov 15 17:50:01 2012
@@ -58,13 +58,15 @@
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID);
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) {
return 0;
}
+ bool applyPermissions(std::string *ErrMsg) { return false; }
+
// Invalidate instruction cache for sections with execute permissions.
// Some platforms with separate data cache and instruction cache require
// explicit cache flush, otherwise JIT code manipulations (like resolved
@@ -82,7 +84,8 @@
uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
unsigned Alignment,
- unsigned SectionID) {
+ unsigned SectionID,
+ bool IsReadOnly) {
sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
DataMemory.push_back(MB);
return (uint8_t*)MB.base();
Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Thu Nov 15 17:50:01 2012
@@ -118,13 +118,14 @@
Base->endFunctionBody(F, FunctionStart, FunctionEnd);
}
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID) {
- return Base->allocateDataSection(Size, Alignment, SectionID);
+ unsigned SectionID, bool IsReadOnly) {
+ return Base->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
}
virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID) {
return Base->allocateCodeSection(Size, Alignment, SectionID);
}
+ virtual bool applyPermissions(std::string *ErrMsg) { return false; }
virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
return Base->allocateSpace(Size, Alignment);
}
Modified: llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.cpp Thu Nov 15 17:50:01 2012
@@ -32,7 +32,8 @@
uint8_t *SectionMemoryManager::allocateDataSection(uintptr_t Size,
unsigned Alignment,
- unsigned SectionID) {
+ unsigned SectionID,
+ bool IsReadOnly) {
if (!Alignment)
Alignment = 16;
// Ensure that enough memory is requested to allow aligning.
Modified: llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h?rev=168114&r1=168113&r2=168114&view=diff
==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h (original)
+++ llvm/trunk/unittests/ExecutionEngine/MCJIT/SectionMemoryManager.h Thu Nov 15 17:50:01 2012
@@ -34,7 +34,9 @@
unsigned SectionID);
virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
+
+ virtual bool applyPermissions(std::string *ErrMsg) { return false; }
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
More information about the llvm-commits
mailing list