Skip to content

Commit daff7b8

Browse files
author
Georgii Rymar
committed
[yaml2obj] - Make DynamicSymbols to be Optional<> too.
We already have Symbols property to list regular symbols and it is currently Optional<>. This patch makes DynamicSymbols to be optional too. With this there is no need to define a dummy symbol anymore to trigger creation of the .dynsym and it is now possible to define an empty .dynsym using just the following line: DynamicSymbols: [] (it is important to have when you do not want to have dynamic symbols, but want to have a .dynsym) Now the code is consistent and it helped to fix a bug: previously we did not report an error when both Content/Size and an empty Symbols/DynamicSymbols list were specified. Differential revision: https://reviews.llvm.org/D70956
1 parent 150c8dd commit daff7b8

File tree

9 files changed

+109
-54
lines changed

9 files changed

+109
-54
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ struct Object {
481481
// top-level key, which automatically ensures that invariants like there
482482
// being a single SHT_SYMTAB section are upheld.
483483
Optional<std::vector<Symbol>> Symbols;
484-
std::vector<Symbol> DynamicSymbols;
484+
Optional<std::vector<Symbol>> DynamicSymbols;
485485

486486
std::vector<Section *> getSections() {
487487
std::vector<Section *> Ret;

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ ELFState<ELFT>::ELFState(ELFYAML::Object &D, yaml::ErrorHandler EH)
248248
ImplicitSections.push_back(".symtab");
249249
ImplicitSections.insert(ImplicitSections.end(), {".strtab", ".shstrtab"});
250250

251-
if (!Doc.DynamicSymbols.empty())
251+
if (Doc.DynamicSymbols)
252252
ImplicitSections.insert(ImplicitSections.end(), {".dynsym", ".dynstr"});
253253

254254
// Insert placeholders for implicit sections that are not
@@ -562,21 +562,24 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
562562
ArrayRef<ELFYAML::Symbol> Symbols;
563563
if (IsStatic && Doc.Symbols)
564564
Symbols = *Doc.Symbols;
565-
else if (!IsStatic)
566-
Symbols = Doc.DynamicSymbols;
565+
else if (!IsStatic && Doc.DynamicSymbols)
566+
Symbols = *Doc.DynamicSymbols;
567567

568568
ELFYAML::RawContentSection *RawSec =
569569
dyn_cast_or_null<ELFYAML::RawContentSection>(YAMLSec);
570-
if (RawSec && !Symbols.empty() && (RawSec->Content || RawSec->Size)) {
571-
if (RawSec->Content)
572-
reportError("cannot specify both `Content` and " +
573-
(IsStatic ? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
574-
" for symbol table section '" + RawSec->Name + "'");
575-
if (RawSec->Size)
576-
reportError("cannot specify both `Size` and " +
577-
(IsStatic ? Twine("`Symbols`") : Twine("`DynamicSymbols`")) +
578-
" for symbol table section '" + RawSec->Name + "'");
579-
return;
570+
if (RawSec && (RawSec->Content || RawSec->Size)) {
571+
bool HasSymbolsDescription =
572+
(IsStatic && Doc.Symbols) || (!IsStatic && Doc.DynamicSymbols);
573+
if (HasSymbolsDescription) {
574+
StringRef Property = (IsStatic ? "`Symbols`" : "`DynamicSymbols`");
575+
if (RawSec->Content)
576+
reportError("cannot specify both `Content` and " + Property +
577+
" for symbol table section '" + RawSec->Name + "'");
578+
if (RawSec->Size)
579+
reportError("cannot specify both `Size` and " + Property +
580+
" for symbol table section '" + RawSec->Name + "'");
581+
return;
582+
}
580583
}
581584

582585
zero(SHeader);
@@ -1334,7 +1337,8 @@ template <class ELFT> void ELFState<ELFT>::buildSymbolIndexes() {
13341337

13351338
if (Doc.Symbols)
13361339
Build(*Doc.Symbols, SymN2I);
1337-
Build(Doc.DynamicSymbols, DynSymN2I);
1340+
if (Doc.DynamicSymbols)
1341+
Build(*Doc.DynamicSymbols, DynSymN2I);
13381342
}
13391343

13401344
template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
@@ -1345,8 +1349,9 @@ template <class ELFT> void ELFState<ELFT>::finalizeStrings() {
13451349
DotStrtab.finalize();
13461350

13471351
// Add the dynamic symbol names to .dynstr section.
1348-
for (const ELFYAML::Symbol &Sym : Doc.DynamicSymbols)
1349-
DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name));
1352+
if (Doc.DynamicSymbols)
1353+
for (const ELFYAML::Symbol &Sym : *Doc.DynamicSymbols)
1354+
DotDynstr.add(ELFYAML::dropUniqueSuffix(Sym.Name));
13501355

13511356
// SHT_GNU_verdef and SHT_GNU_verneed sections might also
13521357
// add strings to .dynstr section.

llvm/test/tools/yaml2obj/ELF/dynsymtab-implicit-sections-size-content.yaml

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ DynamicSymbols:
3030
## Specifying both `Size` and symbols at the same time is not allowed for .dynsym.
3131

3232
# RUN: not yaml2obj --docnum=2 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE2
33+
# RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE2
3334

3435
# CASE2: yaml2obj: error: cannot specify both `Size` and `DynamicSymbols` for symbol table section '.dynsym'
3536

@@ -50,9 +51,25 @@ DynamicSymbols:
5051
- Name: foo
5152
Binding: STB_GLOBAL
5253

54+
--- !ELF
55+
FileHeader:
56+
Class: ELFCLASS64
57+
Data: ELFDATA2LSB
58+
Type: ET_DYN
59+
Machine: EM_X86_64
60+
Sections:
61+
- Name: .dynsym
62+
Type: SHT_DYNSYM
63+
Size: 0x100
64+
- Name: .dynsym2
65+
Type: SHT_DYNSYM
66+
Size: 0x100
67+
DynamicSymbols: []
68+
5369
## Specifying both `Content` and symbols at the same time is not allowed for .dynsym.
5470

55-
# RUN: not yaml2obj --docnum=3 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE3
71+
# RUN: not yaml2obj --docnum=4 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE3
72+
# RUN: not yaml2obj --docnum=5 %s 2>&1 | FileCheck %s --implicit-check-not=error --check-prefix=CASE3
5673

5774
# CASE3: yaml2obj: error: cannot specify both `Content` and `DynamicSymbols` for symbol table section '.dynsym'
5875

@@ -63,18 +80,33 @@ FileHeader:
6380
Type: ET_DYN
6481
Machine: EM_X86_64
6582
Sections:
66-
- Name: .dynsym
67-
Type: SHT_DYNSYM
83+
- Name: .dynsym
84+
Type: SHT_DYNSYM
6885
Content: "00"
69-
- Name: .dynsym2
70-
Type: SHT_DYNSYM
86+
- Name: .dynsym2
87+
Type: SHT_DYNSYM
7188
Content: "00"
7289
DynamicSymbols:
7390
- Name: foo
7491
Binding: STB_GLOBAL
7592

93+
--- !ELF
94+
FileHeader:
95+
Class: ELFCLASS64
96+
Data: ELFDATA2LSB
97+
Type: ET_DYN
98+
Machine: EM_X86_64
99+
Sections:
100+
- Name: .dynsym
101+
Type: SHT_DYNSYM
102+
Content: "00"
103+
- Name: .dynsym2
104+
Type: SHT_DYNSYM
105+
Content: "00"
106+
DynamicSymbols: []
107+
76108
## Check we can use just `Content` to emit custom data in the symbol table section.
77-
# RUN: yaml2obj --docnum=4 %s -o %t4
109+
# RUN: yaml2obj --docnum=6 %s -o %t4
78110
# RUN: llvm-readobj --section-data -S %t4 | FileCheck %s --check-prefix=CASE4
79111

80112
# CASE4: Name: .dynsym
@@ -106,7 +138,7 @@ Sections:
106138

107139
## Check we can use just `Size` to emit custom data filled with zeroes
108140
## in the symbol table section.
109-
# RUN: yaml2obj --docnum=5 %s -o %t5
141+
# RUN: yaml2obj --docnum=7 %s -o %t5
110142
# RUN: llvm-readobj --section-data -S %t5 | FileCheck %s --check-prefix=CASE5
111143

112144
# CASE5: Name: .dynsym
@@ -140,7 +172,7 @@ Sections:
140172
## than content size. In this case zeroes are added as padding
141173
## after after the specified content.
142174

143-
# RUN: yaml2obj --docnum=6 %s -o %t6
175+
# RUN: yaml2obj --docnum=8 %s -o %t6
144176
# RUN: llvm-readobj %t6 --section-data -S | FileCheck %s --check-prefix=CASE6
145177

146178
# CASE6: Name: .dynsym
@@ -174,7 +206,7 @@ Sections:
174206
## Check we can specify both `Size` and `Content` when size is
175207
## equal to content size.
176208

177-
# RUN: yaml2obj --docnum=7 %s -o %t7
209+
# RUN: yaml2obj --docnum=9 %s -o %t7
178210
# RUN: llvm-readobj --section-data -S %t7 | FileCheck %s --check-prefix=CASE7
179211

180212
# CASE7: Name: .dynsym

llvm/test/tools/yaml2obj/ELF/gnu-hash-section.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ Sections:
3232
Type: SHT_GNU_HASH
3333
Content: "001122"
3434
## Used to trigger .dynsym creation.
35-
DynamicSymbols:
36-
- Name: foo
37-
Binding: STB_GLOBAL
35+
DynamicSymbols: []
3836

3937
## Check we can use "Header", "BloomFilter", "HashBuckets" and "HashValues" keys to describe
4038
## the hash section. Check we can set sh_link to any arbitrary value. Check both ELFCLASS32 and 64 bit output.

llvm/test/tools/yaml2obj/ELF/implicit-sections-addr.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,4 @@ Sections:
5252
- Name: .symtab
5353
Type: SHT_SYMTAB
5454
Address: 0x4000
55-
DynamicSymbols:
56-
- Name: foo
57-
Binding: STB_GLOBAL
55+
DynamicSymbols: []

llvm/test/tools/yaml2obj/ELF/implicit-sections-types.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ FileHeader:
2727
## Needed to force the creation of the .symtab.
2828
Symbols: []
2929
## Needed to force the creation of the .dynsym and .dynstr.
30-
DynamicSymbols:
31-
- Name: foo
32-
- Binding: STB_GLOBAL
30+
DynamicSymbols: []
3331

3432
## Check we can set any arbitrary types when describing sections
3533
## that are usually implicit.

llvm/test/tools/yaml2obj/ELF/implicit-sections.yaml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
# CHECK: Section Headers:
1212
# CHECK-NEXT: [Nr] Name Type Address Off Size
1313
# CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000
14-
# CHECK-NEXT: [ 1] .dynstr STRTAB 0000000000000100 000040 000009
15-
# CHECK-NEXT: [ 2] .dynsym DYNSYM 0000000000000150 000049 000030
16-
# CHECK-NEXT: [ 3] .symtab SYMTAB 0000000000000000 000079 000018
17-
# CHECK-NEXT: [ 4] .strtab STRTAB 0000000000000000 000091 000001
18-
# CHECK-NEXT: [ 5] .shstrtab STRTAB 0000000000000000 000092 000035
19-
# CHECK-NEXT: [ 6] .text.foo PROGBITS 0000000000000200 0000c7 000000
14+
# CHECK-NEXT: [ 1] .dynstr STRTAB 0000000000000100 000040 000001
15+
# CHECK-NEXT: [ 2] .dynsym DYNSYM 0000000000000150 000041 000018
16+
# CHECK-NEXT: [ 3] .symtab SYMTAB 0000000000000000 000059 000018
17+
# CHECK-NEXT: [ 4] .strtab STRTAB 0000000000000000 000071 000001
18+
# CHECK-NEXT: [ 5] .shstrtab STRTAB 0000000000000000 000072 000035
19+
# CHECK-NEXT: [ 6] .text.foo PROGBITS 0000000000000200 0000a7 000000
2020

2121
--- !ELF
2222
FileHeader:
@@ -40,10 +40,6 @@ Sections:
4040
- Name: .text.foo
4141
Type: SHT_PROGBITS
4242
Address: 0x200
43-
## Symbol is required for the .dynsym to be generated.
44-
DynamicSymbols:
45-
- Name: _Z3fooi
46-
Binding: STB_GLOBAL
4743

4844
## Check that yaml2obj creates empty .dynstr and .dynsym sections for
4945
## the case when no dynamic symbols were specified and Content wasn't set,

llvm/test/tools/yaml2obj/ELF/symtab-implicit-sections-size-content.yaml

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Symbols:
2727

2828
## Specifying both `Size` and symbols at the same time is not allowed.
2929
# RUN: not yaml2obj --docnum=2 %s -o %t2 2>&1 | FileCheck %s --check-prefix=CASE2
30+
# RUN: not yaml2obj --docnum=3 %s -o %t2 2>&1 | FileCheck %s --check-prefix=CASE2
3031

3132
# CASE2: error: cannot specify both `Size` and `Symbols` for symbol table section '.symtab'
3233

@@ -43,8 +44,21 @@ Sections:
4344
Symbols:
4445
- Name: foo
4546

47+
--- !ELF
48+
FileHeader:
49+
Class: ELFCLASS64
50+
Data: ELFDATA2LSB
51+
Type: ET_DYN
52+
Machine: EM_X86_64
53+
Sections:
54+
- Name: .symtab
55+
Type: SHT_SYMTAB
56+
Size: 0x100
57+
Symbols: []
58+
4659
## Specifying both `Content` and symbols at the same time is not allowed.
47-
# RUN: not yaml2obj --docnum=3 %s -o %t3 2>&1 | FileCheck %s --check-prefix=CASE3
60+
# RUN: not yaml2obj --docnum=4 %s -o %t3 2>&1 | FileCheck %s --check-prefix=CASE3
61+
# RUN: not yaml2obj --docnum=5 %s -o %t3 2>&1 | FileCheck %s --check-prefix=CASE3
4862

4963
# CASE3: error: cannot specify both `Content` and `Symbols` for symbol table section '.symtab'
5064

@@ -55,14 +69,26 @@ FileHeader:
5569
Type: ET_DYN
5670
Machine: EM_X86_64
5771
Sections:
58-
- Name: .symtab
59-
Type: SHT_SYMTAB
72+
- Name: .symtab
73+
Type: SHT_SYMTAB
6074
Content: "00"
6175
Symbols:
6276
- Name: foo
6377

78+
--- !ELF
79+
FileHeader:
80+
Class: ELFCLASS64
81+
Data: ELFDATA2LSB
82+
Type: ET_DYN
83+
Machine: EM_X86_64
84+
Sections:
85+
- Name: .symtab
86+
Type: SHT_SYMTAB
87+
Content: "00"
88+
Symbols: []
89+
6490
## Check we can use just `Content` to emit custom data in the symbol table section.
65-
# RUN: yaml2obj --docnum=4 %s -o %t4
91+
# RUN: yaml2obj --docnum=6 %s -o %t4
6692
# RUN: llvm-readobj --section-data -S %t4 | FileCheck %s --check-prefix=CASE4
6793

6894
# CASE4: Name: .symtab
@@ -93,7 +119,7 @@ Sections:
93119

94120
## Check we can use just `Size` to emit custom data filled with zeroes
95121
## in the symbol table section.
96-
# RUN: yaml2obj --docnum=5 %s -o %t5
122+
# RUN: yaml2obj --docnum=7 %s -o %t5
97123
# RUN: llvm-readobj --section-data -S %t5 | FileCheck %s --check-prefix=CASE5
98124

99125
# CASE5: Name: .symtab (19)
@@ -126,7 +152,7 @@ Sections:
126152
## than content size. In this case zeroes are added as padding
127153
## after the specified content.
128154

129-
# RUN: yaml2obj --docnum=6 %s -o %t6
155+
# RUN: yaml2obj --docnum=8 %s -o %t6
130156
# RUN: llvm-readobj %t6 --section-data -S | FileCheck %s --check-prefix=CASE6
131157

132158
# CASE6: Name: .symtab
@@ -159,7 +185,7 @@ Sections:
159185
## Check we can specify both `Size` and `Content` when size is
160186
## equal to content size.
161187

162-
# RUN: yaml2obj --docnum=7 %s -o %t7
188+
# RUN: yaml2obj --docnum=9 %s -o %t7
163189
# RUN: llvm-readobj --section-data -S %t7 | FileCheck %s --check-prefix=CASE7
164190

165191
# CASE7: Name: .symtab

llvm/tools/obj2yaml/elf2yaml.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,11 @@ template <class ELFT> Expected<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
215215
return std::move(E);
216216
}
217217

218-
if (DynSymTab)
219-
if (Error E = dumpSymbols(DynSymTab, Y->DynamicSymbols))
218+
if (DynSymTab) {
219+
Y->DynamicSymbols.emplace();
220+
if (Error E = dumpSymbols(DynSymTab, *Y->DynamicSymbols))
220221
return std::move(E);
222+
}
221223

222224
for (const Elf_Shdr &Sec : Sections) {
223225
switch (Sec.sh_type) {

0 commit comments

Comments
 (0)