[llvm-branch-commits] [llvm] abae3c1 - [obj2yaml] - Support dumping objects that have multiple SHT_SYMTAB_SHNDX sections.

Georgii Rymar via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Dec 9 01:28:00 PST 2020


Author: Georgii Rymar
Date: 2020-12-09T12:14:58+03:00
New Revision: abae3c11969defb6537dff99806668eacb6f0057

URL: https://github.com/llvm/llvm-project/commit/abae3c11969defb6537dff99806668eacb6f0057
DIFF: https://github.com/llvm/llvm-project/commit/abae3c11969defb6537dff99806668eacb6f0057.diff

LOG: [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

Added: 
    

Modified: 
    llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml
    llvm/tools/obj2yaml/elf2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml b/llvm/test/tools/obj2yaml/ELF/sht-symtab-shndx.yaml
index 2b337538acba..1c1e95e5bacb 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 405e8b17d2fd..0885e92ee28a 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -53,7 +53,8 @@ class ELFDumper {
 
   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);
@@ -157,7 +158,7 @@ ELFDumper<ELFT>::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 <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::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 <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::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<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))
@@ -682,7 +677,7 @@ Error ELFDumper<ELFT>::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;


        


More information about the llvm-branch-commits mailing list