[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