[llvm] r191938 - Adding support and tests for multiple module handling in lli

Richard Smith richard at metafoo.co.uk
Fri Oct 4 12:28:37 PDT 2013


On Thu, Oct 3, 2013 at 5:49 PM, Andrew Kaylor <andrew.kaylor at intel.com>wrote:

> Author: akaylor
> Date: Thu Oct  3 19:49:38 2013
> New Revision: 191938
>
> URL: http://llvm.org/viewvc/llvm-project?rev=191938&view=rev
> Log:
> Adding support and tests for multiple module handling in lli
>
> Added:
>     llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll
>     llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir
>     llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll
>

This test fails under ASan:

==10866==ERROR: AddressSanitizer: heap-use-after-free on address
0x60c00000a5b4 at pc 0x480401 bp 0x7fff14df7a90 sp 0x7fff14df7a88
READ of size 1 at 0x60c00000a5b4 thread T0
    #0 0x480400 in
llvm::RemoteMemoryManager::notifyObjectLoaded(llvm::ExecutionEngine*,
llvm::ObjectImage const*) llvm/tools/lli/RemoteMemoryManager.cpp:96
    #1 0x59a4de in llvm::MCJIT::NotifyObjectEmitted(llvm::ObjectImage
const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:516
    #2 0x59a267 in llvm::MCJIT::generateCodeForModule(llvm::Module*)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:163
    #3 0x59bb14 in llvm::MCJIT::getSymbolAddress(std::string const&, bool)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:316
    #4 0x59d2ad in llvm::LinkingMemoryManager::getSymbolAddress(std::string
const&) llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:529
    #5 0x5dfa3d in llvm::RuntimeDyldImpl::resolveExternalSymbols()
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:484
    #6 0x5df348 in llvm::RuntimeDyldImpl::resolveRelocations()
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:39
    #7 0x59a6a9 in llvm::MCJIT::finalizeLoadedModules()
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:170
    #8 0x59bc53 in llvm::MCJIT::getFunctionAddress(std::string const&)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:332
    #9 0x487d59 in main llvm/tools/lli/lli.cpp:511
    #10 0x7f4a386f011c in __libc_start_main
    #11 0x47ed99 in _start
0x60c00000a5b4 is located 116 bytes inside of 120-byte region
[0x60c00000a540,0x60c00000a5b8)
freed by thread T0 here:
    #0 0x4757a4 in __interceptor_realloc
    #1 0x177cee9 in llvm::SmallVectorBase::grow_pod(void*, unsigned long,
unsigned long) llvm/lib/Support/SmallVector.cpp:34
    #2 0x4810ef in
llvm::SmallVectorTemplateBase<llvm::RemoteMemoryManager::Allocation,
true>::push_back(llvm::RemoteMemoryManager::Allocation const&)
llvm/include/llvm/ADT/SmallVector.h:357
    #3 0x47f369 in llvm::RemoteMemoryManager::allocateCodeSection(unsigned
long, unsigned int, unsigned int, llvm::StringRef)
llvm/tools/lli/RemoteMemoryManager.cpp:39
    #4 0x5e34bb in llvm::RuntimeDyldImpl::emitSection(llvm::ObjectImage&,
llvm::object::SectionRef const&, bool)
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:281
    #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
    #6 0x5e152c in llvm::RuntimeDyldImpl::loadObject(llvm::ObjectBuffer*)
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:163
    #7 0x5e49c1 in llvm::RuntimeDyld::loadObject(llvm::ObjectBuffer*)
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:562
    #8 0x59a1ee in llvm::MCJIT::generateCodeForModule(llvm::Module*)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:155
    #9 0x59bb14 in llvm::MCJIT::getSymbolAddress(std::string const&, bool)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:316
    #10 0x59d2ad in
llvm::LinkingMemoryManager::getSymbolAddress(std::string const&)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:529
    #11 0x5dfa3d in llvm::RuntimeDyldImpl::resolveExternalSymbols()
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:484
    #12 0x5df348 in llvm::RuntimeDyldImpl::resolveRelocations()
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:39
    #13 0x59a6a9 in llvm::MCJIT::finalizeLoadedModules()
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:170
    #14 0x59bc53 in llvm::MCJIT::getFunctionAddress(std::string const&)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:332
    #15 0x487d59 in main llvm/tools/lli/lli.cpp:511
    #16 0x7f4a386f011c in __libc_start_main
previously allocated by thread T0 here:
    #0 0x475575 in __interceptor_malloc
    #1 0x177cef9 in llvm::SmallVectorBase::grow_pod(void*, unsigned long,
unsigned long) llvm/lib/Support/SmallVector.cpp:28
    #2 0x4810ef in
llvm::SmallVectorTemplateBase<llvm::RemoteMemoryManager::Allocation,
true>::push_back(llvm::RemoteMemoryManager::Allocation const&)
llvm/include/llvm/ADT/SmallVector.h:357
    #3 0x47f369 in llvm::RemoteMemoryManager::allocateCodeSection(unsigned
long, unsigned int, unsigned int, llvm::StringRef)
llvm/tools/lli/RemoteMemoryManager.cpp:39
    #4 0x5e34bb in llvm::RuntimeDyldImpl::emitSection(llvm::ObjectImage&,
llvm::object::SectionRef const&, bool)
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:281
    #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
    #6 0x5e0b04 in llvm::RuntimeDyldImpl::loadObject(llvm::ObjectBuffer*)
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:130
    #7 0x5e49c1 in llvm::RuntimeDyld::loadObject(llvm::ObjectBuffer*)
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:562
    #8 0x59a1ee in llvm::MCJIT::generateCodeForModule(llvm::Module*)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:155
    #9 0x59bb14 in llvm::MCJIT::getSymbolAddress(std::string const&, bool)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:316
    #10 0x59d2ad in
