[llvm] 90e34b5 - [yaml2obj] - Refine handling of the NoHeaders key.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 05:20:50 PDT 2020


Author: Georgii Rymar
Date: 2020-07-14T15:09:06+03:00
New Revision: 90e34b563affb145c43ec73f66410a9d1c4dc57a

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

LOG: [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

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 bfc31ea247ef..651cd6a83398 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -98,7 +98,7 @@ struct SectionHeader {
 struct SectionHeaderTable {
   Optional<std::vector<SectionHeader>> Sections;
   Optional<std::vector<SectionHeader>> Excluded;
-  bool NoHeaders;
+  Optional<bool> NoHeaders;
 };
 
 struct SectionName {

diff  --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index f4ad10a9eb08..8513874ffea8 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -420,7 +420,8 @@ 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;
+  const bool NoShdrs =
+      Doc.SectionHeaders && Doc.SectionHeaders->NoHeaders.getValueOr(false);
 
   if (Doc.Header.SHOff)
     Header.e_shoff = *Doc.Header.SHOff;
@@ -503,11 +504,12 @@ unsigned ELFState<ELFT>::toSectionIndex(StringRef S, StringRef LocSec,
     return 0;
   }
 
-  if (!Doc.SectionHeaders ||
-      (!Doc.SectionHeaders->NoHeaders && !Doc.SectionHeaders->Excluded))
+  if (!Doc.SectionHeaders || (Doc.SectionHeaders->NoHeaders &&
+                              !Doc.SectionHeaders->NoHeaders.getValue()))
     return Index;
 
-  assert(!Doc.SectionHeaders->NoHeaders || !Doc.SectionHeaders->Sections);
+  assert(!Doc.SectionHeaders->NoHeaders.getValueOr(false) ||
+         !Doc.SectionHeaders->Sections);
   size_t FirstExcluded =
       Doc.SectionHeaders->Sections ? Doc.SectionHeaders->Sections->size() : 0;
   if (Index >= FirstExcluded) {
@@ -1776,7 +1778,7 @@ template <class ELFT> void ELFState<ELFT>::buildSectionIndex() {
         if (!ExcludedSectionHeaders.insert(Hdr.Name).second)
           llvm_unreachable("buildSectionIndex() failed");
 
-    if (Doc.SectionHeaders->NoHeaders)
+    if (Doc.SectionHeaders->NoHeaders.getValueOr(false))
       for (const ELFYAML::Section *S : Sections)
         if (!ExcludedSectionHeaders.insert(S->Name).second)
           llvm_unreachable("buildSectionIndex() failed");

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index aa247c53a3c6..dc65f77d565b 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -842,7 +842,7 @@ void MappingTraits<ELFYAML::SectionHeaderTable>::mapping(
     IO &IO, ELFYAML::SectionHeaderTable &SectionHeader) {
   IO.mapOptional("Sections", SectionHeader.Sections);
   IO.mapOptional("Excluded", SectionHeader.Excluded);
-  IO.mapOptional("NoHeaders", SectionHeader.NoHeaders, false);
+  IO.mapOptional("NoHeaders", SectionHeader.NoHeaders);
 }
 
 StringRef MappingTraits<ELFYAML::SectionHeaderTable>::validate(

diff  --git a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
index 140d6e5806aa..83790ab48c78 100644
--- a/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/section-headers-exclude.yaml
@@ -500,7 +500,8 @@ SectionHeaderTable:
     - 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
+# RUN: not yaml2obj %s --docnum=19 -DNOHEADERS=true -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOHEADERS
+# RUN: not yaml2obj %s --docnum=19 -DNOHEADERS=false -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOHEADERS
 # NOHEADERS: NoHeaders can't be used together with Sections/Excluded
 
 --- !ELF
@@ -510,5 +511,5 @@ FileHeader:
   Type:    ET_REL
   Machine: EM_X86_64
 SectionHeaderTable:
-  NoHeaders: true
+  NoHeaders: [[NOHEADERS]]
   Excluded:  []

diff  --git a/llvm/test/tools/yaml2obj/ELF/section-headers.yaml b/llvm/test/tools/yaml2obj/ELF/section-headers.yaml
index 827e93bc76d2..01845ba2a6cb 100644
--- a/llvm/test/tools/yaml2obj/ELF/section-headers.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/section-headers.yaml
@@ -99,13 +99,13 @@ 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
+# RUN: yaml2obj %s --docnum=3 -DNOHEADERS=true -o %t3.1
+# RUN: llvm-readelf --file-headers %t3.1 | FileCheck %s --check-prefix=NO-HEADERS-TRUE
 
-# NO-HEADERS: Start of section headers:          0  (bytes into file)
-# NO-HEADERS: Size of section headers:           64 (bytes)
-# NO-HEADERS: Number of section headers:         0
-# NO-HEADERS: Section header string table index: 0
+# NO-HEADERS-TRUE: Start of section headers:          0  (bytes into file)
+# NO-HEADERS-TRUE: Size of section headers:           64 (bytes)
+# NO-HEADERS-TRUE: Number of section headers:         0
+# NO-HEADERS-TRUE: Section header string table index: 0
 
 --- !ELF
 FileHeader:
@@ -117,10 +117,21 @@ Sections:
   - Name: .foo
     Type: SHT_PROGBITS
 SectionHeaderTable:
-  NoHeaders: true
+  NoHeaders: [[NOHEADERS]]
+
+## Test that we are able to set NoHeaders to false. In this case the tool produces an output
+## as if there were no `SectionHeaderTable` key at all.
+# RUN: yaml2obj %s --docnum=3 -DNOHEADERS=false -o %t3.2
+# RUN: llvm-readelf --file-headers %t3.2 | FileCheck %s --check-prefix=NO-HEADERS-FALSE
+
+# NO-HEADERS-FALSE: Start of section headers:          96 (bytes into file)
+# NO-HEADERS-FALSE: Size of section headers:           64 (bytes)
+# NO-HEADERS-FALSE: Number of section headers:         1
+# NO-HEADERS-FALSE: Section header string table index: 3
 
 ## 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
+# RUN: not yaml2obj %s --docnum=4 -DNOHEADERS=true -o /dev/null 2>&1 | FileCheck %s --check-prefix=SECTIONS-NO-HEADERS
+# RUN: not yaml2obj %s --docnum=4 -DNOHEADERS=false -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
 
@@ -135,7 +146,7 @@ Sections:
     Type: SHT_PROGBITS
 SectionHeaderTable:
   Sections:  []
-  NoHeaders: true
+  NoHeaders: [[NOHEADERS]]
 
 ## 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


        


More information about the llvm-commits mailing list