X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FExecutionEngine%2FRuntimeDyld%2FRuntimeDyldELF.h;h=b4414b08c4806a53805ca4e614803904c1d8519d;hb=973e54ac96b4bfd71bf9999c46f3e267c819bcc0;hp=cbdc0dbc6b734f79ba08a5481f60034451ab1c4d;hpb=f00677d74f1be5b4c7c73e1681a64c9062f4c7ee;p=oota-llvm.git diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index cbdc0dbc6b7..b4414b08c48 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -11,85 +11,120 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_RUNTIME_DYLD_ELF_H -#define LLVM_RUNTIME_DYLD_ELF_H +#ifndef LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H +#define LLVM_LIB_EXECUTIONENGINE_RUNTIMEDYLD_RUNTIMEDYLDELF_H #include "RuntimeDyldImpl.h" +#include "llvm/ADT/DenseMap.h" using namespace llvm; namespace llvm { - namespace { - // Helper for extensive error checking in debug builds. - error_code Check(error_code Err) { - if (Err) { - report_fatal_error(Err.message()); - } - return Err; +// Helper for extensive error checking in debug builds. +std::error_code Check(std::error_code Err) { + if (Err) { + report_fatal_error(Err.message()); } + return Err; +} + } // end anonymous namespace class RuntimeDyldELF : public RuntimeDyldImpl { -protected: - void resolveX86_64Relocation(uint8_t *LocalAddress, - uint64_t FinalAddress, - uint64_t Value, - uint32_t Type, - int64_t Addend); - - void resolveX86Relocation(uint8_t *LocalAddress, - uint32_t FinalAddress, - uint32_t Value, - uint32_t Type, - int32_t Addend); - - void resolveARMRelocation(uint8_t *LocalAddress, - uint32_t FinalAddress, - uint32_t Value, - uint32_t Type, - int32_t Addend); - - void resolveMIPSRelocation(uint8_t *LocalAddress, - uint32_t FinalAddress, - uint32_t Value, - uint32_t Type, - int32_t Addend); - - void resolvePPC64Relocation(uint8_t *LocalAddress, - uint64_t FinalAddress, - uint64_t Value, - uint32_t Type, - int64_t Addend); - - virtual void resolveRelocation(uint8_t *LocalAddress, - uint64_t FinalAddress, - uint64_t Value, - uint32_t Type, - int64_t Addend); - - virtual void processRelocationRef(const ObjRelocationInfo &Rel, - ObjectImage &Obj, - ObjSectionToIDMap &ObjSectionToID, - const SymbolTableMap &Symbols, - StubMap &Stubs); - - unsigned getCommonSymbolAlignment(const SymbolRef &Sym); - - virtual ObjectImage *createObjectImage(ObjectBuffer *InputBuffer); - - uint64_t findPPC64TOC() const; - void findOPDEntrySection(ObjectImage &Obj, + + void resolveRelocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend, + uint64_t SymOffset = 0); + + void resolveX86_64Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend, + uint64_t SymOffset); + + void resolveX86Relocation(const SectionEntry &Section, uint64_t Offset, + uint32_t Value, uint32_t Type, int32_t Addend); + + void resolveAArch64Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend); + + void resolveARMRelocation(const SectionEntry &Section, uint64_t Offset, + uint32_t Value, uint32_t Type, int32_t Addend); + + void resolveMIPSRelocation(const SectionEntry &Section, uint64_t Offset, + uint32_t Value, uint32_t Type, int32_t Addend); + + void resolvePPC64Relocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend); + + void resolveSystemZRelocation(const SectionEntry &Section, uint64_t Offset, + uint64_t Value, uint32_t Type, int64_t Addend); + + unsigned getMaxStubSize() override { + if (Arch == Triple::aarch64 || Arch == Triple::aarch64_be) + return 20; // movz; movk; movk; movk; br + if (Arch == Triple::arm || Arch == Triple::thumb) + return 8; // 32-bit instruction and 32-bit address + else if (Arch == Triple::mipsel || Arch == Triple::mips) + return 16; + else if (Arch == Triple::ppc64 || Arch == Triple::ppc64le) + return 44; + else if (Arch == Triple::x86_64) + return 6; // 2-byte jmp instruction + 32-bit relative address + else if (Arch == Triple::systemz) + return 16; + else + return 0; + } + + unsigned getStubAlignment() override { + if (Arch == Triple::systemz) + return 8; + else + return 1; + } + + void findPPC64TOCSection(const ObjectFile &Obj, + ObjSectionToIDMap &LocalSections, + RelocationValueRef &Rel); + void findOPDEntrySection(const ObjectFile &Obj, ObjSectionToIDMap &LocalSections, RelocationValueRef &Rel); -public: - RuntimeDyldELF(RTDyldMemoryManager *mm) - : RuntimeDyldImpl(mm) {} + uint64_t findGOTEntry(uint64_t LoadAddr, uint64_t Offset); + size_t getGOTEntrySize(); + + void updateGOTEntries(StringRef Name, uint64_t Addr) override; + // Relocation entries for symbols whose position-independent offset is + // updated in a global offset table. + typedef SmallVector GOTRelocations; + GOTRelocations GOTEntries; // List of entries requiring finalization. + SmallVector, 8> GOTs; // Allocated tables. + + // When a module is loaded we save the SectionID of the EH frame section + // in a table until we receive a request to register all unregistered + // EH frame sections with the memory manager. + SmallVector UnregisteredEHFrameSections; + SmallVector RegisteredEHFrameSections; + +public: + RuntimeDyldELF(RTDyldMemoryManager *mm); virtual ~RuntimeDyldELF(); - bool isCompatibleFormat(const ObjectBuffer *Buffer) const; + std::unique_ptr + loadObject(const object::ObjectFile &O) override; + + void resolveRelocation(const RelocationEntry &RE, uint64_t Value) override; + relocation_iterator + processRelocationRef(unsigned SectionID, relocation_iterator RelI, + const ObjectFile &Obj, + ObjSectionToIDMap &ObjSectionToID, + StubMap &Stubs) override; + bool isCompatibleFile(const object::ObjectFile &Obj) const override; + void registerEHFrames() override; + void deregisterEHFrames() override; + void finalizeLoad(const ObjectFile &Obj, + ObjSectionToIDMap &SectionMap) override; }; } // end namespace llvm