From abae3c11969defb6537dff99806668eacb6f0057 Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Fri, 4 Dec 2020 13:23:26 +0300 Subject: [PATCH] [obj2yaml] - Support dumping objects that have multiple SHT_SYMTAB_SHNDX sections. It is allowed to have multiple `SHT_SYMTAB_SHNDX` sections, though we currently don't implement it. The current implementation assumes that there is a maximum of one SHT_SYMTAB_SHNDX section and that it is always linked with .symtab section. This patch drops this limitations. Differential revision: https://reviews.llvm.org/D92644 --- llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml | 67 ++++++++++++---------- llvm/tools/obj2yaml/elf2yaml.cpp | 47 +++++++-------- 2 files changed, 58 insertions(+), 56 deletions(-) diff --git a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml index 2b33753..1c1e95e 100644 --- a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml +++ b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml @@ -94,7 +94,7 @@ Symbols: # 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 @@ Symbols: 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 @@ 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). @@ -143,7 +172,7 @@ Symbols: [] # 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 @@ Sections: 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 index 405e8b1..0885e92 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -53,7 +53,8 @@ class ELFDumper { const object::ELFFile &Obj; std::unique_ptr DWARFCtx; - ArrayRef ShndxTable; + + DenseMap> ShndxTables; Expected> dumpProgramHeaders(ArrayRef> Sections); @@ -157,7 +158,7 @@ ELFDumper::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable, 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 @@ template Expected ELFDumper::dump() { // 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 @@ template Expected ELFDumper::dump() { } 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 @@ Error ELFDumper::dumpSymbol(const Elf_Sym *Sym, const Elf_Shdr *SymTab, 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; -- 2.7.4