# 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:
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:
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).
# 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:
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
const object::ELFFile<ELFT> &Obj;
std::unique_ptr<DWARFContext> DWARFCtx;
- ArrayRef<Elf_Word> ShndxTable;
+
+ DenseMap<const Elf_Shdr *, ArrayRef<Elf_Word>> ShndxTables;
Expected<std::vector<ELFYAML::ProgramHeader>>
dumpProgramHeaders(ArrayRef<std::unique_ptr<ELFYAML::Chunk>> Sections);
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);
// 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) {
} 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<ArrayRef<Elf_Word>> 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))
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;