[llvm] r364282 - [yaml2obj/obj2yaml] - Allow having the symbols and sections with duplicated names.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 25 01:22:57 PDT 2019


Author: grimar
Date: Tue Jun 25 01:22:57 2019
New Revision: 364282

URL: http://llvm.org/viewvc/llvm-project?rev=364282&view=rev
Log:
[yaml2obj/obj2yaml] - Allow having the symbols and sections with duplicated names.

The patch teaches yaml2obj/obj2yaml to support parsing/dumping
the sections and symbols with the same name.
A special suffix is added to a name to make it unique.

Differential revision: https://reviews.llvm.org/D63596

Added:
    llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test
    llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test
    llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test
Modified:
    llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s
    llvm/trunk/tools/obj2yaml/elf2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s?rev=364282&r1=364281&r2=364282&view=diff
==============================================================================
--- llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s (original)
+++ llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s Tue Jun 25 01:22:57 2019
@@ -9,16 +9,16 @@
 # CHECK: - Name:            .text.foo{{$}}
 # CHECK: - Name:            .rela.text.foo{{$}}
 # CHECK:   Info:            .text.foo{{$}}
-# CHECK: - Name:            .group1{{$}}
+# CHECK: - Name:            '.group [1]'
 # CHECK:   Members:
-# CHECK:     - SectionOrType:   .text.foo2{{$}}
-# CHECK:     - SectionOrType:   .rela.text.foo3{{$}}
-# CHECK: - Name:            .text.foo2{{$}}
-# CHECK: - Name:            .rela.text.foo3{{$}}
-# CHECK:   Info:            .text.foo2{{$}}
+# CHECK:     - SectionOrType:   '.text.foo [1]'
+# CHECK:     - SectionOrType:   '.rela.text.foo [1]'
+# CHECK: - Name:            '.text.foo [1]'
+# CHECK: - Name:            '.rela.text.foo [1]'
+# CHECK:   Info:            '.text.foo [1]'
 # CHECK: Symbols:
 # CHECK:   Section:         .group{{$}}
-# CHECK:   Section:         .group1{{$}}
+# CHECK:   Section:         '.group [1]'
 
 
         .section        .text.foo,"axG", at progbits,sym1,comdat