llvm::LinkingMemoryManager::getSymbolAddress(std::string const&)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:529
    #11 0x5dfa3d in llvm::RuntimeDyldImpl::resolveExternalSymbols()
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:484
    #12 0x5df348 in llvm::RuntimeDyldImpl::resolveRelocations()
llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp:39
    #13 0x59a6a9 in llvm::MCJIT::finalizeLoadedModules()
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:170
    #14 0x59bc53 in llvm::MCJIT::getFunctionAddress(std::string const&)
llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp:332
    #15 0x487d59 in main llvm/tools/lli/lli.cpp:511
    #16 0x7f4a386f011c in __libc_start_main
SUMMARY: AddressSanitizer: heap-use-after-free
llvm/tools/lli/RemoteMemoryManager.cpp:96
llvm::RemoteMemoryManager::notifyObjectLoaded(llvm::ExecutionEngine*,
llvm::ObjectImage const*)
Shadow bytes around the buggy address:
  0x0c187fff9460: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c187fff9470: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c187fff9480: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
  0x0c187fff9490: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
  0x0c187fff94a0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c187fff94b0: fd fd fd fd fd fd[fd]fa fa fa fa fa fa fa fa fa
  0x0c187fff94c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c187fff94d0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c187fff94e0: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x0c187fff94f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c187fff9500: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:     fa
  Heap right redzone:    fb
  Freed heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==10866==ABORTING


