1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 18:42:46 +02:00

[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
This commit is contained in:
George Rimar 2019-06-25 08:22:57 +00:00
parent 5b2aa25659
commit 5646c326e2
6 changed files with 499 additions and 40 deletions

View File

@ -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

View File

@ -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

View File

@ -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]'

View File

@ -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]'

View File

@ -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;

View File

@ -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.