Skip to content

Commit 1957d68

Browse files
author
George Rimar
committed
[yaml2obj] - Add a support for defining null sections in YAMLs.
ELF spec shows (Figure 4-10: Section Header Table Entry:Index 0, http://www.sco.com/developers/gabi/latest/ch4.sheader.html) that section header at index 0 (null section) can have sh_size and sh_link fields set to non-zero values. It says (https://docs.oracle.com/cd/E19683-01/817-3677/6mj8mbtc9/index.html): "If the number of sections is greater than or equal to SHN_LORESERVE (0xff00), this member has the value zero and the actual number of section header table entries is contained in the sh_size field of the section header at index 0. Otherwise, the sh_size member of the initial entry contains 0." and: "If the section name string table section index is greater than or equal to SHN_LORESERVE (0xff00), this member has the value SHN_XINDEX (0xffff) and the actual index of the section name string table section is contained in the sh_link field of the section header at index 0. Otherwise, the sh_link member of the initial entry contains 0." At this moment it is not possible to create custom section headers at index 0 using yaml2obj. This patch implements this. Differential revision: https://reviews.llvm.org/D64913 llvm-svn: 366794
1 parent 87adcf8 commit 1957d68

File tree

2 files changed

+192
-5
lines changed

2 files changed

+192
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
## In this test we check that can redefine the null section in the YAML.
2+
3+
## Test the default output first.
4+
5+
# RUN: yaml2obj --docnum=1 %s -o %t1
6+
# RUN: llvm-readelf --sections %t1 | FileCheck %s --check-prefix=DEFAULT
7+
8+
# DEFAULT: Section Headers:
9+
# DEFAULT-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
10+
# DEFAULT-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
11+
# DEFAULT-NEXT: [ 1] .symtab SYMTAB 0000000000000000 000140 000018 18 2 1 8
12+
# DEFAULT-NEXT: [ 2] .strtab STRTAB 0000000000000000 000158 000001 00 0 0 1
13+
# DEFAULT-NEXT: [ 3] .shstrtab STRTAB 0000000000000000 000159 00001b 00 0 0 1
14+
15+
--- !ELF
16+
FileHeader:
17+
Class: ELFCLASS64
18+
Data: ELFDATA2LSB
19+
Type: ET_REL
20+
Machine: EM_X86_64
21+
22+
## Now define a SHT_NULL section with fields all zeroed.
23+
## In this case it is equal to the section created by default.
24+
25+
# RUN: yaml2obj --docnum=2 %s -o %t2
26+
# RUN: llvm-readelf --sections %t2 | FileCheck %s --check-prefix=DEFAULT
27+
28+
--- !ELF
29+
FileHeader:
30+
Class: ELFCLASS64
31+
Data: ELFDATA2LSB
32+
Type: ET_REL
33+
Machine: EM_X86_64
34+
Sections:
35+
- Type: SHT_NULL
36+
Name: ''
37+
Flags: [ ]
38+
AddressAlign: 0x0
39+
Size: 0x0
40+
EntSize: 0x0
41+
Link: 0
42+
Info: 0
43+
Address: 0x0
44+
45+
## Check we are still able to describe other sections too.
46+
47+
# RUN: yaml2obj --docnum=3 %s -o %t3
48+
# RUN: llvm-readelf --sections %t3 | FileCheck %s --check-prefix=OTHER-SECTION
49+
50+
# OTHER-SECTION: Section Headers:
51+
# OTHER-SECTION-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
52+
# OTHER-SECTION-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
53+
# OTHER-SECTION-NEXT: [ 1] foo PROGBITS 0000000000000000 000180 000000 00 0 0 0
54+
# OTHER-SECTION-NEXT: [ 2] .symtab SYMTAB 0000000000000000 000180 000018 18 3 1 8
55+
# OTHER-SECTION-NEXT: [ 3] .strtab STRTAB 0000000000000000 000198 000001 00 0 0 1
56+
# OTHER-SECTION-NEXT: [ 4] .shstrtab STRTAB 0000000000000000 000199 00001f 00 0 0 1
57+
58+
--- !ELF
59+
FileHeader:
60+
Class: ELFCLASS64
61+
Data: ELFDATA2LSB
62+
Type: ET_REL
63+
Machine: EM_X86_64
64+
Sections:
65+
- Type: SHT_NULL
66+
Name: ''
67+
Flags: [ ]
68+
AddressAlign: 0x0
69+
Size: 0x0
70+
EntSize: 0x0
71+
Link: 0
72+
- Type: SHT_PROGBITS
73+
Name: 'foo'
74+
75+
## Check we can redefine sh_size and sh_link fields of the SHT_NULL section.
76+
77+
# RUN: yaml2obj --docnum=4 %s -o %t4
78+
# RUN: llvm-readelf --sections %t4 | FileCheck %s --check-prefix=REDEFINE
79+
80+
# REDEFINE: Section Headers:
81+
# REDEFINE-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
82+
# REDEFINE-NEXT: [ 0] NULL 0000000000000000 000000 000123 00 1 0 0
83+
84+
--- !ELF
85+
FileHeader:
86+
Class: ELFCLASS64
87+
Data: ELFDATA2LSB
88+
Type: ET_REL
89+
Machine: EM_X86_64
90+
Sections:
91+
- Type: SHT_NULL
92+
Link: .foo
93+
Size: 0x123
94+
- Type: SHT_PROGBITS
95+
Name: .foo
96+
97+
## The same as above, but using a number as a Link value.
98+
99+
# RUN: yaml2obj --docnum=5 %s -o %t5
100+
# RUN: llvm-readelf --sections %t5 | FileCheck %s --check-prefix=REDEFINE
101+
102+
--- !ELF
103+
FileHeader:
104+
Class: ELFCLASS64
105+
Data: ELFDATA2LSB
106+
Type: ET_REL
107+
Machine: EM_X86_64
108+
Sections:
109+
- Type: SHT_NULL
110+
Link: 1
111+
Size: 0x123
112+
- Type: SHT_PROGBITS
113+
Name: .foo
114+
115+
## Check we report an error if null section sh_link field refers to an unknown section.
116+
117+
# RUN: not yaml2obj --docnum=6 %s -o %t6 2>&1 | FileCheck %s --check-prefix=CASE4
118+
119+
# CASE4: error: Unknown section referenced: '.foo' at YAML section ''.
120+
121+
--- !ELF
122+
FileHeader:
123+
Class: ELFCLASS64
124+
Data: ELFDATA2LSB
125+
Type: ET_REL
126+
Machine: EM_X86_64
127+
Sections:
128+
- Type: SHT_NULL
129+
Link: .foo
130+
131+
## Check that null section fields are set to zero, if they are unspecified.
132+
133+
# RUN: yaml2obj --docnum=7 %s -o %t7
134+
# RUN: llvm-readelf --sections %t7 | FileCheck %s --check-prefix=DEFAULT
135+
136+
--- !ELF
137+
FileHeader:
138+
Class: ELFCLASS64
139+
Data: ELFDATA2LSB
140+
Type: ET_REL
141+
Machine: EM_X86_64
142+
Sections:
143+
- Type: SHT_NULL
144+
145+
## Check we do not crash if we have more than one SHT_NULL section.
146+
147+
# RUN: yaml2obj --docnum=8 %s -o %t8
148+
# RUN: llvm-readelf --sections %t8 | FileCheck %s --check-prefix=MULTIPLE
149+
150+
# MULTIPLE: Section Headers:
151+
# MULTIPLE-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al
152+
# MULTIPLE-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
153+
# MULTIPLE-NEXT: [ 1] NULL 0000000000000123 000180 000020 10 A 1 2 0
154+
155+
--- !ELF
156+
FileHeader:
157+
Class: ELFCLASS64
158+
Data: ELFDATA2LSB
159+
Type: ET_REL
160+
Machine: EM_X86_64
161+
Sections:
162+
- Type: SHT_NULL
163+
- Type: SHT_NULL
164+
Flags: [ SHF_ALLOC ]
165+
Size: 0x20
166+
EntSize: 0x10
167+
Link: 1
168+
Info: 2
169+
Address: 0x123

llvm/tools/yaml2obj/yaml2elf.cpp

+23-5
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,11 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D) : Doc(D) {
192192
if (!D->Name.empty())
193193
DocSections.insert(D->Name);
194194

195-
// Insert SHT_NULL section implicitly.
196-
Doc.Sections.insert(
197-
Doc.Sections.begin(),
198-
llvm::make_unique<ELFYAML::Section>(
195+
// Insert SHT_NULL section implicitly when it is not defined in YAML.
196+
if (Doc.Sections.empty() || Doc.Sections.front()->Type != ELF::SHT_NULL)
197+
Doc.Sections.insert(
198+
Doc.Sections.begin(),
199+
llvm::make_unique<ELFYAML::Section>(
199200
ELFYAML::Section::SectionKind::RawContent, /*IsImplicit=*/true));
200201

201202
std::vector<StringRef> ImplicitSections = {".symtab", ".strtab", ".shstrtab"};
@@ -325,10 +326,27 @@ bool ELFState<ELFT>::initSectionHeaders(ELFState<ELFT> &State,
325326
// valid SHN_UNDEF entry since SHT_NULL == 0.
326327
SHeaders.resize(Doc.Sections.size());
327328

328-
for (size_t I = 1; I < Doc.Sections.size(); ++I) {
329+
for (size_t I = 0; I < Doc.Sections.size(); ++I) {
329330
Elf_Shdr &SHeader = SHeaders[I];
330331
ELFYAML::Section *Sec = Doc.Sections[I].get();
331332

333+
if (I == 0) {
334+
if (Sec->IsImplicit)
335+
continue;
336+
337+
if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec))
338+
if (S->Size)
339+
SHeader.sh_size = *S->Size;
340+
341+
if (!Sec->Link.empty()) {
342+
unsigned Index;
343+
if (!convertSectionIndex(SN2I, Sec->Name, Sec->Link, Index))
344+
return false;
345+
SHeader.sh_link = Index;
346+
}
347+
continue;
348+
}
349+
332350
// We have a few sections like string or symbol tables that are usually
333351
// added implicitly to the end. However, if they are explicitly specified
334352
// in the YAML, we need to write them here. This ensures the file offset

0 commit comments

Comments
 (0)