Added: llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test?rev=364282&view=auto
==============================================================================
--- llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test (added)
+++ llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test Tue Jun 25 01:22:57 2019
@@ -0,0 +1,152 @@
+## Check that obj2yaml is able to produce YAML from
+## an object containing symbols and sections with duplicate
+## names and produces same-named sections and symbols
+## with distinguishing suffixes.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj -s -t %t1 | FileCheck %s
+
+# CHECK: Name: .foo (
+# CHECK: Name: .foo (
+# CHECK: Name: .foo (
+# CHECK: Name: .bar (
+# CHECK: Name: .bar (
+# CHECK: Name: .bar (
+
+# CHECK: Name: localfoo (
+# CHECK: Name: localfoo (
+# CHECK: Name: localfoo (
+# CHECK: Name: localbar (
+# CHECK: Name: localbar (
+# CHECK: Name: localbar (
+
+# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=CASE1
+
+# CASE1:      --- !ELF
+# CASE1-NEXT: FileHeader:
+# CASE1-NEXT:   Class:   ELFCLASS64
+# CASE1-NEXT:   Data:    ELFDATA2LSB
+# CASE1-NEXT:   Type:    ET_REL
+# CASE1-NEXT:   Machine: EM_X86_64
+# CASE1-NEXT: Sections:
+# CASE1-NEXT:   - Name: .foo
+# CASE1-NEXT:     Type: SHT_PROGBITS
+# CASE1-NEXT:   - Name: '.foo [1]'
+# CASE1-NEXT:     Type: SHT_PROGBITS
+# CASE1-NEXT:   - Name: '.foo [2]'
+# CASE1-NEXT:     Type: SHT_PROGBITS
+# CASE1-NEXT:   - Name: .bar
+# CASE1-NEXT:     Type: SHT_PROGBITS
+# CASE1-NEXT:   - Name: '.bar [1]'
+# CASE1-NEXT:     Type: SHT_PROGBITS
+# CASE1-NEXT:   - Name: '.bar [2]'
+# CASE1-NEXT:     Type: SHT_PROGBITS
+# CASE1-NEXT: Symbols:
+# CASE1-NEXT:   - Name: localfoo
+# CASE1-NEXT:   - Name: 'localfoo [1]'
+# CASE1-NEXT:   - Name: 'localfoo [2]'
+# CASE1-NEXT:   - Name: localbar
+# CASE1-NEXT:   - Name: 'localbar [1]'
+# CASE1-NEXT:   - Name: 'localbar [2]'
+# CASE1-NEXT: ...
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+  - Name: '.foo [555]'
+    Type: SHT_PROGBITS
+  - Name: '.foo [random_tag]'
+    Type: SHT_PROGBITS
+  - Name: .bar
+    Type: SHT_PROGBITS
+  - Name: '.bar [666]'
+    Type: SHT_PROGBITS
+  - Name: '.bar [random_tag]'
+    Type: SHT_PROGBITS
+Symbols:
+  - Name: 'localfoo [111]'
+  - Name: 'localfoo [222]'
+  - Name: 'localfoo [random_tag]' 
+  - Name: 'localbar [333]'
+  - Name: 'localbar [444]'
+  - Name: 'localbar [random_tag]' 
+
+## Check we can refer to symbols with the same
+## name from relocations.
+
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=CASE2
+
+# CASE2:      Relocations:
+# CASE2-NEXT:  - Offset: 0x0000000000000000
+# CASE2-NEXT:    Symbol: 'foo [1]'
+# CASE2-NEXT:    Type:   R_X86_64_PC32
+# CASE2-NEXT:  - Offset: 0x0000000000000004
+# CASE2-NEXT:    Symbol: foo
+# CASE2-NEXT:    Type:   R_X86_64_PC32
+# CASE2-NEXT: Symbols:
+# CASE2-NEXT:  - Name: foo
+# CASE2-NEXT:  - Name: 'foo [1]'
+  
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .text
+    Type: SHT_PROGBITS
+    Size: 8
+  - Name: .rela.text
+    Type: SHT_RELA
+    Info: .text
+    Link: .symtab
+    Relocations:
+      - Type: R_X86_64_PC32
+        Offset: 0
+        Symbol: 'foo [1]'
+      - Type: R_X86_64_PC32
+        Offset: 4
+        Symbol: foo
+Symbols:
+  - Name: foo
+  - Name: 'foo [1]'
+
+## Check obj2yaml does not add a suffix to a name if the
+## symbol is in .symtab and .dynsym at the same time.
+
+# RUN: yaml2obj --docnum=3 %s -o %t3
+# RUN: obj2yaml %t3 | FileCheck %s --check-prefix=CASE3
+
+# CASE3:      --- !ELF
+# CASE3-NEXT: FileHeader:
+# CASE3-NEXT:   Class:   ELFCLASS64
+# CASE3-NEXT:   Data:    ELFDATA2LSB
+# CASE3-NEXT:   Type:    ET_DYN
+# CASE3-NEXT:   Machine: EM_X86_64
+# CASE3-NEXT: Symbols:
+# CASE3-NEXT:   - Name:    foo
+# CASE3-NEXT:     Binding: STB_GLOBAL
+# CASE3-NEXT: DynamicSymbols:
+# CASE3-NEXT:   - Name:    foo
+# CASE3-NEXT:     Binding: STB_GLOBAL
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_DYN
+  Machine: EM_X86_64
+Symbols:
+  - Name:    foo
+    Binding: STB_GLOBAL
+DynamicSymbols:
+  - Name:    foo
+    Binding: STB_GLOBAL

