From 71784d611d211c07efc5686ee795dfd7907ff7b5 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 30 Jun 2015 00:33:59 +0000 Subject: Cleanup getRelocationAddend. Realistically, this will be returning ErrorOr for some time as refactoring the user code to check once per section will take some time. Given that, use it for checking if a relocation has addend or not. While at it, add ELFRelocationRef to simplify the users. llvm-svn: 241028 --- llvm/include/llvm/Object/ELFObjectFile.h | 46 ++++++++++++++++++++++++-------- llvm/include/llvm/Object/RelocVisitor.h | 4 +-- 2 files changed, 36 insertions(+), 14 deletions(-) (limited to 'llvm/include') 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 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_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(RelocationRef::getObject())); + } + + const ELFObjectFileBase *getObject() const { + return cast(RelocationRef::getObject()); + } + + ErrorOr 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(B->getObject()))) {} + + const ELFRelocationRef *operator->() const { + return static_cast( + relocation_iterator::operator->()); + } + + const ELFRelocationRef &operator*() const { + return static_cast( + 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 getRelocationAddend(DataRefImpl Rel) const override; - bool hasRelocationAddend(DataRefImpl Rel) const override; uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; @@ -733,11 +762,6 @@ ELFObjectFile::getRelocationAddend(DataRefImpl Rel) const { return (int64_t)getRela(Rel)->r_addend; } -template -bool ELFObjectFile::hasRelocationAddend(DataRefImpl Rel) const { - return getRelSection(Rel)->sh_type == ELF::SHT_RELA; -} - template const typename ELFFile::Elf_Sym * ELFObjectFile::getSymbol(DataRefImpl Symb) const { 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(R.getObject()); - DataRefImpl DRI = R.getRawDataRefImpl(); - ErrorOr AddendOrErr = Obj->getRelocationAddend(DRI); + ErrorOr AddendOrErr = ELFRelocationRef(R).getAddend(); if (std::error_code EC = AddendOrErr.getError()) report_fatal_error(EC.message()); return *AddendOrErr; -- cgit v1.2.3