diff options
| author | George Rimar <grimar@accesssoftek.com> | 2019-06-25 08:22:57 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2019-06-25 08:22:57 +0000 |
| commit | 60dc5d4b61b0b513c1b66ba9565caf3b2703d8f5 (patch) | |
| tree | e0715fe3def6d7000b99f4c4853136def8417535 | |
| parent | 3bc5ad551a4fd947bcc7f417ae5bedbe0d6f0cdf (diff) | |
| download | bcm5719-llvm-60dc5d4b61b0b513c1b66ba9565caf3b2703d8f5.tar.gz bcm5719-llvm-60dc5d4b61b0b513c1b66ba9565caf3b2703d8f5.zip | |
[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
llvm-svn: 364282
| -rw-r--r-- | llvm/test/Object/X86/obj2yaml-dup-section-name.s | 14 | ||||
| -rw-r--r-- | llvm/test/tools/obj2yaml/duplicate-symbol-and-section-names.test | 152 | ||||
| -rw-r--r-- | llvm/test/tools/yaml2obj/duplicate-section-names.test | 170 | ||||
| -rw-r--r-- | llvm/test/tools/yaml2obj/duplicate-symbol-names.test | 100 | ||||
| -rw-r--r-- | llvm/tools/obj2yaml/elf2yaml.cpp | 86 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2elf.cpp | 17 |
6 files changed, 499 insertions, 40 deletions
diff --git a/llvm/test/Object/X86/obj2yaml-dup-section-name.s b/llvm/test/Object/X86/obj2yaml-dup-section-name.s index a02e93fa54a..0c480b420c2 100644 --- a/llvm/test/Object/X86/obj2yaml-dup-section-name.s +++ b/llvm/test/Object/X86/obj2yaml-dup-section-name.s @@ -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",@progbits,sym1,comdat diff --git a/llvm/test/tools/obj2yaml/duplicate-symbol-and-section-names.test b/llvm/test/tools/obj2yaml/duplicate-symbol-and-section-names.test new file mode 100644 index 00000000000..9dc198392c9 --- /dev/null +++ b/llvm/test/tools/obj2yaml/duplicate-symbol-and-section-names.test @@ -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 diff --git a/llvm/test/tools/yaml2obj/duplicate-section-names.test b/llvm/test/tools/yaml2obj/duplicate-section-names.test new file mode 100644 index 00000000000..68905adee5c --- /dev/null +++ b/llvm/test/tools/yaml2obj/duplicate-section-names.test @@ -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]' diff --git a/llvm/test/tools/yaml2obj/duplicate-symbol-names.test b/llvm/test/tools/yaml2obj/duplicate-symbol-names.test new file mode 100644 index 00000000000..f4a6be942cf --- /dev/null +++ b/llvm/test/tools/yaml2obj/duplicate-symbol-names.test @@ -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]' diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp index a9ea774c452..a47d5537a87 100644 --- a/llvm/tools/obj2yaml/elf2yaml.cpp +++ b/llvm/tools/obj2yaml/elf2yaml.cpp @@ -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(const Elf_Shdr *Sec) { 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>::getSymbolName(const Elf_Sym *Sym, 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::Object *> ELFDumper<ELFT>::dump() { 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::Object *> ELFDumper<ELFT>::dump() { } 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::Object *> ELFDumper<ELFT>::dump() { } } - 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_Shdr *Symtab, 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_Sym *Sym, const Elf_Shdr *SymTab, 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>::dumpRelocation(const RelT *Rel, 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>::dumpGroup(const Elf_Shdr *Shdr) { return errorToErrorCode(StrTabOrErr.takeError()); Expected<StringRef> SymbolName = - getSymbolName(*SymOrErr, *StrTabOrErr, Symtab); + getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab); if (!SymbolName) return errorToErrorCode(SymbolName.takeError()); S->Signature = *SymbolName; diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp index 43d51de4431..f3f78005043 100644 --- a/llvm/tools/yaml2obj/yaml2elf.cpp +++ b/llvm/tools/yaml2obj/yaml2elf.cpp @@ -266,6 +266,13 @@ bool ELFState<ELFT>::initImplicitHeader(ELFState<ELFT> &State, 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(ELFState<ELFT> &State, 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, ArrayRef<ELFYAML::Symbol> Symbols, 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(Elf_Shdr &SHeader, 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(ArrayRef<ELFYAML::Symbol> Symbols) { 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. |

