diff options
-rw-r--r-- | llvm/include/llvm/Object/ELFObjectFile.h | 46 | ||||
-rw-r--r-- | llvm/include/llvm/Object/RelocVisitor.h | 4 | ||||
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp | 3 |
4 files changed, 42 insertions, 23 deletions
diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 39c504848e7..b21a1a1c99c 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -37,10 +37,12 @@ namespace object { class elf_symbol_iterator; class ELFSymbolRef; +class ELFRelocationRef; class ELFObjectFileBase : public ObjectFile { friend class ELFSymbolRef; friend class ELFSectionRef; + friend class ELFRelocationRef; protected: ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); @@ -52,12 +54,8 @@ protected: virtual uint32_t getSectionType(DataRefImpl Sec) const = 0; virtual uint64_t getSectionFlags(DataRefImpl Sec) const = 0; -public: virtual ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const = 0; - - // FIXME: This is a bit of a hack. Every caller should know if it expecting - // and addend or not. - virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0; +public: typedef iterator_range<elf_symbol_iterator> elf_symbol_iterator_range; virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0; @@ -139,6 +137,38 @@ public: } }; +class ELFRelocationRef : public RelocationRef { +public: + ELFRelocationRef(const RelocationRef &B) : RelocationRef(B) { + assert(isa<ELFObjectFileBase>(RelocationRef::getObject())); + } + + const ELFObjectFileBase *getObject() const { + return cast<ELFObjectFileBase>(RelocationRef::getObject()); + } + + ErrorOr<int64_t> getAddend() const { + return getObject()->getRelocationAddend(getRawDataRefImpl()); + } +}; + +class elf_relocation_iterator : public relocation_iterator { +public: + elf_relocation_iterator(const relocation_iterator &B) + : relocation_iterator(RelocationRef( + B->getRawDataRefImpl(), cast<ELFObjectFileBase>(B->getObject()))) {} + + const ELFRelocationRef *operator->() const { + return static_cast<const ELFRelocationRef *>( + relocation_iterator::operator->()); + } + + const ELFRelocationRef &operator*() const { + return static_cast<const ELFRelocationRef &>( + relocation_iterator::operator*()); + } +}; + inline ELFObjectFileBase::elf_symbol_iterator_range ELFObjectFileBase::symbols() const { return elf_symbol_iterator_range(symbol_begin(), symbol_end()); @@ -295,7 +325,6 @@ public: section_iterator section_end() const override; ErrorOr<int64_t> getRelocationAddend(DataRefImpl Rel) const override; - bool hasRelocationAddend(DataRefImpl Rel) const override; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; @@ -734,11 +763,6 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel) const { } template <class ELFT> -bool ELFObjectFile<ELFT>::hasRelocationAddend(DataRefImpl Rel) const { - return getRelSection(Rel)->sh_type == ELF::SHT_RELA; -} - -template <class ELFT> const typename ELFFile<ELFT>::Elf_Sym * ELFObjectFile<ELFT>::getSymbol(DataRefImpl Symb) const { return &*toELFSymIter(Symb); diff --git a/llvm/include/llvm/Object/RelocVisitor.h b/llvm/include/llvm/Object/RelocVisitor.h index 4dca6a29593..950e2ed0e33 100644 --- a/llvm/include/llvm/Object/RelocVisitor.h +++ b/llvm/include/llvm/Object/RelocVisitor.h @@ -240,9 +240,7 @@ private: } int64_t getELFAddend(RelocationRef R) { - const auto *Obj = cast<ELFObjectFileBase>(R.getObject()); - DataRefImpl DRI = R.getRawDataRefImpl(); - ErrorOr<int64_t> AddendOrErr = Obj->getRelocationAddend(DRI); + ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend(); if (std::error_code EC = AddendOrErr.getError()) report_fatal_error(EC.message()); return *AddendOrErr; diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index b303e300470..6311c6ec5e4 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -767,8 +767,8 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj, if (RelSectionName != ".opd") continue; - for (relocation_iterator i = si->relocation_begin(), - e = si->relocation_end(); + for (elf_relocation_iterator i = si->relocation_begin(), + e = si->relocation_end(); i != e;) { // The R_PPC64_ADDR64 relocation indicates the first field // of a .opd entry @@ -781,8 +781,7 @@ void RuntimeDyldELF::findOPDEntrySection(const ELFObjectFileBase &Obj, uint64_t TargetSymbolOffset = i->getOffset(); symbol_iterator TargetSymbol = i->getSymbol(); - ErrorOr<int64_t> AddendOrErr = - Obj.getRelocationAddend(i->getRawDataRefImpl()); + ErrorOr<int64_t> AddendOrErr = i->getAddend(); Check(AddendOrErr.getError()); int64_t Addend = *AddendOrErr; @@ -1062,9 +1061,8 @@ relocation_iterator RuntimeDyldELF::processRelocationRef( const auto &Obj = cast<ELFObjectFileBase>(O); uint64_t RelType; Check(RelI->getType(RelType)); - int64_t Addend = 0; - if (Obj.hasRelocationAddend(RelI->getRawDataRefImpl())) - Addend = *Obj.getRelocationAddend(RelI->getRawDataRefImpl()); + ErrorOr<int64_t> AddendOrErr = ELFRelocationRef(*RelI).getAddend(); + int64_t Addend = AddendOrErr ? *AddendOrErr : 0; elf_symbol_iterator Symbol = RelI->getSymbol(); // Obtain the symbol name which is referenced in the relocation diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp index 8d2ae67dd7b..85783844358 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp @@ -31,9 +31,8 @@ public: StringRef SymName; SymI->getName(SymName); uint64_t SymAddr; SymI->getAddress(SymAddr); - auto *Obj = cast<ELFObjectFileBase>(Rel.getObject()); uint64_t SymSize = SymI->getSize(); - int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl()); + int64_t Addend = *ELFRelocationRef(Rel).getAddend(); MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName); // FIXME: check that the value is actually the same. |