X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FExecutionEngine%2FRuntimeDyld%2FRuntimeDyldImpl.h;h=cf7dbb2abe197ce36caddeb9d6376672b402cf27;hp=c153ee1671ce045411072efbf6f9c1957e062540;hb=51bd393f52d833d7c3542417f849217c125a539d;hpb=56db3a97cdc241baf425fa6ebc64383a4902517e diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h index c153ee1671c..cf7dbb2abe1 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldImpl.h @@ -11,15 +11,15 @@ // //===----------------------------------------------------------------------===// -#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" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -28,15 +28,14 @@ #include "llvm/Support/Mutex.h" #include "llvm/Support/SwapByteOrder.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" #include +#include using namespace llvm; using namespace llvm::object; namespace llvm { -class ObjectBuffer; class Twine; /// SectionEntry - represents a section emitted into memory by the dynamic @@ -69,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) {} }; @@ -90,9 +89,17 @@ public: /// used to make a relocation section relative instead of symbol relative. int64_t Addend; + struct SectionPair { + uint32_t SectionA; + uint32_t SectionB; + }; + /// SymOffset - Section offset of the relocation entry's symbol (used for GOT /// lookup). - uint64_t SymOffset; + union { + uint64_t SymOffset; + SectionPair Sections; + }; /// True if this is a PCRel relocation (MachO specific). bool IsPCRel; @@ -113,6 +120,16 @@ public: bool IsPCRel, unsigned Size) : SectionID(id), Offset(offset), RelType(type), Addend(addend), SymOffset(0), IsPCRel(IsPCRel), Size(Size) {} + + RelocationEntry(unsigned id, uint64_t offset, uint32_t type, int64_t addend, + unsigned SectionA, uint64_t SectionAOffset, unsigned SectionB, + uint64_t SectionBOffset, bool IsPCRel, unsigned Size) + : SectionID(id), Offset(offset), RelType(type), + Addend(SectionAOffset - SectionBOffset + addend), IsPCRel(IsPCRel), + Size(Size) { + Sections.SectionA = SectionA; + Sections.SectionB = SectionB; + } }; class RelocationValueRef { @@ -121,7 +138,8 @@ public: uint64_t Offset; int64_t Addend; const char *SymbolName; - RelocationValueRef() : SectionID(0), Offset(0), Addend(0), SymbolName(0) {} + RelocationValueRef() : SectionID(0), Offset(0), Addend(0), + SymbolName(nullptr) {} inline bool operator==(const RelocationValueRef &Other) const { return SectionID == Other.SectionID && Offset == Other.Offset && @@ -139,10 +157,15 @@ public: }; 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; @@ -182,6 +205,7 @@ protected: // modules. This map is indexed by symbol name. StringMap ExternalSymbolRelocations; + typedef std::map StubMap; Triple::ArchType Arch; @@ -216,24 +240,24 @@ 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; } void writeInt16BE(uint8_t *Addr, uint16_t Value) { if (IsTargetLittleEndian) - Value = sys::SwapByteOrder(Value); + sys::swapByteOrder(Value); *Addr = (Value >> 8) & 0xFF; *(Addr + 1) = Value & 0xFF; } void writeInt32BE(uint8_t *Addr, uint32_t Value) { if (IsTargetLittleEndian) - Value = sys::SwapByteOrder(Value); + sys::swapByteOrder(Value); *Addr = (Value >> 24) & 0xFF; *(Addr + 1) = (Value >> 16) & 0xFF; *(Addr + 2) = (Value >> 8) & 0xFF; @@ -242,7 +266,7 @@ protected: void writeInt64BE(uint8_t *Addr, uint64_t Value) { if (IsTargetLittleEndian) - Value = sys::SwapByteOrder(Value); + sys::swapByteOrder(Value); *Addr = (Value >> 56) & 0xFF; *(Addr + 1) = (Value >> 48) & 0xFF; *(Addr + 2) = (Value >> 40) & 0xFF; @@ -253,17 +277,25 @@ 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, + void emitCommonSymbols(const ObjectFile &Obj, + const CommonSymbolMap &CommonSymbols, uint64_t TotalSize, SymbolTableMap &SymbolTable); /// \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 @@ -271,7 +303,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. @@ -283,7 +315,7 @@ protected: /// \brief Emits long jump instruction to Addr. /// \return Pointer to the memory area for emitting target address. - uint8_t *createStubFunction(uint8_t *Addr); + uint8_t *createStubFunction(uint8_t *Addr, unsigned AbiVariant = 0); /// \brief Resolves relocations from Relocs list with address from Value. void resolveRelocationList(const RelocationList &Relocs, uint64_t Value); @@ -299,7 +331,7 @@ 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 ObjectFile &Obj, ObjSectionToIDMap &ObjSectionToID, const SymbolTableMap &Symbols, StubMap &Stubs) = 0; /// \brief Resolve relocations to external symbols. @@ -311,16 +343,20 @@ 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(); @@ -328,19 +364,24 @@ 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; - void *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); if (pos == GlobalSymbolTable.end()) - return 0; + return nullptr; SymbolLoc Loc = pos->second; return getSectionAddress(Loc.first) + Loc.second; } - 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); @@ -365,14 +406,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(ObjSectionToIDMap &SectionMap) {} + virtual void finalizeLoad(const ObjectFile &ObjImg, + ObjSectionToIDMap &SectionMap) {} }; } // end namespace llvm