>     llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir
>     llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir
>     llvm/trunk/tools/lli/RemoteMemoryManager.cpp
>       - copied, changed from r191860,
> llvm/trunk/tools/lli/RecordingMemoryManager.cpp
>     llvm/trunk/tools/lli/RemoteMemoryManager.h
>       - copied, changed from r191860,
> llvm/trunk/tools/lli/RecordingMemoryManager.h
> Removed:
>     llvm/trunk/tools/lli/RecordingMemoryManager.cpp
>     llvm/trunk/tools/lli/RecordingMemoryManager.h
> Modified:
>     llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
>     llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
>     llvm/trunk/tools/lli/CMakeLists.txt
>     llvm/trunk/tools/lli/lli.cpp
>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h?rev=191938&r1=191937&r2=191938&view=diff
>
> ==============================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/RTDyldMemoryManager.h Thu Oct
>  3 19:49:38 2013
> @@ -21,6 +21,9 @@
>
>  namespace llvm {
>
> +class ExecutionEngine;
> +class ObjectImage;
> +
>  // RuntimeDyld clients often want to handle the memory management of
>  // what gets placed where. For JIT clients, this is the subset of
>  // JITMemoryManager required for dynamic loading of binaries.
> @@ -41,7 +44,7 @@ public:
>    virtual uint8_t *allocateCodeSection(
>      uintptr_t Size, unsigned Alignment, unsigned SectionID,
>      StringRef SectionName) = 0;
> -
> +
>    /// Allocate a memory block of (at least) the given size suitable for
> data.
>    /// The SectionID is a unique identifier assigned by the JIT engine, and
>    /// optionally recorded by the memory manager to access a loaded
> section.
> @@ -63,11 +66,24 @@ public:
>    /// found, this function returns a null pointer. Otherwise, it prints a
>    /// message to stderr and aborts.
>    ///
> -  /// This function is deprecated for memory managers used to be used with
> +  /// This function is deprecated for memory managers to be used with
>    /// MCJIT or RuntimeDyld.  Use getSymbolAddress instead.
>    virtual void *getPointerToNamedFunction(const std::string &Name,
>                                            bool AbortOnFailure = true);
>
> +  /// This method is called after an object has been loaded into memory
> but
> +  /// before relocations are applied to the loaded sections.  The object
> load
> +  /// may have been initiated by MCJIT to resolve an external symbol for
> another
> +  /// object that is being finalized.  In that case, the object about
> which
> +  /// the memory manager is being notified will be finalized immediately
> after
> +  /// the memory manager returns from this call.
> +  ///
> +  /// Memory managers which are preparing code for execution in an
> external
> +  /// address space can use this call to remap the section addresses for
> the
> +  /// newly loaded object.
> +  virtual void notifyObjectLoaded(ExecutionEngine *EE,
> +                                  const ObjectImage *) {}
> +
>    /// 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
>
> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=191938&r1=191937&r2=191938&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Thu Oct  3 19:49:38 2013
> @@ -513,6 +513,7 @@ void MCJIT::UnregisterJITEventListener(J
>  }
>  void MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) {
>    MutexGuard locked(lock);
> +  MemMgr.notifyObjectLoaded(this, &Obj);
>    for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
>      EventListeners[I]->NotifyObjectEmitted(Obj);
>    }
>
> Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=191938&r1=191937&r2=191938&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
> +++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Thu Oct  3 19:49:38 2013
> @@ -46,6 +46,11 @@ public:
>                                           SectionID, SectionName,
> IsReadOnly);
>    }
>
> +  virtual void notifyObjectLoaded(ExecutionEngine *EE,
> +                                  const ObjectImage *Obj) {
> +    ClientMM->notifyObjectLoaded(EE, Obj);
> +  }
> +
>    virtual void registerEHFrames(StringRef SectionData) {
>      ClientMM->registerEHFrames(SectionData);
>    }
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-a.ll Thu Oct  3
> 19:49:38 2013
> @@ -0,0 +1,13 @@
> +; RUN: %lli_mcjit -extra-modules=%p/cross-module-b.ir %s > /dev/null
> +
> +declare i32 @FB()
> +
> +define i32 @FA() {
> +  ret i32 0
> +}
> +
> +define i32 @main() {
> +  %r = call i32 @FB( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/cross-module-b.ir Thu Oct  3
> 19:49:38 2013
> @@ -0,0 +1,7 @@
> +declare i32 @FA()
> +
> +define i32 @FB() {
> +  %r = call i32 @FA( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-a.ll Thu Oct  3
> 19:49:38 2013
> @@ -0,0 +1,9 @@
> +; RUN: %lli_mcjit -extra-modules=%p/multi-module-b.ir,%p/
> multi-module-c.ir %s > /dev/null
> +
> +declare i32 @FB()
> +
> +define i32 @main() {
> +  %r = call i32 @FB( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-b.ir Thu Oct  3
> 19:49:38 2013
> @@ -0,0 +1,7 @@
> +declare i32 @FC()
> +
> +define i32 @FB() {
> +  %r = call i32 @FC( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/multi-module-c.ir Thu Oct  3
> 19:49:38 2013
> @@ -0,0 +1,4 @@
> +define i32 @FC() {
> +  ret i32 0
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-a.ll Thu Oct
>  3 19:49:38 2013
> @@ -0,0 +1,13 @@
> +; RUN: %lli_mcjit -extra-modules=%p/cross-module-b.ir -disable-lazy-compilation=true -remote-mcjit
> -mcjit-remote-process=lli-child-target %s > /dev/null
> +
> +declare i32 @FB()
> +
> +define i32 @FA() {
> +  ret i32 0
> +}
> +
> +define i32 @main() {
> +  %r = call i32 @FB( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/cross-module-b.ir Thu
> Oct  3 19:49:38 2013
> @@ -0,0 +1,7 @@
> +declare i32 @FA()
> +
> +define i32 @FB() {
> +  %r = call i32 @FA( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-a.ll Thu Oct
>  3 19:49:38 2013
> @@ -0,0 +1,9 @@
> +; RUN: %lli_mcjit -extra-modules=%p/multi-module-b.ir,%p/
> multi-module-c.ir  -disable-lazy-compilation=true -remote-mcjit
> -mcjit-remote-process=lli-child-target %s > /dev/null
> +
> +declare i32 @FB()
> +
> +define i32 @main() {
> +  %r = call i32 @FB( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-b.ir Thu
> Oct  3 19:49:38 2013
> @@ -0,0 +1,7 @@
> +declare i32 @FC()
> +
> +define i32 @FB() {
> +  %r = call i32 @FC( )   ; <i32> [#uses=1]
> +  ret i32 %r
> +}
> +
>
> Added: llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir?rev=191938&view=auto
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir (added)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/multi-module-c.ir Thu
> Oct  3 19:49:38 2013
> @@ -0,0 +1,4 @@
> +define i32 @FC() {
> +  ret i32 0
> +}
> +
>
> Modified: llvm/trunk/tools/lli/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/CMakeLists.txt?rev=191938&r1=191937&r2=191938&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/CMakeLists.txt (original)
> +++ llvm/trunk/tools/lli/CMakeLists.txt Thu Oct  3 19:49:38 2013
> @@ -21,7 +21,7 @@ endif( LLVM_USE_INTEL_JITEVENTS )
>
>  add_llvm_tool(lli
>    lli.cpp
> -  RecordingMemoryManager.cpp
> +  RemoteMemoryManager.cpp
>    RemoteTarget.cpp
>    RemoteTargetExternal.cpp
>    )
>
> Removed: llvm/trunk/tools/lli/RecordingMemoryManager.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.cpp?rev=191937&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RecordingMemoryManager.cpp (original)
> +++ llvm/trunk/tools/lli/RecordingMemoryManager.cpp (removed)
> @@ -1,126 +0,0 @@
> -//===- RecordingMemoryManager.cpp - Recording memory manager
> --------------===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -//
> -// This memory manager allocates local storage and keeps a record of each
> -// allocation. Iterators are provided for all data and code allocations.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#include "RecordingMemoryManager.h"
> -using namespace llvm;
> -
> -RecordingMemoryManager::~RecordingMemoryManager() {
> -  for (SmallVectorImpl<Allocation>::iterator
> -         I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();
> -       I != E; ++I)
> -    sys::Memory::releaseMappedMemory(I->first);
> -  for (SmallVectorImpl<Allocation>::iterator
> -         I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();
> -       I != E; ++I)
> -    sys::Memory::releaseMappedMemory(I->first);
> -}
> -
> -uint8_t *RecordingMemoryManager::
> -allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned
> SectionID,
> -                    StringRef SectionName) {
> -  // 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, but we're using mapped memory to
> work
> -  // around a bug in MCJIT.
> -  sys::MemoryBlock Block = allocateSection(Size);
> -  AllocatedCodeMem.push_back(Allocation(Block, Alignment));
> -  return (uint8_t*)Block.base();
> -}
> -
> -uint8_t *RecordingMemoryManager::
> -allocateDataSection(uintptr_t Size, unsigned Alignment,
> -                    unsigned SectionID, StringRef SectionName,
> -                    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, but we're using mapped memory to
> work
> -  // around a bug in MCJIT.
> -  sys::MemoryBlock Block = allocateSection(Size);
> -  AllocatedDataMem.push_back(Allocation(Block, Alignment));
> -  return (uint8_t*)Block.base();
> -}
> -
> -sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) {
> -  error_code ec;
> -  sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size,
> -                                                          &Near,
> -
>  sys::Memory::MF_READ |
> -
>  sys::Memory::MF_WRITE,
> -                                                          ec);
> -  assert(!ec && MB.base());
> -
> -  // FIXME: This is part of a work around to keep sections near one
> another
> -  // when MCJIT performs relocations after code emission but before
> -  // the generated code is moved to the remote target.
> -  // Save this address as the basis for our next request
> -  Near = MB;
> -  return MB;
> -}
> -
> -void RecordingMemoryManager::setMemoryWritable() {
> llvm_unreachable("Unexpected!"); }
> -void RecordingMemoryManager::setMemoryExecutable() {
> llvm_unreachable("Unexpected!"); }
> -void RecordingMemoryManager::setPoisonMemory(bool poison) {
> llvm_unreachable("Unexpected!"); }
> -void RecordingMemoryManager::AllocateGOT() {
> llvm_unreachable("Unexpected!"); }
> -uint8_t *RecordingMemoryManager::getGOTBase() const {
> -  llvm_unreachable("Unexpected!");
> -  return 0;
> -}
> -uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F,
> uintptr_t &ActualSize){
> -  llvm_unreachable("Unexpected!");
> -  return 0;
> -}
> -uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F,
> unsigned StubSize,
> -                                              unsigned Alignment) {
> -  llvm_unreachable("Unexpected!");
> -  return 0;
> -}
> -void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t
> *FunctionStart,
> -                                             uint8_t *FunctionEnd) {
> -  llvm_unreachable("Unexpected!");
> -}
> -uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned
> Alignment) {
> -  llvm_unreachable("Unexpected!");
> -  return 0;
> -}
> -uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned
> Alignment) {
> -  llvm_unreachable("Unexpected!");
> -  return 0;
> -}
> -void RecordingMemoryManager::deallocateFunctionBody(void *Body) {
> -  llvm_unreachable("Unexpected!");
> -}
> -
> -static int jit_noop() {
> -  return 0;
> -}
> -
> -void *RecordingMemoryManager::getPointerToNamedFunction(const std::string
> &Name,
> -                                                        bool
> AbortOnFailure) {
> -  // We should not invoke parent's ctors/dtors from generated main()!
> -  // On Mingw and Cygwin, the symbol __main is resolved to
> -  // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
> -  // (and register wrong callee's dtors with atexit(3)).
> -  // We expect ExecutionEngine::runStaticConstructorsDestructors()
> -  // is called before ExecutionEngine::runFunctionAsMain() is called.
> -  if (Name == "__main") return (void*)(intptr_t)&jit_noop;
> -
> -  // FIXME: Would it be responsible to provide GOT?
> -  if (AbortOnFailure) {
> -    if (Name == "_GLOBAL_OFFSET_TABLE_")
> -      report_fatal_error("Program used external function '" + Name +
> -                         "' which could not be resolved!");
> -  }
> -
> -  return NULL;
> -}
>
> Removed: llvm/trunk/tools/lli/RecordingMemoryManager.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RecordingMemoryManager.h?rev=191937&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RecordingMemoryManager.h (original)
> +++ llvm/trunk/tools/lli/RecordingMemoryManager.h (removed)
> @@ -1,83 +0,0 @@
> -//===- RecordingMemoryManager.h - LLI MCJIT recording memory manager
> ------===//
> -//
> -//                     The LLVM Compiler Infrastructure
> -//
> -// This file is distributed under the University of Illinois Open Source
> -// License. See LICENSE.TXT for details.
> -//
>
> -//===----------------------------------------------------------------------===//
> -//
> -// This memory manager allocates local storage and keeps a record of each
> -// allocation. Iterators are provided for all data and code allocations.
> -//
>
> -//===----------------------------------------------------------------------===//
> -
> -#ifndef RECORDINGMEMORYMANAGER_H
> -#define RECORDINGMEMORYMANAGER_H
> -
> -#include "llvm/ADT/SmallVector.h"
> -#include "llvm/ExecutionEngine/JITMemoryManager.h"
> -#include "llvm/Support/ErrorHandling.h"
> -#include "llvm/Support/Memory.h"
> -#include <utility>
> -
> -namespace llvm {
> -
> -class RecordingMemoryManager : public JITMemoryManager {
> -public:
> -  typedef std::pair<sys::MemoryBlock, unsigned> Allocation;
> -
> -private:
> -  SmallVector<Allocation, 16> AllocatedDataMem;
> -  SmallVector<Allocation, 16> AllocatedCodeMem;
> -
> -  // FIXME: This is part of a work around to keep sections near one
> another
> -  // when MCJIT performs relocations after code emission but before
> -  // the generated code is moved to the remote target.
> -  sys::MemoryBlock Near;
> -  sys::MemoryBlock allocateSection(uintptr_t Size);
> -
> -public:
> -  RecordingMemoryManager() {}
> -  virtual ~RecordingMemoryManager();
> -
> -  typedef SmallVectorImpl<Allocation>::const_iterator const_data_iterator;
> -  typedef SmallVectorImpl<Allocation>::const_iterator const_code_iterator;
> -
> -  const_data_iterator data_begin() const { return
> AllocatedDataMem.begin(); }
> -  const_data_iterator   data_end() const { return AllocatedDataMem.end();
> }
> -  const_code_iterator code_begin() const { return
> AllocatedCodeMem.begin(); }
> -  const_code_iterator   code_end() const { return AllocatedCodeMem.end();
> }
> -
> -  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
> -                               unsigned SectionID, StringRef SectionName);
> -
> -  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
> -                               unsigned SectionID, StringRef SectionName,
> -                               bool IsReadOnly);
> -
> -  void *getPointerToNamedFunction(const std::string &Name,
> -                                  bool AbortOnFailure = true);
> -
> -  bool finalizeMemory(std::string *ErrMsg) { return false; }
> -
> -  // The following obsolete JITMemoryManager calls are stubbed out for
> -  // this model.
> -  void setMemoryWritable();
> -  void setMemoryExecutable();
> -  void setPoisonMemory(bool poison);
> -  void AllocateGOT();
> -  uint8_t *getGOTBase() const;
> -  uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize);
> -  uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
> -                        unsigned Alignment);
> -  void endFunctionBody(const Function *F, uint8_t *FunctionStart,
> -                       uint8_t *FunctionEnd);
> -  uint8_t *allocateSpace(intptr_t Size, unsigned Alignment);
> -  uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment);
> -  void deallocateFunctionBody(void *Body);
> -};
> -
> -} // end namespace llvm
> -
> -#endif
>
> Copied: llvm/trunk/tools/lli/RemoteMemoryManager.cpp (from r191860,
> llvm/trunk/tools/lli/RecordingMemoryManager.cpp)
> URL:
> 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
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RecordingMemoryManager.cpp (original)
> +++ llvm/trunk/tools/lli/RemoteMemoryManager.cpp Thu Oct  3 19:49:38 2013
> @@ -1,4 +1,4 @@
> -//===- RecordingMemoryManager.cpp - Recording memory manager
> --------------===//
> +//===---- RemoteMemoryManager.cpp - Recording memory manager
> --------------===//
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
> @@ -12,21 +12,23 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#include "RecordingMemoryManager.h"
> +#define DEBUG_TYPE "lli"
> +#include "RemoteMemoryManager.h"
> +#include "llvm/ExecutionEngine/ExecutionEngine.h"
> +#include "llvm/ExecutionEngine/ObjectImage.h"
> +#include "llvm/Support/Debug.h"
> +#include "llvm/Support/Format.h"
> +
>  using namespace llvm;
>
> -RecordingMemoryManager::~RecordingMemoryManager() {
> -  for (SmallVectorImpl<Allocation>::iterator
> -         I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end();
> -       I != E; ++I)
> -    sys::Memory::releaseMappedMemory(I->first);
> -  for (SmallVectorImpl<Allocation>::iterator
> -         I = AllocatedDataMem.begin(), E = AllocatedDataMem.end();
> +RemoteMemoryManager::~RemoteMemoryManager() {
> +  for (SmallVector<Allocation, 2>::iterator
> +         I = AllocatedSections.begin(), E = AllocatedSections.end();
>         I != E; ++I)
> -    sys::Memory::releaseMappedMemory(I->first);
> +    sys::Memory::releaseMappedMemory(I->MB);
>  }
>
> -uint8_t *RecordingMemoryManager::
> +uint8_t *RemoteMemoryManager::
>  allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned
> SectionID,
>                      StringRef SectionName) {
>    // The recording memory manager is just a local copy of the remote
> target.
> @@ -34,11 +36,12 @@ allocateCodeSection(uintptr_t Size, unsi
>    // heap storage is sufficient here, but we're using mapped memory to
> work
>    // around a bug in MCJIT.
>    sys::MemoryBlock Block = allocateSection(Size);
> -  AllocatedCodeMem.push_back(Allocation(Block, Alignment));
> +  AllocatedSections.push_back( Allocation(Block, Alignment, true) );
> +  UnmappedSections.push_back( &AllocatedSections.back() );
>    return (uint8_t*)Block.base();
>  }
>
> -uint8_t *RecordingMemoryManager::
> +uint8_t *RemoteMemoryManager::
>  allocateDataSection(uintptr_t Size, unsigned Alignment,
>                      unsigned SectionID, StringRef SectionName,
>                      bool IsReadOnly) {
> @@ -47,11 +50,12 @@ allocateDataSection(uintptr_t Size, unsi
>    // heap storage is sufficient here, but we're using mapped memory to
> work
>    // around a bug in MCJIT.
>    sys::MemoryBlock Block = allocateSection(Size);
> -  AllocatedDataMem.push_back(Allocation(Block, Alignment));
> +  AllocatedSections.push_back( Allocation(Block, Alignment, false) );
> +  UnmappedSections.push_back( &AllocatedSections.back() );
>    return (uint8_t*)Block.base();
>  }
>
> -sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) {
> +sys::MemoryBlock RemoteMemoryManager::allocateSection(uintptr_t Size) {
>    error_code ec;
>    sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size,
>                                                            &Near,
> @@ -68,36 +72,136 @@ sys::MemoryBlock RecordingMemoryManager:
>    return MB;
>  }
>
> -void RecordingMemoryManager::setMemoryWritable() {
> llvm_unreachable("Unexpected!"); }
> -void RecordingMemoryManager::setMemoryExecutable() {
> llvm_unreachable("Unexpected!"); }
> -void RecordingMemoryManager::setPoisonMemory(bool poison) {
> llvm_unreachable("Unexpected!"); }
> -void RecordingMemoryManager::AllocateGOT() {
> llvm_unreachable("Unexpected!"); }
> -uint8_t *RecordingMemoryManager::getGOTBase() const {
> +void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE,
> +                                                const ObjectImage *Obj) {
> +  // The client should have called setRemoteTarget() before triggering any
> +  // code generation.
> +  assert(Target);
> +  if (!Target)
> +    return;
> +
> +  // FIXME: Make this function thread safe.
> +
> +  // Lay out our sections in order, with all the code sections first, then
> +  // all the data sections.
> +  uint64_t CurOffset = 0;
> +  unsigned MaxAlign = Target->getPageAlignment();
> +  SmallVector<std::pair<const Allocation*, uint64_t>, 16> Offsets;
> +  unsigned NumSections = UnmappedSections.size();
> +  // We're going to go through the list twice to separate code and data,
> but
> +  // it's a very small list, so that's OK.
> +  for (size_t i = 0, e = NumSections; i != e; ++i) {
> +    const Allocation *Section = UnmappedSections[i];
> +    assert(Section);
> +    if (Section->IsCode) {
> +      unsigned Size = Section->MB.size();
> +      unsigned Align = Section->Alignment;
> +      DEBUG(dbgs() << "code region: size " << Size
> +                  << ", alignment " << Align << "\n");
> +      // Align the current offset up to whatever is needed for the next
> +      // section.
> +      CurOffset = (CurOffset + Align - 1) / Align * Align;
> +      // Save off the address of the new section and allocate its space.
> +      Offsets.push_back(std::pair<const Allocation*,uint64_t>(Section,
> +                                                              CurOffset));
> +      CurOffset += Size;
> +    }
> +  }
> +  // Adjust to keep code and data aligned on seperate pages.
> +  CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign;
> +  for (size_t i = 0, e = NumSections; i != e; ++i) {
> +    const Allocation *Section = UnmappedSections[i];
> +    assert(Section);
> +    if (!Section->IsCode) {
> +      unsigned Size = Section->MB.size();
> +      unsigned Align = Section->Alignment;
> +      DEBUG(dbgs() << "data region: size " << Size
> +                  << ", alignment " << Align << "\n");
> +      // Align the current offset up to whatever is needed for the next
> +      // section.
> +      CurOffset = (CurOffset + Align - 1) / Align * Align;
> +      // Save off the address of the new section and allocate its space.
> +      Offsets.push_back(std::pair<const Allocation*,uint64_t>(Section,
> +                                                              CurOffset));
> +      CurOffset += Size;
> +    }
> +  }
> +
> +  // Allocate space in the remote target.
> +  uint64_t RemoteAddr;
> +  if (Target->allocateSpace(CurOffset, MaxAlign, RemoteAddr))
> +    report_fatal_error(Target->getErrorMsg());
> +
> +  // Map the section addresses so relocations will get updated in the
> local
> +  // copies of the sections.
> +  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
> +    uint64_t Addr = RemoteAddr + Offsets[i].second;
> +    EE->mapSectionAddress(const_cast<void*>(Offsets[i].first->MB.base()),
> Addr);
> +
> +    DEBUG(dbgs() << "  Mapping local: " << Offsets[i].first->MB.base()
> +                 << " to remote: 0x" << format("%llx", Addr) << "\n");
> +
> +    MappedSections[Addr] = Offsets[i].first;
> +  }
> +
> +  UnmappedSections.clear();
> +}
> +
> +bool RemoteMemoryManager::finalizeMemory(std::string *ErrMsg) {
> +  // FIXME: Make this function thread safe.
> +  for (DenseMap<uint64_t, const Allocation*>::iterator
> +         I = MappedSections.begin(), E = MappedSections.end();
> +       I != E; ++I) {
> +    uint64_t RemoteAddr = I->first;
> +    const Allocation *Section = I->second;
> +    if (Section->IsCode) {
> +      Target->loadCode(RemoteAddr, Section->MB.base(),
> Section->MB.size());
> +
> +      DEBUG(dbgs() << "  loading code: " << Section->MB.base()
> +            << " to remote: 0x" << format("%llx", RemoteAddr) << "\n");
> +    } else {
> +      Target->loadData(RemoteAddr, Section->MB.base(),
> Section->MB.size());
> +
> +      DEBUG(dbgs() << "  loading data: " << Section->MB.base()
> +            << " to remote: 0x" << format("%llx", RemoteAddr) << "\n");
> +    }
> +  }
> +
> +  MappedSections.clear();
> +
> +  return false;
> +}
> +
> +void RemoteMemoryManager::setMemoryWritable() {
> llvm_unreachable("Unexpected!"); }
> +void RemoteMemoryManager::setMemoryExecutable() {
> llvm_unreachable("Unexpected!"); }
> +void RemoteMemoryManager::setPoisonMemory(bool poison) {
> llvm_unreachable("Unexpected!"); }
> +void RemoteMemoryManager::AllocateGOT() {
> llvm_unreachable("Unexpected!"); }
> +uint8_t *RemoteMemoryManager::getGOTBase() const {
>    llvm_unreachable("Unexpected!");
>    return 0;
>  }
> -uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F,
> uintptr_t &ActualSize){
> +uint8_t *RemoteMemoryManager::startFunctionBody(const Function *F,
> uintptr_t &ActualSize){
>    llvm_unreachable("Unexpected!");
>    return 0;
>  }
> -uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F,
> unsigned StubSize,
> +uint8_t *RemoteMemoryManager::allocateStub(const GlobalValue* F, unsigned
> StubSize,
>                                                unsigned Alignment) {
>    llvm_unreachable("Unexpected!");
>    return 0;
>  }
> -void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t
> *FunctionStart,
> +void RemoteMemoryManager::endFunctionBody(const Function *F, uint8_t
> *FunctionStart,
>                                               uint8_t *FunctionEnd) {
>    llvm_unreachable("Unexpected!");
>  }
> -uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned
> Alignment) {
> +uint8_t *RemoteMemoryManager::allocateSpace(intptr_t Size, unsigned
> Alignment) {
>    llvm_unreachable("Unexpected!");
>    return 0;
>  }
> -uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned
> Alignment) {
> +uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned
> Alignment) {
>    llvm_unreachable("Unexpected!");
>    return 0;
>  }
> -void RecordingMemoryManager::deallocateFunctionBody(void *Body) {
> +void RemoteMemoryManager::deallocateFunctionBody(void *Body) {
>    llvm_unreachable("Unexpected!");
>  }
>
> @@ -105,7 +209,7 @@ static int jit_noop() {
>    return 0;
>  }
>
> -void *RecordingMemoryManager::getPointerToNamedFunction(const std::string
> &Name,
> +void *RemoteMemoryManager::getPointerToNamedFunction(const std::string
> &Name,
>                                                          bool
> AbortOnFailure) {
>    // We should not invoke parent's ctors/dtors from generated main()!
>    // On Mingw and Cygwin, the symbol __main is resolved to
>
> Copied: llvm/trunk/tools/lli/RemoteMemoryManager.h (from r191860,
> llvm/trunk/tools/lli/RecordingMemoryManager.h)
> URL:
> 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
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RecordingMemoryManager.h (original)
> +++ llvm/trunk/tools/lli/RemoteMemoryManager.h Thu Oct  3 19:49:38 2013
> @@ -1,4 +1,4 @@
> -//===- RecordingMemoryManager.h - LLI MCJIT recording memory manager
> ------===//
> +//===- RemoteMemoryManager.h - LLI MCJIT recording memory manager
> ------===//
>  //
>  //                     The LLVM Compiler Infrastructure
>  //
> @@ -12,24 +12,47 @@
>  //
>
>  //===----------------------------------------------------------------------===//
>
> -#ifndef RECORDINGMEMORYMANAGER_H
> -#define RECORDINGMEMORYMANAGER_H
> +#ifndef REMOTEMEMORYMANAGER_H
> +#define REMOTEMEMORYMANAGER_H
>
> +#include "llvm/ADT/DenseMap.h"
>  #include "llvm/ADT/SmallVector.h"
>  #include "llvm/ExecutionEngine/JITMemoryManager.h"
>  #include "llvm/Support/ErrorHandling.h"
>  #include "llvm/Support/Memory.h"
>  #include <utility>
>
> +#include "RemoteTarget.h"
> +
>  namespace llvm {
>
> -class RecordingMemoryManager : public JITMemoryManager {
> +class RemoteMemoryManager : public JITMemoryManager {
>  public:
> -  typedef std::pair<sys::MemoryBlock, unsigned> Allocation;
> +  // Notice that this structure takes ownership of the memory allocated.
> +  struct Allocation {
> +    Allocation(sys::MemoryBlock mb, unsigned a, bool code)
> +      : MB(mb), Alignment(a), IsCode(code) {}
> +
> +    sys::MemoryBlock  MB;
> +    unsigned          Alignment;
> +    bool              IsCode;
> +  };
>
>  private:
> -  SmallVector<Allocation, 16> AllocatedDataMem;
> -  SmallVector<Allocation, 16> AllocatedCodeMem;
> +  // This vector contains Allocation objects for all sections which we
> have
> +  // allocated.  This vector effectively owns the memory associated with
> the
> +  // allocations.
> +  SmallVector<Allocation, 2>  AllocatedSections;
> +
> +  // This vector contains pointers to Allocation objects for any sections
> we
> +  // have allocated locally but have not yet remapped for the remote
> target.
> +  // When we receive notification of a completed module load, we will map
> +  // these sections into the remote target.
> +  SmallVector<const Allocation *, 2>  UnmappedSections;
> +
> +  // This map tracks the sections we have remapped for the remote target
> +  // but have not yet copied to the target.
> +  DenseMap<uint64_t, const Allocation *>  MappedSections;
>
>    // FIXME: This is part of a work around to keep sections near one
> another
>    // when MCJIT performs relocations after code emission but before
> @@ -37,17 +60,11 @@ private:
>    sys::MemoryBlock Near;
>    sys::MemoryBlock allocateSection(uintptr_t Size);
>
> -public:
> -  RecordingMemoryManager() {}
> -  virtual ~RecordingMemoryManager();
> -
> -  typedef SmallVectorImpl<Allocation>::const_iterator const_data_iterator;
> -  typedef SmallVectorImpl<Allocation>::const_iterator const_code_iterator;
> +  RemoteTarget *Target;
>
> -  const_data_iterator data_begin() const { return
> AllocatedDataMem.begin(); }
> -  const_data_iterator   data_end() const { return AllocatedDataMem.end();
> }
> -  const_code_iterator code_begin() const { return
> AllocatedCodeMem.begin(); }
> -  const_code_iterator   code_end() const { return AllocatedCodeMem.end();
> }
> +public:
> +  RemoteMemoryManager() : Target(NULL) {}
> +  virtual ~RemoteMemoryManager();
>
>    uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
>                                 unsigned SectionID, StringRef SectionName);
> @@ -59,7 +76,12 @@ public:
>    void *getPointerToNamedFunction(const std::string &Name,
>                                    bool AbortOnFailure = true);
>
> -  bool finalizeMemory(std::string *ErrMsg) { return false; }
> +  void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj);
> +
> +  bool finalizeMemory(std::string *ErrMsg);
> +
> +  // This is a non-interface function used by lli
> +  void setRemoteTarget(RemoteTarget *T) { Target = T; }
>
>    // The following obsolete JITMemoryManager calls are stubbed out for
>    // this model.
>
> Modified: llvm/trunk/tools/lli/lli.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=191938&r1=191937&r2=191938&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/lli.cpp (original)
> +++ llvm/trunk/tools/lli/lli.cpp Thu Oct  3 19:49:38 2013
> @@ -15,7 +15,7 @@
>
>  #define DEBUG_TYPE "lli"
>  #include "llvm/IR/LLVMContext.h"
> -#include "RecordingMemoryManager.h"
> +#include "RemoteMemoryManager.h"
>  #include "RemoteTarget.h"
>  #include "llvm/ADT/Triple.h"
>  #include "llvm/Bitcode/ReaderWriter.h"
> @@ -131,6 +131,12 @@ namespace {
>              cl::value_desc("function"),
>              cl::init("main"));
>
> +  cl::list<std::string>
> +  ExtraModules("extra-modules",
> +         cl::CommaSeparated,
> +         cl::desc("Extra modules to be loaded"),
> +         cl::value_desc("<input bitcode 2>,<input bitcode 3>,..."));
> +
>    cl::opt<std::string>
>    FakeArgv0("fake-argv0",
>              cl::desc("Override the 'argv[0]' value passed into the
> executing"
> @@ -222,82 +228,6 @@ static void do_shutdown() {
>  #endif
>  }
>
> -void layoutRemoteTargetMemory(RemoteTarget *T, RecordingMemoryManager
> *JMM) {
> -  // Lay out our sections in order, with all the code sections first, then
> -  // all the data sections.
> -  uint64_t CurOffset = 0;
> -  unsigned MaxAlign = T->getPageAlignment();
> -  SmallVector<std::pair<const void*, uint64_t>, 16> Offsets;
> -  SmallVector<unsigned, 16> Sizes;
> -  for (RecordingMemoryManager::const_code_iterator I = JMM->code_begin(),
> -                                                   E = JMM->code_end();
> -       I != E; ++I) {
> -    DEBUG(dbgs() << "code region: size " << I->first.size()
> -                 << ", alignment " << I->second << "\n");
> -    // Align the current offset up to whatever is needed for the next
> -    // section.
> -    unsigned Align = I->second;
> -    CurOffset = (CurOffset + Align - 1) / Align * Align;
> -    // Save off the address of the new section and allocate its space.
> -    Offsets.push_back(std::pair<const void*,uint64_t>(I->first.base(),
> CurOffset));
> -    Sizes.push_back(I->first.size());
> -    CurOffset += I->first.size();
> -  }
> -  // Adjust to keep code and data aligned on seperate pages.
> -  CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign;
> -  unsigned FirstDataIndex = Offsets.size();
> -  for (RecordingMemoryManager::const_data_iterator I = JMM->data_begin(),
> -                                                   E = JMM->data_end();
> -       I != E; ++I) {
> -    DEBUG(dbgs() << "data region: size " << I->first.size()
> -                 << ", alignment " << I->second << "\n");
> -    // Align the current offset up to whatever is needed for the next
> -    // section.
> -    unsigned Align = I->second;
> -    CurOffset = (CurOffset + Align - 1) / Align * Align;
> -    // Save off the address of the new section and allocate its space.
> -    Offsets.push_back(std::pair<const void*,uint64_t>(I->first.base(),
> CurOffset));
> -    Sizes.push_back(I->first.size());
> -    CurOffset += I->first.size();
> -  }
> -
> -  // Allocate space in the remote target.
> -  uint64_t RemoteAddr;
> -  if (T->allocateSpace(CurOffset, MaxAlign, RemoteAddr))
> -    report_fatal_error(T->getErrorMsg());
> -  // Map the section addresses so relocations will get updated in the
> local
> -  // copies of the sections.
> -  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
> -    uint64_t Addr = RemoteAddr + Offsets[i].second;
> -    EE->mapSectionAddress(const_cast<void*>(Offsets[i].first), Addr);
> -
> -    DEBUG(dbgs() << "  Mapping local: " << Offsets[i].first
> -                 << " to remote: 0x" << format("%llx", Addr) << "\n");
> -
> -  }
> -
> -  // Trigger application of relocations
> -  EE->finalizeObject();
> -
> -  // Now load it all to the target.
> -  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
> -    uint64_t Addr = RemoteAddr + Offsets[i].second;
> -
> -    if (i < FirstDataIndex) {
> -      T->loadCode(Addr, Offsets[i].first, Sizes[i]);
> -
> -      DEBUG(dbgs() << "  loading code: " << Offsets[i].first
> -            << " to remote: 0x" << format("%llx", Addr) << "\n");
> -    } else {
> -      T->loadData(Addr, Offsets[i].first, Sizes[i]);
> -
> -      DEBUG(dbgs() << "  loading data: " << Offsets[i].first
> -            << " to remote: 0x" << format("%llx", Addr) << "\n");
> -    }
> -
> -  }
> -}
> -
>
>  //===----------------------------------------------------------------------===//
>  // main Driver function
>  //
> @@ -370,7 +300,7 @@ int main(int argc, char **argv, char * c
>    if (UseMCJIT && !ForceInterpreter) {
>      builder.setUseMCJIT(true);
>      if (RemoteMCJIT)
> -      RTDyldMM = new RecordingMemoryManager();
> +      RTDyldMM = new RemoteMemoryManager();
>      else
>        RTDyldMM = new SectionMemoryManager();
>      builder.setMCJITMemoryManager(RTDyldMM);
> @@ -420,6 +350,16 @@ int main(int argc, char **argv, char * c
>      exit(1);
>    }
>
> +  // Load any additional modules specified on the command line.
> +  for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) {
> +    Module *XMod = ParseIRFile(ExtraModules[i], Err, Context);
> +    if (!XMod) {
> +      Err.print(argv[0], errs());
> +      return 1;
> +    }
> +    EE->addModule(XMod);
> +  }
> +
>    // The following functions have no effect if their respective profiling
>    // support wasn't enabled in the build configuration.
>    EE->RegisterJITEventListener(
> @@ -519,7 +459,7 @@ int main(int argc, char **argv, char * c
>      // it couldn't. This is a limitation of the LLI implemantation, not
> the
>      // MCJIT itself. FIXME.
>      //
> -    RecordingMemoryManager *MM =
> static_cast<RecordingMemoryManager*>(RTDyldMM);
> +    RemoteMemoryManager *MM = static_cast<RemoteMemoryManager*>(RTDyldMM);
>      // Everything is prepared now, so lay out our program for the target
>      // address space, assign the section addresses to resolve any
> relocations,
>      // and send it to the target.
> @@ -543,19 +483,30 @@ int main(int argc, char **argv, char * c
>        Target.reset(RemoteTarget::createRemoteTarget());
>      }
>
> -    // Create the remote target
> +    // Give the memory manager a pointer to our remote target interface
> object.
> +    MM->setRemoteTarget(Target.get());
> +
> +    // Create the remote target.
>      Target->create();
>
> +// FIXME: Don't commit like this.  I don't think these calls are
> necessary.
>

!!!


> +#if 0
>      // Trigger compilation.
>      EE->generateCodeForModule(Mod);
>
> -    // Layout the target memory.
> -    layoutRemoteTargetMemory(Target.get(), MM);
> +    // Get everything ready to execute.
> +    EE->finalizeModule(Mod);
> +#endif
>
>      // Since we're executing in a (at least simulated) remote address
> space,
>      // we can't use the ExecutionEngine::runFunctionAsMain(). We have to
>      // grab the function address directly here and tell the remote target
>      // to execute the function.
> +    //
> +    // Our memory manager will map generated code into the remote address
> +    // space as it is loaded and copy the bits over during the
> finalizeMemory
> +    // operation.
> +    //
>      // FIXME: argv and envp handling.
>      uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str());
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131004/176105d1/attachment.html>


More information about the llvm-commits mailing list