Index: llvm/include/llvm/ObjectYAML/ELFYAML.h =================================================================== --- llvm/include/llvm/ObjectYAML/ELFYAML.h +++ llvm/include/llvm/ObjectYAML/ELFYAML.h @@ -93,6 +93,7 @@ struct SectionHeaderTable { std::vector Sections; + Optional> Excluded; }; struct SectionName { Index: llvm/lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFEmitter.cpp +++ llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -128,6 +128,8 @@ NameToIdxMap DynSymN2I; ELFYAML::Object &Doc; + llvm::SetVector ExcludedSectionHeaders; + uint64_t LocationCounter = 0; bool HasError = false; yaml::ErrorHandler ErrHandler; @@ -230,6 +232,8 @@ uint64_t alignToOffset(ContiguousBlobAccumulator &CBA, uint64_t Align, llvm::Optional Offset); + uint64_t getSectionNameOffset(StringRef Name); + public: static bool writeELF(raw_ostream &OS, ELFYAML::Object &Doc, yaml::ErrorHandler EH); @@ -350,7 +354,8 @@ if (Doc.Header.SHStrNdx) Header.e_shstrndx = *Doc.Header.SHStrNdx; - else if (!Doc.SectionHeaders || !Doc.SectionHeaders->Sections.empty()) + else if ((!Doc.SectionHeaders || !Doc.SectionHeaders->Sections.empty()) && + !ExcludedSectionHeaders.count(".shstrtab")) Header.e_shstrndx = SN2I.get(".shstrtab"); else Header.e_shstrndx = 0; @@ -397,18 +402,33 @@ template unsigned ELFState::toSectionIndex(StringRef S, StringRef LocSec, StringRef LocSym) { + assert(LocSec.empty() || LocSym.empty()); + unsigned Index; - if (SN2I.lookup(S, Index) || to_integer(S, Index)) + if (!SN2I.lookup(S, Index) && !to_integer(S, Index)) { + if (!LocSym.empty()) + reportError("unknown section referenced: '" + S + "' by YAML symbol '" + + LocSym + "'"); + else + reportError("unknown section referenced: '" + S + "' by YAML section '" + + LocSec + "'"); + return 0; + } + + if (!Doc.SectionHeaders || !Doc.SectionHeaders->Excluded) return Index; - assert(LocSec.empty() || LocSym.empty()); - if (!LocSym.empty()) - reportError("unknown section referenced: '" + S + "' by YAML symbol '" + - LocSym + "'"); - else - reportError("unknown section referenced: '" + S + "' by YAML section '" + - LocSec + "'"); - return 0; + StringRef Name = LocSec.empty() ? LocSym : LocSec; + assert(!Doc.SectionHeaders->Sections.empty()); + if (Index >= Doc.SectionHeaders->Sections.size()) { + if (LocSym.empty()) + reportError("unable to link '" + LocSec + "' to excluded section '" + S + + "'"); + else + reportError("excluded section referenced: '" + S + "' by YAML symbol '" + + LocSym + "'"); + } + return Index; } template @@ -498,6 +518,15 @@ return S.substr(0, SuffixPos - 1); } +template +uint64_t ELFState::getSectionNameOffset(StringRef Name) { + // If a section is excluded from section headers, we do not save it's name in + // the string table. + if (ExcludedSectionHeaders.count(Name)) + return 0; + return DotShStrtab.getOffset(Name); +} + template void ELFState::initSectionHeaders(std::vector &SHeaders, ContiguousBlobAccumulator &CBA) { @@ -531,7 +560,7 @@ "implicit sections should already have been handled above."); SHeader.sh_name = - DotShStrtab.getOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); + getSectionNameOffset(ELFYAML::dropUniqueSuffix(Sec->Name)); SHeader.sh_type = Sec->Type; if (Sec->Flags) SHeader.sh_flags = *Sec->Flags; @@ -716,7 +745,7 @@ } zero(SHeader); - SHeader.sh_name = DotShStrtab.getOffset(IsStatic ? ".symtab" : ".dynsym"); + SHeader.sh_name = getSectionNameOffset(IsStatic ? ".symtab" : ".dynsym"); if (YAMLSec) SHeader.sh_type = YAMLSec->Type; @@ -733,10 +762,13 @@ // added implicitly and we should be able to leave the Link zeroed if // .dynstr is not defined. unsigned Link = 0; - if (IsStatic) - Link = SN2I.get(".strtab"); - else - SN2I.lookup(".dynstr", Link); + if (IsStatic) { + if (!ExcludedSectionHeaders.count(".strtab")) + Link = SN2I.get(".strtab"); + } else { + if (!ExcludedSectionHeaders.count(".dynstr")) + SN2I.lookup(".dynstr", Link); + } SHeader.sh_link = Link; } @@ -777,7 +809,7 @@ ContiguousBlobAccumulator &CBA, ELFYAML::Section *YAMLSec) { zero(SHeader); - SHeader.sh_name = DotShStrtab.getOffset(Name); + SHeader.sh_name = getSectionNameOffset(Name); SHeader.sh_type = YAMLSec ? YAMLSec->Type : ELF::SHT_STRTAB; SHeader.sh_addralign = YAMLSec ? (uint64_t)YAMLSec->AddressAlign : 1; @@ -830,7 +862,7 @@ ContiguousBlobAccumulator &CBA, ELFYAML::Section *YAMLSec) { zero(SHeader); - SHeader.sh_name = DotShStrtab.getOffset(ELFYAML::dropUniqueSuffix(Name)); + 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; SHeader.sh_offset = alignToOffset(CBA, SHeader.sh_addralign, @@ -864,9 +896,8 @@ else if (Name == ".debug_str") SHeader.sh_flags = ELF::SHF_MERGE | ELF::SHF_STRINGS; - unsigned Link = 0; - if (YAMLSec && !YAMLSec->Link.empty() && SN2I.lookup(YAMLSec->Link, Link)) - SHeader.sh_link = Link; + if (YAMLSec && !YAMLSec->Link.empty()) + SHeader.sh_link = toSectionIndex(YAMLSec->Link, Name); assignSectionAddress(SHeader, YAMLSec); } @@ -990,7 +1021,8 @@ // For relocation section set link to .symtab by default. unsigned Link = 0; - if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) + if (Section.Link.empty() && !ExcludedSectionHeaders.count(".symtab") && + SN2I.lookup(".symtab", Link)) SHeader.sh_link = Link; if (!Section.RelocatableSec.empty()) @@ -1063,7 +1095,8 @@ "Section type is not SHT_GROUP"); unsigned Link = 0; - if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) + if (Section.Link.empty() && !ExcludedSectionHeaders.count(".symtab") && + SN2I.lookup(".symtab", Link)) SHeader.sh_link = Link; SHeader.sh_entsize = 4; @@ -1188,7 +1221,8 @@ SHeader.sh_entsize = 16; unsigned Link = 0; - if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) + if (Section.Link.empty() && !ExcludedSectionHeaders.count(".symtab") && + SN2I.lookup(".symtab", Link)) SHeader.sh_link = Link; raw_ostream &OS = CBA.getOS(); @@ -1216,7 +1250,8 @@ const ELFYAML::HashSection &Section, ContiguousBlobAccumulator &CBA) { unsigned Link = 0; - if (Section.Link.empty() && SN2I.lookup(".dynsym", Link)) + if (Section.Link.empty() && !ExcludedSectionHeaders.count(".dynsym") && + SN2I.lookup(".dynsym", Link)) SHeader.sh_link = Link; raw_ostream &OS = CBA.getOS(); @@ -1406,7 +1441,8 @@ const ELFYAML::AddrsigSection &Section, ContiguousBlobAccumulator &CBA) { unsigned Link = 0; - if (Section.Link.empty() && SN2I.lookup(".symtab", Link)) + if (Section.Link.empty() && !ExcludedSectionHeaders.count(".symtab") && + SN2I.lookup(".symtab", Link)) SHeader.sh_link = Link; raw_ostream &OS = CBA.getOS(); @@ -1472,7 +1508,8 @@ const ELFYAML::GnuHashSection &Section, ContiguousBlobAccumulator &CBA) { unsigned Link = 0; - if (Section.Link.empty() && SN2I.lookup(".dynsym", Link)) + if (Section.Link.empty() && !ExcludedSectionHeaders.count(".dynsym") && + SN2I.lookup(".dynsym", Link)) SHeader.sh_link = Link; raw_ostream &OS = CBA.getOS(); @@ -1548,18 +1585,29 @@ template DenseMap ELFState::buildSectionHeaderReorderMap() { - if (!Doc.SectionHeaders || Doc.SectionHeaders->Sections.empty()) + if (!Doc.SectionHeaders || Doc.SectionHeaders->Sections.empty()) { + if (Doc.SectionHeaders && Doc.SectionHeaders->Excluded) + reportError("'Excluded' can't be used with an empty `Sections` list"); return DenseMap(); + } DenseMap Ret; size_t SecNdx = 0; StringSet<> Seen; - for (const ELFYAML::SectionHeader &Hdr : Doc.SectionHeaders->Sections) { + + auto AddSection = [&](const ELFYAML::SectionHeader &Hdr) { if (!Ret.try_emplace(Hdr.Name, ++SecNdx).second) reportError("repeated section name: '" + Hdr.Name + "' in the section header description"); Seen.insert(Hdr.Name); - } + }; + + for (const ELFYAML::SectionHeader &Hdr : Doc.SectionHeaders->Sections) + AddSection(Hdr); + + if (Doc.SectionHeaders->Excluded) + for (const ELFYAML::SectionHeader &Hdr : *Doc.SectionHeaders->Excluded) + AddSection(Hdr); for (const ELFYAML::Section *S : Doc.getSections()) { // Ignore special first SHT_NULL section. @@ -1567,7 +1615,7 @@ continue; if (!Seen.count(S->Name)) reportError("section '" + S->Name + - "' should be present in the 'Sections' list"); + "' should be present in the 'Sections' or `Excluded` lists"); Seen.erase(S->Name); } @@ -1577,21 +1625,36 @@ return Ret; } +static bool hasSectionHeader(const ELFYAML::Object &Doc, size_t SecNdx) { + if (!Doc.SectionHeaders) + return true; + return SecNdx < Doc.SectionHeaders->Sections.size(); +} + template void ELFState::buildSectionIndex() { - // A YAML description can have an explicit section header declaration that allows - // to change the order of section headers. + // A YAML description can have an explicit section header declaration that + // allows to change the order of section headers. DenseMap ReorderMap = buildSectionHeaderReorderMap(); + if (HasError) + return; + + // Build excluded section headers map. + if (Doc.SectionHeaders && Doc.SectionHeaders->Excluded) + for (const ELFYAML::SectionHeader &Hdr : *Doc.SectionHeaders->Excluded) + if (!ExcludedSectionHeaders.insert(Hdr.Name)) + llvm_unreachable("buildSectionIndex() failed"); + size_t SecNdx = -1; - for (const std::unique_ptr &C : Doc.Chunks) { - if (!isa(C.get())) - continue; + for (const ELFYAML::Section *S : Doc.getSections()) { ++SecNdx; - size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(C->Name); - if (!SN2I.addName(C->Name, Index)) + size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name); + if (!SN2I.addName(S->Name, Index)) llvm_unreachable("buildSectionIndex() failed"); - DotShStrtab.add(ELFYAML::dropUniqueSuffix(C->Name)); + + if (!ExcludedSectionHeaders.count(S->Name)) + DotShStrtab.add(ELFYAML::dropUniqueSuffix(S->Name)); } DotShStrtab.finalize(); @@ -1661,6 +1724,9 @@ State.buildSectionIndex(); State.buildSymbolIndexes(); + if (State.HasError) + return false; + std::vector PHeaders; State.initProgramHeaders(PHeaders); Index: llvm/lib/ObjectYAML/ELFYAML.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFYAML.cpp +++ llvm/lib/ObjectYAML/ELFYAML.cpp @@ -840,6 +840,7 @@ void MappingTraits::mapping( IO &IO, ELFYAML::SectionHeaderTable &SectionHeader) { IO.mapRequired("Sections", SectionHeader.Sections); + IO.mapOptional("Excluded", SectionHeader.Excluded); } void MappingTraits::mapping(IO &IO, Index: llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml =================================================================== --- /dev/null +++ llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml @@ -0,0 +1,433 @@ +## Check how we can use the "Excluded" key of the "SectionHeaderTable" tag to exclude +## entries from the section headers. + +## Check we can use the "Excluded" key to omit a section from the sections header table. +## Check we do not include the name of the excluded section to the sections string table. +# RUN: yaml2obj %s -DINCLUDED=.foo -DEXCLUDED=.bar --docnum=1 -o %t1 +# RUN: llvm-readelf --section-headers -x .shstrtab %t1 | \ +# RUN: FileCheck %s -DSEC=.foo --check-prefixes=INCLUDE-SEC,INCLUDE-FOO +# RUN: yaml2obj %s -DINCLUDED=.bar -DEXCLUDED=.foo --docnum=1 -o %t2 +# RUN: llvm-readelf --section-headers -x .shstrtab %t2 | \ +# RUN: FileCheck %s -DSEC=.bar --check-prefixes=INCLUDE-SEC,INCLUDE-BAR + +# INCLUDE-SEC: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# INCLUDE-SEC: [ 1] [[SEC]] PROGBITS 0000000000000000 000040 000000 00 0 0 0 +# INCLUDE-SEC-NEXT: [ 2] .strtab STRTAB 0000000000000000 000040 000001 00 0 0 1 +# INCLUDE-SEC-NEXT: [ 3] .shstrtab STRTAB 0000000000000000 000041 000018 00 0 0 1 + +# INCLUDE-SEC: Hex dump of section '.shstrtab': +# INCLUDE-FOO-NEXT: 0x00000000 002e666f 6f002e73 68737472 74616200 ..foo..shstrtab. +# INCLUDE-BAR-NEXT: 0x00000000 002e6261 72002e73 68737472 74616200 ..bar..shstrtab. +# INCLUDE-SEC-NEXT: 0x00000010 2e737472 74616200 .strtab. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + - Name: .bar + Type: SHT_PROGBITS +SectionHeaderTable: + Sections: + - Name: [[INCLUDED]] + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: [[EXCLUDED]] + +## Check we report an error when a section is in the both "Sections" and "Excluded" lists at the same time. +# RUN: not yaml2obj %s -DINCLUDED=.bar -DEXCLUDED=.strtab --docnum=1 -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=EXCLUDE-INCLUDED + +# EXCLUDE-INCLUDED: error: repeated section name: '.strtab' in the section header description +# EXCLUDE-INCLUDED: error: section '.foo' should be present in the 'Sections' or `Excluded` lists + +## Check we report an error when the `Excluded` key mentions an unknown section. +# RUN: not yaml2obj %s -DINCLUDED=.bar -DEXCLUDED=.unknown --docnum=1 -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=EXCLUDE-UNKNOWN + +# EXCLUDE-UNKNOWN: error: section '.foo' should be present in the 'Sections' or `Excluded` lists +# EXCLUDE-UNKNOWN: error: section header contains undefined section '.unknown' + +## Check we report an error when the `Excluded` key mentions a section more than once. +# RUN: not yaml2obj %s --docnum=2 -o /dev/null 2>&1 | FileCheck %s --check-prefix=EXCLUDE-TWICE + +# EXCLUDE-TWICE: error: repeated section name: '.strtab' in the section header description +# EXCLUDE-TWICE: error: repeated section name: '.strtab' in the section header description + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +SectionHeaderTable: + Sections: + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .strtab + - Name: .strtab + +## Check we report an error when the `Excluded` key is used, but an empty +## section header is requested. +# RUN: not yaml2obj %s --docnum=3 -o /dev/null 2>&1 | FileCheck %s --check-prefix=NO-SECTIONS +# RUN: not yaml2obj %s --docnum=4 -o /dev/null 2>&1 | FileCheck %s --check-prefix=NO-SECTIONS + +# NO-SECTIONS: error: 'Excluded' can't be used with an empty `Sections` list + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +SectionHeaderTable: + Sections: [] + Excluded: + - Name: .strtab + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +SectionHeaderTable: + Sections: [] + Excluded: [] + +## Check how we handle cases when a section is excluded, but it's section index is needed. +## The general rule is: when a section is explicitly linked with another section, which is +## excluded, then we report an error. In the case when it is linked implicitly with an excluded +## section, we use 0 as index value. + +## Case A: check we report an error when a regular section has the Link field which +## points to an excluded section. +# RUN: not yaml2obj %s --docnum=5 -DINCLUDED=.foo -DEXCLUDED=.bar -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK -DSEC=.foo -DTARGET=.bar +# RUN: not yaml2obj %s --docnum=5 -DINCLUDED=.bar -DEXCLUDED=.foo -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK -DSEC=.bar -DTARGET=.foo + +# LINK: error: unable to link '[[SEC]]' to excluded section '[[TARGET]]' + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS + Link: .bar + - Name: .bar + Type: SHT_PROGBITS + Link: .foo +SectionHeaderTable: + Sections: + - Name: [[INCLUDED]] + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: [[EXCLUDED]] + +## Case B.1: check we report an error when a symbol table section has the Link field which +## points to an excluded section. +# RUN: not yaml2obj %s --docnum=6 -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK -DSEC=.symtab -DTARGET=.foo + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + Link: .foo + - Name: .foo + Type: SHT_PROGBITS +SectionHeaderTable: + Sections: + - Name: .symtab + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .foo + +## Case B.2: check we do not link .dynsym with .dynstr implicitly when the latter one is excluded. +# RUN: yaml2obj %s --docnum=7 -o %t7 +# RUN: llvm-readelf %t7 --section-headers | FileCheck %s --check-prefix=LINK-DYNSYM + +# LINK-DYNSYM: [Nr] Name Type Address Off Size ES Flg Lk +# LINK-DYNSYM: [ 1] .dynsym DYNSYM 0000000000000000 000040 000018 18 A 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .dynsym + Type: SHT_DYNSYM + - Name: .dynstr + Type: SHT_PROGBITS +SectionHeaderTable: + Sections: + - Name: .dynsym + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .dynstr + +## Case B.3: check we do not link .symtab with .strtab implicitly when the latter one is excluded. +# RUN: yaml2obj %s --docnum=8 -o %t8 +# RUN: llvm-readelf %t8 --section-headers | FileCheck %s --check-prefix=LINK-SYMTAB + +# LINK-SYMTAB: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# LINK-SYMTAB: [ 1] .symtab SYMTAB 0000000000000000 000040 000018 18 0 1 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .symtab + Type: SHT_SYMTAB + - Name: .strtab + Type: SHT_PROGBITS +SectionHeaderTable: + Sections: + - Name: .symtab + - Name: .shstrtab + Excluded: + - Name: .strtab + +## Case C: check we report an error when a debug section has the Link field which +## points to an excluded section. +# RUN: not yaml2obj %s --docnum=9 -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK -DSEC=.debug_unknown -DTARGET=.strtab + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_unknown + Type: SHT_PROGBITS + Link: .strtab +SectionHeaderTable: + Sections: + - Name: .debug_unknown + - Name: .shstrtab + Excluded: + - Name: .strtab + +## Case D.1: check we do not link the SHT_REL[A] section with .symtab implicitly +## when the latter one is excluded. +# RUN: yaml2obj %s --docnum=10 -o %t10 -DINCLUDED=.strtab -DEXCLUDED=.symtab +# RUN: llvm-readelf %t10 --section-headers | FileCheck %s --check-prefix=LINK-REL + +# LINK-REL: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# LINK-REL: [ 1] .rela RELA 0000000000000000 000040 000000 18 0 2 0 + +## Case D.2: check we report an error when a relocatable section has the Info field which +## points to an excluded section. +# RUN: not yaml2obj %s --docnum=10 -DINCLUDED=.symtab -DEXCLUDED=.strtab -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK -DSEC=.rela -DTARGET=.strtab + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .rela + Type: SHT_RELA + Info: .strtab + Relocations: [] + - Name: .symtab + Type: SHT_PROGBITS +SectionHeaderTable: + Sections: + - Name: .rela + - Name: [[INCLUDED]] + - Name: .shstrtab + Excluded: + - Name: [[EXCLUDED]] + +## Case C: check we report an error when a symbol references an excluded section. +# RUN: not yaml2obj %s --docnum=11 -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=SYMBOL-SECTION + +# SYMBOL-SECTION: error: excluded section referenced: '.foo' by YAML symbol 'foo' + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .foo + Type: SHT_PROGBITS +Symbols: + - Name: foo + Type: STT_OBJECT + Section: .foo +SectionHeaderTable: + Sections: + - Name: .symtab + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .foo + +## Case D.1: check we report an error when a group section +## contains an excluded section member. +# RUN: not yaml2obj %s --docnum=12 -o /dev/null 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK -DSEC=.group -DTARGET=.strtab + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Members: + - SectionOrType: .strtab +SectionHeaderTable: + Sections: + - Name: .group + - Name: .shstrtab + Excluded: + - Name: .strtab + +## Case D.2: check we do not link the SHT_GROUP section with .symtab +## implicitly when the latter one is excluded. +# RUN: yaml2obj %s --docnum=13 -o %t9 +# RUN: llvm-readelf %t9 --section-headers | FileCheck %s --check-prefix=LINK-GROUP + +# LINK-GROUP: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# LINK-GROUP: [ 1] .group GROUP 0000000000000000 000040 000000 04 0 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +Sections: + - Name: .group + Type: SHT_GROUP + Members: [] + - Name: .symtab + Type: SHT_SYMTAB +SectionHeaderTable: + Sections: + - Name: .group + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .symtab + +## Case E: check we do not link SHT_LLVM_CALL_GRAPH_PROFILE/SHT_LLVM_ADDRSIG sections +## with .symtab implicitly when the latter one is excluded. +# RUN: yaml2obj %s --docnum=14 -o %t10 +# RUN: llvm-readelf %t10 --section-headers | FileCheck %s --check-prefix=LINK-CGP + +# LINK-CGP: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# LINK-CGP: [ 1] .cgp LLVM_CALL_GRAPH_PROFILE 0000000000000000 000040 000000 10 0 0 0 +# LINK-CGP: [ 2] .llvm_addrsig LLVM_ADDRSIG 0000000000000000 000040 000000 00 0 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .cgp + Type: SHT_LLVM_CALL_GRAPH_PROFILE + Content: "" + - Name: .llvm_addrsig + Type: SHT_LLVM_ADDRSIG + Content: "" + - Name: .symtab + Type: SHT_SYMTAB +SectionHeaderTable: + Sections: + - Name: .cgp + - Name: .llvm_addrsig + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .symtab + +## Case F: check we do not link SHT_HASH/SHT_GNU_HASH sections with .dynsym +## implicitly when the latter one is excluded. +# RUN: yaml2obj %s --docnum=15 -o %t11 +# RUN: llvm-readelf %t11 --section-headers | FileCheck %s --check-prefix=LINK-HASH + +# LINK-HASH: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# LINK-HASH: [ 1] .hash HASH 0000000000000000 000040 000000 00 0 0 0 +# LINK-HASH: [ 2] .gnu_hash GNU_HASH 0000000000000000 000040 000000 00 0 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_DYN + Machine: EM_X86_64 +Sections: + - Name: .hash + Type: SHT_HASH + Content: "" + - Name: .gnu_hash + Type: SHT_GNU_HASH + Content: "" + - Name: .dynsym + Type: SHT_DYNSYM +SectionHeaderTable: + Sections: + - Name: .hash + - Name: .gnu_hash + - Name: .strtab + - Name: .shstrtab + Excluded: + - Name: .dynsym + +## Check we set e_shstrndx field to 0 when the section header string table is excluded. +## Check that the e_shnum field is adjusted properly when a section is removed. +# RUN: yaml2obj --docnum=16 %s -o %t12 +# RUN: llvm-readelf --file-headers %t12 | FileCheck %s --check-prefix=SHSTRTAB + +# SHSTRTAB: Number of section headers: 2 +# SHSTRTAB: Section header string table index: 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +SectionHeaderTable: + Sections: + - Name: .strtab + Excluded: + - Name: .shstrtab Index: llvm/test/tools/yaml2obj/ELF/section-headers.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/section-headers.yaml +++ llvm/test/tools/yaml2obj/ELF/section-headers.yaml @@ -68,15 +68,15 @@ # RUN: FileCheck %s --check-prefix=ERR2 # ERR1: error: repeated section name: '.section.foo' in the section header description -# ERR1-NEXT: error: section '.section (1)' should be present in the 'Sections' list -# ERR1-NEXT: error: section '.section (2)' should be present in the 'Sections' list +# ERR1-NEXT: error: section '.section (1)' should be present in the 'Sections' or `Excluded` lists +# ERR1-NEXT: error: section '.section (2)' should be present in the 'Sections' or `Excluded` lists # ERR1-NEXT: error: section header contains undefined section 'unknown' # ERR2: error: repeated section name: '.strtab' in the section header description # ERR2-NEXT: error: repeated section name: '.shstrtab' in the section header description -# ERR2-NEXT: error: section '.section (1)' should be present in the 'Sections' list -# ERR2-NEXT: error: section '.section (2)' should be present in the 'Sections' list -# ERR2-NEXT: error: section '.section.foo' should be present in the 'Sections' list +# ERR2-NEXT: error: section '.section (1)' should be present in the 'Sections' or `Excluded` lists +# ERR2-NEXT: error: section '.section (2)' should be present in the 'Sections' or `Excluded` lists +# ERR2-NEXT: error: section '.section.foo' should be present in the 'Sections' or `Excluded` lists # ERR2-NEXT: error: section header contains undefined section '.filler' ## Test that we are able to specify an empty sections list for