[yaml2obj] - Allow overriding e_shentsize, e_shoff, e_shnum and e_shstrndx fields in the YAML.

This allows setting different values for e_shentsize, e_shoff, e_shnum
and e_shstrndx fields and is useful for producing broken inputs for various
test cases.

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

llvm-svn: 364517
diff --git a/llvm/tools/obj2yaml/elf2yaml.cpp b/llvm/tools/obj2yaml/elf2yaml.cpp
index a47d553..804101f 100644
--- a/llvm/tools/obj2yaml/elf2yaml.cpp
+++ b/llvm/tools/obj2yaml/elf2yaml.cpp
@@ -137,7 +137,9 @@
 template <class ELFT> ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
   auto Y = make_unique<ELFYAML::Object>();
 
-  // Dump header
+  // Dump header. We do not dump SHEntSize, SHOffset, SHNum and SHStrNdx field.
+  // 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];
diff --git a/llvm/tools/yaml2obj/yaml2elf.cpp b/llvm/tools/yaml2obj/yaml2elf.cpp
index f3f7800..e093ed8 100644
--- a/llvm/tools/yaml2obj/yaml2elf.cpp
+++ b/llvm/tools/yaml2obj/yaml2elf.cpp
@@ -208,12 +208,18 @@
   Header.e_ehsize = sizeof(Elf_Ehdr);
   Header.e_phentsize = sizeof(Elf_Phdr);
   Header.e_phnum = Doc.ProgramHeaders.size();
-  Header.e_shentsize = sizeof(Elf_Shdr);
+
+  Header.e_shentsize =
+      Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr);
   // Immediately following the ELF header and program headers.
   Header.e_shoff =
-      sizeof(Header) + sizeof(Elf_Phdr) * Doc.ProgramHeaders.size();
-  Header.e_shnum = SN2I.size() + 1;
-  Header.e_shstrndx = SN2I.get(".shstrtab");
+      Doc.Header.SHOffset
+          ? (uint16_t)*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;
+  Header.e_shstrndx = Doc.Header.SHStrNdx ? (uint16_t)*Doc.Header.SHStrNdx
+                                          : SN2I.get(".shstrtab");
 }
 
 template <class ELFT>