Added: llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test?rev=364282&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test (added)
+++ llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test Tue Jun 25 01:22:57 2019
@@ -0,0 +1,170 @@
+## Check that yaml2obj is able to produce an object from YAML
+## containing sections with duplicate names (but different name suffixes).
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=CASE1
+
+# CASE1: Name: .foo1 (
+# CASE1: Name: .foo (
+# CASE1: Name: .foo (
+# CASE1: Name: .foo2 (
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo1
+    Type: SHT_PROGBITS
+  - Name: .foo
+    Type: SHT_PROGBITS
+  - Name: '.foo [1]'
+    Type: SHT_PROGBITS
+  - Name: .foo2
+    Type: SHT_PROGBITS
+
+## Check that yaml2obj reports an error in case we have
+## sections with equal names and suffixes.
+
+# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --check-prefix=CASE2
+# CASE2: error: Repeated section name: '.foo [1]' at YAML section number 1.
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: '.foo [1]'
+    Type: SHT_PROGBITS
+  - Name: '.foo [1]'
+    Type: SHT_PROGBITS
+
+## Check that yaml2obj reports an error in case we have
+## symbols without suffixes in the names and their
+## names are equal.
+
+# RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --check-prefix=CASE3
+# CASE3: error: Repeated section name: '.foo' at YAML section number 1.
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+  - Name: .foo
+    Type: SHT_PROGBITS
+
+## Check that yaml2obj can produce an object when symbols are defined
+## relative to sections with duplicate names (but different name suffixes).
+
+# RUN: yaml2obj --docnum=4 %s -o %t4
+# RUN: llvm-readobj -s -t %t4 | FileCheck %s --check-prefix=CASE4
+
+# CASE4:      Section {
+# CASE4:       Index: 1
+# CASE4-NEXT:  Name: .foo
+# CASE4:       Index: 2
+# CASE4-NEXT:  Name: .foo
+
+# CASE4:      Symbol {
+# CASE4:       Name: foo
+# CASE4-NEXT:  Value:
+# CASE4-NEXT:  Size:
+# CASE4-NEXT:  Binding:
+# CASE4-NEXT:  Type:
+# CASE4-NEXT:  Other:
+# CASE4-NEXT:  Section: .foo (0x1)
+# CASE4:       Name: bar
+# CASE4-NEXT:  Value:
+# CASE4-NEXT:  Size:
+# CASE4-NEXT:  Binding:
+# CASE4-NEXT:  Type:
+# CASE4-NEXT:  Other:
+# CASE4-NEXT:  Section: .foo (0x2)
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+  - Name: '.foo [1]'
+    Type: SHT_PROGBITS
+Symbols:
+  - Name:    foo
+    Section: .foo
+  - Name:    bar
+    Section: '.foo [1]'
+
+## Check that yaml2obj can produce SHT_GROUP sections that
+## reference sections and symbols with name suffixes.
+
+# RUN: yaml2obj --docnum=5 %s -o %t5
+# RUN: llvm-readobj --elf-section-groups %t5 | FileCheck %s --check-prefix=CASE5
+
+# CASE5:      Groups {
+# CASE5-NEXT:   Group {
+# CASE5-NEXT:     Name: .group (1)
+# CASE5-NEXT:     Index: 1
+# CASE5-NEXT:     Link: 5
+# CASE5-NEXT:     Info: 1
+# CASE5-NEXT:     Type: COMDAT (0x1)
+# CASE5-NEXT:     Signature: foo
+# CASE5-NEXT:     Section(s) in group [
+# CASE5-NEXT:       .text.foo (2)
+# CASE5-NEXT:     ]
+# CASE5-NEXT:   }
+# CASE5-NEXT:   Group {
+# CASE5-NEXT:     Name: .group (1)
+# CASE5-NEXT:     Index: 3
+# CASE5-NEXT:     Link: 5
+# CASE5-NEXT:     Info: 2
+# CASE5-NEXT:     Type: COMDAT (0x1)
+# CASE5-NEXT:     Signature: foo
+# CASE5-NEXT:     Section(s) in group [
+# CASE5-NEXT:       .text.foo (4)
+# CASE5-NEXT:     ]
+# CASE5-NEXT:   }
+# CASE5-NEXT: }
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .group
+    Type: SHT_GROUP
+    Link: .symtab
+    Info: foo
+    Members:
+      - SectionOrType: GRP_COMDAT
+      - SectionOrType: .text.foo
+  - Name: .text.foo
+    Type: SHT_PROGBITS
+  - Name: '.group [1]'
+    Type: SHT_GROUP
+    Link: .symtab
+    Info: 'foo [1]'
+    Members:         
+      - SectionOrType: GRP_COMDAT
+      - SectionOrType: '.text.foo [1]'
+  - Name: '.text.foo [1]'
+    Type: SHT_PROGBITS
+Symbols:
+  - Name:    foo
+    Section: .text.foo
+  - Name:    'foo [1]'
+    Section: '.text.foo [1]'

