diff options
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h')
-rw-r--r-- | lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h | 96 |
1 files changed, 75 insertions, 21 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index c38ca69..829fd6c 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -14,8 +14,8 @@ #ifndef LLVM_RUNTIME_DYLD_IMPL_H #define LLVM_RUNTIME_DYLD_IMPL_H -#include "ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" +#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" @@ -24,6 +24,8 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" #include <map> @@ -33,7 +35,7 @@ using namespace llvm::object; namespace llvm { -class MemoryBuffer; +class ObjectBuffer; class Twine; @@ -41,6 +43,9 @@ class Twine; /// linker. class SectionEntry { public: + /// Name - section name. + StringRef Name; + /// Address - address in the linker's memory where the section resides. uint8_t *Address; @@ -61,9 +66,9 @@ public: /// for calculating relocations in some object formats (like MachO). uintptr_t ObjAddress; - SectionEntry(uint8_t *address, size_t size, uintptr_t stubOffset, - uintptr_t objAddress) - : Address(address), Size(size), LoadAddress((uintptr_t)address), + SectionEntry(StringRef name, uint8_t *address, size_t size, + uintptr_t stubOffset, uintptr_t objAddress) + : Name(name), Address(address), Size(size), LoadAddress((uintptr_t)address), StubOffset(stubOffset), ObjAddress(objAddress) {} }; @@ -135,8 +140,10 @@ protected: typedef StringMap<SymbolLoc> SymbolTableMap; SymbolTableMap GlobalSymbolTable; - // Keep a map of common symbols to their sizes - typedef std::map<SymbolRef, unsigned> CommonSymbolMap; + // Pair representing the size and alignment requirement for a common symbol. + typedef std::pair<unsigned, unsigned> CommonSymbolInfo; + // Keep a map of common symbols to their info pairs + typedef std::map<SymbolRef, CommonSymbolInfo> CommonSymbolMap; // For each symbol, keep a list of relocations based on it. Anytime // its address is reassigned (the JIT re-compiled the function, e.g.), @@ -161,6 +168,10 @@ protected: inline unsigned getMaxStubSize() { if (Arch == Triple::arm || Arch == Triple::thumb) return 8; // 32-bit instruction and 32-bit address + else if (Arch == Triple::mipsel) + return 16; + else if (Arch == Triple::ppc64) + return 44; else return 0; } @@ -175,10 +186,50 @@ protected: return true; } + uint64_t getSectionLoadAddress(unsigned SectionID) { + return Sections[SectionID].LoadAddress; + } + uint8_t *getSectionAddress(unsigned SectionID) { return (uint8_t*)Sections[SectionID].Address; } + // Subclasses can override this method to get the alignment requirement of + // a common symbol. Returns no alignment requirement if not implemented. + virtual unsigned getCommonSymbolAlignment(const SymbolRef &Sym) { + return 0; + } + + + void writeInt16BE(uint8_t *Addr, uint16_t Value) { + if (sys::isLittleEndianHost()) + Value = sys::SwapByteOrder(Value); + *Addr = (Value >> 8) & 0xFF; + *(Addr+1) = Value & 0xFF; + } + + void writeInt32BE(uint8_t *Addr, uint32_t Value) { + if (sys::isLittleEndianHost()) + Value = sys::SwapByteOrder(Value); + *Addr = (Value >> 24) & 0xFF; + *(Addr+1) = (Value >> 16) & 0xFF; + *(Addr+2) = (Value >> 8) & 0xFF; + *(Addr+3) = Value & 0xFF; + } + + void writeInt64BE(uint8_t *Addr, uint64_t Value) { + if (sys::isLittleEndianHost()) + Value = sys::SwapByteOrder(Value); + *Addr = (Value >> 56) & 0xFF; + *(Addr+1) = (Value >> 48) & 0xFF; + *(Addr+2) = (Value >> 40) & 0xFF; + *(Addr+3) = (Value >> 32) & 0xFF; + *(Addr+4) = (Value >> 24) & 0xFF; + *(Addr+5) = (Value >> 16) & 0xFF; + *(Addr+6) = (Value >> 8) & 0xFF; + *(Addr+7) = Value & 0xFF; + } + /// \brief Given the common symbols discovered in the object file, emit a /// new section for them and update the symbol mappings in the object and /// symbol table. @@ -221,13 +272,14 @@ protected: void resolveRelocationEntry(const RelocationEntry &RE, uint64_t Value); /// \brief A object file specific relocation resolver - /// \param Address Address to apply the relocation action + /// \param Section The section where the relocation is being applied + /// \param Offset The offset into the section for this relocation /// \param Value Target symbol address to apply the relocation action /// \param Type object file specific relocation type /// \param Addend A constant addend used to compute the value to be stored /// into the relocatable field - virtual void resolveRelocation(uint8_t *LocalAddress, - uint64_t FinalAddress, + virtual void resolveRelocation(const SectionEntry &Section, + uint64_t Offset, uint64_t Value, uint32_t Type, int64_t Addend) = 0; @@ -242,19 +294,13 @@ protected: /// \brief Resolve relocations to external symbols. void resolveExternalSymbols(); - virtual ObjectImage *createObjectImage(const MemoryBuffer *InputBuffer); - virtual void handleObjectLoaded(ObjectImage *Obj) - { - // Subclasses may choose to retain this image if they have a use for it - delete Obj; - } - + virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); public: RuntimeDyldImpl(RTDyldMemoryManager *mm) : MemMgr(mm), HasError(false) {} virtual ~RuntimeDyldImpl(); - bool loadObject(const MemoryBuffer *InputBuffer); + ObjectImage *loadObject(ObjectBuffer *InputBuffer); void *getSymbolAddress(StringRef Name) { // FIXME: Just look up as a function for now. Overly simple of course. @@ -265,11 +311,20 @@ public: return getSectionAddress(Loc.first) + Loc.second; } + uint64_t getSymbolLoadAddress(StringRef Name) { + // FIXME: Just look up as a function for now. Overly simple of course. + // Work in progress. + if (GlobalSymbolTable.find(Name) == GlobalSymbolTable.end()) + return 0; + SymbolLoc Loc = GlobalSymbolTable.lookup(Name); + return getSectionLoadAddress(Loc.first) + Loc.second; + } + void resolveRelocations(); void reassignSectionAddress(unsigned SectionID, uint64_t Addr); - void mapSectionAddress(void *LocalAddress, uint64_t TargetAddress); + void mapSectionAddress(const void *LocalAddress, uint64_t TargetAddress); // Is the linker in an error state? bool hasError() { return HasError; } @@ -280,8 +335,7 @@ public: // Get the error message. StringRef getErrorString() { return ErrorStr; } - virtual bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const = 0; - + virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0; }; } // end namespace llvm |