[llvm] r356247 - [yaml2obj]Allow explicit setting of p_filesz, p_memsz, and p_offset

James Henderson via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 15 03:35:27 PDT 2019


Author: jhenderson
Date: Fri Mar 15 03:35:27 2019
New Revision: 356247

URL: http://llvm.org/viewvc/llvm-project?rev=356247&view=rev
Log:
[yaml2obj]Allow explicit setting of p_filesz, p_memsz, and p_offset

yaml2obj currently derives the p_filesz, p_memsz, and p_offset values of
program headers from their sections. This makes writing tests for
certain formats more complex, and sometimes impossible. This patch
allows setting these fields explicitly, overriding the default value,
when relevant.

Reviewed by: jakehehrlich, Higuoxing

Differential Revision: https://reviews.llvm.org/D59372

Added:
    llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml
Modified:
    llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
    llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
    llvm/trunk/tools/yaml2obj/yaml2elf.cpp

Modified: llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h?rev=356247&r1=356246&r2=356247&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/ELFYAML.h Fri Mar 15 03:35:27 2019
@@ -86,6 +86,9 @@ struct ProgramHeader {
   llvm::yaml::Hex64 VAddr;
   llvm::yaml::Hex64 PAddr;
   Optional<llvm::yaml::Hex64> Align;
+  Optional<llvm::yaml::Hex64> FileSize;
+  Optional<llvm::yaml::Hex64> MemSize;
+  Optional<llvm::yaml::Hex64> Offset;
   std::vector<SectionName> Sections;
 };
 

Modified: llvm/trunk/lib/ObjectYAML/ELFYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/ELFYAML.cpp?rev=356247&r1=356246&r2=356247&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/ELFYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/ELFYAML.cpp Fri Mar 15 03:35:27 2019
@@ -819,6 +819,9 @@ void MappingTraits<ELFYAML::ProgramHeade
   IO.mapOptional("VAddr", Phdr.VAddr, Hex64(0));
   IO.mapOptional("PAddr", Phdr.PAddr, Hex64(0));
   IO.mapOptional("Align", Phdr.Align);
