diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h index 9f77ebeb9e6..62adb5546cc 100644 --- a/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -239,6 +239,14 @@ public: virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) = 0; + /// mapSectionAddress - map a section to its target address space value. + /// Map the address of a JIT section as returned from the memory manager + /// to the address in the target process as the running code will see it. + /// This is the address which will be used for relocation resolution. + virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) { + assert(0 && "Re-mapping of section addresses not supported with this EE!"); + } + /// runStaticConstructorsDestructors - This method is used to execute all of /// the static constructors or destructors for a program. /// diff --git a/include/llvm/ExecutionEngine/RuntimeDyld.h b/include/llvm/ExecutionEngine/RuntimeDyld.h index d937ab49f4e..8ad316bc3f9 100644 --- a/include/llvm/ExecutionEngine/RuntimeDyld.h +++ b/include/llvm/ExecutionEngine/RuntimeDyld.h @@ -64,6 +64,10 @@ class RuntimeDyld { // interface. RuntimeDyldImpl *Dyld; RTDyldMemoryManager *MM; +protected: + // Change the address associated with a section when resolving relocations. + // Any relocations already associated with the symbol will be re-resolved. + void reassignSectionAddress(unsigned SectionID, uint64_t Addr); public: RuntimeDyld(RTDyldMemoryManager*); ~RuntimeDyld(); @@ -75,9 +79,13 @@ public: void *getSymbolAddress(StringRef Name); // Resolve the relocations for all symbols we currently know about. void resolveRelocations(); - // Change the address associated with a section when resolving relocations. - // Any relocations already associated with the symbol will be re-resolved. - void reassignSectionAddress(unsigned SectionID, uint64_t Addr); + + /// mapSectionAddress - map a section to its target address space value. + /// Map the address of a JIT section as returned from the memory manager + /// to the address in the target process as the running code will see it. + /// This is the address which will be used for relocation resolution. + void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress); + StringRef getErrorString(); }; diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 51e63d96e45..7f4ae77343d 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -67,6 +67,14 @@ public: /// virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); + /// mapSectionAddress - map a section to its target address space value. + /// Map the address of a JIT section as returned from the memory manager + /// to the address in the target process as the running code will see it. + /// This is the address which will be used for relocation resolution. + virtual void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress) { + Dyld.mapSectionAddress(LocalAddress, TargetAddress); + } + /// @} /// @name (Private) Registration Interfaces /// @{ diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 18827978d9a..99524a3b002 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -54,6 +54,14 @@ void RuntimeDyldImpl::resolveRelocations() { } } +void RuntimeDyldImpl::mapSectionAddress(void *LocalAddress, + uint64_t TargetAddress) { + assert(SectionLocalMemToID.count(LocalAddress) && + "Attempting to remap address of unknown section!"); + unsigned SectionID = SectionLocalMemToID[LocalAddress]; + reassignSectionAddress(SectionID, TargetAddress); +} + //===----------------------------------------------------------------------===// // RuntimeDyld class implementation RuntimeDyld::RuntimeDyld(RTDyldMemoryManager *mm) { @@ -116,6 +124,11 @@ void RuntimeDyld::reassignSectionAddress(unsigned SectionID, Dyld->reassignSectionAddress(SectionID, Addr); } +void RuntimeDyld::mapSectionAddress(void *LocalAddress, + uint64_t TargetAddress) { + Dyld->mapSectionAddress(LocalAddress, TargetAddress); +} + StringRef RuntimeDyld::getErrorString() { return Dyld->getErrorString(); } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index bbfef768c4c..59c863679ef 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -16,6 +16,7 @@ #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/Object/MachOObject.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IndexedMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Twine.h" @@ -45,10 +46,14 @@ protected: // Indexed by SectionID. SmallVector Sections; // For each section, the address it will be considered to live at for - // relocations. The same as the pointer the above memory block for hosted + // relocations. The same as the pointer to the above memory block for hosted // JITs. Indexed by SectionID. SmallVector SectionLoadAddress; + // Keep a map of starting local address to the SectionID which references it. + // Lookup function for when we assign virtual addresses. + DenseMap SectionLocalMemToID; + // Master symbol table. As modules are loaded and external symbols are // resolved, their addresses are stored here as a SectionID/Offset pair. typedef std::pair SymbolLoc; @@ -90,6 +95,8 @@ public: virtual void reassignSectionAddress(unsigned SectionID, uint64_t Addr) = 0; + void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress); + // Is the linker in an error state? bool hasError() { return HasError; } diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp index a3b4919f68b..1cc021ade51 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldMachO.cpp @@ -172,6 +172,7 @@ loadSegment32(const MachOObject *Obj, // Remember what got allocated for this SectionID. Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); + SectionLocalMemToID[Buffer] = SectionID; // By default, the load address of a section is its memory buffer. SectionLoadAddress.push_back((uint64_t)Buffer); @@ -291,6 +292,7 @@ loadSegment64(const MachOObject *Obj, // Remember what got allocated for this SectionID. Sections.push_back(sys::MemoryBlock(Buffer, Sect->Size)); + SectionLocalMemToID[Buffer] = SectionID; // By default, the load address of a section is its memory buffer. SectionLoadAddress.push_back((uint64_t)Buffer);