[llvm] ec4e68e - [yaml2obj] - Introduce the "NoHeaders" key for "SectionHeaderTable"

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 15 02:43:42 PDT 2020


Author: Georgii Rymar
Date: 2020-06-15T12:43:16+03:00
New Revision: ec4e68e667bf0369c36f0e4291618ef2a614bbf0

URL: https://github.com/llvm/llvm-project/commit/ec4e68e667bf0369c36f0e4291618ef2a614bbf0
DIFF: https://github.com/llvm/llvm-project/commit/ec4e68e667bf0369c36f0e4291618ef2a614bbf0.diff

LOG: [yaml2obj] - Introduce the "NoHeaders" key for "SectionHeaderTable"

We have an issue currently. The following YAML piece just ignores the `Excluded` key.

```
SectionHeaderTable:
  Sections: []
  Excluded:
    - Name: .foo
```

Currently the meaning is: exclude the whole table.

The code checks that the `Sections` key is empty and doesn't catch/check
invalid/duplicated/missed `Excluded` entries.

Also there is no way to exclude all sections except the first null section,
because `Sections: []` currently just excludes the whole the sections header table.

To fix it, I suggest a change of the behavior.

1) A new `NoHeaders` key is added. It provides an explicit syntax to drop the whole table.
2) The meaning of the following is changed:

```
SectionHeaderTable:
  Sections: []
  Excluded:
    - Name: .foo

```
Assuming there are 2 sections in the object (a null section and `.foo`), with this patch it
means: exclude the `.foo` section, keep the null section. The null section is an implicit
section and I think it is reasonable to make "Sections: []" to mean it is implicitly added.
It will be consistent with the global "Sections" tag that is used to describe sections.

3) `SectionHeaderTable->Sections` is now optional. No `Sections` is the same as
   `Sections: []` (I think it avoids a confusion).
4) Using of `NoHeaders` together with `Sections`/`Excluded` is not allowed.
5) It is possible to use the `Excluded` key without the `Sections` key now (in this case
   `Excluded` must contain all sections).
6) `SectionHeaderTable:` or `SectionHeaderTable: []` is not allowed.
7) When the `SectionHeaderTable` key is present, we still require all sections to be
   present in `Sections` and `Excluded` lists. No changes here, we are still strict.

Differential revision: https://reviews.llvm.org/D81655

Added: 
    

