[llvm] 3001569 - [yaml2obj] - Add a syntax to override e_phoff, e_phentsize and e_phnum fields.

Georgii Rymar via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 14 03:19:44 PDT 2020


Author: Georgii Rymar
Date: 2020-07-14T13:16:19+03:00
New Revision: 300156932321a8b34b46d6a890cce0699525ed20

URL: https://github.com/llvm/llvm-project/commit/300156932321a8b34b46d6a890cce0699525ed20
DIFF: https://github.com/llvm/llvm-project/commit/300156932321a8b34b46d6a890cce0699525ed20.diff

LOG: [yaml2obj] - Add a syntax to override e_phoff, e_phentsize and e_phnum fields.

This adds `EPhOff`, `EPhEntSize` and `EPhNum` keys.
Will be useful for creating broken objects for testing llvm-readelf.

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

Added: 
    

Modified: 
    llvm/include/llvm/ObjectYAML/ELFYAML.h
    llvm/lib/ObjectYAML/ELFEmitter.cpp
    llvm/lib/ObjectYAML/ELFYAML.cpp
    llvm/test/tools/yaml2obj/ELF/header-sh-fields.yaml
    llvm/tools/obj2yaml/elf2yaml.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ObjectYAML/ELFYAML.h b/llvm/include/llvm/ObjectYAML/ELFYAML.h
index e7a2411a3e2a..bfc31ea247ef 100644
--- a/llvm/include/llvm/ObjectYAML/ELFYAML.h
+++ b/llvm/include/llvm/ObjectYAML/ELFYAML.h
@@ -81,6 +81,10 @@ struct FileHeader {
   ELF_EF Flags;
   llvm::yaml::Hex64 Entry;
 
+  Optional<llvm::yaml::Hex64> EPhOff;
+  Optional<llvm::yaml::Hex16> EPhEntSize;
+  Optional<llvm::yaml::Hex16> EPhNum;
+
   Optional<llvm::yaml::Hex16> SHEntSize;
   Optional<llvm::yaml::Hex64> SHOff;
   Optional<llvm::yaml::Hex16> SHNum;

diff  --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp
index 218e7df8e39a..f4ad10a9eb08 100644
--- a/llvm/lib/ObjectYAML/ELFEmitter.cpp
+++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp
@@ -393,11 +393,29 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS, uint64_t SHOff) {
   Header.e_machine = Doc.Header.Machine;
   Header.e_version = EV_CURRENT;
   Header.e_entry = Doc.Header.Entry;
-  Header.e_phoff = Doc.ProgramHeaders.size() ? sizeof(Header) : 0;
   Header.e_flags = Doc.Header.Flags;
   Header.e_ehsize = sizeof(Elf_Ehdr);
-  Header.e_phentsize = Doc.ProgramHeaders.size() ? sizeof(Elf_Phdr) : 0;
-  Header.e_phnum = Doc.ProgramHeaders.size();
+
+  if (Doc.Header.EPhOff)
+    Header.e_phoff = *Doc.Header.EPhOff;
+  else if (!Doc.ProgramHeaders.empty())
+    Header.e_phoff = sizeof(Header);
+  else
+    Header.e_phoff = 0;
+
+  if (Doc.Header.EPhEntSize)
+    Header.e_phentsize = *Doc.Header.EPhEntSize;
+  else if (!Doc.ProgramHeaders.empty())
+    Header.e_phentsize = sizeof(Elf_Phdr);
+  else
+    Header.e_phentsize = 0;
+
+  if (Doc.Header.EPhNum)
+    Header.e_phnum = *Doc.Header.EPhNum;
+  else if (!Doc.ProgramHeaders.empty())
+    Header.e_phnum = Doc.ProgramHeaders.size();
+  else
+    Header.e_phnum = 0;
 
   Header.e_shentsize =
       Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr);

diff  --git a/llvm/lib/ObjectYAML/ELFYAML.cpp b/llvm/lib/ObjectYAML/ELFYAML.cpp
index 3de1ae006ce4..aa247c53a3c6 100644
--- a/llvm/lib/ObjectYAML/ELFYAML.cpp
+++ b/llvm/lib/ObjectYAML/ELFYAML.cpp
@@ -866,6 +866,13 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
   IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
   IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
 
+  // obj2yaml does not dump these fields.
+  assert(!IO.outputting() ||
+         (!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum));
+  IO.mapOptional("EPhOff", FileHdr.EPhOff);
+  IO.mapOptional("EPhEntSize", FileHdr.EPhEntSize);
+  IO.mapOptional("EPhNum", FileHdr.EPhNum);
+
   IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
   IO.mapOptional("SHOff", FileHdr.SHOff);
   IO.mapOptional("SHNum", FileHdr.SHNum);

