Recommit "rL366894: [yaml2obj] - Allow custom fields for the SHT_UNDEF sections."
authorGeorge Rimar <grimar@accesssoftek.com>
Thu, 25 Jul 2019 10:19:23 +0000 (10:19 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Thu, 25 Jul 2019 10:19:23 +0000 (10:19 +0000)
With fix: do not use `stat` tool.

Original commit message:

This is a follow-up refactoring patch for recently
introduced functionality which which reduces the code duplication
and also makes possible to redefine all possible fields of
the first SHT_NULL section (previously it was only possible to set
sh_link and sh_size).

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

llvm-svn: 367003

llvm/test/tools/yaml2obj/elf-custom-null-section.yaml
llvm/tools/yaml2obj/yaml2elf.cpp

index 23b877f..dc74a7b 100644 (file)
@@ -42,18 +42,14 @@ Sections:
     Info:         0
     Address:      0x0
 
-## Check we are still able to describe other sections too.
+## Check we can redefine fields of the first SHT_NULL section.
 
 # RUN: yaml2obj --docnum=3 %s -o %t3
-# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=OTHER-SECTION
+# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=REDEFINE
 
-# 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
+# REDEFINE:      Section Headers:
+# REDEFINE-NEXT:  [Nr] Name Type Address          Off    Size   ES Flg Lk Inf Al
+# REDEFINE-NEXT:  [ 0] .foo NULL 0000000000000006 000000 000002 03   A 4   5  1
 
 --- !ELF
 FileHeader:
@@ -63,23 +59,25 @@ FileHeader:
   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.
+    Name:         .foo
+    Flags:        [ SHF_ALLOC ]
+    AddressAlign: 0x1
+    Size:         0x2
+    EntSize:      0x3
+    Link:         4
+    Info:         5
+    Address:      0x6
+
+## Check that file size does not change if we redefine the Size
+## of the first SHT_NULL section.
 
 # RUN: yaml2obj --docnum=4 %s -o %t4
-# RUN: llvm-readelf --sections %t4 | FileCheck %s --check-prefix=REDEFINE
+# RUN: ls -l %t3 | tr -s ' ' | cut -d ' ' -f 5 > %t.txt
+# RUN: ls -l %t4 | tr -s ' ' | cut -d ' ' -f 5 >> %t.txt
+# RUN: FileCheck %s --input-file=%t.txt --check-prefix=SIZE
 
-# 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
+# SIZE: [[FILESIZE:.*]]
+# SIZE: [[FILESIZE]]
 
 --- !ELF
 FileHeader:
@@ -88,16 +86,28 @@ FileHeader:
   Type:    ET_REL
   Machine: EM_X86_64
 Sections:
-  - Type: SHT_NULL
-    Link: .foo
-    Size: 0x123
-  - Type: SHT_PROGBITS
-    Name: .foo
+  - Type:         SHT_NULL
+    Name:         .foo
+    Flags:        [ SHF_ALLOC ]
+    AddressAlign: 0x1
+    Size:         0xFFFF
+    EntSize:      0x3
+    Link:         4
+    Info:         5
+    Address:      0x6
 
-## The same as above, but using a number as a Link value.
+## Check we are still able to describe other sections too.
 
 # RUN: yaml2obj --docnum=5 %s -o %t5
-# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=REDEFINE
+# RUN: llvm-readelf --sections %t5 | 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:
@@ -106,11 +116,15 @@ FileHeader:
   Type:    ET_REL
   Machine: EM_X86_64
 Sections:
-  - Type: SHT_NULL
-    Link: 1
-    Size: 0x123
+  - Type:         SHT_NULL
+    Name:         ''
+    Flags:        [ ]
+    AddressAlign: 0x0
+    Size:         0x0
+    EntSize:      0x0
+    Link:         0
   - Type: SHT_PROGBITS
-    Name: .foo
+    Name: 'foo'
 
 ## Check we report an error if null section sh_link field refers to an unknown section.
 
@@ -150,7 +164,7 @@ Sections:
 # 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
+# MULTIPLE-NEXT:  [ 1] .foo NULL 0000000000000123 000180 000020 10 A   1  2   0
 
 --- !ELF
 FileHeader:
@@ -161,9 +175,31 @@ FileHeader:
 Sections:
   - Type: SHT_NULL
   - Type:    SHT_NULL
+    Name:    .foo
     Flags:   [ SHF_ALLOC ]
     Size:    0x20
     EntSize: 0x10
     Link:    1
     Info:    2
     Address: 0x123
+
+## Check we can override the sh_offset/sh_size fields of the first SHT_NULL section if requested.
+
+# RUN: yaml2obj --docnum=9 %s -o %t9
+# RUN: llvm-readelf --sections %t9 | FileCheck %s --check-prefix=OVERRIDE
+
+# OVERRIDE:      Section Headers:
+# OVERRIDE-NEXT:  [Nr] Name Type Address          Off    Size   ES Flg Lk Inf Al
+# OVERRIDE-NEXT:  [ 0]      NULL 0000000000000000 000007 000008 00   0 0  0
+
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_REL
+  Machine: EM_X86_64
+Sections:
+  - Type:     SHT_NULL
+    Size:     0x2
+    ShOffset: 0x7
+    ShSize:   0x8
index c6be508..e11d8fe 100644 (file)
@@ -247,7 +247,7 @@ void ELFState<ELFT>::initELFHeader(Elf_Ehdr &Header) {
           ? (typename ELFT::uint)(*Doc.Header.SHOffset)
           : sizeof(Header) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
   Header.e_shnum =
-      Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : SN2I.size() + 1;
+      Doc.Header.SHNum ? (uint16_t)*Doc.Header.SHNum : Doc.Sections.size();
   Header.e_shstrndx = Doc.Header.SHStrNdx ? (uint16_t)*Doc.Header.SHStrNdx
                                           : SN2I.get(".shstrtab");
 }
@@ -327,30 +327,15 @@ bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
   SHeaders.resize(Doc.Sections.size());
 
   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;
-      }
+    if (I == 0 && Sec->IsImplicit)
       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
     // remains correct.
+    Elf_Shdr &SHeader = SHeaders[I];
     if (initImplicitHeader(State, CBA, SHeader, Sec->Name,
                            Sec->IsImplicit ? nullptr : Sec))
       continue;
@@ -372,7 +357,17 @@ bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
       SHeader.sh_link = Index;
     }
 
-    if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
+    if (I == 0) {
+      if (auto RawSec = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
+        // We do not write any content for special SHN_UNDEF section.
+        if (RawSec->Size)
+          SHeader.sh_size = *RawSec->Size;
+        if (RawSec->Info)
+          SHeader.sh_info = *RawSec->Info;
+      }
+      if (Sec->EntSize)
+        SHeader.sh_entsize = *Sec->EntSize;
+    } else if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec)) {
       if (!writeSectionContent(SHeader, *S, CBA))
         return false;
     } else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec)) {
@@ -966,8 +961,11 @@ bool ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
 }
 
 template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
-  for (unsigned I = 1, E = Doc.Sections.size(); I != E; ++I) {
+  for (unsigned I = 0, E = Doc.Sections.size(); I != E; ++I) {
     StringRef Name = Doc.Sections[I]->Name;
+    if (Name.empty())
+      continue;
+
     DotShStrtab.add(dropUniqueSuffix(Name));
     if (!SN2I.addName(Name, I)) {
       WithColor::error() << "Repeated section name: '" << Name