From 3f01c789e05efc97a8e5dd7e6cdd4571535d36c6 Mon Sep 17 00:00:00 2001 From: Georgii Rymar Date: Mon, 25 Jan 2021 16:26:21 +0300 Subject: [PATCH] [yaml2obj] - Refine how we set the sh_link field. NFCI. This refactors the logic that sets the `sh_link` field. With this patch we set it in a single place for all sections. Differential revision: https://reviews.llvm.org/D95354 --- lib/ObjectYAML/ELFEmitter.cpp | 119 ++++++++++++---------------------- 1 file changed, 42 insertions(+), 77 deletions(-) diff --git a/lib/ObjectYAML/ELFEmitter.cpp b/lib/ObjectYAML/ELFEmitter.cpp index 5f1b031fe1d..1a6f0f1df84 100644 --- a/lib/ObjectYAML/ELFEmitter.cpp +++ b/lib/ObjectYAML/ELFEmitter.cpp @@ -383,10 +383,17 @@ ELFState::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH) if (DocSections.count(SecName)) continue; - std::unique_ptr Sec = std::make_unique( + std::unique_ptr Sec = std::make_unique( ELFYAML::Chunk::ChunkKind::RawContent, true /*IsImplicit*/); Sec->Name = SecName; + if (SecName == ".dynsym") + Sec->Type = ELF::SHT_DYNSYM; + else if (SecName == ".symtab") + Sec->Type = ELF::SHT_SYMTAB; + else + Sec->Type = ELF::SHT_STRTAB; + // When the section header table is explicitly defined at the end of the // sections list, it is reasonable to assume that the user wants to reorder // section headers, but still wants to place the section header table after @@ -682,6 +689,29 @@ static uint64_t writeContent(ContiguousBlobAccumulator &CBA, return *Size; } +static StringRef getDefaultLinkSec(unsigned SecType) { + switch (SecType) { + case ELF::SHT_REL: + case ELF::SHT_RELA: + case ELF::SHT_GROUP: + case ELF::SHT_LLVM_CALL_GRAPH_PROFILE: + case ELF::SHT_LLVM_ADDRSIG: + return ".symtab"; + case ELF::SHT_GNU_versym: + case ELF::SHT_HASH: + case ELF::SHT_GNU_HASH: + return ".dynsym"; + case ELF::SHT_DYNSYM: + case ELF::SHT_GNU_verdef: + case ELF::SHT_GNU_verneed: + return ".dynstr"; + case ELF::SHT_SYMTAB: + return ".strtab"; + default: + return ""; + } +} + template void ELFState::initSectionHeaders(std::vector &SHeaders, ContiguousBlobAccumulator &CBA) { @@ -721,11 +751,21 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, if (IsFirstUndefSection && Sec->IsImplicit) continue; + Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)]; + if (Sec->Link) { + SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name); + } else { + StringRef LinkSec = getDefaultLinkSec(Sec->Type); + unsigned Link = 0; + if (!LinkSec.empty() && !ExcludedSectionHeaders.count(LinkSec) && + SN2I.lookup(LinkSec, Link)) + SHeader.sh_link = Link; + } + // We have a few sections like string or symbol tables that are usually // added implicitly to the end. However, if they are explicitly specified // in the YAML, we need to write them here. This ensures the file offset // remains correct. - Elf_Shdr &SHeader = SHeaders[SN2I.get(Sec->Name)]; if (initImplicitHeader(CBA, SHeader, Sec->Name, Sec->IsImplicit ? nullptr : Sec)) continue; @@ -747,9 +787,6 @@ void ELFState::initSectionHeaders(std::vector &SHeaders, assignSectionAddress(SHeader, Sec); - if (Sec->Link) - SHeader.sh_link = toSectionIndex(*Sec->Link, Sec->Name); - if (Sec->EntSize) SHeader.sh_entsize = *Sec->EntSize; else @@ -917,7 +954,6 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, } } - zero(SHeader); SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym"); if (YAMLSec) @@ -925,26 +961,6 @@ void ELFState::initSymtabSectionHeader(Elf_Shdr &SHeader, else SHeader.sh_type = IsStatic ? ELF::SHT_SYMTAB : ELF::SHT_DYNSYM; - if (RawSec && RawSec->Link) { - // If the Link field is explicitly defined in the document, - // we should use it. - SHeader.sh_link = toSectionIndex(*RawSec->Link, RawSec->Name); - } else { - // When we describe the .dynsym section in the document explicitly, it is - // allowed to omit the "DynamicSymbols" tag. In this case .dynstr is not - // added implicitly and we should be able to leave the Link zeroed if - // .dynstr is not defined. - unsigned Link = 0; - if (IsStatic) { - if (!ExcludedSectionHeaders.count(".strtab")) - Link = SN2I.get(".strtab"); - } else { - if (!ExcludedSectionHeaders.count(".dynstr")) - SN2I.lookup(".dynstr", Link); - } - SHeader.sh_link = Link; - } - if (YAMLSec && YAMLSec->Flags) SHeader.sh_flags = *YAMLSec->Flags; else if (!IsStatic) @@ -981,7 +997,6 @@ void ELFState::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name, StringTableBuilder &STB, ContiguousBlobAccumulator &CBA, ELFYAML::Section *YAMLSec) { - zero(SHeader); SHeader.sh_name = getSectionNameOffset(Name); SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; @@ -1043,7 +1058,6 @@ template void ELFState::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, ContiguousBlobAccumulator &CBA, ELFYAML::Section *YAMLSec) { - zero(SHeader); SHeader.sh_name = getSectionNameOffset(ELFYAML::dropUniqueSuffix(Name)); SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_PROGBITS; SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; @@ -1083,9 +1097,6 @@ void ELFState::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name, else if (Name == ".debug_str") SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS; - if (YAMLSec && YAMLSec->Link) - SHeader.sh_link = toSectionIndex(*YAMLSec->Link, Name); - assignSectionAddress(SHeader, YAMLSec); } @@ -1229,12 +1240,6 @@ void ELFState::writeSectionContent( Section.Type == llvm::ELF::SHT_RELA) && "Section type is not SHT_REL nor SHT_RELA"); - // For relocation section set link to .symtab by default. - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".symtab") && - SN2I.lookup(".symtab", Link)) - SHeader.sh_link = Link; - if (!Section.RelocatableSec.empty()) SHeader.sh_info = toSectionIndex(Section.RelocatableSec, Section.Name); @@ -1307,11 +1312,6 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, assert(Section.Type == llvm::ELF::SHT_GROUP && "Section type is not SHT_GROUP"); - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".symtab") && - SN2I.lookup(".symtab", Link)) - SHeader.sh_link = Link; - if (Section.Signature) SHeader.sh_info = toSymbolIndex(*Section.Signature, Section.Name, /*IsDynamic=*/false); @@ -1334,11 +1334,6 @@ template void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::SymverSection &Section, ContiguousBlobAccumulator &CBA) { - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".dynsym") && - SN2I.lookup(".dynsym", Link)) - SHeader.sh_link = Link; - if (!Section.Entries) return; @@ -1444,11 +1439,6 @@ template void ELFState::writeSectionContent( Elf_Shdr &SHeader, const ELFYAML::CallGraphProfileSection &Section, ContiguousBlobAccumulator &CBA) { - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".symtab") && - SN2I.lookup(".symtab", Link)) - SHeader.sh_link = Link; - if (!Section.Entries) return; @@ -1467,11 +1457,6 @@ template void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::HashSection &Section, ContiguousBlobAccumulator &CBA) { - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".dynsym") && - SN2I.lookup(".dynsym", Link)) - SHeader.sh_link = Link; - if (!Section.Bucket) return; @@ -1503,11 +1488,6 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, else if (Section.Entries) SHeader.sh_info = Section.Entries->size(); - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".dynstr") && - SN2I.lookup(".dynstr", Link)) - SHeader.sh_link = Link; - if (!Section.Entries) return; @@ -1553,11 +1533,6 @@ void ELFState::writeSectionContent(Elf_Shdr &SHeader, else if (Section.VerneedV) SHeader.sh_info = Section.VerneedV->size(); - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".dynstr") && - SN2I.lookup(".dynstr", Link)) - SHeader.sh_link = Link; - if (!Section.VerneedV) return; @@ -1657,11 +1632,6 @@ template void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::AddrsigSection &Section, ContiguousBlobAccumulator &CBA) { - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".symtab") && - SN2I.lookup(".symtab", Link)) - SHeader.sh_link = Link; - if (!Section.Symbols) return; @@ -1718,11 +1688,6 @@ template void ELFState::writeSectionContent(Elf_Shdr &SHeader, const ELFYAML::GnuHashSection &Section, ContiguousBlobAccumulator &CBA) { - unsigned Link = 0; - if (!Section.Link && !ExcludedSectionHeaders.count(".dynsym") && - SN2I.lookup(".dynsym", Link)) - SHeader.sh_link = Link; - if (!Section.HashBuckets) return;