Skip to content

Commit 90e34b5

Browse files
author
Georgii Rymar
committed
[yaml2obj] - Refine handling of the NoHeaders key.
Imagine we have an YAML description for some object and we want to produce 2 outputs: with and without the section header. A natural way to do it would look like: ``` --- !ELF FileHeader: Class: ELFCLASS64 Data: ELFDATA2LSB Type: ET_REL Machine: EM_X86_64 Sections: ... SectionHeaderTable: NoHeaders: [[NOHEADERS]] ``` But currently, we do not distinguish between no `NoHeaders` key case and `NoHeaders == false`. Because of this we can't simply specify `NOHEADERS = false`, as tool starts to complain. With this patch the behavior changed. When we have: ``` SectionHeaderTable: NoHeaders: false ``` it is the same as we have no `SectionHeaderTable` at all. (`NoHeaders` key still can't be used with `Sections/Excluded` keys) Differential revision: https://reviews.llvm.org/D83672
1 parent 34d35d4 commit 90e34b5

File tree

5 files changed

+32
-18
lines changed

5 files changed

+32
-18
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ struct SectionHeader {
9898
struct SectionHeaderTable {
9999
Optional<std::vector<SectionHeader>> Sections;
100100
Optional<std::vector<SectionHeader>> Excluded;
101-
bool NoHeaders;
101+
Optional<bool> NoHeaders;
102102
};
103103

104104
struct SectionName {

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,8 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS, uint64_t SHOff) {
420420
Header.e_shentsize =
421421
Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr);
422422

423-
const bool NoShdrs = Doc.SectionHeaders && Doc.SectionHeaders->NoHeaders;
423+
const bool NoShdrs =
424+
Doc.SectionHeaders && Doc.SectionHeaders->NoHeaders.getValueOr(false);
424425

425426
if (Doc.Header.SHOff)
426427
Header.e_shoff = *Doc.Header.SHOff;
@@ -503,11 +504,12 @@ unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,
503504
return 0;
504505
}
505506

506-
if (!Doc.SectionHeaders ||
507-
(!Doc.SectionHeaders->NoHeaders && !Doc.SectionHeaders->Excluded))
507+
if (!Doc.SectionHeaders || (Doc.SectionHeaders->NoHeaders &&
508+
!Doc.SectionHeaders->NoHeaders.getValue()))
508509
return Index;
509510

