<div dir="ltr">On Thu, Oct 3, 2013 at 5:49 PM, Andrew Kaylor <span dir="ltr"><<a href="mailto:andrew.kaylor@intel.com" target="_blank">andrew.kaylor@intel.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: akaylor<br>
Date: Thu Oct 3 19:49:38 2013<br>
New Revision: 191938<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=191938&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=191938&view=rev</a><br>
Log:<br>
Adding support and tests for multiple module handling in lli<br>
<br>
Added:<br>
llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll<br>
llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a><br>
llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll<br></blockquote><div><br></div><div>This test fails under ASan:</div><div><br></div><div><div>==10866==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c00000a5b4 at pc 0x480401 bp 0x7fff14df7a90 sp 0x7fff14df7a88</div>
<div>READ of size 1 at 0x60c00000a5b4 thread T0</div><div> #0 0x480400 in llvm::RemoteMemoryManager::notifyObjectLoaded(llvm::ExecutionEngine*, llvm::ObjectImage const*) llvm/tools/lli/RemoteMemoryManager.cpp:96</div><div>
#1 0x59a4de in llvm::MCJIT::NotifyObjectEmitted(llvm::ObjectImage const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:516</div><div> #2 0x59a267 in llvm::MCJIT::generateCodeForModule(llvm::Module*) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:163</div>
<div> #3 0x59bb14 in llvm::MCJIT::getSymbolAddress(std::string const&, bool) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:316</div><div> #4 0x59d2ad in llvm::LinkingMemoryManager::getSymbolAddress(std::string const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:529</div>
<div> #5 0x5dfa3d in llvm::RuntimeDyldImpl::resolveExternalSymbols() llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:484</div><div> #6 0x5df348 in llvm::RuntimeDyldImpl::resolveRelocations() llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:39</div>
<div> #7 0x59a6a9 in llvm::MCJIT::finalizeLoadedModules() llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:170</div><div> #8 0x59bc53 in llvm::MCJIT::getFunctionAddress(std::string const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:332</div>
<div> #9 0x487d59 in main llvm/tools/lli/lli.cpp:511</div><div> #10 0x7f4a386f011c in __libc_start_main</div><div> #11 0x47ed99 in _start</div><div>0x60c00000a5b4 is located 116 bytes inside of 120-byte region [0x60c00000a540,0x60c00000a5b8)</div>
<div>freed by thread T0 here:</div><div> #0 0x4757a4 in __interceptor_realloc</div><div> #1 0x177cee9 in llvm::SmallVectorBase::grow_pod(void*, unsigned long, unsigned long) llvm/lib/Support/SmallVector.cpp:34</div>
<div> #2 0x4810ef in llvm::SmallVectorTemplateBase<llvm::RemoteMemoryManager::Allocation, true>::push_back(llvm::RemoteMemoryManager::Allocation const&) llvm/include/llvm/ADT/SmallVector.h:357</div><div> #3 0x47f369 in llvm::RemoteMemoryManager::allocateCodeSection(unsigned long, unsigned int, unsigned int, llvm::StringRef) llvm/tools/lli/RemoteMemoryManager.cpp:39</div>
<div> #4 0x5e34bb in llvm::RuntimeDyldImpl::emitSection(llvm::ObjectImage&, llvm::object::SectionRef const&, bool) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:281</div><div> #5 0x5e1fa0 in llvm::RuntimeDyldImpl::findOrEmitSection(llvm::ObjectImage&, llvm::object::SectionRef const&, bool, std::map<llvm::object::SectionRef, unsigned int, std::less<llvm::object::SectionRef>, std::allocator<std::pair<llvm::object::SectionRef const, unsigned int> > >&) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:337</div>
<div> #6 0x5e152c in llvm::RuntimeDyldImpl::loadObject(llvm::ObjectBuffer*) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:163</div><div> #7 0x5e49c1 in llvm::RuntimeDyld::loadObject(llvm::ObjectBuffer*) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:562</div>
<div> #8 0x59a1ee in llvm::MCJIT::generateCodeForModule(llvm::Module*) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:155</div><div> #9 0x59bb14 in llvm::MCJIT::getSymbolAddress(std::string const&, bool) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:316</div>
<div> #10 0x59d2ad in llvm::LinkingMemoryManager::getSymbolAddress(std::string const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:529</div><div> #11 0x5dfa3d in llvm::RuntimeDyldImpl::resolveExternalSymbols() llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:484</div>
<div> #12 0x5df348 in llvm::RuntimeDyldImpl::resolveRelocations() llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:39</div><div> #13 0x59a6a9 in llvm::MCJIT::finalizeLoadedModules() llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:170</div>
<div> #14 0x59bc53 in llvm::MCJIT::getFunctionAddress(std::string const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:332</div><div> #15 0x487d59 in main llvm/tools/lli/lli.cpp:511</div><div> #16 0x7f4a386f011c in __libc_start_main</div>
<div>previously allocated by thread T0 here:</div><div> #0 0x475575 in __interceptor_malloc</div><div> #1 0x177cef9 in llvm::SmallVectorBase::grow_pod(void*, unsigned long, unsigned long) llvm/lib/Support/SmallVector.cpp:28</div>
<div> #2 0x4810ef in llvm::SmallVectorTemplateBase<llvm::RemoteMemoryManager::Allocation, true>::push_back(llvm::RemoteMemoryManager::Allocation const&) llvm/include/llvm/ADT/SmallVector.h:357</div><div> #3 0x47f369 in llvm::RemoteMemoryManager::allocateCodeSection(unsigned long, unsigned int, unsigned int, llvm::StringRef) llvm/tools/lli/RemoteMemoryManager.cpp:39</div>
<div> #4 0x5e34bb in llvm::RuntimeDyldImpl::emitSection(llvm::ObjectImage&, llvm::object::SectionRef const&, bool) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:281</div><div> #5 0x5e1fa0 in llvm::RuntimeDyldImpl::findOrEmitSection(llvm::ObjectImage&, llvm::object::SectionRef const&, bool, std::map<llvm::object::SectionRef, unsigned int, std::less<llvm::object::SectionRef>, std::allocator<std::pair<llvm::object::SectionRef const, unsigned int> > >&) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:337</div>
<div> #6 0x5e0b04 in llvm::RuntimeDyldImpl::loadObject(llvm::ObjectBuffer*) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:130</div><div> #7 0x5e49c1 in llvm::RuntimeDyld::loadObject(llvm::ObjectBuffer*) llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:562</div>
<div> #8 0x59a1ee in llvm::MCJIT::generateCodeForModule(llvm::Module*) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:155</div><div> #9 0x59bb14 in llvm::MCJIT::getSymbolAddress(std::string const&, bool) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:316</div>
<div> #10 0x59d2ad in llvm::LinkingMemoryManager::getSymbolAddress(std::string const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:529</div><div> #11 0x5dfa3d in llvm::RuntimeDyldImpl::resolveExternalSymbols() llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:484</div>
<div> #12 0x5df348 in llvm::RuntimeDyldImpl::resolveRelocations() llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:39</div><div> #13 0x59a6a9 in llvm::MCJIT::finalizeLoadedModules() llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:170</div>
<div> #14 0x59bc53 in llvm::MCJIT::getFunctionAddress(std::string const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:332</div><div> #15 0x487d59 in main llvm/tools/lli/lli.cpp:511</div><div> #16 0x7f4a386f011c in __libc_start_main</div>
<div>SUMMARY: AddressSanitizer: heap-use-after-free llvm/tools/lli/RemoteMemoryManager.cpp:96 llvm::RemoteMemoryManager::notifyObjectLoaded(llvm::ExecutionEngine*, llvm::ObjectImage const*)</div><div>Shadow bytes around the buggy address:</div>
<div> 0x0c187fff9460: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd</div><div> 0x0c187fff9470: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</div><div> 0x0c187fff9480: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa</div>
<div> 0x0c187fff9490: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa</div><div> 0x0c187fff94a0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</div><div>=>0x0c187fff94b0: fd fd fd fd fd fd[fd]fa fa fa fa fa fa fa fa fa</div>
<div> 0x0c187fff94c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd</div><div> 0x0c187fff94d0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</div><div> 0x0c187fff94e0: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa</div>
<div> 0x0c187fff94f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd</div><div> 0x0c187fff9500: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd</div><div>Shadow byte legend (one shadow byte represents 8 application bytes):</div>
<div> Addressable: 00</div><div> Partially addressable: 01 02 03 04 05 06 07 </div><div> Heap left redzone: fa</div><div> Heap right redzone: fb</div><div> Freed heap region: fd</div><div> Stack left redzone: f1</div>
<div> Stack mid redzone: f2</div><div> Stack right redzone: f3</div><div> Stack partial redzone: f4</div><div> Stack after return: f5</div><div> Stack use after scope: f8</div><div> Global redzone: f9</div>
<div> Global init order: f6</div><div> Poisoned by user: f7</div><div> ASan internal: fe</div><div>==10866==ABORTING</div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a><br>
llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a><br>
llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll<br>
llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a><br>
llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll<br>
llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a><br>
llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a><br>
llvm/trunk/tools/lli/RemoteMemoryManager.cpp<br>
- copied, changed from r191860, llvm/trunk/tools/lli/RecordingMemoryManager.cpp<br>
llvm/trunk/tools/lli/RemoteMemoryManager.h<br>
- copied, changed from r191860, llvm/trunk/tools/lli/RecordingMemoryManager.h<br>
Removed:<br>
llvm/trunk/tools/lli/RecordingMemoryManager.cpp<br>
llvm/trunk/tools/lli/RecordingMemoryManager.h<br>
Modified:<br>
llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h<br>
llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp<br>
llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h<br>
llvm/trunk/tools/lli/CMakeLists.txt<br>
llvm/trunk/tools/lli/lli.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=191938&r1=191937&r2=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=191938&r1=191937&r2=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Thu Oct 3 19:49:38 2013<br>
@@ -21,6 +21,9 @@<br>
<br>
namespace llvm {<br>
<br>
+class ExecutionEngine;<br>
+class ObjectImage;<br>
+<br>
// RuntimeDyld clients often want to handle the memory management of<br>
// what gets placed where. For JIT clients, this is the subset of<br>
// JITMemoryManager required for dynamic loading of binaries.<br>
@@ -41,7 +44,7 @@ public:<br>
virtual uint8_t *allocateCodeSection(<br>
uintptr_t Size, unsigned Alignment, unsigned SectionID,<br>
StringRef SectionName) = 0;<br>
-<br>
+<br>
/// Allocate a memory block of (at least) the given size suitable for data.<br>
/// The SectionID is a unique identifier assigned by the JIT engine, and<br>
/// optionally recorded by the memory manager to access a loaded section.<br>
@@ -63,11 +66,24 @@ public:<br>
/// found, this function returns a null pointer. Otherwise, it prints a<br>
/// message to stderr and aborts.<br>
///<br>
- /// This function is deprecated for memory managers used to be used with<br>
+ /// This function is deprecated for memory managers to be used with<br>
/// MCJIT or RuntimeDyld. Use getSymbolAddress instead.<br>
virtual void *getPointerToNamedFunction(const std::string &Name,<br>
bool AbortOnFailure = true);<br>
<br>
+ /// This method is called after an object has been loaded into memory but<br>
+ /// before relocations are applied to the loaded sections. The object load<br>
+ /// may have been initiated by MCJIT to resolve an external symbol for another<br>
+ /// object that is being finalized. In that case, the object about which<br>
+ /// the memory manager is being notified will be finalized immediately after<br>
+ /// the memory manager returns from this call.<br>
+ ///<br>
+ /// Memory managers which are preparing code for execution in an external<br>
+ /// address space can use this call to remap the section addresses for the<br>
+ /// newly loaded object.<br>
+ virtual void notifyObjectLoaded(ExecutionEngine *EE,<br>
+ const ObjectImage *) {}<br>
+<br>
/// This method is called when object loading is complete and section page<br>
/// permissions can be applied. It is up to the memory manager implementation<br>
/// to decide whether or not to act on this method. The memory manager will<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=191938&r1=191937&r2=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=191938&r1=191937&r2=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Thu Oct 3 19:49:38 2013<br>
@@ -513,6 +513,7 @@ void MCJIT::UnregisterJITEventListener(J<br>
}<br>
void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {<br>
MutexGuard locked(lock);<br>
+ MemMgr.notifyObjectLoaded(this, &Obj);<br>
for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {<br>
EventListeners[I]->NotifyObjectEmitted(Obj);<br>
}<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=191938&r1=191937&r2=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=191938&r1=191937&r2=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Thu Oct 3 19:49:38 2013<br>
@@ -46,6 +46,11 @@ public:<br>
SectionID, SectionName, IsReadOnly);<br>
}<br>
<br>
+ virtual void notifyObjectLoaded(ExecutionEngine *EE,<br>
+ const ObjectImage *Obj) {<br>
+ ClientMM->notifyObjectLoaded(EE, Obj);<br>
+ }<br>
+<br>
virtual void registerEHFrames(StringRef SectionData) {<br>
ClientMM->registerEHFrames(SectionData);<br>
}<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,13 @@<br>
+; RUN: %lli_mcjit -extra-modules=%p/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a> %s > /dev/null<br>
+<br>
+declare i32 @FB()<br>
+<br>
+define i32 @FA() {<br>
+ ret i32 0<br>
+}<br>
+<br>
+define i32 @main() {<br>
+ %r = call i32 @FB( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a> (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a> Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,7 @@<br>
+declare i32 @FA()<br>
+<br>
+define i32 @FB() {<br>
+ %r = call i32 @FA( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,9 @@<br>
+; RUN: %lli_mcjit -extra-modules=%p/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a>,%p/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a> %s > /dev/null<br>
+<br>
+declare i32 @FB()<br>
+<br>
+define i32 @main() {<br>
+ %r = call i32 @FB( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a> (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a> Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,7 @@<br>
+declare i32 @FC()<br>
+<br>
+define i32 @FB() {<br>
+ %r = call i32 @FC( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a> (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a> Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,4 @@<br>
+define i32 @FC() {<br>
+ ret i32 0<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,13 @@<br>
+; RUN: %lli_mcjit -extra-modules=%p/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a> -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null<br>
+<br>
+declare i32 @FB()<br>
+<br>
+define i32 @FA() {<br>
+ ret i32 0<br>
+}<br>
+<br>
+define i32 @main() {<br>
+ %r = call i32 @FB( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a> (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://cross-module-b.ir" target="_blank">cross-module-b.ir</a> Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,7 @@<br>
+declare i32 @FA()<br>
+<br>
+define i32 @FB() {<br>
+ %r = call i32 @FA( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,9 @@<br>
+; RUN: %lli_mcjit -extra-modules=%p/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a>,%p/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a> -disable-lazy-compilation=true -remote-mcjit -mcjit-remote-process=lli-child-target %s > /dev/null<br>
+<br>
+declare i32 @FB()<br>
+<br>
+define i32 @main() {<br>
+ %r = call i32 @FB( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a> (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-b.ir" target="_blank">multi-module-b.ir</a> Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,7 @@<br>
+declare i32 @FC()<br>
+<br>
+define i32 @FB() {<br>
+ %r = call i32 @FC( ) ; <i32> [#uses=1]<br>
+ ret i32 %r<br>
+}<br>
+<br>
<br>
Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a><br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir?rev=191938&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir?rev=191938&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a> (added)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/<a href="http://multi-module-c.ir" target="_blank">multi-module-c.ir</a> Thu Oct 3 19:49:38 2013<br>
@@ -0,0 +1,4 @@<br>
+define i32 @FC() {<br>
+ ret i32 0<br>
+}<br>
+<br>
<br>
Modified: llvm/trunk/tools/lli/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/CMakeLists.txt?rev=191938&r1=191937&r2=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/CMakeLists.txt?rev=191938&r1=191937&r2=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/CMakeLists.txt (original)<br>
+++ llvm/trunk/tools/lli/CMakeLists.txt Thu Oct 3 19:49:38 2013<br>
@@ -21,7 +21,7 @@ endif( LLVM_USE_INTEL_JITEVENTS )<br>
<br>
add_llvm_tool(lli<br>
lli.cpp<br>
- RecordingMemoryManager.cpp<br>
+ RemoteMemoryManager.cpp<br>
RemoteTarget.cpp<br>
RemoteTargetExternal.cpp<br>
)<br>
<br>
Removed: llvm/trunk/tools/lli/RecordingMemoryManager.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.cpp?rev=191937&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.cpp?rev=191937&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RecordingMemoryManager.cpp (original)<br>
+++ llvm/trunk/tools/lli/RecordingMemoryManager.cpp (removed)<br>
@@ -1,126 +0,0 @@<br>
-//===- RecordingMemoryManager.cpp - Recording memory manager --------------===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// This memory manager allocates local storage and keeps a record of each<br>
-// allocation. Iterators are provided for all data and code allocations.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#include "RecordingMemoryManager.h"<br>
-using namespace llvm;<br>
-<br>
-RecordingMemoryManager::~RecordingMemoryManager() {<br>
- for (SmallVectorImpl<Allocation>::iterator<br>
- I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();<br>
- I != E; ++I)<br>
- sys::Memory::releaseMappedMemory(I->first);<br>
- for (SmallVectorImpl<Allocation>::iterator<br>
- I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();<br>
- I != E; ++I)<br>
- sys::Memory::releaseMappedMemory(I->first);<br>
-}<br>
-<br>
-uint8_t *RecordingMemoryManager::<br>
-allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,<br>
- StringRef SectionName) {<br>
- // The recording memory manager is just a local copy of the remote target.<br>
- // The alignment requirement is just stored here for later use. Regular<br>
- // heap storage is sufficient here, but we're using mapped memory to work<br>
- // around a bug in MCJIT.<br>
- sys::MemoryBlock Block = allocateSection(Size);<br>
- AllocatedCodeMem.push_back(Allocation(Block, Alignment));<br>
- return (uint8_t*)Block.base();<br>
-}<br>
-<br>
-uint8_t *RecordingMemoryManager::<br>
-allocateDataSection(uintptr_t Size, unsigned Alignment,<br>
- unsigned SectionID, StringRef SectionName,<br>
- bool IsReadOnly) {<br>
- // The recording memory manager is just a local copy of the remote target.<br>
- // The alignment requirement is just stored here for later use. Regular<br>
- // heap storage is sufficient here, but we're using mapped memory to work<br>
- // around a bug in MCJIT.<br>
- sys::MemoryBlock Block = allocateSection(Size);<br>
- AllocatedDataMem.push_back(Allocation(Block, Alignment));<br>
- return (uint8_t*)Block.base();<br>
-}<br>
-<br>
-sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) {<br>
- error_code ec;<br>
- sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size,<br>
- &Near,<br>
- sys::Memory::MF_READ |<br>
- sys::Memory::MF_WRITE,<br>
- ec);<br>
- assert(!ec && MB.base());<br>
-<br>
- // FIXME: This is part of a work around to keep sections near one another<br>
- // when MCJIT performs relocations after code emission but before<br>
- // the generated code is moved to the remote target.<br>
- // Save this address as the basis for our next request<br>
- Near = MB;<br>
- return MB;<br>
-}<br>
-<br>
-void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); }<br>
-void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); }<br>
-void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); }<br>
-void RecordingMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); }<br>
-uint8_t *RecordingMemoryManager::getGOTBase() const {<br>
- llvm_unreachable("Unexpected!");<br>
- return 0;<br>
-}<br>
-uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){<br>
- llvm_unreachable("Unexpected!");<br>
- return 0;<br>
-}<br>
-uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,<br>
- unsigned Alignment) {<br>
- llvm_unreachable("Unexpected!");<br>
- return 0;<br>
-}<br>
-void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart,<br>
- uint8_t *FunctionEnd) {<br>
- llvm_unreachable("Unexpected!");<br>
-}<br>
-uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {<br>
- llvm_unreachable("Unexpected!");<br>
- return 0;<br>
-}<br>
-uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {<br>
- llvm_unreachable("Unexpected!");<br>
- return 0;<br>
-}<br>
-void RecordingMemoryManager::deallocateFunctionBody(void *Body) {<br>
- llvm_unreachable("Unexpected!");<br>
-}<br>
-<br>
-static int jit_noop() {<br>
- return 0;<br>
-}<br>
-<br>
-void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name,<br>
- bool AbortOnFailure) {<br>
- // We should not invoke parent's ctors/dtors from generated main()!<br>
- // On Mingw and Cygwin, the symbol __main is resolved to<br>
- // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors<br>
- // (and register wrong callee's dtors with atexit(3)).<br>
- // We expect ExecutionEngine::runStaticConstructorsDestructors()<br>
- // is called before ExecutionEngine::runFunctionAsMain() is called.<br>
- if (Name == "__main") return (void*)(intptr_t)&jit_noop;<br>
-<br>
- // FIXME: Would it be responsible to provide GOT?<br>
- if (AbortOnFailure) {<br>
- if (Name == "_GLOBAL_OFFSET_TABLE_")<br>
- report_fatal_error("Program used external function '" + Name +<br>
- "' which could not be resolved!");<br>
- }<br>
-<br>
- return NULL;<br>
-}<br>
<br>
Removed: llvm/trunk/tools/lli/RecordingMemoryManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.h?rev=191937&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.h?rev=191937&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RecordingMemoryManager.h (original)<br>
+++ llvm/trunk/tools/lli/RecordingMemoryManager.h (removed)<br>
@@ -1,83 +0,0 @@<br>
-//===- RecordingMemoryManager.h - LLI MCJIT recording memory manager ------===//<br>
-//<br>
-// The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// This memory manager allocates local storage and keeps a record of each<br>
-// allocation. Iterators are provided for all data and code allocations.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef RECORDINGMEMORYMANAGER_H<br>
-#define RECORDINGMEMORYMANAGER_H<br>
-<br>
-#include "llvm/ADT/SmallVector.h"<br>
-#include "llvm/ExecutionEngine/JITMemoryManager.h"<br>
-#include "llvm/Support/ErrorHandling.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include <utility><br>
-<br>
-namespace llvm {<br>
-<br>
-class RecordingMemoryManager : public JITMemoryManager {<br>
-public:<br>
- typedef std::pair<sys::MemoryBlock, unsigned> Allocation;<br>
-<br>
-private:<br>
- SmallVector<Allocation, 16> AllocatedDataMem;<br>
- SmallVector<Allocation, 16> AllocatedCodeMem;<br>
-<br>
- // FIXME: This is part of a work around to keep sections near one another<br>
- // when MCJIT performs relocations after code emission but before<br>
- // the generated code is moved to the remote target.<br>
- sys::MemoryBlock Near;<br>
- sys::MemoryBlock allocateSection(uintptr_t Size);<br>
-<br>
-public:<br>
- RecordingMemoryManager() {}<br>
- virtual ~RecordingMemoryManager();<br>
-<br>
- typedef SmallVectorImpl<Allocation>::const_iterator const_data_iterator;<br>
- typedef SmallVectorImpl<Allocation>::const_iterator const_code_iterator;<br>
-<br>
- const_data_iterator data_begin() const { return AllocatedDataMem.begin(); }<br>
- const_data_iterator data_end() const { return AllocatedDataMem.end(); }<br>
- const_code_iterator code_begin() const { return AllocatedCodeMem.begin(); }<br>
- const_code_iterator code_end() const { return AllocatedCodeMem.end(); }<br>
-<br>
- uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,<br>
- unsigned SectionID, StringRef SectionName);<br>
-<br>
- uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,<br>
- unsigned SectionID, StringRef SectionName,<br>
- bool IsReadOnly);<br>
-<br>
- void *getPointerToNamedFunction(const std::string &Name,<br>
- bool AbortOnFailure = true);<br>
-<br>
- bool finalizeMemory(std::string *ErrMsg) { return false; }<br>
-<br>
- // The following obsolete JITMemoryManager calls are stubbed out for<br>
- // this model.<br>
- void setMemoryWritable();<br>
- void setMemoryExecutable();<br>
- void setPoisonMemory(bool poison);<br>
- void AllocateGOT();<br>
- uint8_t *getGOTBase() const;<br>
- uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize);<br>
- uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,<br>
- unsigned Alignment);<br>
- void endFunctionBody(const Function *F, uint8_t *FunctionStart,<br>
- uint8_t *FunctionEnd);<br>
- uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);<br>
- uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);<br>
- void deallocateFunctionBody(void *Body);<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif<br>
<br>
Copied: llvm/trunk/tools/lli/RemoteMemoryManager.cpp (from r191860, llvm/trunk/tools/lli/RecordingMemoryManager.cpp)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.cpp?p2=llvm/trunk/tools/lli/RemoteMemoryManager.cpp&p1=llvm/trunk/tools/lli/RecordingMemoryManager.cpp&r1=191860&r2=191938&rev=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.cpp?p2=llvm/trunk/tools/lli/RemoteMemoryManager.cpp&p1=llvm/trunk/tools/lli/RecordingMemoryManager.cpp&r1=191860&r2=191938&rev=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RecordingMemoryManager.cpp (original)<br>
+++ llvm/trunk/tools/lli/RemoteMemoryManager.cpp Thu Oct 3 19:49:38 2013<br>
@@ -1,4 +1,4 @@<br>
-//===- RecordingMemoryManager.cpp - Recording memory manager --------------===//<br>
+//===---- RemoteMemoryManager.cpp - Recording memory manager --------------===//<br>
//<br>
// The LLVM Compiler Infrastructure<br>
//<br>
@@ -12,21 +12,23 @@<br>
//<br>
//===----------------------------------------------------------------------===//<br>
<br>
-#include "RecordingMemoryManager.h"<br>
+#define DEBUG_TYPE "lli"<br>
+#include "RemoteMemoryManager.h"<br>
+#include "llvm/ExecutionEngine/ExecutionEngine.h"<br>
+#include "llvm/ExecutionEngine/ObjectImage.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/Format.h"<br>
+<br>
using namespace llvm;<br>
<br>
-RecordingMemoryManager::~RecordingMemoryManager() {<br>
- for (SmallVectorImpl<Allocation>::iterator<br>
- I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();<br>
- I != E; ++I)<br>
- sys::Memory::releaseMappedMemory(I->first);<br>
- for (SmallVectorImpl<Allocation>::iterator<br>
- I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();<br>
+RemoteMemoryManager::~RemoteMemoryManager() {<br>
+ for (SmallVector<Allocation, 2>::iterator<br>
+ I = AllocatedSections.begin(), E = AllocatedSections.end();<br>
I != E; ++I)<br>
- sys::Memory::releaseMappedMemory(I->first);<br>
+ sys::Memory::releaseMappedMemory(I->MB);<br>
}<br>
<br>
-uint8_t *RecordingMemoryManager::<br>
+uint8_t *RemoteMemoryManager::<br>
allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,<br>
StringRef SectionName) {<br>
// The recording memory manager is just a local copy of the remote target.<br>
@@ -34,11 +36,12 @@ allocateCodeSection(uintptr_t Size, unsi<br>
// heap storage is sufficient here, but we're using mapped memory to work<br>
// around a bug in MCJIT.<br>
sys::MemoryBlock Block = allocateSection(Size);<br>
- AllocatedCodeMem.push_back(Allocation(Block, Alignment));<br>
+ AllocatedSections.push_back( Allocation(Block, Alignment, true) );<br>
+ UnmappedSections.push_back( &AllocatedSections.back() );<br>
return (uint8_t*)Block.base();<br>
}<br>
<br>
-uint8_t *RecordingMemoryManager::<br>
+uint8_t *RemoteMemoryManager::<br>
allocateDataSection(uintptr_t Size, unsigned Alignment,<br>
unsigned SectionID, StringRef SectionName,<br>
bool IsReadOnly) {<br>
@@ -47,11 +50,12 @@ allocateDataSection(uintptr_t Size, unsi<br>
// heap storage is sufficient here, but we're using mapped memory to work<br>
// around a bug in MCJIT.<br>
sys::MemoryBlock Block = allocateSection(Size);<br>
- AllocatedDataMem.push_back(Allocation(Block, Alignment));<br>
+ AllocatedSections.push_back( Allocation(Block, Alignment, false) );<br>
+ UnmappedSections.push_back( &AllocatedSections.back() );<br>
return (uint8_t*)Block.base();<br>
}<br>
<br>
-sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) {<br>
+sys::MemoryBlock RemoteMemoryManager::allocateSection(uintptr_t Size) {<br>
error_code ec;<br>
sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size,<br>
&Near,<br>
@@ -68,36 +72,136 @@ sys::MemoryBlock RecordingMemoryManager:<br>
return MB;<br>
}<br>
<br>
-void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); }<br>
-void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); }<br>
-void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); }<br>
-void RecordingMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); }<br>
-uint8_t *RecordingMemoryManager::getGOTBase() const {<br>
+void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE,<br>
+ const ObjectImage *Obj) {<br>
+ // The client should have called setRemoteTarget() before triggering any<br>
+ // code generation.<br>
+ assert(Target);<br>
+ if (!Target)<br>
+ return;<br>
+<br>
+ // FIXME: Make this function thread safe.<br>
+<br>
+ // Lay out our sections in order, with all the code sections first, then<br>
+ // all the data sections.<br>
+ uint64_t CurOffset = 0;<br>
+ unsigned MaxAlign = Target->getPageAlignment();<br>
+ SmallVector<std::pair<const Allocation*, uint64_t>, 16> Offsets;<br>
+ unsigned NumSections = UnmappedSections.size();<br>
+ // We're going to go through the list twice to separate code and data, but<br>
+ // it's a very small list, so that's OK.<br>
+ for (size_t i = 0, e = NumSections; i != e; ++i) {<br>
+ const Allocation *Section = UnmappedSections[i];<br>
+ assert(Section);<br>
+ if (Section->IsCode) {<br>
+ unsigned Size = Section->MB.size();<br>
+ unsigned Align = Section->Alignment;<br>
+ DEBUG(dbgs() << "code region: size " << Size<br>
+ << ", alignment " << Align << "\n");<br>
+ // Align the current offset up to whatever is needed for the next<br>
+ // section.<br>
+ CurOffset = (CurOffset + Align - 1) / Align * Align;<br>
+ // Save off the address of the new section and allocate its space.<br>
+ Offsets.push_back(std::pair<const Allocation*,uint64_t>(Section,<br>
+ CurOffset));<br>
+ CurOffset += Size;<br>
+ }<br>
+ }<br>
+ // Adjust to keep code and data aligned on seperate pages.<br>
+ CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign;<br>
+ for (size_t i = 0, e = NumSections; i != e; ++i) {<br>
+ const Allocation *Section = UnmappedSections[i];<br>
+ assert(Section);<br>
+ if (!Section->IsCode) {<br>
+ unsigned Size = Section->MB.size();<br>
+ unsigned Align = Section->Alignment;<br>
+ DEBUG(dbgs() << "data region: size " << Size<br>
+ << ", alignment " << Align << "\n");<br>
+ // Align the current offset up to whatever is needed for the next<br>
+ // section.<br>
+ CurOffset = (CurOffset + Align - 1) / Align * Align;<br>
+ // Save off the address of the new section and allocate its space.<br>
+ Offsets.push_back(std::pair<const Allocation*,uint64_t>(Section,<br>
+ CurOffset));<br>
+ CurOffset += Size;<br>
+ }<br>
+ }<br>
+<br>
+ // Allocate space in the remote target.<br>
+ uint64_t RemoteAddr;<br>
+ if (Target->allocateSpace(CurOffset, MaxAlign, RemoteAddr))<br>
+ report_fatal_error(Target->getErrorMsg());<br>
+<br>
+ // Map the section addresses so relocations will get updated in the local<br>
+ // copies of the sections.<br>
+ for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {<br>
+ uint64_t Addr = RemoteAddr + Offsets[i].second;<br>
+ EE->mapSectionAddress(const_cast<void*>(Offsets[i].first->MB.base()), Addr);<br>
+<br>
+ DEBUG(dbgs() << " Mapping local: " << Offsets[i].first->MB.base()<br>
+ << " to remote: 0x" << format("%llx", Addr) << "\n");<br>
+<br>
+ MappedSections[Addr] = Offsets[i].first;<br>
+ }<br>
+<br>
+ UnmappedSections.clear();<br>
+}<br>
+<br>
+bool RemoteMemoryManager::finalizeMemory(std::string *ErrMsg) {<br>
+ // FIXME: Make this function thread safe.<br>
+ for (DenseMap<uint64_t, const Allocation*>::iterator<br>
+ I = MappedSections.begin(), E = MappedSections.end();<br>
+ I != E; ++I) {<br>
+ uint64_t RemoteAddr = I->first;<br>
+ const Allocation *Section = I->second;<br>
+ if (Section->IsCode) {<br>
+ Target->loadCode(RemoteAddr, Section->MB.base(), Section->MB.size());<br>
+<br>
+ DEBUG(dbgs() << " loading code: " << Section->MB.base()<br>
+ << " to remote: 0x" << format("%llx", RemoteAddr) << "\n");<br>
+ } else {<br>
+ Target->loadData(RemoteAddr, Section->MB.base(), Section->MB.size());<br>
+<br>
+ DEBUG(dbgs() << " loading data: " << Section->MB.base()<br>
+ << " to remote: 0x" << format("%llx", RemoteAddr) << "\n");<br>
+ }<br>
+ }<br>
+<br>
+ MappedSections.clear();<br>
+<br>
+ return false;<br>
+}<br>
+<br>
+void RemoteMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); }<br>
+void RemoteMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); }<br>
+void RemoteMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); }<br>
+void RemoteMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); }<br>
+uint8_t *RemoteMemoryManager::getGOTBase() const {<br>
llvm_unreachable("Unexpected!");<br>
return 0;<br>
}<br>
-uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){<br>
+uint8_t *RemoteMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){<br>
llvm_unreachable("Unexpected!");<br>
return 0;<br>
}<br>
-uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,<br>
+uint8_t *RemoteMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,<br>
unsigned Alignment) {<br>
llvm_unreachable("Unexpected!");<br>
return 0;<br>
}<br>
-void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart,<br>
+void RemoteMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart,<br>
uint8_t *FunctionEnd) {<br>
llvm_unreachable("Unexpected!");<br>
}<br>
-uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {<br>
+uint8_t *RemoteMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {<br>
llvm_unreachable("Unexpected!");<br>
return 0;<br>
}<br>
-uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {<br>
+uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {<br>
llvm_unreachable("Unexpected!");<br>
return 0;<br>
}<br>
-void RecordingMemoryManager::deallocateFunctionBody(void *Body) {<br>
+void RemoteMemoryManager::deallocateFunctionBody(void *Body) {<br>
llvm_unreachable("Unexpected!");<br>
}<br>
<br>
@@ -105,7 +209,7 @@ static int jit_noop() {<br>
return 0;<br>
}<br>
<br>
-void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name,<br>
+void *RemoteMemoryManager::getPointerToNamedFunction(const std::string &Name,<br>
bool AbortOnFailure) {<br>
// We should not invoke parent's ctors/dtors from generated main()!<br>
// On Mingw and Cygwin, the symbol __main is resolved to<br>
<br>
Copied: llvm/trunk/tools/lli/RemoteMemoryManager.h (from r191860, llvm/trunk/tools/lli/RecordingMemoryManager.h)<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.h?p2=llvm/trunk/tools/lli/RemoteMemoryManager.h&p1=llvm/trunk/tools/lli/RecordingMemoryManager.h&r1=191860&r2=191938&rev=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.h?p2=llvm/trunk/tools/lli/RemoteMemoryManager.h&p1=llvm/trunk/tools/lli/RecordingMemoryManager.h&r1=191860&r2=191938&rev=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RecordingMemoryManager.h (original)<br>
+++ llvm/trunk/tools/lli/RemoteMemoryManager.h Thu Oct 3 19:49:38 2013<br>
@@ -1,4 +1,4 @@<br>
-//===- RecordingMemoryManager.h - LLI MCJIT recording memory manager ------===//<br>
+//===- RemoteMemoryManager.h - LLI MCJIT recording memory manager ------===//<br>
//<br>
// The LLVM Compiler Infrastructure<br>
//<br>
@@ -12,24 +12,47 @@<br>
//<br>
//===----------------------------------------------------------------------===//<br>
<br>
-#ifndef RECORDINGMEMORYMANAGER_H<br>
-#define RECORDINGMEMORYMANAGER_H<br>
+#ifndef REMOTEMEMORYMANAGER_H<br>
+#define REMOTEMEMORYMANAGER_H<br>
<br>
+#include "llvm/ADT/DenseMap.h"<br>
#include "llvm/ADT/SmallVector.h"<br>
#include "llvm/ExecutionEngine/JITMemoryManager.h"<br>
#include "llvm/Support/ErrorHandling.h"<br>
#include "llvm/Support/Memory.h"<br>
#include <utility><br>
<br>
+#include "RemoteTarget.h"<br>
+<br>
namespace llvm {<br>
<br>
-class RecordingMemoryManager : public JITMemoryManager {<br>
+class RemoteMemoryManager : public JITMemoryManager {<br>
public:<br>
- typedef std::pair<sys::MemoryBlock, unsigned> Allocation;<br>
+ // Notice that this structure takes ownership of the memory allocated.<br>
+ struct Allocation {<br>
+ Allocation(sys::MemoryBlock mb, unsigned a, bool code)<br>
+ : MB(mb), Alignment(a), IsCode(code) {}<br>
+<br>
+ sys::MemoryBlock MB;<br>
+ unsigned Alignment;<br>
+ bool IsCode;<br>
+ };<br>
<br>
private:<br>
- SmallVector<Allocation, 16> AllocatedDataMem;<br>
- SmallVector<Allocation, 16> AllocatedCodeMem;<br>
+ // This vector contains Allocation objects for all sections which we have<br>
+ // allocated. This vector effectively owns the memory associated with the<br>
+ // allocations.<br>
+ SmallVector<Allocation, 2> AllocatedSections;<br>
+<br>
+ // This vector contains pointers to Allocation objects for any sections we<br>
+ // have allocated locally but have not yet remapped for the remote target.<br>
+ // When we receive notification of a completed module load, we will map<br>
+ // these sections into the remote target.<br>
+ SmallVector<const Allocation *, 2> UnmappedSections;<br>
+<br>
+ // This map tracks the sections we have remapped for the remote target<br>
+ // but have not yet copied to the target.<br>
+ DenseMap<uint64_t, const Allocation *> MappedSections;<br>
<br>
// FIXME: This is part of a work around to keep sections near one another<br>
// when MCJIT performs relocations after code emission but before<br>
@@ -37,17 +60,11 @@ private:<br>
sys::MemoryBlock Near;<br>
sys::MemoryBlock allocateSection(uintptr_t Size);<br>
<br>
-public:<br>
- RecordingMemoryManager() {}<br>
- virtual ~RecordingMemoryManager();<br>
-<br>
- typedef SmallVectorImpl<Allocation>::const_iterator const_data_iterator;<br>
- typedef SmallVectorImpl<Allocation>::const_iterator const_code_iterator;<br>
+ RemoteTarget *Target;<br>
<br>
- const_data_iterator data_begin() const { return AllocatedDataMem.begin(); }<br>
- const_data_iterator data_end() const { return AllocatedDataMem.end(); }<br>
- const_code_iterator code_begin() const { return AllocatedCodeMem.begin(); }<br>
- const_code_iterator code_end() const { return AllocatedCodeMem.end(); }<br>
+public:<br>
+ RemoteMemoryManager() : Target(NULL) {}<br>
+ virtual ~RemoteMemoryManager();<br>
<br>
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,<br>
unsigned SectionID, StringRef SectionName);<br>
@@ -59,7 +76,12 @@ public:<br>
void *getPointerToNamedFunction(const std::string &Name,<br>
bool AbortOnFailure = true);<br>
<br>
- bool finalizeMemory(std::string *ErrMsg) { return false; }<br>
+ void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj);<br>
+<br>
+ bool finalizeMemory(std::string *ErrMsg);<br>
+<br>
+ // This is a non-interface function used by lli<br>
+ void setRemoteTarget(RemoteTarget *T) { Target = T; }<br>
<br>
// The following obsolete JITMemoryManager calls are stubbed out for<br>
// this model.<br>
<br>
Modified: llvm/trunk/tools/lli/lli.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=191938&r1=191937&r2=191938&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=191938&r1=191937&r2=191938&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/lli.cpp (original)<br>
+++ llvm/trunk/tools/lli/lli.cpp Thu Oct 3 19:49:38 2013<br>
@@ -15,7 +15,7 @@<br>
<br>
#define DEBUG_TYPE "lli"<br>
#include "llvm/IR/LLVMContext.h"<br>
-#include "RecordingMemoryManager.h"<br>
+#include "RemoteMemoryManager.h"<br>
#include "RemoteTarget.h"<br>
#include "llvm/ADT/Triple.h"<br>
#include "llvm/Bitcode/ReaderWriter.h"<br>
@@ -131,6 +131,12 @@ namespace {<br>
cl::value_desc("function"),<br>
cl::init("main"));<br>
<br>
+ cl::list<std::string><br>
+ ExtraModules("extra-modules",<br>
+ cl::CommaSeparated,<br>
+ cl::desc("Extra modules to be loaded"),<br>
+ cl::value_desc("<input bitcode 2>,<input bitcode 3>,..."));<br>
+<br>
cl::opt<std::string><br>
FakeArgv0("fake-argv0",<br>
cl::desc("Override the 'argv[0]' value passed into the executing"<br>
@@ -222,82 +228,6 @@ static void do_shutdown() {<br>
#endif<br>
}<br>
<br>
-void layoutRemoteTargetMemory(RemoteTarget *T, RecordingMemoryManager *JMM) {<br>
- // Lay out our sections in order, with all the code sections first, then<br>
- // all the data sections.<br>
- uint64_t CurOffset = 0;<br>
- unsigned MaxAlign = T->getPageAlignment();<br>
- SmallVector<std::pair<const void*, uint64_t>, 16> Offsets;<br>
- SmallVector<unsigned, 16> Sizes;<br>
- for (RecordingMemoryManager::const_code_iterator I = JMM->code_begin(),<br>
- E = JMM->code_end();<br>
- I != E; ++I) {<br>
- DEBUG(dbgs() << "code region: size " << I->first.size()<br>
- << ", alignment " << I->second << "\n");<br>
- // Align the current offset up to whatever is needed for the next<br>
- // section.<br>
- unsigned Align = I->second;<br>
- CurOffset = (CurOffset + Align - 1) / Align * Align;<br>
- // Save off the address of the new section and allocate its space.<br>
- Offsets.push_back(std::pair<const void*,uint64_t>(I->first.base(), CurOffset));<br>
- Sizes.push_back(I->first.size());<br>
- CurOffset += I->first.size();<br>
- }<br>
- // Adjust to keep code and data aligned on seperate pages.<br>
- CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign;<br>
- unsigned FirstDataIndex = Offsets.size();<br>
- for (RecordingMemoryManager::const_data_iterator I = JMM->data_begin(),<br>
- E = JMM->data_end();<br>
- I != E; ++I) {<br>
- DEBUG(dbgs() << "data region: size " << I->first.size()<br>
- << ", alignment " << I->second << "\n");<br>
- // Align the current offset up to whatever is needed for the next<br>
- // section.<br>
- unsigned Align = I->second;<br>
- CurOffset = (CurOffset + Align - 1) / Align * Align;<br>
- // Save off the address of the new section and allocate its space.<br>
- Offsets.push_back(std::pair<const void*,uint64_t>(I->first.base(), CurOffset));<br>
- Sizes.push_back(I->first.size());<br>
- CurOffset += I->first.size();<br>
- }<br>
-<br>
- // Allocate space in the remote target.<br>
- uint64_t RemoteAddr;<br>
- if (T->allocateSpace(CurOffset, MaxAlign, RemoteAddr))<br>
- report_fatal_error(T->getErrorMsg());<br>
- // Map the section addresses so relocations will get updated in the local<br>
- // copies of the sections.<br>
- for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {<br>
- uint64_t Addr = RemoteAddr + Offsets[i].second;<br>
- EE->mapSectionAddress(const_cast<void*>(Offsets[i].first), Addr);<br>
-<br>
- DEBUG(dbgs() << " Mapping local: " << Offsets[i].first<br>
- << " to remote: 0x" << format("%llx", Addr) << "\n");<br>
-<br>
- }<br>
-<br>
- // Trigger application of relocations<br>
- EE->finalizeObject();<br>
-<br>
- // Now load it all to the target.<br>
- for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {<br>
- uint64_t Addr = RemoteAddr + Offsets[i].second;<br>
-<br>
- if (i < FirstDataIndex) {<br>
- T->loadCode(Addr, Offsets[i].first, Sizes[i]);<br>
-<br>
- DEBUG(dbgs() << " loading code: " << Offsets[i].first<br>
- << " to remote: 0x" << format("%llx", Addr) << "\n");<br>
- } else {<br>
- T->loadData(Addr, Offsets[i].first, Sizes[i]);<br>
-<br>
- DEBUG(dbgs() << " loading data: " << Offsets[i].first<br>
- << " to remote: 0x" << format("%llx", Addr) << "\n");<br>
- }<br>
-<br>
- }<br>
-}<br>
-<br>
//===----------------------------------------------------------------------===//<br>
// main Driver function<br>
//<br>
@@ -370,7 +300,7 @@ int main(int argc, char **argv, char * c<br>
if (UseMCJIT && !ForceInterpreter) {<br>
builder.setUseMCJIT(true);<br>
if (RemoteMCJIT)<br>
- RTDyldMM = new RecordingMemoryManager();<br>
+ RTDyldMM = new RemoteMemoryManager();<br>
else<br>
RTDyldMM = new SectionMemoryManager();<br>
builder.setMCJITMemoryManager(RTDyldMM);<br>
@@ -420,6 +350,16 @@ int main(int argc, char **argv, char * c<br>
exit(1);<br>
}<br>
<br>
+ // Load any additional modules specified on the command line.<br>
+ for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) {<br>
+ Module *XMod = ParseIRFile(ExtraModules[i], Err, Context);<br>
+ if (!XMod) {<br>
+ Err.print(argv[0], errs());<br>
+ return 1;<br>
+ }<br>
+ EE->addModule(XMod);<br>
+ }<br>
+<br>
// The following functions have no effect if their respective profiling<br>
// support wasn't enabled in the build configuration.<br>
EE->RegisterJITEventListener(<br>
@@ -519,7 +459,7 @@ int main(int argc, char **argv, char * c<br>
// it couldn't. This is a limitation of the LLI implemantation, not the<br>
// MCJIT itself. FIXME.<br>
//<br>
- RecordingMemoryManager *MM = static_cast<RecordingMemoryManager*>(RTDyldMM);<br>
+ RemoteMemoryManager *MM = static_cast<RemoteMemoryManager*>(RTDyldMM);<br>
// Everything is prepared now, so lay out our program for the target<br>
// address space, assign the section addresses to resolve any relocations,<br>
// and send it to the target.<br>
@@ -543,19 +483,30 @@ int main(int argc, char **argv, char * c<br>
Target.reset(RemoteTarget::createRemoteTarget());<br>
}<br>
<br>
- // Create the remote target<br>
+ // Give the memory manager a pointer to our remote target interface object.<br>
+ MM->setRemoteTarget(Target.get());<br>
+<br>
+ // Create the remote target.<br>
Target->create();<br>
<br>
+// FIXME: Don't commit like this. I don't think these calls are necessary.<br></blockquote><div><br></div><div>!!!</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+#if 0<br>
// Trigger compilation.<br>
EE->generateCodeForModule(Mod);<br>
<br>
- // Layout the target memory.<br>
- layoutRemoteTargetMemory(Target.get(), MM);<br>
+ // Get everything ready to execute.<br>
+ EE->finalizeModule(Mod);<br>
+#endif<br>
<br>
// Since we're executing in a (at least simulated) remote address space,<br>
// we can't use the ExecutionEngine::runFunctionAsMain(). We have to<br>
// grab the function address directly here and tell the remote target<br>
// to execute the function.<br>
+ //<br>
+ // Our memory manager will map generated code into the remote address<br>
+ // space as it is loaded and copy the bits over during the finalizeMemory<br>
+ // operation.<br>
+ //<br>
// FIXME: argv and envp handling.<br>
uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str());<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>