diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-08-10 21:29:35 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-08-10 21:29:35 +0000 |
commit | aae5541455a0251f1e1e55b169c4c6c5fe7a70a3 (patch) | |
tree | faac46391773706e04a40f54be3ac4e459fc8c64 /llvm/tools/llvm-readobj/ELFDumper.cpp | |
parent | cc6554361c6cf4150ce3bcb9d1e76b60f85f2821 (diff) | |
download | bcm5719-llvm-aae5541455a0251f1e1e55b169c4c6c5fe7a70a3.tar.gz bcm5719-llvm-aae5541455a0251f1e1e55b169c4c6c5fe7a70a3.zip |
Don't iterate over all sections in the ELFFile constructor.
With this we finally have an ELFFile that is O(1) to construct. This is helpful
for programs like lld which have to do their own section walk.
llvm-svn: 244510
Diffstat (limited to 'llvm/tools/llvm-readobj/ELFDumper.cpp')
-rw-r--r-- | llvm/tools/llvm-readobj/ELFDumper.cpp | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp index 8fab52e79dd..7feb6e038a7 100644 --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -77,6 +77,7 @@ private: typedef typename ELFO::Elf_Phdr Elf_Phdr; typedef typename ELFO::Elf_Hash Elf_Hash; typedef typename ELFO::Elf_Ehdr Elf_Ehdr; + typedef typename ELFO::Elf_Word Elf_Word; typedef typename ELFO::uintX_t uintX_t; typedef typename ELFO::Elf_Versym Elf_Versym; typedef typename ELFO::Elf_Verneed Elf_Verneed; @@ -94,7 +95,8 @@ private: uintX_t EntSize; }; - void printSymbol(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic); + void printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab, + StringRef StrTable, bool IsDynamic); void printRelocations(const Elf_Shdr *Sec); void printRelocation(const Elf_Shdr *Sec, Elf_Rela Rel); @@ -135,6 +137,7 @@ private: const Elf_Hash *HashTable = nullptr; const Elf_Shdr *DotDynSymSec = nullptr; const Elf_Shdr *DotSymtabSec = nullptr; + ArrayRef<Elf_Word> ShndxTable; const Elf_Shdr *dot_gnu_version_sec = nullptr; // .gnu.version const Elf_Shdr *dot_gnu_version_r_sec = nullptr; // .gnu.version_r @@ -167,6 +170,8 @@ public: std::string getFullSymbolName(const Elf_Sym *Symbol, StringRef StrTable, bool IsDynamic); const Elf_Shdr *getDotDynSymSec() const { return DotDynSymSec; } + const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; } + ArrayRef<Elf_Word> getShndxTable() { return ShndxTable; } }; template <class T> T errorOrDefault(ErrorOr<T> Val, T Default = T()) { @@ -368,6 +373,8 @@ std::string ELFDumper<ELFT>::getFullSymbolName(const Elf_Sym *Symbol, template <typename ELFO> static void getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, + const typename ELFO::Elf_Shdr *SymTab, + ArrayRef<typename ELFO::Elf_Word> ShndxTable, StringRef &SectionName, unsigned &SectionIndex) { SectionIndex = Symbol->st_shndx; if (Symbol->isUndefined()) @@ -384,7 +391,8 @@ getSectionNameIndex(const ELFO &Obj, const typename ELFO::Elf_Sym *Symbol, SectionName = "Reserved"; else { if (SectionIndex == SHN_XINDEX) - SectionIndex = Obj.getExtendedSymbolTableIndex(Symbol); + SectionIndex = + Obj.getExtendedSymbolTableIndex(Symbol, SymTab, ShndxTable); ErrorOr<const typename ELFO::Elf_Shdr *> Sec = Obj.getSection(SectionIndex); error(Sec.getError()); SectionName = errorOrDefault(Obj.getSectionName(*Sec)); @@ -897,6 +905,12 @@ ELFDumper<ELFT>::ELFDumper(const ELFFile<ELFT> *Obj, StreamWriter &Writer) reportError("Multilpe SHT_SYMTAB"); DotSymtabSec = &Sec; break; + case ELF::SHT_SYMTAB_SHNDX: { + ErrorOr<ArrayRef<Elf_Word>> TableOrErr = Obj->getSHNDXTable(Sec); + error(TableOrErr.getError()); + ShndxTable = *TableOrErr; + break; + } } } } @@ -1009,11 +1023,12 @@ void ELFDumper<ELFT>::printSections() { StringRef StrTable = *StrTableOrErr; for (const Elf_Sym &Sym : Obj->symbols(Symtab)) { - ErrorOr<const Elf_Shdr *> SymSec = Obj->getSection(&Sym); + ErrorOr<const Elf_Shdr *> SymSec = + Obj->getSection(&Sym, Symtab, ShndxTable); if (!SymSec) continue; if (*SymSec == &Sec) - printSymbol(&Sym, StrTable, false); + printSymbol(&Sym, Symtab, StrTable, false); } } @@ -1104,7 +1119,8 @@ void ELFDumper<ELFT>::printRelocation(const Elf_Shdr *Sec, Elf_Rela Rel) { std::pair<const Elf_Shdr *, const Elf_Sym *> Sym = Obj->getRelocationSymbol(Sec, &Rel); if (Sym.second && Sym.second->getType() == ELF::STT_SECTION) { - ErrorOr<const Elf_Shdr *> Sec = Obj->getSection(Sym.second); + ErrorOr<const Elf_Shdr *> Sec = + Obj->getSection(Sym.second, Sym.first, ShndxTable); error(Sec.getError()); ErrorOr<StringRef> SecName = Obj->getSectionName(*Sec); if (SecName) @@ -1140,7 +1156,7 @@ void ELFDumper<ELFT>::printSymbols() { error(StrTableOrErr.getError()); StringRef StrTable = *StrTableOrErr; for (const Elf_Sym &Sym : Obj->symbols(Symtab)) - printSymbol(&Sym, StrTable, false); + printSymbol(&Sym, Symtab, StrTable, false); } template<class ELFT> @@ -1152,15 +1168,16 @@ void ELFDumper<ELFT>::printDynamicSymbols() { error(StrTableOrErr.getError()); StringRef StrTable = *StrTableOrErr; for (const Elf_Sym &Sym : Obj->symbols(Symtab)) - printSymbol(&Sym, StrTable, true); + printSymbol(&Sym, Symtab, StrTable, true); } template <class ELFT> -void ELFDumper<ELFT>::printSymbol(const Elf_Sym *Symbol, StringRef StrTable, - bool IsDynamic) { +void ELFDumper<ELFT>::printSymbol(const Elf_Sym *Symbol, const Elf_Shdr *SymTab, + StringRef StrTable, bool IsDynamic) { unsigned SectionIndex = 0; StringRef SectionName; - getSectionNameIndex(*Obj, Symbol, SectionName, SectionIndex); + getSectionNameIndex(*Obj, Symbol, SymTab, ShndxTable, SectionName, + SectionIndex); std::string FullSymbolName = getFullSymbolName(Symbol, StrTable, IsDynamic); unsigned char SymbolType = Symbol->getType(); @@ -1824,7 +1841,8 @@ void MipsGOTParser<ELFT>::printGlobalGotEntry( unsigned SectionIndex = 0; StringRef SectionName; - getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex); + getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(), + Dumper->getShndxTable(), SectionName, SectionIndex); W.printHex("Section", SectionName, SectionIndex); std::string FullSymbolName = @@ -1857,7 +1875,8 @@ void MipsGOTParser<ELFT>::printPLTEntry(uint64_t PLTAddr, unsigned SectionIndex = 0; StringRef SectionName; - getSectionNameIndex(*Obj, Sym, SectionName, SectionIndex); + getSectionNameIndex(*Obj, Sym, Dumper->getDotDynSymSec(), + Dumper->getShndxTable(), SectionName, SectionIndex); W.printHex("Section", SectionName, SectionIndex); std::string FullSymbolName = Dumper->getFullSymbolName(Sym, StrTable, true); |