diff options
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Object/ELF.h | 11 | ||||
-rw-r--r-- | llvm/include/llvm/Object/ELFObjectFile.h | 26 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 11 |
3 files changed, 30 insertions, 18 deletions
diff --git a/llvm/include/llvm/Object/ELF.h b/llvm/include/llvm/Object/ELF.h index 78e035986b3..d8bad4564ea 100644 --- a/llvm/include/llvm/Object/ELF.h +++ b/llvm/include/llvm/Object/ELF.h @@ -70,7 +70,6 @@ private: StringRef DotShstrtab; // Section header string table. StringRef DotStrtab; // Symbol header string table. const Elf_Shdr *dot_symtab_sec = nullptr; // Symbol table section. - const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section. const Elf_Shdr *SymbolTableSectionHeaderIndex = nullptr; @@ -81,7 +80,6 @@ public: const T *getEntry(const Elf_Shdr *Section, uint32_t Entry) const; const Elf_Shdr *getDotSymtabSec() const { return dot_symtab_sec; } - const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; } ErrorOr<StringRef> getStringTable(const Elf_Shdr *Section) const; ErrorOr<StringRef> getStringTableForSymtab(const Elf_Shdr &Section) const; @@ -384,15 +382,6 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) return; DotStrtab = *SymtabOrErr; } break; - case ELF::SHT_DYNSYM: { - if (DotDynSymSec) { - // More than one .dynsym! - EC = object_error::parse_failed; - return; - } - DotDynSymSec = &Sec; - break; - } } } diff --git a/llvm/include/llvm/Object/ELFObjectFile.h b/llvm/include/llvm/Object/ELFObjectFile.h index 4b628e1df97..c3483378eb9 100644 --- a/llvm/include/llvm/Object/ELFObjectFile.h +++ b/llvm/include/llvm/Object/ELFObjectFile.h @@ -192,6 +192,8 @@ public: protected: ELFFile<ELFT> EF; + const Elf_Shdr *DotDynSymSec = nullptr; // Dynamic symbol table section. + void moveSymbolNext(DataRefImpl &Symb) const override; ErrorOr<StringRef> getSymbolName(DataRefImpl Symb) const override; ErrorOr<uint64_t> getSymbolAddress(DataRefImpl Symb) const override; @@ -475,7 +477,7 @@ uint32_t ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Sym) const { if (ESym->getType() == ELF::STT_FILE || ESym->getType() == ELF::STT_SECTION || ESym == EF.symbol_begin(EF.getDotSymtabSec()) || - ESym == EF.symbol_begin(EF.getDotDynSymSec())) + ESym == EF.symbol_begin(DotDynSymSec)) Result |= SymbolRef::SF_FormatSpecific; if (EF.getHeader()->e_machine == ELF::EM_ARM) { @@ -666,7 +668,7 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { bool IsDyn = Rel.d.b & 1; DataRefImpl SymbolData; if (IsDyn) - SymbolData = toDRI(EF.getDotDynSymSec(), symbolIdx); + SymbolData = toDRI(DotDynSymSec, symbolIdx); else SymbolData = toDRI(EF.getDotSymtabSec(), symbolIdx); return symbol_iterator(SymbolRef(SymbolData, this)); @@ -737,7 +739,21 @@ ELFObjectFile<ELFT>::ELFObjectFile(MemoryBufferRef Object, std::error_code &EC) : ELFObjectFileBase( getELFType(ELFT::TargetEndianness == support::little, ELFT::Is64Bits), Object), - EF(Data.getBuffer(), EC) {} + EF(Data.getBuffer(), EC) { + for (const Elf_Shdr &Sec : EF.sections()) { + switch (Sec.sh_type) { + case ELF::SHT_DYNSYM: { + if (DotDynSymSec) { + // More than one .dynsym! + EC = object_error::parse_failed; + return; + } + DotDynSymSec = &Sec; + break; + } + } + } +} template <class ELFT> basic_symbol_iterator ELFObjectFile<ELFT>::symbol_begin_impl() const { @@ -756,13 +772,13 @@ basic_symbol_iterator ELFObjectFile<ELFT>::symbol_end_impl() const { template <class ELFT> elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_begin() const { - DataRefImpl Sym = toDRI(EF.getDotDynSymSec(), 0); + DataRefImpl Sym = toDRI(DotDynSymSec, 0); return symbol_iterator(SymbolRef(Sym, this)); } template <class ELFT> elf_symbol_iterator ELFObjectFile<ELFT>::dynamic_symbol_end() const { - const Elf_Shdr *SymTab = EF.getDotDynSymSec(); + const Elf_Shdr *SymTab = DotDynSymSec; DataRefImpl Sym = toDRI(SymTab, SymTab->sh_size / sizeof(Elf_Sym)); return basic_symbol_iterator(SymbolRef(Sym, this)); } diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 50473d7bb04..05fef7262ff 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -133,6 +133,7 @@ private: const Elf_Sym *DynSymStart = nullptr; StringRef SOName; const Elf_Hash *HashTable = nullptr; + const Elf_Shdr *DotDynSymSec = nullptr; const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r @@ -164,6 +165,7 @@ private: public: std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic); + const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; } }; template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) { @@ -884,6 +886,11 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) reportError("Multilpe SHT_GNU_verneed"); dot_gnu_version_r_sec = &Sec; break; + case ELF::SHT_DYNSYM: + if (DotDynSymSec != nullptr) + reportError("Multilpe SHT_DYNSYM"); + DotDynSymSec = &Sec; + break; } } } @@ -1134,7 +1141,7 @@ template<class ELFT> void ELFDumper<ELFT>::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); - const Elf_Shdr *Symtab = Obj->getDotDynSymSec(); + const Elf_Shdr *Symtab = DotDynSymSec; ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(*Symtab); error(StrTableOrErr.getError()); StringRef StrTable = *StrTableOrErr; @@ -1643,7 +1650,7 @@ template <class ELFT> void MipsGOTParser<ELFT>::parseGOT() { return; } - const Elf_Shdr *DynSymSec = Obj->getDotDynSymSec(); + const Elf_Shdr *DynSymSec = Dumper->getDotDynSymSec(); ErrorOr<StringRef> StrTable = Obj->getStringTableForSymtab(*DynSymSec); error(StrTable.getError()); const Elf_Sym *DynSymBegin = Obj->symbol_begin(DynSymSec); |