510-
assert(!Doc.SectionHeaders->NoHeaders || !Doc.SectionHeaders->Sections);
511+
assert(!Doc.SectionHeaders->NoHeaders.getValueOr(false) ||
512+
!Doc.SectionHeaders->Sections);
511513
size_t FirstExcluded =
512514
Doc.SectionHeaders->Sections ? Doc.SectionHeaders->Sections->size() : 0;
513515
if (Index >= FirstExcluded) {
@@ -1776,7 +1778,7 @@ template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
17761778
if (!ExcludedSectionHeaders.insert(Hdr.Name).second)
17771779
llvm_unreachable("buildSectionIndex() failed");
17781780

1779-
if (Doc.SectionHeaders->NoHeaders)
1781+
if (Doc.SectionHeaders->NoHeaders.getValueOr(false))
17801782
for (const ELFYAML::Section *S : Sections)
17811783
if (!ExcludedSectionHeaders.insert(S->Name).second)
17821784
llvm_unreachable("buildSectionIndex() failed");

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -842,7 +842,7 @@ void MappingTraits<ELFYAML::SectionHeaderTable>::mapping(
842842
IO &IO, ELFYAML::SectionHeaderTable &SectionHeader) {
843843
IO.mapOptional("Sections", SectionHeader.Sections);
844844
IO.mapOptional("Excluded", SectionHeader.Excluded);
845-
IO.mapOptional("NoHeaders", SectionHeader.NoHeaders, false);
845+
IO.mapOptional("NoHeaders", SectionHeader.NoHeaders);
846846
}
847847

848848
StringRef MappingTraits<ELFYAML::SectionHeaderTable>::validate(

llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,8 @@ SectionHeaderTable:
500500
- Name: .shstrtab
501501

502502
## Check we do not allow using "Excluded" together with "NoHeaders".
503-
# RUN: not yaml2obj %s --docnum=19 -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOHEADERS
503+
# RUN: not yaml2obj %s --docnum=19 -DNOHEADERS=true -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOHEADERS
504+
# RUN: not yaml2obj %s --docnum=19 -DNOHEADERS=false -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOHEADERS
504505
# NOHEADERS: NoHeaders can't be used together with Sections/Excluded
505506

506507
--- !ELF
@@ -510,5 +511,5 @@ FileHeader:
510511
Type: ET_REL
511512
Machine: EM_X86_64
512513
SectionHeaderTable:
513-
NoHeaders: true
514+
NoHeaders: [[NOHEADERS]]
514515
Excluded: []

llvm/test/tools/yaml2obj/ELF/section-headers.yaml

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ SectionHeaderTable:
9999
Sections: []
100100

101101
## Test that we are able to use "NoHeaders" property to produce an empty section header table.
102-
# RUN: yaml2obj %s --docnum=3 -o %t3
103-
# RUN: llvm-readelf --file-headers %t3 | FileCheck %s --check-prefix=NO-HEADERS
102+
# RUN: yaml2obj %s --docnum=3 -DNOHEADERS=true -o %t3.1
103+
# RUN: llvm-readelf --file-headers %t3.1 | FileCheck %s --check-prefix=NO-HEADERS-TRUE
104104

105-
# NO-HEADERS: Start of section headers: 0 (bytes into file)
106-
# NO-HEADERS: Size of section headers: 64 (bytes)
107-
# NO-HEADERS: Number of section headers: 0
108-
# NO-HEADERS: Section header string table index: 0
105+
# NO-HEADERS-TRUE: Start of section headers: 0 (bytes into file)
106+
# NO-HEADERS-TRUE: Size of section headers: 64 (bytes)
107+
# NO-HEADERS-TRUE: Number of section headers: 0
108+
# NO-HEADERS-TRUE: Section header string table index: 0
109109

110110
--- !ELF
111111
FileHeader:
@@ -117,10 +117,21 @@ Sections:
117117
- Name: .foo
118118
Type: SHT_PROGBITS
119119
SectionHeaderTable:
120-
NoHeaders: true
120+
NoHeaders: [[NOHEADERS]]
121+
122+
## Test that we are able to set NoHeaders to false. In this case the tool produces an output
123+
## as if there were no `SectionHeaderTable` key at all.
124+
# RUN: yaml2obj %s --docnum=3 -DNOHEADERS=false -o %t3.2
125+
# RUN: llvm-readelf --file-headers %t3.2 | FileCheck %s --check-prefix=NO-HEADERS-FALSE
126+
127+
# NO-HEADERS-FALSE: Start of section headers: 96 (bytes into file)
128+
# NO-HEADERS-FALSE: Size of section headers: 64 (bytes)
129+
# NO-HEADERS-FALSE: Number of section headers: 1
130+
# NO-HEADERS-FALSE: Section header string table index: 3
121131

122132
## Check we do not allow using "Sections" together with "NoHeaders".
123-
# RUN: not yaml2obj %s --docnum=4 -o /dev/null 2>&1 | FileCheck %s --check-prefix=SECTIONS-NO-HEADERS
133+
# RUN: not yaml2obj %s --docnum=4 -DNOHEADERS=true -o /dev/null 2>&1 | FileCheck %s --check-prefix=SECTIONS-NO-HEADERS
134+
# RUN: not yaml2obj %s --docnum=4 -DNOHEADERS=false -o /dev/null 2>&1 | FileCheck %s --check-prefix=SECTIONS-NO-HEADERS
124135

125136
# SECTIONS-NO-HEADERS: error: NoHeaders can't be used together with Sections/Excluded
126137

@@ -135,7 +146,7 @@ Sections:
135146
Type: SHT_PROGBITS
136147
SectionHeaderTable:
137148
Sections: []
138-
NoHeaders: true
149+
NoHeaders: [[NOHEADERS]]
139150

140151
## Check that we do not allow an empty SectionHeaderTable tag and suggest to use an explicit syntax instead.
141152
# RUN: not yaml2obj %s --docnum=5 -DVAL="" -o /dev/null 2>&1 | FileCheck %s --check-prefix=NO-VALUE

0 commit comments

Comments
 (0)