[PATCH] D95341: [yaml2obj] - Allow empty SectionHeaderTable definitions.

George Rimar via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 25 03:47:29 PST 2021


grimar created this revision.
grimar added reviewers: jhenderson, MaskRay.
Herald added subscribers: hiraditya, emaste.
grimar requested review of this revision.
Herald added a project: LLVM.

Currently we don't allow the following definition:

  Sections:
    - Type: SectionHeaderTable
    - Name: .foo
      Type: SHT_PROGBITS

We report an error: "SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop the section header table".

It was implemented in this way earlier, when `SectionHeaderTable`
was a dedicated key outside of the `Sections` list. And we did not
allow to select where the table is written.

Currently it makes sense to allow it, because a user might
want to place the default section header table at an arbitrary position,
e.g. before other sections. In this case it is not convenient and error prone
to require specifying all sections:

  Sections:
    - Type: SectionHeaderTable
      Sections:
        - Name: .foo
        - Name: .strtab
        - Name: .shstrtab
    - Name: .foo
      Type: SHT_PROGBITS

This patch allows empty SectionHeaderTable definitions.


https://reviews.llvm.org/D95341

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


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
@@ -151,10 +151,18 @@
     Sections:  []
     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 -o /dev/null 2>&1 | FileCheck %s --check-prefix=NO-VALUE
+## Check that we allow using an empty SectionHeaderTable definition.
+## It can be used to emit a default section header content at an arbitrary position.
 
-# NO-VALUE: SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop the section header table
+# RUN: yaml2obj %s --docnum=5 -o %t5.novalues
+# RUN: llvm-readelf --sections %t5.novalues | \
+# RUN:   FileCheck %s --check-prefix=NO-VALUES
+
+## Check we placed the section header table before the .foo section.
+
+# NO-VALUES: There are 4 section headers, starting at offset 0x40:
+# NO-VALUES: [Nr] Name Type     Address          Off    Size
+# NO-VALUES: [ 1] .foo PROGBITS 0000000000000000 000140 000000
 
 --- !ELF
 FileHeader:
@@ -162,9 +170,9 @@
   Data:  ELFDATA2LSB
   Type:  ET_REL
 Sections:
+  - Type: SectionHeaderTable
   - Name: .foo
     Type: SHT_PROGBITS
-  - Type: SectionHeaderTable
 
 ## Test that we are still able to override e_shoff, e_shnum and e_shstrndx
 ## fields even when we do not produce section headers.
Index: llvm/lib/ObjectYAML/ELFYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFYAML.cpp
+++ llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -1474,9 +1474,6 @@
   if (const auto *SHT = dyn_cast<ELFYAML::SectionHeaderTable>(C.get())) {
     if (SHT->NoHeaders && (SHT->Sections || SHT->Excluded || SHT->Offset))
       return "NoHeaders can't be used together with Offset/Sections/Excluded";
-    if (!SHT->NoHeaders && !SHT->Sections && !SHT->Excluded)
-      return "SectionHeaderTable can't be empty. Use 'NoHeaders' key to drop "
-             "the section header table";
     return "";
   }
 
Index: llvm/lib/ObjectYAML/ELFEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -548,7 +548,8 @@
   const ELFYAML::SectionHeaderTable &SectionHeaders =
       Doc.getSectionHeaderTable();
   if (SectionHeaders.IsImplicit ||
-      (SectionHeaders.NoHeaders && !SectionHeaders.NoHeaders.getValue()))
+      (SectionHeaders.NoHeaders && !SectionHeaders.NoHeaders.getValue()) ||
+      SectionHeaders.isDefault())
     return Index;
 
   assert(!SectionHeaders.NoHeaders.getValueOr(false) ||
@@ -1790,7 +1791,8 @@
 DenseMap<StringRef, size_t> ELFState<ELFT>::buildSectionHeaderReorderMap() {
   const ELFYAML::SectionHeaderTable &SectionHeaders =
       Doc.getSectionHeaderTable();
-  if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders)
+  if (SectionHeaders.IsImplicit || SectionHeaders.NoHeaders ||
+      SectionHeaders.isDefault())
     return DenseMap<StringRef, size_t>();
 
   DenseMap<StringRef, size_t> Ret;
Index: llvm/include/llvm/ObjectYAML/ELFYAML.h
===================================================================
--- llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -293,13 +293,15 @@
   Optional<bool> NoHeaders;
 
   size_t getNumHeaders(size_t SectionsNum) const {
-    if (IsImplicit)
+    if (IsImplicit || isDefault())
       return SectionsNum;
     if (NoHeaders)
       return (*NoHeaders) ? 0 : SectionsNum;
     return (Sections ? Sections->size() : 0) + /*Null section*/ 1;
   }
 
+  bool isDefault() const { return !Sections && !Excluded && !NoHeaders; }
+
   static constexpr StringRef TypeStr = "SectionHeaderTable";
 };
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D95341.318945.patch
Type: text/x-patch
Size: 3855 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210125/031920a4/attachment.bin>


More information about the llvm-commits mailing list