Index: llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s =================================================================== --- llvm/trunk/test/Object/X86/obj2yaml-dup-section-name.s +++ llvm/trunk/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 Index: llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test =================================================================== --- llvm/trunk/test/tools/obj2yaml/duplicate-symbol-and-section-names.test +++ llvm/trunk/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 Index: llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test =================================================================== --- llvm/trunk/test/tools/yaml2obj/duplicate-section-names.test +++ llvm/trunk/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]' Index: llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test =================================================================== --- llvm/trunk/test/tools/yaml2obj/duplicate-symbol-names.test +++ llvm/trunk/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]' Index: llvm/trunk/tools/obj2yaml/elf2yaml.cpp =================================================================== --- llvm/trunk/tools/obj2yaml/elf2yaml.cpp +++ llvm/trunk/tools/obj2yaml/elf2yaml.cpp @@ -28,15 +28,18 @@ typedef typename ELFT::Rela Elf_Rela; ArrayRef Sections; + ArrayRef SymTable; - // If the file has multiple sections with the same name, we add a - // suffix to make them unique. - unsigned Suffix = 0; - DenseSet UsedSectionNames; + DenseMap UsedSectionNames; std::vector SectionNames; + + DenseMap UsedSymbolNames; + std::vector SymbolNames; + Expected getUniquedSectionName(const Elf_Shdr *Sec); - Expected getSymbolName(const Elf_Sym *Sym, StringRef StrTable, - const Elf_Shdr *SymTab); + Expected getUniquedSymbolName(const Elf_Sym *Sym, + StringRef StrTable, + const Elf_Shdr *SymTab); const object::ELFFile &Obj; ArrayRef ShndxTable; @@ -87,16 +90,19 @@ 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 -Expected ELFDumper::getSymbolName(const Elf_Sym *Sym, - StringRef StrTable, - const Elf_Shdr *SymTab) { +Expected +ELFDumper::getUniquedSymbolName(const Elf_Sym *Sym, StringRef StrTable, + const Elf_Shdr *SymTab) { Expected SymbolNameOrErr = Sym->getName(StrTable); if (!SymbolNameOrErr) return SymbolNameOrErr; @@ -107,6 +113,24 @@ 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 @@ 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 @@ } 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 @@ } } - 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 @@ 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 @@ S.Other = Sym->st_other; S.Binding = Sym->getBinding(); - Expected SymbolNameOrErr = getSymbolName(Sym, StrTable, SymTab); + Expected SymbolNameOrErr = + getUniquedSymbolName(Sym, StrTable, SymTab); if (!SymbolNameOrErr) return errorToErrorCode(SymbolNameOrErr.takeError()); S.Name = SymbolNameOrErr.get(); @@ -310,7 +340,7 @@ StringRef StrTab = *StrTabOrErr; if (Sym) { - Expected NameOrErr = getSymbolName(Sym, StrTab, SymTab); + Expected NameOrErr = getUniquedSymbolName(Sym, StrTab, SymTab); if (!NameOrErr) return errorToErrorCode(NameOrErr.takeError()); R.Symbol = NameOrErr.get(); @@ -603,7 +633,7 @@ return errorToErrorCode(StrTabOrErr.takeError()); Expected SymbolName = - getSymbolName(*SymOrErr, *StrTabOrErr, Symtab); + getUniquedSymbolName(*SymOrErr, *StrTabOrErr, Symtab); if (!SymbolName) return errorToErrorCode(SymbolName.takeError()); S->Signature = *SymbolName; Index: llvm/trunk/tools/yaml2obj/yaml2elf.cpp =================================================================== --- llvm/trunk/tools/yaml2obj/yaml2elf.cpp +++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp @@ -266,6 +266,13 @@ return true; } +static StringRef dropUniqueSuffix(StringRef S) { + size_t SuffixPos = S.rfind(" ["); + if (SuffixPos == StringRef::npos) + return S; + return S.substr(0, SuffixPos); +} + template bool ELFState::initSectionHeaders(ELFState &State, std::vector &SHeaders, @@ -299,7 +306,7 @@ 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 @@ 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 @@ template bool ELFState::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 @@ template void ELFState::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.