diff  --git a/llvm/test/tools/yaml2obj/ELF/header-sh-fields.yaml b/llvm/test/tools/yaml2obj/ELF/header-sh-fields.yaml
index 166c68405bb7..f52e5731271f 100644
--- a/llvm/test/tools/yaml2obj/ELF/header-sh-fields.yaml
+++ b/llvm/test/tools/yaml2obj/ELF/header-sh-fields.yaml
@@ -1,15 +1,18 @@
 ## In this test case we check that we can override the default values for
-## e_shentsize, e_shoff, e_shnum and e_shstrndx fields in the YAML.
+## ELF header fields in the YAML.
 
 ## First we check the default values.
 
 # RUN: yaml2obj %s -o %t-default
 # RUN: llvm-readelf --file-headers %t-default | FileCheck %s --check-prefix=DEFAULT
 
-# DEFAULT:   Start of section headers:          88 (bytes into file)
-# DEFAULT:   Size of section headers:           64 (bytes)
-# DEFAULT:   Number of section headers:         3
-# DEFAULT:   Section header string table index: 2
+# DEFAULT: Start of program headers:          64 (bytes into file)
+# DEFAULT: Start of section headers:          200 (bytes into file)
+# DEFAULT: Size of program headers:           56 (bytes)
+# DEFAULT: Number of program headers:         2
+# DEFAULT: Size of section headers:           64 (bytes)
+# DEFAULT: Number of section headers:         3
+# DEFAULT: Section header string table index: 2
 
 --- !ELF
 FileHeader:
@@ -17,6 +20,11 @@ FileHeader:
   Data:    ELFDATA2LSB
   Type:    ET_REL
   Machine: EM_X86_64
+ProgramHeaders:
+  - Type:     PT_LOAD
+    Sections: []
+  - Type:     PT_LOAD
+    Sections: []
 
 ## Check we can override all default values using the same values
 ## and that this does not change the output.
@@ -29,10 +37,18 @@ FileHeader:
   Data:      ELFDATA2LSB
   Type:      ET_REL
   Machine:   EM_X86_64
-  SHEntSize: [[SHENTSIZE=64]]
-  SHOff:     [[SHOFF=88]]
-  SHNum:     [[SHNUM=3]]
-  SHStrNdx:  [[SHSTRNDX=2]]
+  SHEntSize:  [[SHENTSIZE=64]]
+  SHOff:      [[SHOFF=200]]
+  SHNum:      [[SHNUM=3]]
+  SHStrNdx:   [[SHSTRNDX=2]]
+  EPhOff:     [[PHOFF=64]]
+  EPhEntSize: [[PHENTSIZE=56]]
+  EPhNum:     [[PHNUM=2]]
+ProgramHeaders:
+  - Type:     PT_LOAD
+    Sections: []
+  - Type:     PT_LOAD
+    Sections: []
 
 ## Override 
diff erent fields to check the output produced.
 
@@ -63,3 +79,21 @@ FileHeader:
 # RUN: od -A n -t x1 -v -j 0x3a -N 1 %t-default | FileCheck %s --check-prefix=OLDSIZE
 # NEWSIZE: 01
 # OLDSIZE: 40
+
+## Override the e_phoff field.
+# RUN: yaml2obj --docnum=2 %s -DPHOFF=3 -o %t6
+# RUN: llvm-readelf --file-headers %t6 | FileCheck %s --check-prefix=PHOFF
+
+# PHOFF: Start of program headers: 3 (bytes into file){{$}}
+
+## Override the e_phnum field.
+# RUN: yaml2obj --docnum=2 %s -DPHNUM=1 -o %t7
+# RUN: llvm-readelf --file-headers %t7 | FileCheck %s --check-prefix=PHNUM
+
+# PHNUM: Number of program headers: 1{{$}}
+
+## Override the e_phentsize field.
+# RUN: yaml2obj --docnum=2 %s -DPHENTSIZE=1 -o %t8
+# RUN: not llvm-readelf --file-headers %t8 2>&1 | FileCheck %s --check-prefix=PHENTSIZE
+
+# PHENTSIZE: invalid e_phentsize: 1{{$}}

diff  --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index 868a78e15c66..7b0687a5a5f8 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -200,9 +200,9 @@ bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S,
 template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
   auto Y = std::make_unique<ELFYAML::Object>();
 
-  // Dump header. We do not dump SHEntSize, SHOff, SHNum and SHStrNdx fields.
-  // When not explicitly set, the values are set by yaml2obj automatically
-  // and there is no need to dump them here.
+  // Dump header. We do not dump EPh* and SH* fields. When not explicitly set,
+  // the values are set by yaml2obj automatically and there is no need to dump
+  // them here.
   Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
   Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
   Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];


        


More information about the llvm-commits mailing list