X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FExecutionEngine%2FRuntimeDyld%2FRuntimeDyldImpl.h;h=f37a9a768a2e5de8d71c23c8bf003ed1343393ac;hp=0211d2bbbb0520b9e2c96a56110b7607923e23e9;hb=f2a51a78f59cff657805a3b0c6dc3efd78c67bf2;hpb=68b292b026dbf397e869eb7c430a9e36ba4c7bc5 diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index 0211d2bbbb0..f37a9a768a2 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -11,14 +11,13 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_RUNTIME_DYLD_IMPL_H -#define LLVM_RUNTIME_DYLD_IMPL_H +#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDIMPL_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/Triple.h" -#include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" #include "llvm/ExecutionEngine/RuntimeDyldChecker.h" #include "llvm/Object/ObjectFile.h" @@ -37,7 +36,6 @@ using namespace llvm::object; namespace llvm { -class ObjectBuffer; class Twine; /// SectionEntry - represents a section emitted into memory by the dynamic @@ -70,7 +68,7 @@ public: SectionEntry(StringRef name, uint8_t *address, size_t size, uintptr_t objAddress) : Name(name), Address(address), Size(size), - LoadAddress((uintptr_t)address), StubOffset(size), + LoadAddress(reinterpret_cast(address)), StubOffset(size), ObjAddress(objAddress) {} }; @@ -158,20 +156,38 @@ public: } }; -class RuntimeDyldImpl { - friend class RuntimeDyldChecker; +/// @brief Symbol info for RuntimeDyld. +class SymbolInfo { +public: + typedef enum { Hidden = 0, Default = 1 } Visibility; + + SymbolInfo() : Offset(0), SectionID(0), Vis(Hidden) {} + + SymbolInfo(unsigned SectionID, uint64_t Offset, Visibility Vis) + : Offset(Offset), SectionID(SectionID), Vis(Vis) {} + + unsigned getSectionID() const { return SectionID; } + uint64_t getOffset() const { return Offset; } + Visibility getVisibility() const { return Vis; } + private: + uint64_t Offset; + unsigned SectionID : 31; + Visibility Vis : 1; +}; - uint64_t getAnySymbolRemoteAddress(StringRef Symbol) { - if (uint64_t InternalSymbolAddr = getSymbolLoadAddress(Symbol)) - return InternalSymbolAddr; - return MemMgr->getSymbolAddress(Symbol); - } +typedef StringMap RTDyldSymbolTable; +class RuntimeDyldImpl { + friend class RuntimeDyld::LoadedObjectInfo; + friend class RuntimeDyldCheckerImpl; protected: // The MemoryManager to load objects into. RTDyldMemoryManager *MemMgr; + // Attached RuntimeDyldChecker instance. Null if no instance attached. + RuntimeDyldCheckerImpl *Checker; + // A list of all sections emitted by the dynamic linker. These sections are // referenced in the code by means of their index in this list - SectionID. typedef SmallVector SectionList; @@ -184,16 +200,11 @@ protected: // references it. typedef std::map ObjSectionToIDMap; - // A global symbol table for symbols from all loaded modules. Maps the - // symbol name to a (SectionID, offset in section) pair. - typedef std::pair SymbolLoc; - typedef StringMap SymbolTableMap; - SymbolTableMap GlobalSymbolTable; + // A global symbol table for symbols from all loaded modules. + RTDyldSymbolTable GlobalSymbolTable; - // Pair representing the size and alignment requirement for a common symbol. - typedef std::pair CommonSymbolInfo; // Keep a map of common symbols to their info pairs - typedef std::map CommonSymbolMap; + typedef std::vector CommonSymbolList; // For each symbol, keep a list of relocations based on it. Anytime // its address is reassigned (the JIT re-compiled the function, e.g.), @@ -211,6 +222,7 @@ protected: // modules. This map is indexed by symbol name. StringMap ExternalSymbolRelocations; + typedef std::map StubMap; Triple::ArchType Arch; @@ -245,11 +257,11 @@ protected: return true; } - uint64_t getSectionLoadAddress(unsigned SectionID) { + uint64_t getSectionLoadAddress(unsigned SectionID) const { return Sections[SectionID].LoadAddress; } - uint8_t *getSectionAddress(unsigned SectionID) { + uint8_t *getSectionAddress(unsigned SectionID) const { return (uint8_t *)Sections[SectionID].Address; } @@ -282,17 +294,23 @@ protected: *(Addr + 7) = Value & 0xFF; } + /// Endian-aware read Read the least significant Size bytes from Src. + uint64_t readBytesUnaligned(uint8_t *Src, unsigned Size) const; + + /// Endian-aware write. Write the least significant Size bytes from Value to + /// Dst. + void writeBytesUnaligned(uint64_t Value, uint8_t *Dst, unsigned Size) const; + /// \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. - void emitCommonSymbols(ObjectImage &Obj, const CommonSymbolMap &CommonSymbols, - uint64_t TotalSize, SymbolTableMap &SymbolTable); + void emitCommonSymbols(const ObjectFile &Obj, CommonSymbolList &CommonSymbols); /// \brief Emits section data from the object file to the MemoryManager. /// \param IsCode if it's true then allocateCodeSection() will be /// used for emits, else allocateDataSection() will be used. /// \return SectionID. - unsigned emitSection(ObjectImage &Obj, const SectionRef &Section, + unsigned emitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode); /// \brief Find Section in LocalSections. If the secton is not found - emit @@ -300,7 +318,7 @@ protected: /// \param IsCode if it's true then allocateCodeSection() will be /// used for emmits, else allocateDataSection() will be used. /// \return SectionID. - unsigned findOrEmitSection(ObjectImage &Obj, const SectionRef &Section, + unsigned findOrEmitSection(const ObjectFile &Obj, const SectionRef &Section, bool IsCode, ObjSectionToIDMap &LocalSections); // \brief Add a relocation entry that uses the given section. @@ -328,8 +346,8 @@ protected: /// \return Iterator to the next relocation that needs to be parsed. virtual relocation_iterator processRelocationRef(unsigned SectionID, relocation_iterator RelI, - ObjectImage &Obj, ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, StubMap &Stubs) = 0; + const ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, + StubMap &Stubs) = 0; /// \brief Resolve relocations to external symbols. void resolveExternalSymbols(); @@ -340,16 +358,19 @@ protected: // \brief Compute an upper bound of the memory that is required to load all // sections - void computeTotalAllocSize(ObjectImage &Obj, uint64_t &CodeSize, + void computeTotalAllocSize(const ObjectFile &Obj, uint64_t &CodeSize, uint64_t &DataSizeRO, uint64_t &DataSizeRW); // \brief Compute the stub buffer size required for a section - unsigned computeSectionStubBufSize(ObjectImage &Obj, + unsigned computeSectionStubBufSize(const ObjectFile &Obj, const SectionRef &Section); + // \brief Implementation of the generic part of the loadObject algorithm. + std::pair loadObjectImpl(const object::ObjectFile &Obj); + public: RuntimeDyldImpl(RTDyldMemoryManager *mm) - : MemMgr(mm), ProcessAllSections(false), HasError(false) { + : MemMgr(mm), Checker(nullptr), ProcessAllSections(false), HasError(false) { } virtual ~RuntimeDyldImpl(); @@ -358,26 +379,41 @@ public: this->ProcessAllSections = ProcessAllSections; } - ObjectImage *loadObject(ObjectImage *InputObject); + void setRuntimeDyldChecker(RuntimeDyldCheckerImpl *Checker) { + this->Checker = Checker; + } + + virtual std::unique_ptr + loadObject(const object::ObjectFile &Obj) = 0; - uint8_t* getSymbolAddress(StringRef Name) { + uint8_t* getSymbolAddress(StringRef Name) const { // FIXME: Just look up as a function for now. Overly simple of course. // Work in progress. - SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name); + RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); if (pos == GlobalSymbolTable.end()) return nullptr; - SymbolLoc Loc = pos->second; - return getSectionAddress(Loc.first) + Loc.second; + const auto &SymInfo = pos->second; + return getSectionAddress(SymInfo.getSectionID()) + SymInfo.getOffset(); } - uint64_t getSymbolLoadAddress(StringRef Name) { + uint64_t getSymbolLoadAddress(StringRef Name) const { // FIXME: Just look up as a function for now. Overly simple of course. // Work in progress. - SymbolTableMap::const_iterator pos = GlobalSymbolTable.find(Name); + RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); if (pos == GlobalSymbolTable.end()) return 0; - SymbolLoc Loc = pos->second; - return getSectionLoadAddress(Loc.first) + Loc.second; + const auto &SymInfo = pos->second; + return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset(); + } + + uint64_t getExportedSymbolLoadAddress(StringRef Name) const { + RTDyldSymbolTable::const_iterator pos = GlobalSymbolTable.find(Name); + if (pos == GlobalSymbolTable.end()) + return 0; + const auto &SymInfo = pos->second; + if (SymInfo.getVisibility() == SymbolInfo::Hidden) + return 0; + return getSectionLoadAddress(SymInfo.getSectionID()) + SymInfo.getOffset(); } void resolveRelocations(); @@ -395,14 +431,14 @@ public: // Get the error message. StringRef getErrorString() { return ErrorStr; } - virtual bool isCompatibleFormat(const ObjectBuffer *Buffer) const = 0; - virtual bool isCompatibleFile(const ObjectFile *Obj) const = 0; + virtual bool isCompatibleFile(const ObjectFile &Obj) const = 0; virtual void registerEHFrames(); virtual void deregisterEHFrames(); - virtual void finalizeLoad(ObjectImage &ObjImg, ObjSectionToIDMap &SectionMap) {} + virtual void finalizeLoad(const ObjectFile &ObjImg, + ObjSectionToIDMap &SectionMap) {} }; } // end namespace llvm