Skip to content

Commit 3001569

Browse files
author
Georgii Rymar
committed
[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
1 parent 1d15bbb commit 3001569

File tree

5 files changed

+78
-15
lines changed

5 files changed

+78
-15
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

+4
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ struct FileHeader {
8181
ELF_EF Flags;
8282
llvm::yaml::Hex64 Entry;
8383

84+
Optional<llvm::yaml::Hex64> EPhOff;
85+
Optional<llvm::yaml::Hex16> EPhEntSize;
86+
Optional<llvm::yaml::Hex16> EPhNum;
87+
8488
Optional<llvm::yaml::Hex16> SHEntSize;
8589
Optional<llvm::yaml::Hex64> SHOff;
8690
Optional<llvm::yaml::Hex16> SHNum;

llvm/lib/ObjectYAML/ELFEmitter.cpp

+21-3
Original file line numberDiff line numberDiff line change
@@ -393,11 +393,29 @@ void ELFState<ELFT>::writeELFHeader(raw_ostream &OS, uint64_t SHOff) {
393393
Header.e_machine = Doc.Header.Machine;
394394
Header.e_version = EV_CURRENT;
395395
Header.e_entry = Doc.Header.Entry;
396-
Header.e_phoff = Doc.ProgramHeaders.size() ? sizeof(Header) : 0;
397396
Header.e_flags = Doc.Header.Flags;
398397
Header.e_ehsize = sizeof(Elf_Ehdr);
399-
Header.e_phentsize = Doc.ProgramHeaders.size() ? sizeof(Elf_Phdr) : 0;
400-
Header.e_phnum = Doc.ProgramHeaders.size();
398+
399+
if (Doc.Header.EPhOff)
400+
Header.e_phoff = *Doc.Header.EPhOff;
401+
else if (!Doc.ProgramHeaders.empty())
402+
Header.e_phoff = sizeof(Header);
403+
else
404+
Header.e_phoff = 0;
405+
406+
if (Doc.Header.EPhEntSize)
407+
Header.e_phentsize = *Doc.Header.EPhEntSize;
408+
else if (!Doc.ProgramHeaders.empty())
409+
Header.e_phentsize = sizeof(Elf_Phdr);
410+
else
411+
Header.e_phentsize = 0;
412+
413+
if (Doc.Header.EPhNum)
414+
Header.e_phnum = *Doc.Header.EPhNum;
415+
else if (!Doc.ProgramHeaders.empty())
416+
Header.e_phnum = Doc.ProgramHeaders.size();
417+
else
418+
Header.e_phnum = 0;
401419

402420
Header.e_shentsize =
403421
Doc.Header.SHEntSize ? (uint16_t)*Doc.Header.SHEntSize : sizeof(Elf_Shdr);

llvm/lib/ObjectYAML/ELFYAML.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,13 @@ void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
866866
IO.mapOptional("Flags", FileHdr.Flags, ELFYAML::ELF_EF(0));
867867
IO.mapOptional("Entry", FileHdr.Entry, Hex64(0));
868868

869+
// obj2yaml does not dump these fields.
870+
assert(!IO.outputting() ||
871+
(!FileHdr.EPhOff && !FileHdr.EPhEntSize && !FileHdr.EPhNum));
872+
IO.mapOptional("EPhOff", FileHdr.EPhOff);
873+
IO.mapOptional("EPhEntSize", FileHdr.EPhEntSize);
874+
IO.mapOptional("EPhNum", FileHdr.EPhNum);
875+
869876
IO.mapOptional("SHEntSize", FileHdr.SHEntSize);
870877
IO.mapOptional("SHOff", FileHdr.SHOff);
871878
IO.mapOptional("SHNum", FileHdr.SHNum);

llvm/test/tools/yaml2obj/ELF/header-sh-fields.yaml

+43-9
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
## In this test case we check that we can override the default values for
2-
## e_shentsize, e_shoff, e_shnum and e_shstrndx fields in the YAML.
2+
## ELF header fields in the YAML.
33

44
## First we check the default values.
55

66
# RUN: yaml2obj %s -o %t-default
77
# RUN: llvm-readelf --file-headers %t-default | FileCheck %s --check-prefix=DEFAULT
88

9-
# DEFAULT: Start of section headers: 88 (bytes into file)
10-
# DEFAULT: Size of section headers: 64 (bytes)
11-
# DEFAULT: Number of section headers: 3
12-
# DEFAULT: Section header string table index: 2
9+
# DEFAULT: Start of program headers: 64 (bytes into file)
10+
# DEFAULT: Start of section headers: 200 (bytes into file)
11+
# DEFAULT: Size of program headers: 56 (bytes)
12+
# DEFAULT: Number of program headers: 2
13+
# DEFAULT: Size of section headers: 64 (bytes)
14+
# DEFAULT: Number of section headers: 3
15+
# DEFAULT: Section header string table index: 2
1316

1417
--- !ELF
1518
FileHeader:
1619
Class: ELFCLASS64
1720
Data: ELFDATA2LSB
1821
Type: ET_REL
1922
Machine: EM_X86_64
23+
ProgramHeaders:
24+
- Type: PT_LOAD
25+
Sections: []
26+
- Type: PT_LOAD
27+
Sections: []
2028

2129
## Check we can override all default values using the same values
2230
## and that this does not change the output.
@@ -29,10 +37,18 @@ FileHeader:
2937
Data: ELFDATA2LSB
3038
Type: ET_REL
3139
Machine: EM_X86_64
32-
SHEntSize: [[SHENTSIZE=64]]
33-
SHOff: [[SHOFF=88]]
34-
SHNum: [[SHNUM=3]]
35-
SHStrNdx: [[SHSTRNDX=2]]
40+
SHEntSize: [[SHENTSIZE=64]]
41+
SHOff: [[SHOFF=200]]
42+
SHNum: [[SHNUM=3]]
43+
SHStrNdx: [[SHSTRNDX=2]]
44+
EPhOff: [[PHOFF=64]]
45+
EPhEntSize: [[PHENTSIZE=56]]
46+
EPhNum: [[PHNUM=2]]
47+
ProgramHeaders:
48+
- Type: PT_LOAD
49+
Sections: []
50+
- Type: PT_LOAD
51+
Sections: []
3652

3753
## Override different fields to check the output produced.
3854

@@ -63,3 +79,21 @@ FileHeader:
6379
# RUN: od -A n -t x1 -v -j 0x3a -N 1 %t-default | FileCheck %s --check-prefix=OLDSIZE
6480
# NEWSIZE: 01
6581
# OLDSIZE: 40
82+
83+
## Override the e_phoff field.
84+
# RUN: yaml2obj --docnum=2 %s -DPHOFF=3 -o %t6
85+
# RUN: llvm-readelf --file-headers %t6 | FileCheck %s --check-prefix=PHOFF
86+
87+
# PHOFF: Start of program headers: 3 (bytes into file){{$}}
88+
89+
## Override the e_phnum field.
90+
# RUN: yaml2obj --docnum=2 %s -DPHNUM=1 -o %t7
91+
# RUN: llvm-readelf --file-headers %t7 | FileCheck %s --check-prefix=PHNUM
92+
93+
# PHNUM: Number of program headers: 1{{$}}
94+
95+
## Override the e_phentsize field.
96+
# RUN: yaml2obj --docnum=2 %s -DPHENTSIZE=1 -o %t8
97+
# RUN: not llvm-readelf --file-headers %t8 2>&1 | FileCheck %s --check-prefix=PHENTSIZE
98+
99+
# PHENTSIZE: invalid e_phentsize: 1{{$}}

llvm/tools/obj2yaml/elf2yaml.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,9 @@ bool ELFDumper<ELFT>::shouldPrintSection(const ELFYAML::Section &S,
200200
template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
201201
auto Y = std::make_unique<ELFYAML::Object>();
202202

203-
// Dump header. We do not dump SHEntSize, SHOff, SHNum and SHStrNdx fields.
204-
// When not explicitly set, the values are set by yaml2obj automatically
205-
// and there is no need to dump them here.
203+
// Dump header. We do not dump EPh* and SH* fields. When not explicitly set,
204+
// the values are set by yaml2obj automatically and there is no need to dump
205+
// them here.
206206
Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
207207
Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
208208
Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];

0 commit comments

Comments
 (0)