+  IO.mapOptional("FileSize", Phdr.FileSize);
+  IO.mapOptional("MemSize", Phdr.MemSize);
+  IO.mapOptional("Offset", Phdr.Offset);
 }
 
 namespace {

Added: llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml?rev=356247&view=auto
==============================================================================
--- llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml (added)
+++ llvm/trunk/test/tools/yaml2obj/program-header-size-offset.yaml Fri Mar 15 03:35:27 2019
@@ -0,0 +1,85 @@
+# Show that yaml2obj properly emits program headers with explicit file size,
+# memory size and offset parameters.
+
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-readobj %t --program-headers | FileCheck %s
+
+# CHECK: ProgramHeaders [
+# CHECK:    Offset: 0x1234
+# CHECK:    FileSize: 1111
+# CHECK:    MemSize: 9999
+
+# CHECK:    Offset: 0x2000
+# CHECK:    FileSize: 6
+# CHECK:    MemSize: 6
+
+# CHECK:    Offset: 0x2000
+# CHECK:    FileSize: 4
+# CHECK:    MemSize: 6
+
+# CHECK:    Offset: 0x1FFF
+# CHECK:    FileSize: 5
+# CHECK:    MemSize: 5
+
+# CHECK:    Offset: 0xFFE
+# CHECK:    FileSize: 7
+# CHECK:    MemSize: 9
+
+# CHECK:    Offset: 0x3000
+# CHECK:    FileSize: 3
+# CHECK:    MemSize: 2
+# CHECK: ]
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Sections:
+  - Name: .text
+    Type: SHT_PROGBITS
+    Size: 4
+    AddressAlign: 0x1000
+  - Name: .rodata
+    Type: SHT_PROGBITS
+    Size: 4
+    AddressAlign: 0x1000
+  - Name: .data
+    Type: SHT_PROGBITS
+    Size: 4
+ProgramHeaders:
+  # Program header with no sections.
+  - Type:     0x6abcdef0 # arbitrary type
+    Offset:   0x1234
+    FileSize: 1111
+    MemSize:  9999
+  # Program header with only file size set.
+  - Type:     0x6abcdef0
+    FileSize: 6
+    Sections:
+      - Section: .rodata
+  # Program header with only mem size set.
+  - Type:     0x6abcdef0
+    MemSize: 6
+    Sections:
+      - Section: .rodata
+  # Program header with only offset set.
+  - Type:     0x6abcdef0
+    Offset:   0x1fff
+    Sections:
+      - Section: .rodata
+  # Program header with sections, valid properties.
+  - Type:     0x6abcdef0
+    Offset:   0xffe
+    FileSize: 7
+    MemSize:  9
+    Sections:
+      - Section: .text
+  # Program header with sections, invalid properties.
+  - Type:     0x6abcdef0
+    Offset:   0x3000
+    FileSize: 3
+    MemSize:  2
+    Sections:
+      - Section: .data

Modified: llvm/trunk/tools/yaml2obj/yaml2elf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2elf.cpp?rev=356247&r1=356246&r2=356247&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2elf.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2elf.cpp Fri Mar 15 03:35:27 2019
@@ -397,44 +397,58 @@ void ELFState<ELFT>::setProgramHeaderLay
   for (auto &YamlPhdr : Doc.ProgramHeaders) {
     auto &PHeader = PHeaders[PhdrIdx++];
 
-    if (YamlPhdr.Sections.size())
-      PHeader.p_offset = UINT32_MAX;
-    else
-      PHeader.p_offset = 0;
+    if (YamlPhdr.Offset) {
+      PHeader.p_offset = *YamlPhdr.Offset;
+    } else {
+      if (YamlPhdr.Sections.size())
+        PHeader.p_offset = UINT32_MAX;
+      else
+        PHeader.p_offset = 0;
 
-    // Find the minimum offset for the program header.
-    for (auto SecName : YamlPhdr.Sections) {
-      uint32_t Index = 0;
-      SN2I.lookup(SecName.Section, Index);
-      const auto &SHeader = SHeaders[Index];
-      PHeader.p_offset = std::min(PHeader.p_offset, SHeader.sh_offset);
+      // Find the minimum offset for the program header.
+      for (auto SecName : YamlPhdr.Sections) {
+        uint32_t Index = 0;
+        SN2I.lookup(SecName.Section, Index);
+        const auto &SHeader = SHeaders[Index];
+        PHeader.p_offset = std::min(PHeader.p_offset, SHeader.sh_offset);
+      }
     }
 
-    // Find the maximum offset of the end of a section in order to set p_filesz.
-    PHeader.p_filesz = 0;
-    for (auto SecName : YamlPhdr.Sections) {
-      uint32_t Index = 0;
-      SN2I.lookup(SecName.Section, Index);
-      const auto &SHeader = SHeaders[Index];
-      uint64_t EndOfSection;
-      if (SHeader.sh_type == llvm::ELF::SHT_NOBITS)
-        EndOfSection = SHeader.sh_offset;
-      else
-        EndOfSection = SHeader.sh_offset + SHeader.sh_size;
-      uint64_t EndOfSegment = PHeader.p_offset + PHeader.p_filesz;
-      EndOfSegment = std::max(EndOfSegment, EndOfSection);
-      PHeader.p_filesz = EndOfSegment - PHeader.p_offset;
+    // Find the maximum offset of the end of a section in order to set p_filesz,
+    // if not set explicitly.
+    if (YamlPhdr.FileSize) {
+      PHeader.p_filesz = *YamlPhdr.FileSize;
+    } else {
+      PHeader.p_filesz = 0;
+      for (auto SecName : YamlPhdr.Sections) {
+        uint32_t Index = 0;
+        SN2I.lookup(SecName.Section, Index);
+        const auto &SHeader = SHeaders[Index];
+        uint64_t EndOfSection;
+        if (SHeader.sh_type == llvm::ELF::SHT_NOBITS)
+          EndOfSection = SHeader.sh_offset;
+        else
+          EndOfSection = SHeader.sh_offset + SHeader.sh_size;
+        uint64_t EndOfSegment = PHeader.p_offset + PHeader.p_filesz;
+        EndOfSegment = std::max(EndOfSegment, EndOfSection);
+        PHeader.p_filesz = EndOfSegment - PHeader.p_offset;
+      }
     }
 
-    // Find the memory size by adding the size of sections at the end of the
-    // segment. These should be empty (size of zero) and NOBITS sections.
-    PHeader.p_memsz = PHeader.p_filesz;
-    for (auto SecName : YamlPhdr.Sections) {
-      uint32_t Index = 0;
-      SN2I.lookup(SecName.Section, Index);
-      const auto &SHeader = SHeaders[Index];
-      if (SHeader.sh_offset == PHeader.p_offset + PHeader.p_filesz)
-        PHeader.p_memsz += SHeader.sh_size;
+    // If not set explicitly, find the memory size by adding the size of
+    // sections at the end of the segment. These should be empty (size of zero)
+    // and NOBITS sections.
+    if (YamlPhdr.MemSize) {
+      PHeader.p_memsz = *YamlPhdr.MemSize;
+    } else {
+      PHeader.p_memsz = PHeader.p_filesz;
+      for (auto SecName : YamlPhdr.Sections) {
+        uint32_t Index = 0;
+        SN2I.lookup(SecName.Section, Index);
+        const auto &SHeader = SHeaders[Index];
+        if (SHeader.sh_offset == PHeader.p_offset + PHeader.p_filesz)
+          PHeader.p_memsz += SHeader.sh_size;
+      }
     }
 
     // Set the alignment of the segment to be the same as the maximum alignment




More information about the llvm-commits mailing list