diff --git a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml --- a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml +++ b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml @@ -94,7 +94,7 @@ # RUN: yaml2obj --docnum=4 %s -o %t4 # RUN: not obj2yaml %t4 2>&1 | FileCheck %s -DFILE=%t4 --check-prefix=CASE4 -## CASE4: Error reading file: [[FILE]]: SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2 +## CASE4: Error reading file: [[FILE]]: unable to read extended section indexes: SHT_SYMTAB_SHNDX has 3 entries, but the symbol table associated has 2 --- !ELF FileHeader: @@ -113,12 +113,14 @@ Index: SHN_XINDEX ## ELF gABI allows having multiple SHT_SYMTAB_SHNDX sections. -## We only support having one associated with .symtab now. +## Only one is allowed to be linked with a corresponding symbol table section though. +## Check we report an error when multiple SHT_SYMTAB_SHNDX sections are linked +## to the same symbol table. # RUN: yaml2obj --docnum=5 %s -o %t5 # RUN: not obj2yaml %t5 2>&1 | FileCheck %s -DFILE=%t5 --check-prefix=CASE5 -# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are not supported +# CASE5: Error reading file: [[FILE]]: multiple SHT_SYMTAB_SHNDX sections are linked to the same symbol table with index 5 --- !ELF FileHeader: @@ -128,14 +130,41 @@ Sections: - Name: .symtab_shndx1 Type: SHT_SYMTAB_SHNDX - Entries: [ 0 ] + Entries: [ 0, 1 ] EntSize: 4 Link: .symtab - Name: .symtab_shndx2 Type: SHT_SYMTAB_SHNDX - Entries: [ 0 ] - Link: .symtab -Symbols: [] + Entries: [ 0, 2 ] + Link: [[LINK=.symtab]] +Symbols: + - Type: STT_SECTION + Index: SHN_XINDEX +DynamicSymbols: + - Type: STT_SECTION + Index: SHN_XINDEX + +## Check it is possible to dump an object that has multiple SHT_SYMTAB_SHNDX sections. +## Check that yaml2obj can dump the object and dynamic symbols properly when +## the SHT_SYMTAB_SHNDX section is associated with a SHT_DYNSYM section. + +# RUN: yaml2obj --docnum=5 -DLINK=.dynsym %s -o %t5.multiple +# RUN: obj2yaml %t5.multiple | FileCheck %s --check-prefix=MULTIPLE-SYMTAB + +# MULTIPLE-SYMTAB: - Name: .symtab_shndx1 +# MULTIPLE-SYMTAB-NEXT: Type: SHT_SYMTAB_SHNDX +# MULTIPLE-SYMTAB-NEXT: Link: .symtab +# MULTIPLE-SYMTAB: - Name: .symtab_shndx2 +# MULTIPLE-SYMTAB-NEXT: Type: SHT_SYMTAB_SHNDX +# MULTIPLE-SYMTAB-NEXT: Link: .dynsym +# MULTIPLE-SYMTAB: Symbols: +# MULTIPLE-SYMTAB-NEXT: - Name: .symtab_shndx1 +# MULTIPLE-SYMTAB-NEXT: Type: STT_SECTION +# MULTIPLE-SYMTAB-NEXT: Index: SHN_XINDEX +# MULTIPLE-SYMTAB-NEXT: DynamicSymbols: +# MULTIPLE-SYMTAB-NEXT: - Name: .symtab_shndx2 +# MULTIPLE-SYMTAB-NEXT: Type: STT_SECTION +# MULTIPLE-SYMTAB-NEXT: Index: SHN_XINDEX ## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is ## not associated with a SHT_SYMTAB section (this case is illegal). @@ -143,7 +172,7 @@ # RUN: yaml2obj --docnum=6 %s -o %t6 # RUN: not obj2yaml %t6 2>&1 | FileCheck %s -DFILE=%t6 --check-prefix=CASE6 -# CASE6: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported +# CASE6: Error reading file: [[FILE]]: unable to read extended section indexes: SHT_SYMTAB_SHNDX section is linked with SHT_PROGBITS section (expected SHT_SYMTAB/SHT_DYNSYM) --- !ELF FileHeader: @@ -157,25 +186,3 @@ Link: .foo - Name: .foo Type: SHT_PROGBITS - -## Check that yaml2obj can't dump the object if SHT_SYMTAB_SHNDX is -## associated with a SHT_DYNSYM section (not implemented yet). - -# RUN: yaml2obj --docnum=7 %s -o %t7 -# RUN: not obj2yaml %t7 2>&1 | FileCheck %s -DFILE=%t7 --check-prefix=CASE7 - -# CASE7: Error reading file: [[FILE]]: only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported - ---- !ELF -FileHeader: - Class: ELFCLASS64 - Data: ELFDATA2LSB - Type: ET_REL -Sections: - - Name: .symtab_shndx - Type: SHT_SYMTAB_SHNDX - Entries: [ 0, 1 ] - Link: .dynsym -DynamicSymbols: - - Type: STT_SECTION - Index: SHN_XINDEX diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -53,7 +53,8 @@ const object::ELFFile &Obj; std::unique_ptr DWARFCtx; - ArrayRef ShndxTable; + + DenseMap> ShndxTables; Expected> dumpProgramHeaders(ArrayRef> Sections); @@ -157,7 +158,7 @@ return SymbolNameOrErr; StringRef Name = *SymbolNameOrErr; if (Name.empty() && Sym->getType() == ELF::STT_SECTION) { - auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTable); + auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab)); if (!ShdrOrErr) return ShdrOrErr.takeError(); return getUniquedSectionName(*ShdrOrErr); @@ -303,7 +304,6 @@ // Dump symbols. We need to do this early because other sections might want // to access the deduplicated symbol names that we also create here. const Elf_Shdr *SymTab = nullptr; - const Elf_Shdr *SymTabShndx = nullptr; const Elf_Shdr *DynSymTab = nullptr; for (const Elf_Shdr &Sec : Sections) { @@ -312,31 +312,26 @@ } else if (Sec.sh_type == ELF::SHT_DYNSYM) { DynSymTab = &Sec; } else if (Sec.sh_type == ELF::SHT_SYMTAB_SHNDX) { - // ABI allows us to have one SHT_SYMTAB_SHNDX for each symbol table. - // We only support having the SHT_SYMTAB_SHNDX for SHT_SYMTAB now. - if (SymTabShndx) - return createStringError( - errc::not_supported, - "multiple SHT_SYMTAB_SHNDX sections are not supported"); - SymTabShndx = &Sec; + // We need to locate SHT_SYMTAB_SHNDX sections early, because they + // might be needed for dumping symbols. + if (Expected> TableOrErr = Obj.getSHNDXTable(Sec)) { + // The `getSHNDXTable` calls the `getSection` internally when validates + // the symbol table section linked to the SHT_SYMTAB_SHNDX section. + const Elf_Shdr *LinkedSymTab = cantFail(Obj.getSection(Sec.sh_link)); + if (!ShndxTables.insert({LinkedSymTab, *TableOrErr}).second) + return createStringError( + errc::invalid_argument, + "multiple SHT_SYMTAB_SHNDX sections are " + "linked to the same symbol table with index " + + Twine(Sec.sh_link)); + } else { + return createStringError(errc::invalid_argument, + "unable to read extended section indexes: " + + toString(TableOrErr.takeError())); + } } } - // We need to locate the SHT_SYMTAB_SHNDX section early, because it might be - // needed for dumping symbols. - if (SymTabShndx) { - if (!SymTab || - SymTabShndx->sh_link != (unsigned)(SymTab - Sections.begin())) - return createStringError( - errc::not_supported, - "only SHT_SYMTAB_SHNDX associated with SHT_SYMTAB are supported"); - - auto TableOrErr = Obj.getSHNDXTable(*SymTabShndx); - if (!TableOrErr) - return TableOrErr.takeError(); - ShndxTable = *TableOrErr; - } - if (SymTab) { Y->Symbols.emplace(); if (Error E = dumpSymbols(SymTab, *Y->Symbols)) @@ -682,7 +677,7 @@ return Error::success(); } - auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTable); + auto ShdrOrErr = Obj.getSection(*Sym, SymTab, ShndxTables.lookup(SymTab)); if (!ShdrOrErr) return ShdrOrErr.takeError(); const Elf_Shdr *Shdr = *ShdrOrErr;