[llvm] r366794 - [yaml2obj] - Add a support for defining null sections in YAMLs.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 23 04:03:38 PDT 2019


Author: grimar
Date: Tue Jul 23 04:03:37 2019
New Revision: 366794

URL: http://llvm.org/viewvc/llvm-project?rev=366794&view=rev
Log:
[yaml2obj] - Add a support for defining null sections in YAMLs.

ELF spec shows (Figure 4-10: Section Header Table Entry:Index 0,
http://www.sco.com/developers/gabi/latest/ch4.sheader.html)
that section header at index 0 (null section) can have sh_size and
sh_link fields set to non-zero values.

It says (https://docs.oracle.com/cd/E19683-01/817-3677/6mj8mbtc9/index.html):

"If the number of sections is greater than or equal to SHN_LORESERVE (0xff00),
this member has the value zero and the actual number of section header table
entries is contained in the sh_size field of the section header at index 0.
Otherwise, the sh_size member of the initial entry contains 0."

and:

"If the section name string table section index is greater than or equal to SHN_LORESERVE
(0xff00), this member has the value SHN_XINDEX (0xffff) and the actual index of the section
name string table section is contained in the sh_link field of the section header at index 0.
Otherwise, the sh_link member of the initial entry contains 0."

At this moment it is not possible to create custom section headers at index 0 using yaml2obj.

This patch implements this.

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

Added:
    llvm/trunk/test/tools/yaml2obj/elf-custom-null-section.yaml
Modified:
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Added: llvm/trunk/test/tools/yaml2obj/elf-custom-null-section.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/elf-custom-null-section.yaml?rev=366794&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/elf-custom-null-section.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/elf-custom-null-section.yaml Tue Jul 23 04:03:37 2019
@@ -0,0 +1,169 @@
+## In this test we check that can redefine the null section in the YAML.
+
+## Test the default output first.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readelf --sections %t1 | FileCheck %s --check-prefix=DEFAULT
+
+# DEFAULT:      Section Headers:
+# DEFAULT-NEXT:  [Nr] Name      Type   Address          Off    Size   ES Flg Lk Inf Al
+# DEFAULT-NEXT:  [ 0]           NULL   0000000000000000 000000 000000 00 0   0  0
+# DEFAULT-NEXT:  [ 1] .symtab   SYMTAB 0000000000000000 000140 000018 18 2   1  8
+# DEFAULT-NEXT:  [ 2] .strtab   STRTAB 0000000000000000 000158 000001 00 0   0  1
+# DEFAULT-NEXT:  [ 3] .shstrtab STRTAB 0000000000000000 000159 00001b 00 0   0  1
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+
+## Now define a SHT_NULL section with fields all zeroed.
+## In this case it is equal to the section created by default.
+
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: llvm-readelf --sections %t2 | FileCheck %s --check-prefix=DEFAULT
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type:         SHT_NULL
+    Name:         ''
+    Flags:        [ ]
+    AddressAlign: 0x0
+    Size:         0x0
+    EntSize:      0x0
+    Link:         0
+    Info:         0
+    Address:      0x0
+
+## Check we are still able to describe other sections too.
+
+# RUN: yaml2obj --docnum=3 %s -o %t3
+# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=OTHER-SECTION
+
+# OTHER-SECTION:      Section Headers:
+# OTHER-SECTION-NEXT:   [Nr] Name      Type     Address          Off    Size   ES Flg Lk Inf Al
+# OTHER-SECTION-NEXT:   [ 0]           NULL     0000000000000000 000000 000000 00 0   0  0
+# OTHER-SECTION-NEXT:   [ 1] foo       PROGBITS 0000000000000000 000180 000000 00 0   0  0
+# OTHER-SECTION-NEXT:   [ 2] .symtab   SYMTAB   0000000000000000 000180 000018 18 3   1  8
+# OTHER-SECTION-NEXT:   [ 3] .strtab   STRTAB   0000000000000000 000198 000001 00 0   0  1
+# OTHER-SECTION-NEXT:   [ 4] .shstrtab STRTAB   0000000000000000 000199 00001f 00 0   0  1
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type:         SHT_NULL
+    Name:         ''
+    Flags:        [ ]
+    AddressAlign: 0x0
+    Size:         0x0
+    EntSize:      0x0
+    Link:         0
+  - Type: SHT_PROGBITS
+    Name: 'foo'
+
+## Check we can redefine sh_size and sh_link fields of the SHT_NULL section.
+
+# RUN: yaml2obj --docnum=4 %s -o %t4
+# RUN: llvm-readelf --sections %t4 | FileCheck %s --check-prefix=REDEFINE
+
+# REDEFINE:      Section Headers:
+# REDEFINE-NEXT:  [Nr] Name Type Address          Off    Size   ES Flg Lk Inf Al
+# REDEFINE-NEXT:  [ 0]      NULL 0000000000000000 000000 000123 00     1   0  0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type: SHT_NULL
+    Link: .foo
+    Size: 0x123
+  - Type: SHT_PROGBITS
+    Name: .foo
+
+## The same as above, but using a number as a Link value.
+
+# RUN: yaml2obj --docnum=5 %s -o %t5
+# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=REDEFINE
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type: SHT_NULL
+    Link: 1
+    Size: 0x123
+  - Type: SHT_PROGBITS
+    Name: .foo
+
+## Check we report an error if null section sh_link field refers to an unknown section.
+
+# RUN: not yaml2obj --docnum=6 %s -o %t6 2>&1 | FileCheck %s --check-prefix=CASE4
+
+# CASE4: error: Unknown section referenced: '.foo' at YAML section ''.
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type: SHT_NULL
+    Link: .foo
+
+## Check that null section fields are set to zero, if they are unspecified.
+
+# RUN: yaml2obj --docnum=7 %s -o %t7
+# RUN: llvm-readelf --sections %t7 | FileCheck %s --check-prefix=DEFAULT
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type: SHT_NULL
+
+## Check we do not crash if we have more than one SHT_NULL section.
+
+# RUN: yaml2obj --docnum=8 %s -o %t8
+# RUN: llvm-readelf --sections %t8 | FileCheck %s --check-prefix=MULTIPLE
+
+# MULTIPLE:      Section Headers:
+# MULTIPLE-NEXT:  [Nr] Name Type Address          Off    Size   ES Flg Lk Inf Al
+# MULTIPLE-NEXT:  [ 0]      NULL 0000000000000000 000000 000000 00 0   0  0
+# MULTIPLE-NEXT:  [ 1]      NULL 0000000000000123 000180 000020 10 A   1  2   0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type: SHT_NULL
+  - Type:    SHT_NULL
+    Flags:   [ SHF_ALLOC ]
+    Size:    0x20
+    EntSize: 0x10
+    Link:    1
+    Info:    2
+    Address: 0x123

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=366794&r1=366793&r2=366794&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Tue Jul 23 04:03:37 2019
@@ -192,10 +192,11 @@ ELFState<ELFT>::ELFState(ELFYAML::Object
     if (!D->Name.empty())
       DocSections.insert(D->Name);
 
-  // Insert SHT_NULL section implicitly.
-  Doc.Sections.insert(
-      Doc.Sections.begin(),
-      llvm::make_unique<ELFYAML::Section>(
+  // Insert SHT_NULL section implicitly when it is not defined in YAML.
+  if (Doc.Sections.empty() || Doc.Sections.front()->Type != ELF::SHT_NULL)
+    Doc.Sections.insert(
+        Doc.Sections.begin(),
+        llvm::make_unique<ELFYAML::Section>(
           ELFYAML::Section::SectionKind::RawContent, /*IsImplicit=*/true));
 
   std::vector<StringRef> ImplicitSections = {".symtab", ".strtab", ".shstrtab"};
@@ -325,10 +326,27 @@ bool ELFState<ELFT>::initSectionHeaders(
   // valid SHN_UNDEF entry since SHT_NULL == 0.
   SHeaders.resize(Doc.Sections.size());
 
-  for (size_t I = 1; I < Doc.Sections.size(); ++I) {
+  for (size_t I = 0; I < Doc.Sections.size(); ++I) {
     Elf_Shdr &SHeader = SHeaders[I];
     ELFYAML::Section *Sec = Doc.Sections[I].get();
 
+    if (I == 0) {
+      if (Sec->IsImplicit)
+        continue;
+
+      if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec))
+        if (S->Size)
+          SHeader.sh_size = *S->Size;
+
+      if (!Sec->Link.empty()) {
+        unsigned Index;
+        if (!convertSectionIndex(SN2I, Sec->Name, Sec->Link, Index))
+          return false;
+        SHeader.sh_link = Index;
+      }
+      continue;
+    }
+
     // We have a few sections like string or symbol tables that are usually
     // added implicitly to the end. However, if they are explicitly specified
     // in the YAML, we need to write them here. This ensures the file offset




More information about the llvm-commits mailing list