Added: llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test?rev=364282&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test (added)
+++ llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test Tue Jun 25 01:22:57 2019
@@ -0,0 +1,100 @@
+## Check that yaml2obj is able to produce an object from YAML
+## containing symbols with duplicate names (but different name suffixes).
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readobj -t %t1 | FileCheck %s --check-prefix=CASE1
+
+# CASE1: Name: localfoo (1)
+# CASE1: Name: localfoo (1)
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Symbols:
+  - Name: localfoo
+  - Name: 'localfoo [1]'
+
+## Check that yaml2obj reports an error when we have
+## symbols with equal names and suffixes.
+
+# RUN: not yaml2obj --docnum=2 %s 2>&1| FileCheck %s --check-prefix=CASE2
+# CASE2: error: Repeated symbol name: 'localfoo [1]'.
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Symbols:
+  - Name: 'localfoo [1]'
+  - Name: 'localfoo [1]'
+
+## Check that yaml2obj reports an error when we have
+## symbols without suffixes in the names and their
+## names are equal.
+
+# RUN: not yaml2obj --docnum=3 %s 2>&1| FileCheck %s --check-prefix=CASE3
+# CASE3: error: Repeated symbol name: 'localfoo'.
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Symbols:
+  - Name:    localfoo
+    Section: .text.foo.1
+  - Name:    localfoo
+    Section: .text.foo.2
+
+## Check that yaml2obj can produce correct relocations that
+## reference symbols with name suffixes.
+
+# RUN: yaml2obj --docnum=4 %s -o %t4
+# RUN: llvm-readobj -r --expand-relocs %t4 | FileCheck %s --check-prefix=CASE4
+
+# CASE4:      Relocations [
+# CASE4-NEXT:   Section {{.*}} .rela.text {
+# CASE4-NEXT:     Relocation {
+# CASE4-NEXT:       Offset: 0x0
+# CASE4-NEXT:       Type: R_X86_64_NONE
+# CASE4-NEXT:       Symbol: foo (1)
+# CASE4-NEXT:       Addend: 0x0
+# CASE4-NEXT:     }
+# CASE4-NEXT:     Relocation {
+# CASE4-NEXT:       Offset: 0x1
+# CASE4-NEXT:       Type: R_X86_64_NONE
+# CASE4-NEXT:       Symbol: foo (2)
+# CASE4-NEXT:       Addend: 0x0
+# CASE4-NEXT:     }
+# CASE4-NEXT:   }
+# CASE4-NEXT: ]
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .text
+    Type: SHT_PROGBITS
+  - Name: .rela.text
+    Type: SHT_RELA
+    Info: .text
+    Link: .symtab
+    Relocations:
+      - Offset: 0x0
+        Type:   R_X86_64_NONE
+        Symbol: foo
+      - Offset: 0x1
+        Type:   R_X86_64_NONE
+        Symbol: 'foo [1]'
+Symbols:
+  - Name: foo
+  - Name: 'foo [1]'

Modified: llvm/trunk/tools/obj2yaml/elf2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/elf2yaml.cpp?rev=364282&r1=364281&r2=364282&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/elf2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/elf2yaml.cpp Tue Jun 25 01:22:57 2019
@@ -28,15 +28,18 @@ class ELFDumper {
   typedef typename ELFT::Rela Elf_Rela;
 
   ArrayRef<Elf_Shdr> Sections;
+  ArrayRef<Elf_Sym> SymTable;
 
-  // If the file has multiple sections with the same name, we add a
-  // suffix to make them unique.
-  unsigned Suffix = 0;
-  DenseSet<StringRef> UsedSectionNames;
+  DenseMap<StringRef, uint32_t> UsedSectionNames;
   std::vector<std::string> SectionNames;
+
+  DenseMap<StringRef, uint32_t> UsedSymbolNames;
+  std::vector<std::string> SymbolNames;
+
   Expected<StringRef> getUniquedSectionName(const Elf_Shdr *Sec);
-  Expected<StringRef> getSymbolName(const Elf_Sym *Sym, StringRef StrTable,
-                                    const Elf_Shdr *SymTab);
+  Expected<StringRef> getUniquedSymbolName(const Elf_Sym *Sym,
+                                           StringRef StrTable,
+                                           const Elf_Shdr *SymTab);
 
   const object::ELFFile<ELFT> &Obj;
   ArrayRef<Elf_Word> ShndxTable;
@@ -87,16 +90,19 @@ ELFDumper<ELFT>::getUniquedSectionName(c
     return NameOrErr;
   StringRef Name = *NameOrErr;
   std::string &Ret = SectionNames[SecIndex];
-  Ret = Name;
-  while (!UsedSectionNames.insert(Ret).second)
-    Ret = (Name + to_string(++Suffix)).str();
+
+  auto It = UsedSectionNames.insert({Name, 0});
+  if (!It.second)
+    Ret = (Name + " [" + Twine(++It.first->second) + "]").str();
+  else
+    Ret = Name;
   return Ret;
 }
 
 template <class ELFT>
-Expected<StringRef> ELFDumper<ELFT>::getSymbolName(const Elf_Sym *Sym,
-                                                   StringRef StrTable,
-                                                   const Elf_Shdr *SymTab) {
+Expected<StringRef>
+ELFDumper<ELFT>::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable,
+                                      const Elf_Shdr *SymTab) {
   Expected<StringRef> SymbolNameOrErr = Sym->getName(StrTable);
   if (!SymbolNameOrErr)
     return SymbolNameOrErr;
@@ -107,6 +113,24 @@ Expected<StringRef> ELFDumper<ELFT>::get
       return ShdrOrErr.takeError();
     return getUniquedSectionName(*ShdrOrErr);
   }
+
+  // Symbols in .symtab can have duplicate names. For example, it is a common
+  // situation for local symbols in a relocatable object. Here we assign unique
+  // suffixes for such symbols so that we can differentiate them.
+  if (SymTab->sh_type == ELF::SHT_SYMTAB) {
+    unsigned Index = Sym - SymTable.data();
+    if (!SymbolNames[Index].empty())
+      return SymbolNames[Index];
+
+    auto It = UsedSymbolNames.insert({Name, 0});
+    if (!It.second)
+      SymbolNames[Index] =
+          (Name + " [" + Twine(++It.first->second) + "]").str();
+    else
+      SymbolNames[Index] = Name;
+    return SymbolNames[Index];
+  }
+
   return Name;
 }
 
