Index: llvm/lib/ObjectYAML/ELFEmitter.cpp =================================================================== --- llvm/lib/ObjectYAML/ELFEmitter.cpp +++ llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -399,9 +399,13 @@ Header.e_shentsize = Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr); + const bool NoShdrs = Doc.SectionHeaders && + Doc.SectionHeaders->Sections.empty() && + !Doc.SectionHeaders->Excluded; + if (Doc.Header.SHOff) Header.e_shoff = *Doc.Header.SHOff; - else if (Doc.SectionHeaders && Doc.SectionHeaders->Sections.empty()) + else if (NoShdrs) Header.e_shoff = 0; else Header.e_shoff = SHOff; @@ -410,18 +414,17 @@ Header.e_shnum = *Doc.Header.SHNum; else if (!Doc.SectionHeaders) Header.e_shnum = Doc.getSections().size(); - else if (Doc.SectionHeaders->Sections.empty()) + else if (NoShdrs) Header.e_shnum = 0; else Header.e_shnum = Doc.SectionHeaders->Sections.size() + /*Null section*/ 1; if (Doc.Header.SHStrNdx) Header.e_shstrndx = *Doc.Header.SHStrNdx; - else if ((!Doc.SectionHeaders || !Doc.SectionHeaders->Sections.empty()) && - !ExcludedSectionHeaders.count(".shstrtab")) - Header.e_shstrndx = SN2I.get(".shstrtab"); - else + else if (NoShdrs || ExcludedSectionHeaders.count(".shstrtab")) Header.e_shstrndx = 0; + else + Header.e_shstrndx = SN2I.get(".shstrtab"); OS.write((const char *)&Header, sizeof(Header)); } @@ -1651,7 +1654,8 @@ template DenseMap ELFState::buildSectionHeaderReorderMap() { - if (!Doc.SectionHeaders || Doc.SectionHeaders->Sections.empty()) + if (!Doc.SectionHeaders || + (Doc.SectionHeaders->Sections.empty() && !Doc.SectionHeaders->Excluded)) return DenseMap(); DenseMap Ret; Index: llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml =================================================================== --- llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml +++ llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml @@ -90,9 +90,7 @@ Machine: EM_X86_64 SectionHeaderTable: Sections: [] - Excluded: - - Name: .strtab - + ## Check how we handle cases when a section is excluded, but its 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 @@ -476,3 +474,44 @@ - Name: .strtab Excluded: - Name: .shstrtab + +## Check that we keep the null SHF_UNDEF section when the "Sections" key is empty, +## but the "Excluded" key is not +# RUN: yaml2obj --docnum=18 %s -o %t10 +# RUN: llvm-readelf --sections %t10 | FileCheck %s --check-prefix=KEEP-NULL + +# KEEP-NULL: There are 1 section headers, starting at offset 0x48: +# KEEP-NULL: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# KEEP-NULL-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +SectionHeaderTable: + Sections: [] + Excluded: + - Name: .strtab + - Name: .shstrtab + +## Check we are able to report all possible errors mentioned above even when the "Sections" key is empty. +# RUN: not yaml2obj %s --docnum=19 -o /dev/null 2>&1 | FileCheck %s --check-prefix=INVALID-EXCLUDED + +# INVALID-EXCLUDED: error: repeated section name: '.strtab' in the section header description +# INVALID-EXCLUDED: error: section '.shstrtab' should be present in the 'Sections' or 'Excluded' lists +# INVALID-EXCLUDED: error: section header contains undefined section '.unknown' + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_X86_64 +SectionHeaderTable: + Sections: [] + Excluded: + - Name: .strtab + - Name: .strtab + - Name: .unknown