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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364517
91177308-0d34-0410-b5e6-
96231b3b80d8
ELF_EM Machine;
ELF_EF Flags;
llvm::yaml::Hex64 Entry;
+
+ Optional<llvm::yaml::Hex16> SHEntSize;
+ Optional<llvm::yaml::Hex16> SHOffset;
+ Optional<llvm::yaml::Hex16> SHNum;
+ Optional<llvm::yaml::Hex16> SHStrNdx;
};
struct SectionName {
IO.mapRequired("Machine", FileHdr.Machine);
IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
+
+ IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
+ IO.mapOptional("SHOffset", FileHdr.SHOffset);
+ IO.mapOptional("SHNum", FileHdr.SHNum);
+ IO.mapOptional("SHStrNdx", FileHdr.SHStrNdx);
}
void MappingTraits<ELFYAML::ProgramHeader>::mapping(
--- /dev/null
+## 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.
+
+## First we check the default values.
+
+# RUN: yaml2obj --docnum=1 %s -o %t1
+# RUN: llvm-readelf --file-headers %t1 | FileCheck %s --check-prefix=DEFAULT
+
+# DEFAULT: Start of section headers: 64 (bytes into file)
+# DEFAULT: Size of section headers: 64 (bytes)
+# DEFAULT: Number of section headers: 4
+# DEFAULT: Section header string table index: 3
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+
+## Override 3 fields: e_shoff, e_shnum and e_shstrndx. Check the output.
+
+# RUN: yaml2obj --docnum=2 %s -o %t2
+# RUN: llvm-readelf --file-headers %t2 | FileCheck %s --check-prefix=CUSTOM
+
+# CUSTOM: Start of section headers: 2 (bytes into file)
+# CUSTOM: Size of section headers: 64 (bytes)
+# CUSTOM: Number of section headers: 3
+# CUSTOM: Section header string table index: 4
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SHEntSize: 64
+ SHOffset: 2
+ SHNum: 3
+ SHStrNdx: 4
+
+## Finally, we use the same YAML as above, but set e_shentsize to 1.
+## Check the result using raw output from 'od' because llvm-readelf
+## is unable to dump such headers.
+
+# RUN: yaml2obj --docnum=3 %s -o %t3
+# RUN: od -t x1 -v -j 0x3a -N 1 %t3 | FileCheck %s --check-prefix=NEWSIZE
+# RUN: od -t x1 -v -j 0x3a -N 1 %t2 | FileCheck %s --check-prefix=OLDSIZE
+# NEWSIZE: 0000072 01
+# OLDSIZE: 0000072 40
+
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SHEntSize: 1
+ SHOffset: 2
+ SHNum: 3
+ SHStrNdx: 4
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];
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>