diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 9ace1b06a65..d78949cb505 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -35,10 +35,17 @@ namespace llvm { namespace object { +class elf_symbol_iterator; +class ELFSymbolRef; + class ELFObjectFileBase : public ObjectFile { + friend class ELFSymbolRef; + protected: ELFObjectFileBase(unsigned int Type, MemoryBufferRef Source); + virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; + public: virtual ErrorOr getRelocationAddend(DataRefImpl Rel) const = 0; @@ -46,17 +53,55 @@ public: // and addend or not. virtual bool hasRelocationAddend(DataRefImpl Rel) const = 0; - virtual symbol_iterator_range getDynamicSymbolIterators() const = 0; + typedef iterator_range elf_symbol_iterator_range; + virtual elf_symbol_iterator_range getDynamicSymbolIterators() const = 0; virtual uint64_t getSectionFlags(SectionRef Sec) const = 0; virtual uint32_t getSectionType(SectionRef Sec) const = 0; - virtual uint64_t getSymbolSize(SymbolRef Symb) const = 0; + elf_symbol_iterator_range symbols() const; static inline bool classof(const Binary *v) { return v->isELF(); } }; +class ELFSymbolRef : public SymbolRef { +public: + ELFSymbolRef(const SymbolRef &B) : SymbolRef(B) { + assert(isa(SymbolRef::getObject())); + } + + const ELFObjectFileBase *getObject() const { + return cast(BasicSymbolRef::getObject()); + } + + uint64_t getSize() const { + return getObject()->getSymbolSize(getRawDataRefImpl()); + } +}; + +class elf_symbol_iterator : public symbol_iterator { +public: + elf_symbol_iterator(const basic_symbol_iterator &B) + : symbol_iterator(SymbolRef(B->getRawDataRefImpl(), + cast(B->getObject()))) {} + + const ELFSymbolRef *operator->() const { + return static_cast(symbol_iterator::operator->()); + } + + const ELFSymbolRef &operator*() const { + return static_cast(symbol_iterator::operator*()); + } +}; + +inline ELFObjectFileBase::elf_symbol_iterator_range +ELFObjectFileBase::symbols() const { + return elf_symbol_iterator_range(symbol_begin(), symbol_end()); +} + template class ELFObjectFile : public ELFObjectFileBase { + uint64_t getSymbolSize(DataRefImpl Sym) const override; + public: LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) @@ -73,8 +118,6 @@ public: typedef typename ELFFile::Elf_Shdr_Iter Elf_Shdr_Iter; typedef typename ELFFile::Elf_Dyn_Iter Elf_Dyn_Iter; - uint64_t getSymbolSize(SymbolRef Symb) const override; - protected: ELFFile EF; @@ -206,8 +249,8 @@ public: basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_end_impl() const override; - symbol_iterator dynamic_symbol_begin() const; - symbol_iterator dynamic_symbol_end() const; + elf_symbol_iterator dynamic_symbol_begin() const; + elf_symbol_iterator dynamic_symbol_end() const; section_iterator section_begin() const override; section_iterator section_end() const override; @@ -236,7 +279,7 @@ public: ELFT::Is64Bits); } - symbol_iterator_range getDynamicSymbolIterators() const override; + elf_symbol_iterator_range getDynamicSymbolIterators() const override; bool isRelocatableObject() const override; }; @@ -327,8 +370,8 @@ uint32_t ELFObjectFile::getSymbolAlignment(DataRefImpl Symb) const { } template -uint64_t ELFObjectFile::getSymbolSize(SymbolRef Symb) const { - return toELFSymIter(Symb.getRawDataRefImpl())->st_size; +uint64_t ELFObjectFile::getSymbolSize(DataRefImpl Sym) const { + return toELFSymIter(Sym)->st_size; } template @@ -734,12 +777,12 @@ basic_symbol_iterator ELFObjectFile::symbol_end_impl() const { } template -symbol_iterator ELFObjectFile::dynamic_symbol_begin() const { +elf_symbol_iterator ELFObjectFile::dynamic_symbol_begin() const { return symbol_iterator(SymbolRef(toDRI(EF.begin_dynamic_symbols()), this)); } template -symbol_iterator ELFObjectFile::dynamic_symbol_end() const { +elf_symbol_iterator ELFObjectFile::dynamic_symbol_end() const { return symbol_iterator(SymbolRef(toDRI(EF.end_dynamic_symbols()), this)); } @@ -862,7 +905,7 @@ unsigned ELFObjectFile::getArch() const { } template -ObjectFile::symbol_iterator_range +ELFObjectFileBase::elf_symbol_iterator_range ELFObjectFile::getDynamicSymbolIterators() const { return make_range(dynamic_symbol_begin(), dynamic_symbol_end()); } diff --git a/lib/Object/SymbolSize.cpp b/lib/Object/SymbolSize.cpp index 78d620503a8..730e54cf330 100644 --- a/lib/Object/SymbolSize.cpp +++ b/lib/Object/SymbolSize.cpp @@ -55,8 +55,8 @@ llvm::object::computeSymbolSizes(const ObjectFile &O) { auto Syms = E->symbols(); if (Syms.begin() == Syms.end()) Syms = E->getDynamicSymbolIterators(); - for (SymbolRef Sym : Syms) - Ret.push_back({Sym, E->getSymbolSize(Sym)}); + for (ELFSymbolRef Sym : Syms) + Ret.push_back({Sym, Sym.getSize()}); return Ret; } diff --git a/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp b/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp index a84c4c58494..6c7fb0d3e1e 100644 --- a/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp +++ b/lib/Target/X86/MCTargetDesc/X86ELFRelocationInfo.cpp @@ -27,12 +27,12 @@ public: const MCExpr *createExprForRelocation(RelocationRef Rel) override { uint64_t RelType; Rel.getType(RelType); - symbol_iterator SymI = Rel.getSymbol(); + elf_symbol_iterator SymI = Rel.getSymbol(); StringRef SymName; SymI->getName(SymName); uint64_t SymAddr; SymI->getAddress(SymAddr); auto *Obj = cast(Rel.getObjectFile()); - uint64_t SymSize = Obj->getSymbolSize(*SymI); + uint64_t SymSize = SymI->getSize(); int64_t Addend = *Obj->getRelocationAddend(Rel.getRawDataRefImpl()); MCSymbol *Sym = Ctx.getOrCreateSymbol(SymName); diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index feff6aa487b..16579883d75 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -930,8 +930,8 @@ static void dumpSymbolNamesFromObject(SymbolicFile &Obj, bool printName, S.Size = 0; S.Address = UnknownAddress; if (PrintSize) { - if (auto *E = dyn_cast(&Obj)) - S.Size = E->getSymbolSize(Sym); + if (isa(&Obj)) + S.Size = ELFSymbolRef(Sym).getSize(); } if (PrintAddress && isa(Obj)) { if (error(SymbolRef(Sym).getAddress(S.Address))) diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 518d6de34fa..24cedb38297 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -1149,8 +1149,8 @@ void llvm::PrintSymbolTable(const ObjectFile *o) { outs() << '\t'; if (Common || isa(o)) { - uint64_t Val = Common ? Symbol.getAlignment() - : cast(o)->getSymbolSize(Symbol); + uint64_t Val = + Common ? Symbol.getAlignment() : ELFSymbolRef(Symbol).getSize(); outs() << format("\t %08" PRIx64 " ", Val); }