Index: lld/ELF/InputFiles.cpp =================================================================== --- lld/ELF/InputFiles.cpp +++ lld/ELF/InputFiles.cpp @@ -389,9 +389,10 @@ template uint32_t ObjFile::getSectionIndex(const Elf_Sym &sym) const { - return CHECK( - this->getObj().getSectionIndex(sym, getELFSyms(), shndxTable), - this); + return CHECK(this->getObj().getSectionIndex(sym, getELFSyms(), + shndxTable.data(), + shndxTable.size()), + this); } template ArrayRef ObjFile::getLocalSymbols() { Index: llvm/include/llvm/Object/ELF.h =================================================================== --- llvm/include/llvm/Object/ELF.h +++ llvm/include/llvm/Object/ELF.h @@ -298,13 +298,16 @@ Elf_Shdr_Range Sections, WarningHandler WarnHandler = &defaultWarningHandler) const; Expected getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms, - ArrayRef ShndxTable) const; + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const; Expected getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab, - ArrayRef ShndxTable) const; + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const; Expected getSection(const Elf_Sym &Sym, Elf_Sym_Range Symtab, - ArrayRef ShndxTable) const; + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const; Expected getSection(uint32_t Index) const; Expected getSymbol(const Elf_Shdr *Sec, @@ -337,26 +340,37 @@ template inline Expected getExtendedSymbolTableIndex(const typename ELFT::Sym &Sym, unsigned SymIndex, - ArrayRef ShndxTable) { + const typename ELFT::Word *ShndxTable, + size_t ShndxTableSize) { assert(Sym.st_shndx == ELF::SHN_XINDEX); - if (SymIndex >= ShndxTable.size()) + if (!ShndxTable) + return createError( + "found an extended symbol index (" + Twine(SymIndex) + + "), but unable to locate the extended symbol index table"); + + // ShndxTableSize is 0 when the size of the ShndxTable is unknown. + // It might happen when we locate the table using the DT_SYMTAB_SHNDX + // dynamic tag. + if (ShndxTableSize && SymIndex >= ShndxTableSize) return createError( "extended symbol index (" + Twine(SymIndex) + ") is past the end of the SHT_SYMTAB_SHNDX section of size " + - Twine(ShndxTable.size())); + Twine(ShndxTableSize)); + // TODO: report a warning when ShndxTable[SymIndex] goes past the EOF. // The size of the table was checked in getSHNDXTable. return ShndxTable[SymIndex]; } template -Expected -ELFFile::getSectionIndex(const Elf_Sym &Sym, Elf_Sym_Range Syms, - ArrayRef ShndxTable) const { +Expected ELFFile::getSectionIndex(const Elf_Sym &Sym, + Elf_Sym_Range Syms, + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const { uint32_t Index = Sym.st_shndx; if (Index == ELF::SHN_XINDEX) { - Expected ErrorOrIndex = - getExtendedSymbolTableIndex(Sym, &Sym - Syms.begin(), ShndxTable); + Expected ErrorOrIndex = getExtendedSymbolTableIndex( + Sym, &Sym - Syms.begin(), ShndxTable, ShndxTableSize); if (!ErrorOrIndex) return ErrorOrIndex.takeError(); return *ErrorOrIndex; @@ -369,18 +383,20 @@ template Expected ELFFile::getSection(const Elf_Sym &Sym, const Elf_Shdr *SymTab, - ArrayRef ShndxTable) const { + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const { auto SymsOrErr = symbols(SymTab); if (!SymsOrErr) return SymsOrErr.takeError(); - return getSection(Sym, *SymsOrErr, ShndxTable); + return getSection(Sym, *SymsOrErr, ShndxTable, ShndxTableSize); } template Expected ELFFile::getSection(const Elf_Sym &Sym, Elf_Sym_Range Symbols, - ArrayRef ShndxTable) const { - auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable); + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const { + auto IndexOrErr = getSectionIndex(Sym, Symbols, ShndxTable, ShndxTableSize); if (!IndexOrErr) return IndexOrErr.takeError(); uint32_t Index = *IndexOrErr; Index: llvm/include/llvm/Object/ELFObjectFile.h =================================================================== --- llvm/include/llvm/Object/ELFObjectFile.h +++ llvm/include/llvm/Object/ELFObjectFile.h @@ -588,8 +588,8 @@ return ShndxTableOrErr.takeError(); } - Expected SectionOrErr = - EF.getSection(*ESym, *SymTabOrErr, ShndxTable); + Expected SectionOrErr = EF.getSection( + *ESym, *SymTabOrErr, ShndxTable.data(), ShndxTable.size()); if (!SectionOrErr) return SectionOrErr.takeError(); const Elf_Shdr *Section = *SectionOrErr; @@ -744,7 +744,8 @@ ShndxTable = *ShndxTableOrErr; } - auto ESecOrErr = EF.getSection(*ESym, SymTab, ShndxTable); + auto ESecOrErr = + EF.getSection(*ESym, SymTab, ShndxTable.data(), ShndxTable.size()); if (!ESecOrErr) return ESecOrErr.takeError(); Index: llvm/test/Object/invalid.test =================================================================== --- llvm/test/Object/invalid.test +++ llvm/test/Object/invalid.test @@ -244,7 +244,7 @@ # RUN: llvm-readobj --symbols %p/Inputs/invalid-ext-symtab-index.elf-x86-64 2>&1 | \ # RUN: FileCheck -DFILE=%p/Inputs/invalid-ext-symtab-index.elf-x86-64 --check-prefix=INVALID-EXT-SYMTAB-INDEX %s -# INVALID-EXT-SYMTAB-INDEX: warning: '[[FILE]]': extended symbol index (0) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# INVALID-EXT-SYMTAB-INDEX: warning: '[[FILE]]': found an extended symbol index (0), but unable to locate the extended symbol index table # INVALID-EXT-SYMTAB-INDEX: Section: Reserved (0xFFFF) ## Check that llvm-readobj reports an error if a relocation section Index: llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test +++ llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test @@ -364,14 +364,14 @@ # 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: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table # 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: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table # VERSIONED-SEC-SYM-XINDEX-GNU-NEXT: 2: {{.*}} RSV[0xffff] ## Case 8: Check what we print when: Index: llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test +++ llvm/test/tools/llvm-readobj/ELF/dynamic-tags.test @@ -487,6 +487,7 @@ # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': DT_SYMENT value of 0x987 is not the size of a symbol (0x18) # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_REL: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_JMPREL: invalid e_phentsize: 1 +# PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_SYMTAB_SHNDX: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_RELR: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_ANDROID_RELR: invalid e_phentsize: 1 # PHENTSIZE-WARN-NEXT: warning: '[[FILE]]': unable to parse DT_GNU_HASH: invalid e_phentsize: 1 Index: llvm/test/tools/llvm-readobj/ELF/mips-got.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/mips-got.test +++ llvm/test/tools/llvm-readobj/ELF/mips-got.test @@ -558,7 +558,7 @@ # SEC-SYMS-LLVM-NEXT: } # SEC-SYMS-LLVM-NEXT: Entry { # SEC-SYMS-LLVM: Type: Section (0x3) -# SEC-SYMS-LLVM-NEXT: warning: '[[FILE]]': extended symbol index (4) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# SEC-SYMS-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (4), but unable to locate the extended symbol index table # SEC-SYMS-LLVM-NEXT: Section: Reserved (0xFFFF) # SEC-SYMS-LLVM-NEXT: Name: (0) # SEC-SYMS-LLVM-NEXT: } @@ -571,7 +571,7 @@ # SEC-SYMS-GNU-NEXT: {{.*}} 1 .got # SEC-SYMS-GNU-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff2 (SHN_COMMON) # SEC-SYMS-GNU-NEXT: {{.*}} COM -# SEC-SYMS-GNU-NEXT: warning: '[[FILE]]': extended symbol index (4) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# SEC-SYMS-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (4), but unable to locate the extended symbol index table # SEC-SYMS-GNU-NEXT: {{.*}} RSV[0xffff] --- !ELF Index: llvm/test/tools/llvm-readobj/ELF/mips-plt.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/mips-plt.test +++ llvm/test/tools/llvm-readobj/ELF/mips-plt.test @@ -189,7 +189,7 @@ # SEC-SYMS-LLVM-NEXT: } # SEC-SYMS-LLVM-NEXT: Entry { # SEC-SYMS-LLVM: Type: Section (0x3) -# SEC-SYMS-LLVM-NEXT: warning: '[[FILE]]': extended symbol index (4) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# SEC-SYMS-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (4), but unable to locate the extended symbol index table # SEC-SYMS-LLVM-NEXT: Section: Reserved (0xFFFF) # SEC-SYMS-LLVM-NEXT: Name: (0) # SEC-SYMS-LLVM-NEXT: } @@ -204,7 +204,7 @@ # SEC-SYMS-GNU-NEXT: 0000000000002018 {{.*}} 2 .got.plt # SEC-SYMS-GNU-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff2 (SHN_COMMON) # SEC-SYMS-GNU-NEXT: 0000000000002020 {{.*}} COM -# SEC-SYMS-GNU-NEXT: warning: '[[FILE]]': extended symbol index (4) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# SEC-SYMS-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (4), but unable to locate the extended symbol index table # SEC-SYMS-GNU-NEXT: 0000000000002028 {{.*}} RSV[0xffff] --- !ELF Index: llvm/test/tools/llvm-readobj/ELF/section-symbols.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/section-symbols.test +++ llvm/test/tools/llvm-readobj/ELF/section-symbols.test @@ -150,7 +150,7 @@ # GNU2-NEXT: 0: {{.*}} NOTYPE {{.*}} UND {{$}} # GNU2-NEXT: 1: {{.*}} SECTION {{.*}} RSV[0xffff] -# WARN2: warning: '{{.*}}.tmp2': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# WARN2: warning: '{{.*}}.tmp2': found an extended symbol index (1), but unable to locate the extended symbol index table --- !ELF FileHeader: Index: llvm/test/tools/llvm-readobj/ELF/symbol-shndx.test =================================================================== --- llvm/test/tools/llvm-readobj/ELF/symbol-shndx.test +++ llvm/test/tools/llvm-readobj/ELF/symbol-shndx.test @@ -241,8 +241,8 @@ # GNU3-NEXT: 1: {{.*}} RSV[0xffff] no_shndx # GNU3-NEXT: 2: {{.*}} RSV[0xffff] no_shndx2 -# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 -# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': extended symbol index (2) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': found an extended symbol index (1), but unable to locate the extended symbol index table +# NO-SYMTAB-SHNDX: warning: '{{.*}}tmp3': found an extended symbol index (2), but unable to locate the extended symbol index table --- !ELF FileHeader: @@ -267,7 +267,7 @@ # SHNDX-ERR-GNU-NEXT: Symbol table '.symtab' contains 2 entries: # SHNDX-ERR-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name # SHNDX-ERR-GNU-NEXT: 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND -# SHNDX-ERR-GNU-NEXT: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# SHNDX-ERR-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table # SHNDX-ERR-GNU-NEXT: 1: 0000000000000000 0 NOTYPE LOCAL DEFAULT RSV[0xffff] # SHNDX-ERR-GNU-EMPTY: # SHNDX-ERR-GNU-NOT:{{.}} @@ -294,7 +294,7 @@ # SHNDX-ERR-LLVM-NEXT: Binding: Local (0x0) # SHNDX-ERR-LLVM-NEXT: Type: None (0x0) # SHNDX-ERR-LLVM-NEXT: Other: 0 -# SHNDX-ERR-LLVM-NEXT: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# SHNDX-ERR-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table # SHNDX-ERR-LLVM-NEXT: Section: Reserved (0xFFFF) # SHNDX-ERR-LLVM-NEXT: } # SHNDX-ERR-LLVM-NEXT: ] Index: llvm/test/tools/llvm-readobj/ELF/symtab-shndx.test =================================================================== --- /dev/null +++ llvm/test/tools/llvm-readobj/ELF/symtab-shndx.test @@ -0,0 +1,169 @@ +## In this file we have tests for the SHT_SYMTAB_SHNDX section +## and the DT_SYMTAB_SHNDX dynamic tag. + +## Check that different SHT_SYMTAB_SHNDX sections can be used with different symbol tables. +## In this test we check that we print different section indexes for regular and dynamic +## symbol tables that are linked to different SHT_SYMTAB_SHNDX sections. + +# RUN: yaml2obj --docnum=1 %s -o %t1 +# RUN: llvm-readelf --symbols --dyn-syms %t1 2>&1 | FileCheck %s --check-prefix=GNU +# RUN: llvm-readobj --symbols --dyn-syms %t1 2>&1 | FileCheck %s --check-prefix=LLVM + +# GNU: Symbol table '.dynsym' contains 3 entries: +# GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name +# GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND +# GNU-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 3 dynsym1 +# GNU-NEXT: 2: 00000000 0 NOTYPE LOCAL DEFAULT 2 dynsym2 +# GNU: Symbol table '.symtab' contains 3 entries: +# GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name +# GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND +# GNU-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 sym1 +# GNU-NEXT: 2: 00000000 0 NOTYPE LOCAL DEFAULT 1 sym2 + +# LLVM: Symbols [ +# LLVM-NEXT: Symbol { +# LLVM-NEXT: Name: (0) +# LLVM: Section: Undefined (0x0) +# LLVM-NEXT: } +# LLVM-NEXT: Symbol { +# LLVM-NEXT: Name: sym1 (6) +# LLVM: Section: .section2 (0x2) +# LLVM-NEXT: } +# LLVM-NEXT: Symbol { +# LLVM-NEXT: Name: sym2 (1) +# LLVM: Section: .section1 (0x1) +# LLVM-NEXT: } +# LLVM-NEXT: ] +# LLVM: DynamicSymbols [ +# LLVM-NEXT: Symbol { +# LLVM-NEXT: Name: (0) +# LLVM: Section: Undefined (0x0) +# LLVM-NEXT: } +# LLVM-NEXT: Symbol { +# LLVM-NEXT: Name: dynsym1 (9) +# LLVM: Section: .section3 (0x3) +# LLVM-NEXT: } +# LLVM-NEXT: Symbol { +# LLVM-NEXT: Name: dynsym2 (1) +# LLVM: Section: .section2 (0x2) +# LLVM-NEXT: } +# LLVM-NEXT: ] + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_REL +Sections: + - Name: .section1 + Type: SHT_PROGBITS + - Name: .section2 + Type: SHT_PROGBITS + - Name: .section3 + Type: SHT_PROGBITS + - Name: .dynamic + Type: SHT_DYNAMIC + Flags: [ SHF_ALLOC ] + Address: 0x1000 + Offset: 0x1000 + Entries: + - Tag: [[TAGNAME=DT_SYMTAB_SHNDX]] + Value: [[SYMTABSHNDX=0x2100]] ## Address of .bar section. + - Tag: DT_NULL + Value: 0 +## By naming SHT_SYMTAB_SHNDX to .foo and .bar we verify that we +## don't use their names to locate them. + - Name: .foo + Type: SHT_SYMTAB_SHNDX + Flags: [ SHF_ALLOC ] + Link: .symtab + Entries: [ 0, 2, 1 ] + Offset: 0x2000 + Address: 0x2000 + - Name: .bar + Type: SHT_SYMTAB_SHNDX + Flags: [ SHF_ALLOC ] + Link: .dynsym + Entries: [ 0, 3, 2 ] + Offset: 0x2100 + Address: 0x2100 +Symbols: + - Name: sym1 + Index: SHN_XINDEX + - Name: sym2 + Index: SHN_XINDEX +DynamicSymbols: + - Name: dynsym1 + Index: SHN_XINDEX + - Name: dynsym2 + Index: SHN_XINDEX +ProgramHeaders: + - Type: PT_LOAD + VAddr: 0x1000 + FirstSec: .dynamic + LastSec: .bar + - Type: PT_DYNAMIC + VAddr: 0x1000 + FirstSec: .dynamic + LastSec: .dynamic + +## Check that we locate the SHT_SYMTAB_SHNDX section using the DT_SYMTAB_SHNDX +## dynamic tag when dumping dynamic symbols. In this case we make the value of +## DT_SYMTAB_SHNDX to point to the SHT_SYMTAB_SHNDX section that is +## linked with the static symbol table and check that we use it. + +# RUN: yaml2obj --docnum=1 -DSYMTABSHNDX=0x2000 %s -o %t2 +# RUN: llvm-readelf --dyn-syms %t2 2>&1 | FileCheck %s --check-prefix=DYNTAG-GNU +# RUN: llvm-readobj --dyn-syms %t2 2>&1 | FileCheck %s --check-prefix=DYNTAG-LLVM + +# DYNTAG-GNU: Symbol table '.dynsym' contains 3 entries: +# DYNTAG-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name +# DYNTAG-GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND +# DYNTAG-GNU-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT 2 dynsym1 +# DYNTAG-GNU-NEXT: 2: 00000000 0 NOTYPE LOCAL DEFAULT 1 dynsym2 + +# DYNTAG-LLVM: Name: dynsym1 (9) +# DYNTAG-LLVM: Section: .section2 (0x2) +# DYNTAG-LLVM-NEXT: } +# DYNTAG-LLVM-NEXT: Symbol { +# DYNTAG-LLVM-NEXT: Name: dynsym2 (1) +# DYNTAG-LLVM: Section: .section1 (0x1) +# DYNTAG-LLVM-NEXT: } +# DYNTAG-LLVM-NEXT: ] + +## Check that when report a warning when we dump the dynamic symbol table that +## contains symbols with extended indices, but we don't have the DT_SYMTAB_SHNDX tag to locate +## the corresponding extended indexes table. + +# RUN: yaml2obj --docnum=1 -DTAGNAME=0x0 -DSYMTABSHNDX=0x0 %s -o %t3 +# RUN: llvm-readelf --symbols --dyn-syms %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=NOTAG-GNU +# RUN: llvm-readobj --symbols --dyn-syms %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=NOTAG-LLVM + +# NOTAG-GNU: Symbol table '.dynsym' contains 3 entries: +# NOTAG-GNU-NEXT: Num: Value Size Type Bind Vis Ndx Name +# NOTAG-GNU-NEXT: 0: 00000000 0 NOTYPE LOCAL DEFAULT UND +# NOTAG-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table +# NOTAG-GNU-NEXT: 1: 00000000 0 NOTYPE LOCAL DEFAULT RSV[0xffff] dynsym1 +# NOTAG-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table +# NOTAG-GNU-NEXT: 2: 00000000 0 NOTYPE LOCAL DEFAULT RSV[0xffff] dynsym2 + +# NOTAG-LLVM: Symbol { +# NOTAG-LLVM: Name: dynsym1 (9) +# NOTAG-LLVM-NEXT: Value: 0x0 +# NOTAG-LLVM-NEXT: Size: 0 +# NOTAG-LLVM-NEXT: Binding: Local (0x0) +# NOTAG-LLVM-NEXT: Type: None (0x0) +# NOTAG-LLVM-NEXT: Other: 0 +# NOTAG-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table +# NOTAG-LLVM-NEXT: Section: Reserved (0xFFFF) +# NOTAG-LLVM-NEXT: } +# NOTAG-LLVM-NEXT: Symbol { +# NOTAG-LLVM-NEXT: Name: dynsym2 (1) +# NOTAG-LLVM-NEXT: Value: 0x0 +# NOTAG-LLVM-NEXT: Size: 0 +# NOTAG-LLVM-NEXT: Binding: Local (0x0) +# NOTAG-LLVM-NEXT: Type: None (0x0) +# NOTAG-LLVM-NEXT: Other: 0 +# NOTAG-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table +# NOTAG-LLVM-NEXT: Section: Reserved (0xFFFF) +# NOTAG-LLVM-NEXT: } Index: llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml =================================================================== --- llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml +++ llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml @@ -51,7 +51,7 @@ # RUN: yaml2obj --docnum=2 %s -o %t2 # RUN: not obj2yaml %t2 2>&1 | FileCheck %s -DFILE=%t2 --check-prefix=CASE2 -# CASE2: Error reading file: [[FILE]]: extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# CASE2: Error reading file: [[FILE]]: found an extended symbol index (1), but unable to locate the extended symbol index table --- !ELF FileHeader: Index: llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml +++ llvm/test/tools/yaml2obj/ELF/sht-symtab-shndx.yaml @@ -5,7 +5,7 @@ # RUN: yaml2obj --docnum=1 %s -o %t1 # RUN: llvm-readobj --symbols 2>&1 %t1 | FileCheck -DFILE=%t1 %s --check-prefix=CASE1 -# CASE1: warning: '[[FILE]]': extended symbol index (1) is past the end of the SHT_SYMTAB_SHNDX section of size 0 +# CASE1: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table --- !ELF FileHeader: Index: llvm/tools/llvm-readobj/ARMEHABIPrinter.h =================================================================== --- llvm/tools/llvm-readobj/ARMEHABIPrinter.h +++ llvm/tools/llvm-readobj/ARMEHABIPrinter.h @@ -424,7 +424,7 @@ const Elf_Sym *Symbol = unwrapOrError(FileName, ELF.getRelocationSymbol(RelA, SymTab)); - auto Ret = ELF.getSection(*Symbol, SymTab, ShndxTable); + auto Ret = ELF.getSection(*Symbol, SymTab, ShndxTable.data(), ShndxTable.size()); if (!Ret) report_fatal_error(errorToErrorCode(Ret.takeError()).message()); return *Ret; Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -335,6 +335,7 @@ DynRegionInfo DynRelrRegion; DynRegionInfo DynPLTRelRegion; Optional DynSymRegion; + DynRegionInfo DynSymTabShndxRegion; DynRegionInfo DynamicTable; StringRef DynamicStringTable; const Elf_Hash *HashTable = nullptr; @@ -343,7 +344,7 @@ const Elf_Shdr *DotDynsymSec = nullptr; const Elf_Shdr *DotCGProfileSec = nullptr; const Elf_Shdr *DotAddrsigSec = nullptr; - ArrayRef ShndxTable; + DenseMap> ShndxTables; Optional SONameOffset; const Elf_Shdr *SymbolVersionSection = nullptr; // .gnu.version @@ -391,14 +392,22 @@ return DynSymRegion->getAsArrayRef(); } + DynRegionInfo getDynSymTabShndxRegion() const { + return DynSymTabShndxRegion; + } + 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, unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize, Optional StrTable, bool IsDynamic) const; Expected getSymbolSectionIndex(const Elf_Sym &Symbol, - unsigned SymIndex) const; + unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const; Expected getSymbolSectionName(const Elf_Sym &Symbol, unsigned SectionIndex) const; std::string getStaticSymbolName(uint32_t Index) const; @@ -414,7 +423,7 @@ const Elf_Shdr *getDotSymtabSec() const { return DotSymtabSec; } const Elf_Shdr *getDotCGProfileSec() const { return DotCGProfileSec; } const Elf_Shdr *getDotAddrsigSec() const { return DotAddrsigSec; } - ArrayRef getShndxTable() const { return ShndxTable; } + ArrayRef getShndxTable(const Elf_Shdr *Symtab) const; StringRef getDynamicStringTable() const { return DynamicStringTable; } const DynRegionInfo &getDynRelRegion() const { return DynRelRegion; } const DynRegionInfo &getDynRelaRegion() const { return DynRelaRegion; } @@ -424,9 +433,9 @@ const Elf_Hash *getHashTable() const { return HashTable; } const Elf_GnuHash *getGnuHashTable() const { return GnuHashTable; } - Expected> getVersionTable(const Elf_Shdr &Sec, - ArrayRef *SymTab, - StringRef *StrTab) const; + Expected> + getVersionTable(const Elf_Shdr &Sec, ArrayRef *SymTab, + StringRef *StrTab, const Elf_Shdr **SymTabSec) const; Expected> getVersionDefinitions(const Elf_Shdr &Sec) const; Expected> @@ -452,8 +461,21 @@ } template -static Expected getLinkAsStrtab(const ELFFile &Obj, - const typename ELFT::Shdr &Sec) { +ArrayRef +ELFDumper::getShndxTable(const Elf_Shdr *Symtab) const { + if (Symtab) { + auto It = ShndxTables.find(Symtab); + if (It != ShndxTables.end()) + return It->second; + } + return {}; +} + +namespace { + +template +Expected getLinkAsStrtab(const ELFFile &Obj, + const typename ELFT::Shdr &Sec) { Expected StrTabSecOrErr = Obj.getSection(Sec.sh_link); if (!StrTabSecOrErr) @@ -467,11 +489,18 @@ return *StrTabOrErr; } -// Returns the linked symbol table and associated string table for a given section. +template struct SymtabLink { + typename ELFT::SymRange Symbols; + StringRef StringTable; + const typename ELFT::Shdr *SymTab; +}; + +// Returns the linked symbol table, symbols and associated string table for a +// given section. template -static Expected> -getLinkAsSymtab(const ELFFile &Obj, const typename ELFT::Shdr &Sec, - unsigned ExpectedType) { +Expected> getLinkAsSymtab(const ELFFile &Obj, + const typename ELFT::Shdr &Sec, + unsigned ExpectedType) { Expected SymtabOrErr = Obj.getSection(Sec.sh_link); if (!SymtabOrErr) @@ -496,15 +525,16 @@ if (!SymsOrErr) return createError("unable to read symbols from the " + describe(Obj, Sec) + ": " + toString(SymsOrErr.takeError())); - - return std::make_pair(*SymsOrErr, *StrTabOrErr); + return SymtabLink{*SymsOrErr, *StrTabOrErr, *SymtabOrErr}; } +} // namespace template Expected> ELFDumper::getVersionTable(const Elf_Shdr &Sec, ArrayRef *SymTab, - StringRef *StrTab) const { - assert((!SymTab && !StrTab) || (SymTab && StrTab)); + StringRef *StrTab, + const Elf_Shdr **SymTabSec) const { + assert((!SymTab && !StrTab && !SymTabSec) || (SymTab && StrTab && SymTabSec)); if (uintptr_t(Obj.base() + Sec.sh_offset) % sizeof(uint16_t) != 0) return createError("the " + describe(Sec) + " is misaligned"); @@ -514,23 +544,26 @@ return createError("cannot read content of " + describe(Sec) + ": " + toString(VersionsOrErr.takeError())); - Expected, StringRef>> SymTabOrErr = + Expected> SymTabOrErr = getLinkAsSymtab(Obj, Sec, SHT_DYNSYM); if (!SymTabOrErr) { reportUniqueWarning(SymTabOrErr.takeError()); return *VersionsOrErr; } - if (SymTabOrErr->first.size() != VersionsOrErr->size()) + if (SymTabOrErr->Symbols.size() != VersionsOrErr->size()) reportUniqueWarning(describe(Sec) + ": the number of entries (" + Twine(VersionsOrErr->size()) + ") does not match the number of symbols (" + - Twine(SymTabOrErr->first.size()) + + Twine(SymTabOrErr->Symbols.size()) + ") in the symbol table with index " + Twine(Sec.sh_link)); - if (SymTab) - std::tie(*SymTab, *StrTab) = *SymTabOrErr; + if (SymTab) { + *SymTab = SymTabOrErr->Symbols; + *StrTab = SymTabOrErr->StringTable; + *SymTabSec = SymTabOrErr->SymTab; + } return *VersionsOrErr; } @@ -707,11 +740,14 @@ size_t Entries = 0; Elf_Sym_Range Syms(nullptr, nullptr); const Elf_Shdr *SymtabSec = IsDynamic ? DotDynsymSec : DotSymtabSec; + const Elf_Word *SymTabShndxAddr; + size_t SymTabShndxSize = 0; if (IsDynamic) { StrTable = DynamicStringTable; Syms = dynamic_symbols(); Entries = Syms.size(); + SymTabShndxAddr = (const Elf_Word *)this->getDynSymTabShndxRegion().Addr; } else if (DotSymtabSec) { if (Expected StrTableOrErr = Obj.getStringTableForSymtab(*DotSymtabSec)) @@ -728,6 +764,9 @@ "unable to read symbols from the SHT_SYMTAB section: " + toString(SymsOrErr.takeError())); Entries = DotSymtabSec->getEntityCount(); + ArrayRef ShNdxTable = this->getShndxTable(SymtabSec); + SymTabShndxAddr = ShNdxTable.data(); + SymTabShndxSize = ShNdxTable.size(); } if (Syms.begin() == Syms.end()) return; @@ -740,7 +779,8 @@ ELFDumperStyle->printSymtabMessage(SymtabSec, Entries, NonVisibilityBitsUsed); for (const Elf_Sym &Sym : Syms) - ELFDumperStyle->printSymbol(Sym, &Sym - Syms.begin(), StrTable, IsDynamic, + ELFDumperStyle->printSymbol(Sym, &Sym - Syms.begin(), SymTabShndxAddr, + SymTabShndxSize, StrTable, IsDynamic, NonVisibilityBitsUsed); } @@ -771,6 +811,7 @@ virtual void printSymtabMessage(const Elf_Shdr *Symtab, size_t Offset, bool NonVisibilityBitsUsed) {} virtual void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, size_t ShndxTableSize, Optional StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) = 0; virtual void printProgramHeaders(bool PrintProgramHeaders, @@ -932,6 +973,7 @@ return OS; } void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex, + const Elf_Word *ShndxTable, size_t ShndxTableSize, StringRef StrTable, uint32_t Bucket); void printReloc(const Relocation &R, unsigned RelIndex, const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; @@ -940,13 +982,16 @@ void printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym); void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, size_t ShndxTableSize, Optional StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) override; void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg) override; void printDynamicReloc(const Relocation &R) override; - std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex); + std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize); void printProgramHeaders(); void printSectionMapping(); void printGNUVersionSectionProlog(const typename ELFT::Shdr &Sec, @@ -1003,8 +1048,10 @@ void printRelRelaReloc(const Relocation &R, StringRef SymbolName); void printSymbols(); void printDynamicSymbols(); - void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex); + void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, size_t ShndxTableSize); void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, size_t ShndxTableSize, Optional StrTable, bool IsDynamic, bool /*NonVisibilityBitsUsed*/) override; void printProgramHeaders(); @@ -1130,8 +1177,10 @@ const Elf_Sym *FirstSym = cantFail(Obj.template getEntry(*SymTab, 0)); + ArrayRef ShndxTable = getShndxTable(SymTab); std::string SymbolName = getFullSymbolName( - *Sym, Sym - FirstSym, *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); + *Sym, Sym - FirstSym, ShndxTable.begin(), ShndxTable.size(), + *StrTableOrErr, SymTab->sh_type == SHT_DYNSYM); return RelSymbol(Sym, SymbolName); } @@ -1190,10 +1239,9 @@ } template -std::string ELFDumper::getFullSymbolName(const Elf_Sym &Symbol, - unsigned SymIndex, - Optional StrTable, - bool IsDynamic) const { +std::string ELFDumper::getFullSymbolName( + const Elf_Sym &Symbol, unsigned SymIndex, const Elf_Word *ShndxTable, + size_t ShndxTableSize, Optional StrTable, bool IsDynamic) const { if (!StrTable) return ""; @@ -1206,7 +1254,8 @@ } if (SymbolName.empty() && Symbol.getType() == ELF::STT_SECTION) { - Expected SectionIndex = getSymbolSectionIndex(Symbol, SymIndex); + Expected SectionIndex = + getSymbolSectionIndex(Symbol, SymIndex, ShndxTable, ShndxTableSize); if (!SectionIndex) { reportUniqueWarning(SectionIndex.takeError()); return ""; @@ -1238,12 +1287,13 @@ template Expected -ELFDumper::getSymbolSectionIndex(const Elf_Sym &Symbol, - unsigned SymIndex) const { +ELFDumper::getSymbolSectionIndex(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize) const { unsigned Ndx = Symbol.st_shndx; if (Ndx == SHN_XINDEX) - return object::getExtendedSymbolTableIndex(Symbol, SymIndex, - ShndxTable); + return object::getExtendedSymbolTableIndex( + Symbol, SymIndex, ShndxTable, ShndxTableSize); if (Ndx != SHN_UNDEF && Ndx < SHN_LORESERVE) return Ndx; @@ -2014,7 +2064,8 @@ ScopedPrinter &Writer) : ObjDumper(Writer, O.getFileName()), ObjF(O), Obj(O.getELFFile()), DynRelRegion(O, *this), DynRelaRegion(O, *this), DynRelrRegion(O, *this), - DynPLTRelRegion(O, *this), DynamicTable(O, *this) { + DynPLTRelRegion(O, *this), DynSymTabShndxRegion(O, *this), + DynamicTable(O, *this) { if (opts::Output == opts::GNU) ELFDumperStyle.reset(new GNUStyle(Writer, *this)); else @@ -2053,12 +2104,25 @@ } } break; - case ELF::SHT_SYMTAB_SHNDX: + case ELF::SHT_SYMTAB_SHNDX: { + uint32_t SymtabNdx = Sec.sh_link; + if (SymtabNdx >= Sections.size()) { + // TODO: test this warning. + reportUniqueWarning( + "unable to get the associated symbol table for " + describe(Sec) + + ": sh_link (" + Twine(SymtabNdx) + + ") is greater than or equal to the total number of sections (" + + Twine(Sections.size()) + ")"); + continue; + } + + // TODO: add failure on multiple link. if (Expected> ShndxTableOrErr = Obj.getSHNDXTable(Sec)) - ShndxTable = *ShndxTableOrErr; + ShndxTables[&Sections[SymtabNdx]] = *ShndxTableOrErr; else this->reportUniqueWarning(ShndxTableOrErr.takeError()); break; + } case ELF::SHT_GNU_versym: if (!SymbolVersionSection) SymbolVersionSection = &Sec; @@ -2197,6 +2261,10 @@ DynPLTRelRegion.Size = Dyn.getVal(); DynPLTRelRegion.SizePrintName = "DT_PLTRELSZ value"; break; + case ELF::DT_SYMTAB_SHNDX: + DynSymTabShndxRegion.Addr = toMappedAddr(Dyn.getTag(), Dyn.getPtr()); + DynSymTabShndxRegion.EntSize = sizeof(Elf_Word); + break; } } @@ -3969,7 +4037,9 @@ template std::string GNUStyle::getSymbolSectionNdx(const Elf_Sym &Symbol, - unsigned SymIndex) { + unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize) { unsigned SectionIndex = Symbol.st_shndx; switch (SectionIndex) { case ELF::SHN_UNDEF: @@ -3979,8 +4049,8 @@ case ELF::SHN_COMMON: return "COM"; case ELF::SHN_XINDEX: { - Expected IndexOrErr = object::getExtendedSymbolTableIndex( - Symbol, SymIndex, this->dumper().getShndxTable()); + Expected IndexOrErr = + object::getExtendedSymbolTableIndex(Symbol, SymIndex, ShndxTable, ShndxTableSize); if (!IndexOrErr) { assert(Symbol.st_shndx == SHN_XINDEX && "getExtendedSymbolTableIndex should only fail due to an invalid " @@ -4012,6 +4082,8 @@ template void GNUStyle::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize, Optional StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) { unsigned Bias = ELFT::Is64Bits ? 8 : 0; @@ -4038,10 +4110,9 @@ " []"; Fields[6].Column += NonVisibilityBitsUsed ? 13 : 0; - Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex); - - Fields[7].Str = - this->dumper().getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); + Fields[6].Str = getSymbolSectionNdx(Symbol, SymIndex, ShndxTable, ShndxTableSize); + Fields[7].Str = this->dumper().getFullSymbolName( + Symbol, SymIndex, ShndxTable, ShndxTableSize, StrTable, IsDynamic); for (const Field &Entry : Fields) printField(Entry); OS << "\n"; @@ -4049,7 +4120,10 @@ template void GNUStyle::printHashedSymbol(const Elf_Sym *Symbol, unsigned SymIndex, - StringRef StrTable, uint32_t Bucket) { + const Elf_Word *ShndxTable, + size_t ShndxTableSize, + StringRef StrTable, + uint32_t Bucket) { unsigned Bias = ELFT::Is64Bits ? 8 : 0; Field Fields[9] = {0, 6, 11, 20 + Bias, 25 + Bias, 34 + Bias, 41 + Bias, 49 + Bias, 53 + Bias}; @@ -4071,9 +4145,10 @@ printEnum(Symbol->getBinding(), makeArrayRef(ElfSymbolBindings)); Fields[6].Str = printEnum(Symbol->getVisibility(), makeArrayRef(ElfSymbolVisibilities)); - Fields[7].Str = getSymbolSectionNdx(*Symbol, SymIndex); - Fields[8].Str = - this->dumper().getFullSymbolName(*Symbol, SymIndex, StrTable, true); + Fields[7].Str = + getSymbolSectionNdx(*Symbol, SymIndex, ShndxTable, ShndxTableSize); + Fields[8].Str = this->dumper().getFullSymbolName( + *Symbol, SymIndex, ShndxTable, ShndxTableSize, StrTable, true); for (const Field &Entry : Fields) printField(Entry); @@ -4113,6 +4188,7 @@ return; } + DynRegionInfo ShndxTable = this->dumper().getDynSymTabShndxRegion(); auto Buckets = SysVHash.buckets(); auto Chains = SysVHash.chains(); for (uint32_t Buc = 0; Buc < SysVHash.nbucket; Buc++) { @@ -4130,7 +4206,8 @@ break; } - printHashedSymbol(FirstSym + Ch, Ch, StringTable, Buc); + printHashedSymbol(FirstSym + Ch, Ch, (const Elf_Word *)ShndxTable.Addr, + ShndxTable.Size, StringTable, Buc); Visited[Ch] = true; } } @@ -4176,6 +4253,7 @@ else Values = *ValuesOrErr; + DynRegionInfo ShndxTable = this->dumper().getDynSymTabShndxRegion(); ArrayRef Buckets = GnuHash.buckets(); for (uint32_t Buc = 0; Buc < GnuHash.nbuckets; Buc++) { if (Buckets[Buc] == ELF::STN_UNDEF) @@ -4185,7 +4263,8 @@ while (true) { uint32_t SymIndex = Index++; if (const Elf_Sym *Sym = GetSymbol(SymIndex, DynSyms.size())) - printHashedSymbol(Sym, SymIndex, StringTable, Buc); + printHashedSymbol(Sym, SymIndex, (const Elf_Word *)ShndxTable.Addr, + ShndxTable.Size, StringTable, Buc); else break; @@ -4724,7 +4803,7 @@ Sec->sh_size / sizeof(Elf_Versym)); Expected> VerTableOrErr = this->dumper().getVersionTable(*Sec, /*SymTab=*/nullptr, - /*StrTab=*/nullptr); + /*StrTab=*/nullptr, /*SymTabSec=*/nullptr); if (!VerTableOrErr) { this->reportUniqueWarning(VerTableOrErr.takeError()); return; @@ -5844,8 +5923,10 @@ // Check if the symbol is in the right section. FunctionSec == None // means "any section". if (FunctionSec) { - if (Expected SecOrErr = - Obj.getSection(Sym, SymTab, this->dumper().getShndxTable())) { + ArrayRef ShndxTable = + this->dumper().getShndxTable(SymTab); + if (Expected SecOrErr = Obj.getSection( + Sym, SymTab, ShndxTable.begin(), ShndxTable.size())) { if (*FunctionSec != *SecOrErr) continue; } else { @@ -5919,8 +6000,10 @@ uint64_t RelocSymValue = 0; if (Sym) { - Expected SectionOrErr = - this->Obj.getSection(*Sym, SymTab, this->dumper().getShndxTable()); + ArrayRef ShndxTable = + this->dumper().getShndxTable(SymTab); + Expected SectionOrErr = this->Obj.getSection( + *Sym, SymTab, ShndxTable.begin(), ShndxTable.size()); if (!SectionOrErr) { reportUniqueWarning( "cannot identify the section for relocation symbol '" + @@ -6147,8 +6230,10 @@ for (auto &E : Parser.getGlobalEntries()) { const Elf_Sym &Sym = *Parser.getGotSym(&E); const Elf_Sym &FirstSym = this->dumper().dynamic_symbols()[0]; + DynRegionInfo ShndxTable = this->dumper().getDynSymTabShndxRegion(); std::string SymName = this->dumper().getFullSymbolName( - Sym, &Sym - &FirstSym, this->dumper().getDynamicStringTable(), false); + Sym, &Sym - &FirstSym, (const Elf_Word *)ShndxTable.Addr, + ShndxTable.Size, this->dumper().getDynamicStringTable(), false); OS.PadToColumn(2); OS << to_string(format_hex_no_prefix(Parser.getGotAddress(&E), 8 + Bias)); @@ -6162,7 +6247,8 @@ OS << printEnum(Sym.getType(), makeArrayRef(ElfSymbolTypes)); OS.PadToColumn(48 + 3 * Bias); OS << getSymbolSectionNdx( - Sym, &Sym - this->dumper().dynamic_symbols().begin()); + Sym, &Sym - this->dumper().dynamic_symbols().begin(), + (const Elf_Word *)ShndxTable.Addr, ShndxTable.Size); OS.PadToColumn(52 + 3 * Bias); OS << SymName << "\n"; } @@ -6202,8 +6288,10 @@ const Elf_Sym &FirstSym = *cantFail(this->Obj.template getEntry( *Parser.getPltSymTable(), 0)); + DynRegionInfo ShndxTable = this->dumper().getDynSymTabShndxRegion(); std::string SymName = this->dumper().getFullSymbolName( - Sym, &Sym - &FirstSym, this->dumper().getDynamicStringTable(), false); + Sym, &Sym - &FirstSym, (const Elf_Word *)ShndxTable.Addr, + ShndxTable.Size, this->dumper().getDynamicStringTable(), false); OS.PadToColumn(2); OS << to_string(format_hex_no_prefix(Parser.getPltAddress(&E), 8 + Bias)); @@ -6215,7 +6303,8 @@ OS << printEnum(Sym.getType(), makeArrayRef(ElfSymbolTypes)); OS.PadToColumn(37 + 3 * Bias); OS << getSymbolSectionNdx( - Sym, &Sym - this->dumper().dynamic_symbols().begin()); + Sym, &Sym - this->dumper().dynamic_symbols().begin(), + (const Elf_Word *)ShndxTable.Addr, ShndxTable.Size); OS.PadToColumn(41 + 3 * Bias); OS << SymName << "\n"; } @@ -6455,15 +6544,17 @@ if (const Elf_Shdr *Symtab = this->dumper().getDotSymtabSec()) { StringRef StrTable = unwrapOrError( this->FileName, this->Obj.getStringTableForSymtab(*Symtab)); - + ArrayRef ShNdxTable = this->dumper().getShndxTable(Symtab); typename ELFT::SymRange Symbols = unwrapOrError(this->FileName, this->Obj.symbols(Symtab)); for (const Elf_Sym &Sym : Symbols) { - const Elf_Shdr *SymSec = unwrapOrError( - this->FileName, this->Obj.getSection( - Sym, Symtab, this->dumper().getShndxTable())); + const Elf_Shdr *SymSec = + unwrapOrError(this->FileName, + this->Obj.getSection(Sym, Symtab, ShNdxTable.data(), + ShNdxTable.size())); if (SymSec == &Sec) - printSymbol(Sym, &Sym - &Symbols[0], StrTable, false, false); + printSymbol(Sym, &Sym - &Symbols[0], ShNdxTable.data(), + ShNdxTable.size(), StrTable, false, false); } } } @@ -6480,7 +6571,9 @@ template void LLVMStyle::printSymbolSection(const Elf_Sym &Symbol, - unsigned SymIndex) { + unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize) { auto GetSectionSpecialType = [&]() -> Optional { if (Symbol.isUndefined()) return StringRef("Undefined"); @@ -6502,8 +6595,8 @@ return; } - Expected SectionIndex = - this->dumper().getSymbolSectionIndex(Symbol, SymIndex); + Expected SectionIndex = this->dumper().getSymbolSectionIndex( + Symbol, SymIndex, ShndxTable, ShndxTableSize); if (!SectionIndex) { assert(Symbol.st_shndx == SHN_XINDEX && "getSymbolSectionIndex should only fail due to an invalid " @@ -6530,10 +6623,12 @@ template void LLVMStyle::printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, + const Elf_Word *ShndxTable, + size_t ShndxTableSize, Optional StrTable, bool IsDynamic, bool /*NonVisibilityBitsUsed*/) { - std::string FullSymbolName = - this->dumper().getFullSymbolName(Symbol, SymIndex, StrTable, IsDynamic); + std::string FullSymbolName = this->dumper().getFullSymbolName( + Symbol, SymIndex, ShndxTable, ShndxTableSize, StrTable, IsDynamic); unsigned char SymbolType = Symbol.getType(); DictScope D(W, "Symbol"); @@ -6568,7 +6663,7 @@ } W.printFlags("Other", Symbol.st_other, makeArrayRef(SymOtherFlags), 0x3u); } - printSymbolSection(Symbol, SymIndex); + printSymbolSection(Symbol, SymIndex, ShndxTable, ShndxTableSize); } template @@ -6674,8 +6769,9 @@ StringRef StrTable; ArrayRef Syms; + const Elf_Shdr *SymTabSec; Expected> VerTableOrErr = - this->dumper().getVersionTable(*Sec, &Syms, &StrTable); + this->dumper().getVersionTable(*Sec, &Syms, &StrTable, &SymTabSec); if (!VerTableOrErr) { this->reportUniqueWarning(VerTableOrErr.takeError()); return; @@ -6684,11 +6780,14 @@ if (StrTable.empty() || Syms.empty() || Syms.size() != VerTableOrErr->size()) return; + ArrayRef ShNdxTable = this->dumper().getShndxTable(SymTabSec); 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], I, StrTable, - /*IsDynamic=*/true)); + W.printString( + "Name", this->dumper().getFullSymbolName(Syms[I], I, ShNdxTable.data(), + ShNdxTable.size(), StrTable, + /*IsDynamic=*/true)); } } @@ -7018,10 +7117,13 @@ W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes)); const unsigned SymIndex = &Sym - this->dumper().dynamic_symbols().begin(); - printSymbolSection(Sym, SymIndex); + DynRegionInfo ShndxTable = this->dumper().getDynSymTabShndxRegion(); + printSymbolSection(Sym, SymIndex, (const Elf_Word *)ShndxTable.Addr, + ShndxTable.Size); std::string SymName = this->dumper().getFullSymbolName( - Sym, SymIndex, this->dumper().getDynamicStringTable(), true); + Sym, SymIndex, (const Elf_Word *)ShndxTable.Addr, ShndxTable.Size, + this->dumper().getDynamicStringTable(), true); W.printNumber("Name", SymName, Sym.st_name); } } @@ -7055,6 +7157,7 @@ } { ListScope LS(W, "Entries"); + DynRegionInfo ShndxTable = this->dumper().getDynSymTabShndxRegion(); for (auto &E : Parser.getPltEntries()) { DictScope D(W, "Entry"); PrintEntry(&E); @@ -7062,13 +7165,15 @@ const Elf_Sym &Sym = *Parser.getPltSym(&E); W.printHex("Value", Sym.st_value); W.printEnum("Type", Sym.getType(), makeArrayRef(ElfSymbolTypes)); - printSymbolSection(Sym, &Sym - this->dumper().dynamic_symbols().begin()); + printSymbolSection(Sym, &Sym - this->dumper().dynamic_symbols().begin(), + (const Elf_Word *)ShndxTable.Addr, ShndxTable.Size); const Elf_Sym *FirstSym = cantFail(this->Obj.template getEntry( *Parser.getPltSymTable(), 0)); std::string SymName = this->dumper().getFullSymbolName( - Sym, &Sym - FirstSym, Parser.getPltStrTable(), true); + Sym, &Sym - FirstSym, (const Elf_Word *)ShndxTable.Addr, + ShndxTable.Size, Parser.getPltStrTable(), true); W.printNumber("Name", SymName, Sym.st_name); } } Index: llvm/tools/obj2yaml/elf2yaml.cpp =================================================================== --- llvm/tools/obj2yaml/elf2yaml.cpp +++ llvm/tools/obj2yaml/elf2yaml.cpp @@ -158,7 +158,9 @@ return SymbolNameOrErr; StringRef Name = *SymbolNameOrErr; if (Name.empty() && Sym->getType() == ELF::STT_SECTION) { - auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab)); + ArrayRef ShndxTable = ShndxTables.lookup(SymTab); + auto ShdrOrErr = + Obj.getSection(*Sym, SymTab, ShndxTable.data(), ShndxTable.size()); if (!ShdrOrErr) return ShdrOrErr.takeError(); return getUniquedSectionName(*ShdrOrErr); @@ -677,7 +679,9 @@ return Error::success(); } - auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab)); + ArrayRef ShndxTable = ShndxTables.lookup(SymTab); + auto ShdrOrErr = + Obj.getSection(*Sym, SymTab, ShndxTable.data(), ShndxTable.size()); if (!ShdrOrErr) return ShdrOrErr.takeError(); const Elf_Shdr *Shdr = *ShdrOrErr;