@@ -123,15 +147,24 @@ template <class ELFT> ErrorOr<ELFYAML::O
   Y->Header.Flags = Obj.getHeader()->e_flags;
   Y->Header.Entry = Obj.getHeader()->e_entry;
 
-  const Elf_Shdr *Symtab = nullptr;
-  const Elf_Shdr *DynSymtab = nullptr;
-
   // Dump sections
   auto SectionsOrErr = Obj.sections();
   if (!SectionsOrErr)
     return errorToErrorCode(SectionsOrErr.takeError());
   Sections = *SectionsOrErr;
   SectionNames.resize(Sections.size());
+
+  // Dump symbols. We need to do this early because other sections might want
+  // to access the deduplicated symbol names that we also create here.
+  for (const Elf_Shdr &Sec : Sections) {
+    if (Sec.sh_type == ELF::SHT_SYMTAB)
+      if (auto EC = dumpSymbols(&Sec, Y->Symbols))
+        return EC;
+    if (Sec.sh_type == ELF::SHT_DYNSYM)
+      if (auto EC = dumpSymbols(&Sec, Y->DynamicSymbols))
+        return EC;
+  }
+
   for (const Elf_Shdr &Sec : Sections) {
     switch (Sec.sh_type) {
     case ELF::SHT_DYNAMIC: {
@@ -143,13 +176,9 @@ template <class ELFT> ErrorOr<ELFYAML::O
     }
     case ELF::SHT_NULL:
     case ELF::SHT_STRTAB:
-      // Do not dump these sections.
-      break;
     case ELF::SHT_SYMTAB:
-      Symtab = &Sec;
-      break;
     case ELF::SHT_DYNSYM:
-      DynSymtab = &Sec;
+      // Do not dump these sections.
       break;
     case ELF::SHT_SYMTAB_SHNDX: {
       auto TableOrErr = Obj.getSHNDXTable(Sec);
@@ -217,11 +246,6 @@ template <class ELFT> ErrorOr<ELFYAML::O
     }
   }
 
-  if (auto EC = dumpSymbols(Symtab, Y->Symbols))
-    return EC;
-  if (auto EC = dumpSymbols(DynSymtab, Y->DynamicSymbols))
-    return EC;
-
   return Y.release();
 }
 
