mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[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
This commit is contained in:
parent
a91e7c7d2b
commit
3f01c789e0
@ -383,10 +383,17 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
|
||||
if (DocSections.count(SecName))
|
||||
continue;
|
||||
|
||||
std::unique_ptr<ELFYAML::Chunk> Sec = std::make_unique<ELFYAML::Section>(
|
||||
std::unique_ptr<ELFYAML::Section> Sec = std::make_unique<ELFYAML::Section>(
|
||||
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 <class ELFT>
|
||||
void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
|
||||
ContiguousBlobAccumulator &CBA) {
|
||||
@ -721,11 +751,21 @@ void ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &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<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &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<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
|
||||
}
|
||||
}
|
||||
|
||||
zero(SHeader);
|
||||
SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym");
|
||||
|
||||
if (YAMLSec)
|
||||
@ -925,26 +961,6 @@ void ELFState<ELFT>::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<ELFT>::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 <class ELFT>
|
||||
void ELFState<ELFT>::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<ELFT>::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<ELFT>::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<ELFT>::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 <class ELFT>
|
||||
void ELFState<ELFT>::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 <class ELFT>
|
||||
void ELFState<ELFT>::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 <class ELFT>
|
||||
void ELFState<ELFT>::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<ELFT>::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<ELFT>::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 <class ELFT>
|
||||
void ELFState<ELFT>::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 <class ELFT>
|
||||
void ELFState<ELFT>::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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user