diff --git a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test --- a/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ b/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -354,6 +354,26 @@ # VERSIONED-SEC-SYM-GNU-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF) # VERSIONED-SEC-SYM-GNU-NEXT: 3: {{.*}} UND +## Check we print a proper warning when an unnamed versioned section symbol has st_shndx = SHN_XINDEX, but there +## is no SHT_SYMTAB_SHNDX section in the object. +# RUN: yaml2obj %s -DTYPE=STT_SECTION -DNAME="''" -DINDEX=SHN_XINDEX --docnum=6 -o %t6.sec.xindex.sym +# RUN: llvm-readobj -V --dyn-symbols %t6.sec.xindex.sym 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t6.sec.xindex.sym --check-prefix=VERSIONED-SEC-SYM-XINDEX-LLVM +# RUN: llvm-readelf -V --dyn-symbols %t6.sec.xindex.sym 2>&1 | \ +# RUN: FileCheck %s -DFILE=%t6.sec.xindex.sym --check-prefix=VERSIONED-SEC-SYM-XINDEX-GNU + +# VERSIONED-SEC-SYM-XINDEX-LLVM: Name: (0) +# VERSIONED-SEC-SYM-XINDEX-LLVM: Name: foo (12) +# VERSIONED-SEC-SYM-XINDEX-LLVM: warning: '[[FILE]]': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# VERSIONED-SEC-SYM-XINDEX-LLVM-NEXT: Symbol { +# VERSIONED-SEC-SYM-XINDEX-LLVM-NEXT: Name: (0) +# VERSIONED-SEC-SYM-XINDEX-LLVM: Name: (0) + +# VERSIONED-SEC-SYM-XINDEX-GNU: Symbol table '.dynsym' contains 4 entries: +# VERSIONED-SEC-SYM-XINDEX-GNU: Num: {{.*}} Ndx Name +# VERSIONED-SEC-SYM-XINDEX-GNU: warning: '[[FILE]]': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# VERSIONED-SEC-SYM-XINDEX-GNU-NEXT: 2: {{.*}} RSV[0xffff] + ## Case 8: Check what we print when: ## a) The dynamic symbol table does not exist. # RUN: yaml2obj %s --docnum=7 -o %t7 diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp --- a/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -355,7 +355,7 @@ Elf_Rel_Range dyn_rels() const; Elf_Rela_Range dyn_relas() const; Elf_Relr_Range dyn_relrs() const; - std::string getFullSymbolName(const Elf_Sym *Symbol, + std::string getFullSymbolName(const Elf_Sym *Symbol, unsigned SymIndex, Optional StrTable, bool IsDynamic) const; Expected getSymbolSectionIndex(const Elf_Sym *Symbol, @@ -1110,8 +1110,10 @@ if (!StrTableOrErr) return StrTableOrErr.takeError(); - std::string SymbolName = - getFullSymbolName(Sym, *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); + const Elf_Sym *FirstSym = + cantFail(Obj.template getEntry(*SymTab, 0)); + std::string SymbolName = getFullSymbolName( + Sym, FirstSym - Sym, *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); return RelSymbol(Sym, SymbolName); } @@ -1173,6 +1175,7 @@ template std::string ELFDumper::getFullSymbolName(const Elf_Sym *Symbol, + unsigned SymIndex, Optional StrTable, bool IsDynamic) const { if (!StrTable) @@ -1187,10 +1190,7 @@ } if (SymbolName.empty() && Symbol->getType() == ELF::STT_SECTION) { - Elf_Sym_Range Syms = unwrapOrError( - ObjF->getFileName(), ObjF->getELFFile()->symbols(DotSymtabSec)); - Expected SectionIndex = - getSymbolSectionIndex(Symbol, Symbol - Syms.begin()); + Expected SectionIndex = getSymbolSectionIndex(Symbol, SymIndex); if (!SectionIndex) { reportUniqueWarning(SectionIndex.takeError()); return ""; @@ -2949,11 +2949,13 @@ uint64_t getGotAddress(const Entry * E) const; int64_t getGotOffset(const Entry * E) const; const Elf_Sym *getGotSym(const Entry *E) const; + Elf_Sym_Range getGotDynSyms() const { return GotDynSyms; } uint64_t getPltAddress(const Entry * E) const; const Elf_Sym *getPltSym(const Entry *E) const; StringRef getPltStrTable() const { return PltStrTable; } + const Elf_Shdr *getPltSymTable() const { return PltSymTable; } private: const Elf_Shdr *GotSec; @@ -3996,7 +3998,7 @@ Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex); Fields[7].Str = - this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic); + this->dumper()->getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); for (auto &Entry : Fields) printField(Entry); OS << "\n"; @@ -4027,7 +4029,8 @@ Fields[6].Str = printEnum(Symbol->getVisibility(), makeArrayRef(ElfSymbolVisibilities)); Fields[7].Str = getSymbolSectionNdx(Symbol, SymIndex); - Fields[8].Str = this->dumper()->getFullSymbolName(Symbol, StrTable, true); + Fields[8].Str = + this->dumper()->getFullSymbolName(Symbol, SymIndex, StrTable, true); for (auto &Entry : Fields) printField(Entry); @@ -5839,8 +5842,9 @@ OS << " Address Access Initial Sym.Val. Type Ndx Name\n"; for (auto &E : Parser.getGlobalEntries()) { const Elf_Sym *Sym = Parser.getGotSym(&E); + const Elf_Sym *FirstSym = &this->dumper()->dynamic_symbols()[0]; std::string SymName = this->dumper()->getFullSymbolName( - Sym, this->dumper()->getDynamicStringTable(), false); + Sym, FirstSym - Sym, this->dumper()->getDynamicStringTable(), false); OS.PadToColumn(2); OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias)); @@ -5891,8 +5895,11 @@ OS << " Address Initial Sym.Val. Type Ndx Name\n"; for (auto &E : Parser.getPltEntries()) { const Elf_Sym *Sym = Parser.getPltSym(&E); + const Elf_Sym *FirstSym = + cantFail(this->Obj.template getEntry( + *Parser.getPltSymTable(), 0)); std::string SymName = this->dumper()->getFullSymbolName( - Sym, this->dumper()->getDynamicStringTable(), false); + Sym, FirstSym - Sym, this->dumper()->getDynamicStringTable(), false); OS.PadToColumn(2); OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias)); @@ -6225,7 +6232,7 @@ Optional StrTable, bool IsDynamic, bool /*NonVisibilityBitsUsed*/) { std::string FullSymbolName = - this->dumper()->getFullSymbolName(Symbol, StrTable, IsDynamic); + this->dumper()->getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); unsigned char SymbolType = Symbol->getType(); DictScope D(W, "Symbol"); @@ -6380,8 +6387,9 @@ for (size_t I = 0, E = Syms.size(); I < E; ++I) { DictScope S(W, "Symbol"); W.printNumber("Version", (*VerTableOrErr)[I].vs_index & VERSYM_VERSION); - W.printString("Name", this->dumper()->getFullSymbolName(&Syms[I], StrTable, - /*IsDynamic=*/true)); + W.printString("Name", + this->dumper()->getFullSymbolName(&Syms[I], I, StrTable, + /*IsDynamic=*/true)); } } @@ -6767,7 +6775,8 @@ printSymbolSection(Sym, Sym - this->dumper()->dynamic_symbols().begin()); std::string SymName = this->dumper()->getFullSymbolName( - Sym, this->dumper()->getDynamicStringTable(), true); + Sym, Sym - &Parser.getGotDynSyms()[0], + this->dumper()->getDynamicStringTable(), true); W.printNumber("Name", SymName, Sym->st_name); } } @@ -6810,8 +6819,11 @@ W.printEnum("Type", Sym->getType(), makeArrayRef(ElfSymbolTypes)); printSymbolSection(Sym, Sym - this->dumper()->dynamic_symbols().begin()); - std::string SymName = - this->dumper()->getFullSymbolName(Sym, Parser.getPltStrTable(), true); + const Elf_Sym *FirstSym = + cantFail(this->Obj.template getEntry( + *Parser.getPltSymTable(), 0)); + std::string SymName = this->dumper()->getFullSymbolName( + Sym, Sym - FirstSym, Parser.getPltStrTable(), true); W.printNumber("Name", SymName, Sym->st_name); } }