@@ -241,6 +265,11 @@ ELFDumper<ELFT>::dumpSymbols(const Elf_S
   if (!SymtabOrErr)
     return errorToErrorCode(SymtabOrErr.takeError());
 
+  if (Symtab->sh_type == ELF::SHT_SYMTAB) {
+    SymTable = *SymtabOrErr;
+    SymbolNames.resize(SymTable.size());
+  }
+
   for (const auto &Sym : (*SymtabOrErr).drop_front()) {
     ELFYAML::Symbol S;
     if (auto EC = dumpSymbol(&Sym, Symtab, StrTable, S))
@@ -261,7 +290,8 @@ ELFDumper<ELFT>::dumpSymbol(const Elf_Sy
   S.Other = Sym->st_other;
   S.Binding = Sym->getBinding();
 
-  Expected<StringRef> SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab);
+  Expected<StringRef> SymbolNameOrErr =
+      getUniquedSymbolName(Sym, StrTable, SymTab);
   if (!SymbolNameOrErr)
     return errorToErrorCode(SymbolNameOrErr.takeError());
   S.Name = SymbolNameOrErr.get();
@@ -310,7 +340,7 @@ std::error_code ELFDumper<ELFT>::dumpRel
   StringRef StrTab = *StrTabOrErr;
 
   if (Sym) {
-    Expected<StringRef> NameOrErr = getSymbolName(Sym, StrTab, SymTab);
+    Expected<StringRef> NameOrErr = getUniquedSymbolName(Sym, StrTab, SymTab);
     if (!NameOrErr)
       return errorToErrorCode(NameOrErr.takeError());
     R.Symbol = NameOrErr.get();
@@ -603,7 +633,7 @@ ErrorOr<ELFYAML::Group *> ELFDumper<ELFT
     return errorToErrorCode(StrTabOrErr.takeError());
 
   Expected<StringRef> SymbolName =
-      getSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
+      getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab);
   if (!SymbolName)
     return errorToErrorCode(SymbolName.takeError());
   S->Signature = *SymbolName;

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=364282&r1=364281&r2=364282&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Tue Jun 25 01:22:57 2019
@@ -266,6 +266,13 @@ bool ELFState<ELFT>::initImplicitHeader(
   return true;
 }
 
+static StringRef dropUniqueSuffix(StringRef S) {
+  size_t SuffixPos = S.rfind(" [");
+  if (SuffixPos == StringRef::npos)
+    return S;
+  return S.substr(0, SuffixPos);
+}
+
 template <class ELFT>
 bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
                                         std::vector<Elf_Shdr> &SHeaders,
@@ -299,7 +306,7 @@ bool ELFState<ELFT>::initSectionHeaders(
     assert(Sec && "It can't be null unless it is an implicit section. But all "
                   "implicit sections should already have been handled above.");
 
-    SHeader.sh_name = DotShStrtab.getOffset(SecName);
+    SHeader.sh_name = DotShStrtab.getOffset(dropUniqueSuffix(SecName));
     SHeader.sh_type = Sec->Type;
     if (Sec->Flags)
       SHeader.sh_flags = *Sec->Flags;
@@ -391,7 +398,7 @@ toELFSymbols(NameToIdxMap &SN2I, ArrayRe
     if (Sym.NameIndex)
       Symbol.st_name = *Sym.NameIndex;
     else if (!Sym.Name.empty())
-      Symbol.st_name = Strtab.getOffset(Sym.Name);
+      Symbol.st_name = Strtab.getOffset(dropUniqueSuffix(Sym.Name));
 
     Symbol.setBindingAndType(Sym.Binding, Sym.Type);
     if (!Sym.Section.empty()) {
@@ -901,7 +908,7 @@ bool ELFState<ELFT>::writeSectionContent
 template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
   for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
     StringRef Name = Doc.Sections[i]->Name;
-    DotShStrtab.add(Name);
+    DotShStrtab.add(dropUniqueSuffix(Name));
     // "+ 1" to take into account the SHT_NULL entry.
     if (!SN2I.addName(Name, i + 1)) {
       WithColor::error() << "Repeated section name: '" << Name
@@ -950,12 +957,12 @@ bool ELFState<ELFT>::buildSymbolIndex(Ar
 template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
   // Add the regular symbol names to .strtab section.
   for (const ELFYAML::Symbol &Sym : Doc.Symbols)
-    DotStrtab.add(Sym.Name);
+    DotStrtab.add(dropUniqueSuffix(Sym.Name));
   DotStrtab.finalize();
 
   // Add the dynamic symbol names to .dynstr section.
   for (const ELFYAML::Symbol &Sym : Doc.DynamicSymbols)
-    DotDynstr.add(Sym.Name);
+    DotDynstr.add(dropUniqueSuffix(Sym.Name));
 
   // SHT_GNU_verdef and SHT_GNU_verneed sections might also
   // add strings to .dynstr section.




More information about the llvm-commits mailing list