X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FExecutionEngine%2FRuntimeDyld%2FRuntimeDyldELF.h;h=b4414b08c4806a53805ca4e614803904c1d8519d;hb=973e54ac96b4bfd71bf9999c46f3e267c819bcc0;hp=e0f7d54f43174e20c3da88eff9e24755a6391f50;hpb=3e29671cca14f8fce1ea6b602175880cb3df7199;p=oota-llvm.git diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h index e0f7d54f431..b4414b08c48 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.h @@ -11,168 +11,122 @@ // //===----------------------------------------------------------------------===// -#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 { -class RuntimeDyldELF : public RuntimeDyldImpl { - // For each symbol, keep a list of relocations based on it. Anytime - // its address is reassigned (the JIT re-compiled the function, e.g.), - // the relocations get re-resolved. - struct RelocationEntry { - // Function or section this relocation is contained in. - std::string Target; - // Offset into the target function or section for the relocation. - uint32_t Offset; - // Relocation type - uint32_t Type; - // Addend encoded in the instruction itself, if any. - int32_t Addend; - // Has the relocation been recalcuated as an offset within a function? - bool IsFunctionRelative; - // Has this relocation been resolved previously? - bool isResolved; - - RelocationEntry(StringRef t, - uint32_t offset, - uint32_t type, - int32_t addend, - bool isFunctionRelative) - : Target(t) - , Offset(offset) - , Type(type) - , Addend(addend) - , IsFunctionRelative(isFunctionRelative) - , isResolved(false) { } - }; - typedef SmallVector RelocationList; - StringMap Relocations; - unsigned Arch; - - void resolveRelocations(); - - void resolveX86_64Relocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - - void resolveX86Relocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - - void resolveArmRelocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - - void resolveRelocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - -public: - RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} - - bool loadObject(MemoryBuffer *InputBuffer); - - void reassignSymbolAddress(StringRef Name, uint8_t *Addr); - void reassignSectionAddress(unsigned SectionID, uint64_t Addr); - - bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const; -}; - -} // end namespace llvm +namespace { +// 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; +} -#endif +} // end anonymous namespace -//===-- RuntimeDyldELF.h - Run-time dynamic linker for MC-JIT ---*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// ELF support for MC-JIT runtime dynamic linker. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_RUNTIME_DYLD_ELF_H -#define LLVM_RUNTIME_DYLD_ELF_H - -#include "RuntimeDyldImpl.h" - -using namespace llvm; - - -namespace llvm { class RuntimeDyldELF : public RuntimeDyldImpl { - // For each symbol, keep a list of relocations based on it. Anytime - // its address is reassigned (the JIT re-compiled the function, e.g.), - // the relocations get re-resolved. - struct RelocationEntry { - // Function or section this relocation is contained in. - std::string Target; - // Offset into the target function or section for the relocation. - uint32_t Offset; - // Relocation type - uint32_t Type; - // Addend encoded in the instruction itself, if any. - int32_t Addend; - // Has the relocation been recalcuated as an offset within a function? - bool IsFunctionRelative; - // Has this relocation been resolved previously? - bool isResolved; - - RelocationEntry(StringRef t, - uint32_t offset, - uint32_t type, - int32_t addend, - bool isFunctionRelative) - : Target(t) - , Offset(offset) - , Type(type) - , Addend(addend) - , IsFunctionRelative(isFunctionRelative) - , isResolved(false) { } - }; - typedef SmallVector RelocationList; - StringMap Relocations; - unsigned Arch; - - void resolveRelocations(); - - void resolveX86_64Relocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - - void resolveX86Relocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - - void resolveArmRelocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - - void resolveRelocation(StringRef Name, - uint8_t *Addr, - const RelocationEntry &RE); - -public: - RuntimeDyldELF(RTDyldMemoryManager *mm) : RuntimeDyldImpl(mm) {} - - bool loadObject(MemoryBuffer *InputBuffer); - void reassignSymbolAddress(StringRef Name, uint8_t *Addr); - void reassignSectionAddress(unsigned SectionID, uint64_t Addr); + 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); + + 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; - bool isCompatibleFormat(const MemoryBuffer *InputBuffer) const; +public: + RuntimeDyldELF(RTDyldMemoryManager *mm); + virtual ~RuntimeDyldELF(); + + 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 -#endif - +#endif