Modified: 
    llvm/include/llvm/ObjectYAML/ELFYAML.h
    llvm/lib/ObjectYAML/ELFEmitter.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
    llvm/test/tools/yaml2obj/ELF/section-headers.yaml

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index b88a10eecad7..8c15fccf6b07 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -92,8 +92,9 @@ struct SectionHeader {
 };
 
 struct SectionHeaderTable {
-  std::vector<SectionHeader> Sections;
+  Optional<std::vector<SectionHeader>> Sections;
   Optional<std::vector<SectionHeader>> Excluded;
+  bool NoHeaders;
 };
 
 struct SectionName {
@@ -685,6 +686,7 @@ struct MappingTraits<ELFYAML::FileHeader> {
 
 template <> struct MappingTraits<ELFYAML::SectionHeaderTable> {
   static void mapping(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
+  static StringRef validate(IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable);
 };
 
 template <> struct MappingTraits<ELFYAML::SectionHeader> {

diff  --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 6b304869685b..cb9d4f0c2b9d 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -402,9 +402,11 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS, uint64_t SHOff) {
   Header.e_shentsize =
       Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr);
 
+  const bool NoShdrs = Doc.SectionHeaders && Doc.SectionHeaders->NoHeaders;
+
   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;
@@ -413,18 +415,20 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS, uint64_t SHOff) {
     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;
+    Header.e_shnum =
+        (Doc.SectionHeaders->Sections ? Doc.SectionHeaders->Sections->size()
+                                      : 0) +
+        /*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));
 }
@@ -481,11 +485,14 @@ unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,
     return 0;
   }
 
-  if (!Doc.SectionHeaders || !Doc.SectionHeaders->Excluded)
+  if (!Doc.SectionHeaders ||
+      (!Doc.SectionHeaders->NoHeaders && !Doc.SectionHeaders->Excluded))
     return Index;
 
-  assert(!Doc.SectionHeaders->Sections.empty());
-  if (Index >= Doc.SectionHeaders->Sections.size()) {
+  assert(!Doc.SectionHeaders->NoHeaders || !Doc.SectionHeaders->Sections);
+  size_t FirstExcluded =
+      Doc.SectionHeaders->Sections ? Doc.SectionHeaders->Sections->size() : 0;
+  if (Index >= FirstExcluded) {
     if (LocSym.empty())
       reportError("unable to link '" + LocSec + "' to excluded section '" + S +
                   "'");
@@ -1681,7 +1688,7 @@ void ELFState<ELFT>::writeFill(ELFYAML::Fill &Fill,
 
 template <class ELFT>
 DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
-  if (!Doc.SectionHeaders || Doc.SectionHeaders->Sections.empty())
+  if (!Doc.SectionHeaders || Doc.SectionHeaders->NoHeaders)
     return DenseMap<StringRef, size_t>();
 
   DenseMap<StringRef, size_t> Ret;
@@ -1695,8 +1702,9 @@ DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
     Seen.insert(Hdr.Name);
   };
 
-  for (const ELFYAML::SectionHeader &Hdr : Doc.SectionHeaders->Sections)
-    AddSection(Hdr);
+  if (Doc.SectionHeaders->Sections)
+    for (const ELFYAML::SectionHeader &Hdr : *Doc.SectionHeaders->Sections)
+      AddSection(Hdr);
 
   if (Doc.SectionHeaders->Excluded)
     for (const ELFYAML::SectionHeader &Hdr : *Doc.SectionHeaders->Excluded)
@@ -1727,13 +1735,21 @@ template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
     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).second)
-        llvm_unreachable("buildSectionIndex() failed");
+  std::vector<ELFYAML::Section *> Sections = Doc.getSections();
+  if (Doc.SectionHeaders) {
+    if (Doc.SectionHeaders->Excluded)
+      for (const ELFYAML::SectionHeader &Hdr : *Doc.SectionHeaders->Excluded)
+        if (!ExcludedSectionHeaders.insert(Hdr.Name).second)
+          llvm_unreachable("buildSectionIndex() failed");
+
+    if (Doc.SectionHeaders->NoHeaders)
+      for (const ELFYAML::Section *S : Sections)
+        if (!ExcludedSectionHeaders.insert(S->Name).second)
+          llvm_unreachable("buildSectionIndex() failed");
+  }
 
   size_t SecNdx = -1;
-  for (const ELFYAML::Section *S : Doc.getSections()) {
+  for (const ELFYAML::Section *S : Sections) {
     ++SecNdx;
 
     size_t Index = ReorderMap.empty() ? SecNdx : ReorderMap.lookup(S->Name);

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 84fbdb01365d..2f044be4aa5d 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -839,8 +839,19 @@ void MappingTraits<ELFYAML::SectionHeader>::mapping(
 
 void MappingTraits<ELFYAML::SectionHeaderTable>::mapping(
     IO &IO, ELFYAML::SectionHeaderTable &SectionHeader) {
-  IO.mapRequired("Sections", SectionHeader.Sections);
+  IO.mapOptional("Sections", SectionHeader.Sections);
   IO.mapOptional("Excluded", SectionHeader.Excluded);
+  IO.mapOptional("NoHeaders", SectionHeader.NoHeaders, false);
+}
+
+StringRef MappingTraits<ELFYAML::SectionHeaderTable>::validate(
+    IO &IO, ELFYAML::SectionHeaderTable &SecHdrTable) {
+  if (SecHdrTable.NoHeaders && (SecHdrTable.Sections || SecHdrTable.Excluded))
+    return "NoHeaders can't be used together with Sections/Excluded";
+  if (!SecHdrTable.NoHeaders && !SecHdrTable.Sections && !SecHdrTable.Excluded)
+    return "SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop the "
+           "section header table";
+  return StringRef();
 }
 
 void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,

diff  --git a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
index a244643f93e3..140d6e5806aa 100644
--- a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
@@ -76,11 +76,17 @@ SectionHeaderTable:
     - Name: .strtab
     - Name: .strtab
 
-## Check we are able to exclude all sections.
+## Check that we are able to exclude all sections, except the implicit
+## null section, with the use of the "Excluded" key.
+
+## Case A: the "Sections" key is present, but empty.
 # RUN: yaml2obj %s --docnum=3 -o %t3
 # RUN: llvm-readelf --section-headers %t3 | FileCheck %s --check-prefix=NO-SECTIONS
 
-# NO-SECTIONS: There are 0 section headers, starting at offset 0x0:
+# NO-SECTIONS:      There are 1 section headers, starting at offset 0x48:
+# NO-SECTIONS:      Section Headers:
+# NO-SECTIONS-NEXT:  [Nr] Name         Type Address          Off    Size   ES Flg Lk Inf Al
+# NO-SECTIONS-NEXT:  [ 0] <no-strings> NULL 0000000000000000 000000 000000 00      0   0  0
 
 --- !ELF
 FileHeader:
@@ -92,6 +98,22 @@ SectionHeaderTable:
   Sections: []
   Excluded:
     - Name: .strtab
+    - Name: .shstrtab
+
+## Case B: the "Sections" key is not present.
+# RUN: yaml2obj %s --docnum=4 -o %t4
+# RUN: llvm-readelf --section-headers %t4 | FileCheck %s --check-prefix=NO-SECTIONS
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+SectionHeaderTable:
+  Excluded:
+    - Name: .strtab
+    - Name: .shstrtab
 
 ## 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
@@ -100,7 +122,7 @@ SectionHeaderTable:
 
 ## Case A: check we report an error when a regular section has a Link field which
 ##         points to an excluded section.
-# RUN: not yaml2obj %s --docnum=4 -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=5 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.foo -DTARGET=.bar
 
 # LINK: error: unable to link '[[SEC]]' to excluded section '[[TARGET]]'
@@ -127,9 +149,9 @@ SectionHeaderTable:
 
 ## Case B.1: check we report an error when a symbol table section has a Link field which
 ##           points to an excluded section.
-# RUN: not yaml2obj %s --docnum=5 -DNAME=.symtab -DTYPE=SHT_SYMTAB -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=6 -DNAME=.symtab -DTYPE=SHT_SYMTAB -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.symtab -DTARGET=.foo
-# RUN: not yaml2obj %s --docnum=5 -DNAME=.dynsym -DTYPE=SHT_DYNSYM -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=6 -DNAME=.dynsym -DTYPE=SHT_DYNSYM -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.dynsym -DTARGET=.foo
 
 --- !ELF
@@ -153,8 +175,8 @@ SectionHeaderTable:
     - Name: .foo
 
 ## Case B.2: check we do not link .dynsym with .dynstr implicitly when the latter is excluded.
-# RUN: yaml2obj %s --docnum=6 -o %t4
-# RUN: llvm-readelf %t4 --section-headers | FileCheck %s --check-prefix=LINK-DYNSYM
+# RUN: yaml2obj %s --docnum=7 -o %t5
+# RUN: llvm-readelf %t5 --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
@@ -179,8 +201,8 @@ SectionHeaderTable:
     - Name: .dynstr
 
 ## Case B.3: check we do not link .symtab with .strtab implicitly when the latter is excluded.
-# RUN: yaml2obj %s --docnum=7 -o %t5
-# RUN: llvm-readelf %t5 --section-headers | FileCheck %s --check-prefix=LINK-SYMTAB
+# RUN: yaml2obj %s --docnum=8 -o %t6
+# RUN: llvm-readelf %t6 --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
@@ -205,7 +227,7 @@ SectionHeaderTable:
 
 ## Case C: check we report an error when a debug section has a Link field which
 ##         points to an excluded section.
-# RUN: not yaml2obj %s --docnum=8 -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=9 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.debug_unknown -DTARGET=.strtab
 
 --- !ELF
@@ -227,7 +249,7 @@ SectionHeaderTable:
 
 ## Case D.1: check we report an error when a relocatable section has an Info field which
 ##           points to an excluded section.
-# RUN: not yaml2obj %s --docnum=9 -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=10 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.rela -DTARGET=.strtab
 
 --- !ELF
@@ -250,7 +272,7 @@ SectionHeaderTable:
 
 ## Case D.2: check we report an error when the SHT_REL[A] section is linked
 ##           with an excluded section explicitly.
-# RUN: not yaml2obj %s --docnum=10 -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=11 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.rela -DTARGET=.symtab
 
 --- !ELF
@@ -275,7 +297,7 @@ SectionHeaderTable:
     - Name: .symtab
 
 ## Case E: check we report an error when a symbol references an excluded section.
-# RUN: not yaml2obj %s --docnum=11 -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=12 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=SYMBOL-SECTION
 
 # SYMBOL-SECTION: error: excluded section referenced: '.foo' by symbol 'foo'
@@ -303,7 +325,7 @@ SectionHeaderTable:
 
 ## Case F.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: not yaml2obj %s --docnum=13 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.group -DTARGET=.strtab
 
 --- !ELF
@@ -326,7 +348,7 @@ SectionHeaderTable:
 
 ## Case F.2: check we report an error when the group section is linked
 ##           to an excluded section explicitly.
-# RUN: not yaml2obj %s --docnum=13 -o /dev/null 2>&1 | \
+# RUN: not yaml2obj %s --docnum=14 -o /dev/null 2>&1 | \
 # RUN:   FileCheck %s --check-prefix=LINK -DSEC=.group -DTARGET=.symtab
 
 --- !ELF
@@ -352,8 +374,8 @@ SectionHeaderTable:
 
 ## Case G: check we do not link SHT_LLVM_CALL_GRAPH_PROFILE/SHT_LLVM_ADDRSIG/SHT_GROUP/SHT_REL[A] sections
 ##         with .symtab implicitly when the latter is excluded.
-# RUN: yaml2obj %s --docnum=14 -o %t6
-# RUN: llvm-readelf %t6 --section-headers | FileCheck %s --check-prefix=LINK-IMPLICIT
+# RUN: yaml2obj %s --docnum=15 -o %t7
+# RUN: llvm-readelf %t7 --section-headers | FileCheck %s --check-prefix=LINK-IMPLICIT
 
 # LINK-IMPLICIT:      [Nr] Name          Type                    Address          Off    Size   ES Flg Lk Inf Al
 # LINK-IMPLICIT:      [ 1] .cgp          LLVM_CALL_GRAPH_PROFILE 0000000000000000 000040 000000 10      0   0  0
@@ -395,8 +417,8 @@ SectionHeaderTable:
 
 ## Case H: check we do not link SHT_HASH/SHT_GNU_HASH sections with .dynsym
 ##         implicitly when the latter is excluded.
-# RUN: yaml2obj %s --docnum=15 -o %t7
-# RUN: llvm-readelf %t7 --section-headers | FileCheck %s --check-prefix=LINK-HASH
+# RUN: yaml2obj %s --docnum=16 -o %t8
+# RUN: llvm-readelf %t8 --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
@@ -431,7 +453,7 @@ SectionHeaderTable:
 ##         1) It is a reasonable behavior, as it is perhaps usually a result of a mistake
 ##            in a YAML description.
 ##         2) Helps to keep the code simpler.
-# RUN: not yaml2obj %s --docnum=16 -o /dev/null 2>&1 | FileCheck %s --check-prefix=CROSS-LINK
+# RUN: not yaml2obj %s --docnum=17 -o /dev/null 2>&1 | FileCheck %s --check-prefix=CROSS-LINK
 
 # CROSS-LINK:      error: unable to link '.foo' to excluded section '.bar'
 # CROSS-LINK-NEXT: error: unable to link '.bar' to excluded section '.foo'
@@ -459,7 +481,7 @@ SectionHeaderTable:
 
 ## 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=17 %s -o %t9
+# RUN: yaml2obj --docnum=18 %s -o %t9
 # RUN: llvm-readelf --file-headers %t9 | FileCheck %s --check-prefix=SHSTRTAB
 
 # SHSTRTAB: Number of section headers:         2
@@ -476,3 +498,17 @@ SectionHeaderTable:
     - Name: .strtab
   Excluded:
     - Name: .shstrtab
+
+## Check we do not allow using "Excluded" together with "NoHeaders".
+# RUN: not yaml2obj %s --docnum=19 -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOHEADERS
+# NOHEADERS: NoHeaders can't be used together with Sections/Excluded
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+SectionHeaderTable:
+  NoHeaders: true
+  Excluded:  []

diff  --git a/llvm/test/tools/yaml2obj/ELF/section-headers.yaml b/llvm/test/tools/yaml2obj/ELF/section-headers.yaml
index 8e2f6f5a3091..827e93bc76d2 100644
--- a/llvm/test/tools/yaml2obj/ELF/section-headers.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/section-headers.yaml
@@ -79,9 +79,27 @@ SectionHeaderTable:
 # 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
-## the "SectionHeaderTable" tag to produce no section header.
-# RUN: yaml2obj %s --docnum=2 -o %t3
+## Check that when the an empty "Sections" list is used, we do not create an empty section header table.
+# RUN: not yaml2obj %s --docnum=2 -o /dev/null 2>&1 | FileCheck %s --check-prefix=EMPTY-SECTIONS
+
+# EMPTY-SECTIONS:      error: section '.foo' should be present in the 'Sections' or 'Excluded' lists
+# EMPTY-SECTIONS-NEXT: error: section '.strtab' should be present in the 'Sections' or 'Excluded' lists
+# EMPTY-SECTIONS-NEXT: error: section '.shstrtab' should be present in the 'Sections' or 'Excluded' lists
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+SectionHeaderTable:
+  Sections: []
+
+## Test that we are able to use "NoHeaders" property to produce an empty section header table.
+# RUN: yaml2obj %s --docnum=3 -o %t3
 # RUN: llvm-readelf --file-headers %t3 | FileCheck %s --check-prefix=NO-HEADERS
 
 # NO-HEADERS: Start of section headers:          0  (bytes into file)
@@ -99,11 +117,50 @@ Sections:
   - Name: .foo
     Type: SHT_PROGBITS
 SectionHeaderTable:
-  Sections: []
+  NoHeaders: true
+
+## Check we do not allow using "Sections" together with "NoHeaders".
+# RUN: not yaml2obj %s --docnum=4 -o /dev/null 2>&1 | FileCheck %s --check-prefix=SECTIONS-NO-HEADERS
+
+# SECTIONS-NO-HEADERS: error: NoHeaders can't be used together with Sections/Excluded
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+SectionHeaderTable:
+  Sections:  []
+  NoHeaders: true
+
+## Check that we do not allow an empty SectionHeaderTable tag and suggest to use an explicit syntax instead.
+# RUN: not yaml2obj %s --docnum=5 -DVAL="" -o /dev/null 2>&1 | FileCheck %s --check-prefix=NO-VALUE
+
+# NO-VALUE: SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop the section header table
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Name: .foo
+    Type: SHT_PROGBITS
+SectionHeaderTable: [[VAL]]
+
+## An empty mapping is also not allowed for the SectionHeaderTable tag.
+# RUN: not yaml2obj %s --docnum=5 -DVAL="[]" -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOT-A-MAPPING
+
+# NOT-A-MAPPING: error: not a mapping
 
 ## Test that we are still able to override e_shoff, e_shnum and e_shstrndx
 ## fields even when we do not produce section headers.
-# RUN: yaml2obj %s --docnum=3 -o %t4
+# RUN: yaml2obj %s --docnum=6 -o %t4
 # RUN: llvm-readelf --file-headers %t4 | FileCheck %s --check-prefix=NO-HEADERS-OVERRIDE
 
 # NO-HEADERS-OVERRIDE: Start of section headers:          2 (bytes into file)
@@ -123,13 +180,13 @@ Sections:
   - Name: .foo
     Type: SHT_PROGBITS
 SectionHeaderTable:
-  Sections: []
+  NoHeaders: true
 
 ## Check that section indices are updated properly in other places when we
 ## reorder sections in the section header table.
-# RUN: yaml2obj %s --docnum=4 -o %t5 -DSEC1=".foo" -DSEC2=".bar"
+# RUN: yaml2obj %s --docnum=7 -o %t5 -DSEC1=".foo" -DSEC2=".bar"
 # RUN: llvm-readelf --section-headers --symbols %t5 | FileCheck %s --check-prefix=INDICES-A
-# RUN: yaml2obj %s --docnum=4 -o %t6 -DSEC2=".foo" -DSEC1=".bar"
+# RUN: yaml2obj %s --docnum=7 -o %t6 -DSEC2=".foo" -DSEC1=".bar"
 # RUN: llvm-readelf --section-headers --symbols %t6 | FileCheck %s --check-prefix=INDICES-B
 
 # INDICES-A:      [Nr] Name       Type     Address          Off    Size   ES Flg Lk


        


More information about the llvm-commits mailing list