Skip to content

Commit d9afe85

Browse files
author
Georgii Rymar
committed
[yaml2obj/obj2yaml] - Refine handling of SHT_GNU_verdef sections.
This patch: 1) Makes `Version`, `Flags`, `VersionNdx` and `Hash` fields to be `Optional<>`. 2) Disallows dumping version definitions that have `vd_version != 1`. `vd_version` identifies the version of the structure itself. (https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/symversion.html, https://docs.oracle.com/cd/E19683-01/816-7777/chapter6-80869/index.html) 3) Stops dumping default values for `Version`, `Flags`, `VersionNdx` and `Hash` fields. 4) Refines testing. Differential revision: https://reviews.llvm.org/D94659
1 parent 3676ef1 commit d9afe85

File tree

6 files changed

+125
-86
lines changed

6 files changed

+125
-86
lines changed

llvm/include/llvm/ObjectYAML/ELFYAML.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -522,10 +522,10 @@ struct SymverSection : Section {
522522
};
523523

524524
struct VerdefEntry {
525-
uint16_t Version;
526-
uint16_t Flags;
527-
uint16_t VersionNdx;
528-
uint32_t Hash;
525+
Optional<uint16_t> Version;
526+
Optional<uint16_t> Flags;
527+
Optional<uint16_t> VersionNdx;
528+
Optional<uint32_t> Hash;
529529
std::vector<StringRef> VerNames;
530530
};
531531

llvm/lib/ObjectYAML/ELFEmitter.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,10 +1456,10 @@ void ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
14561456
const ELFYAML::VerdefEntry &E = (*Section.Entries)[I];
14571457

14581458
Elf_Verdef VerDef;
1459-
VerDef.vd_version = E.Version;
1460-
VerDef.vd_flags = E.Flags;
1461-
VerDef.vd_ndx = E.VersionNdx;
1462-
VerDef.vd_hash = E.Hash;
1459+
VerDef.vd_version = E.Version.getValueOr(1);
1460+
VerDef.vd_flags = E.Flags.getValueOr(0);
1461+
VerDef.vd_ndx = E.VersionNdx.getValueOr(0);
1462+
VerDef.vd_hash = E.Hash.getValueOr(0);
14631463
VerDef.vd_aux = sizeof(Elf_Verdef);
14641464
VerDef.vd_cnt = E.VerNames.size();
14651465
if (I == Section.Entries->size() - 1)

llvm/lib/ObjectYAML/ELFYAML.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,10 +1584,10 @@ void MappingTraits<ELFYAML::VerdefEntry>::mapping(IO &IO,
15841584
ELFYAML::VerdefEntry &E) {
15851585
assert(IO.getContext() && "The IO context is not initialized");
15861586

1587-
IO.mapRequired("Version", E.Version);
1588-
IO.mapRequired("Flags", E.Flags);
1589-
IO.mapRequired("VersionNdx", E.VersionNdx);
1590-
IO.mapRequired("Hash", E.Hash);
1587+
IO.mapOptional("Version", E.Version);
1588+
IO.mapOptional("Flags", E.Flags);
1589+
IO.mapOptional("VersionNdx", E.VersionNdx);
1590+
IO.mapOptional("Hash", E.Hash);
15911591
IO.mapRequired("Names", E.VerNames);
15921592
}
15931593

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,37 @@
1+
## Check how we dump SHT_GNU_verdef sections.
2+
13
# RUN: yaml2obj %s -o %t
24
# RUN: obj2yaml %t | FileCheck %s
35

4-
## Check we are able to yamalize SHT_GNU_verdef section.
5-
6-
# CHECK: - Name: .gnu.version_d
7-
# CHECK-NEXT: Type: SHT_GNU_verdef
8-
# CHECK-NEXT: Flags: [ SHF_ALLOC ]
9-
# CHECK-NEXT: Address: 0x230
10-
# CHECK-NEXT: Link: .dynstr
11-
# CHECK-NEXT: AddressAlign: 0x4
12-
# CHECK-NEXT: Info: 0x4
13-
# CHECK-NEXT: Entries:
14-
# CHECK-NEXT: - Version: 1
15-
# CHECK-NEXT: Flags: 1
16-
# CHECK-NEXT: VersionNdx: 1
17-
# CHECK-NEXT: Hash: 170240160
18-
# CHECK-NEXT: Names:
19-
# CHECK-NEXT: - dso.so.0
20-
# CHECK-NEXT: - Version: 1
21-
# CHECK-NEXT: Flags: 2
22-
# CHECK-NEXT: VersionNdx: 2
23-
# CHECK-NEXT: Hash: 108387921
24-
# CHECK-NEXT: Names:
25-
# CHECK-NEXT: - VERSION_1
26-
# CHECK-NEXT: - Version: 1
27-
# CHECK-NEXT: Flags: 3
28-
# CHECK-NEXT: VersionNdx: 3
29-
# CHECK-NEXT: Hash: 108387922
30-
# CHECK-NEXT: Names:
31-
# CHECK-NEXT: - VERSION_2
32-
# CHECK-NEXT: - VERSION_3
6+
# CHECK: - Name: .gnu.version_d
7+
# CHECK-NEXT: Type: SHT_GNU_verdef
8+
# CHECK-NEXT: Flags: [ SHF_ALLOC ]
9+
# CHECK-NEXT: Address: 0x230
10+
# CHECK-NEXT: Link: .dynstr
11+
# CHECK-NEXT: AddressAlign: 0x4
12+
# CHECK-NEXT: Info: 0x4
13+
# CHECK-NEXT: Entries:
14+
# CHECK-NEXT: - Names:
15+
# CHECK-NEXT: - VERSION_0
16+
# CHECK-NEXT: - Flags: 2
17+
# CHECK-NEXT: VersionNdx: 2
18+
# CHECK-NEXT: Hash: 108387921
19+
# CHECK-NEXT: Names:
20+
# CHECK-NEXT: - VERSION_1
21+
# CHECK-NEXT: - Flags: 3
22+
# CHECK-NEXT: VersionNdx: 3
23+
# CHECK-NEXT: Hash: 108387922
24+
# CHECK-NEXT: Names:
25+
# CHECK-NEXT: - VERSION_2
26+
# CHECK-NEXT: - VERSION_3
27+
# CHECK-NEXT: - VERSION_4
28+
# CHECK-NEXT: - Name:
3329

3430
--- !ELF
3531
FileHeader:
3632
Class: ELFCLASS64
3733
Data: ELFDATA2LSB
3834
Type: ET_DYN
39-
Entry: 0x1000
4035
Sections:
4136
- Name: .gnu.version_d
4237
Type: SHT_GNU_verdef
@@ -46,26 +41,36 @@ Sections:
4641
AddressAlign: 0x4
4742
Info: 0x4
4843
Entries:
49-
- Version: 1
50-
Flags: 1
51-
VersionNdx: 1
52-
Hash: 170240160
44+
## An entry that has all fields explicitly set to their default values.
45+
## Used to check that we don't dump them.
46+
- Version: [[VERSION=1]]
47+
Flags: 0
48+
VersionNdx: 0
49+
Hash: 0
5350
Names:
54-
- dso.so.0
55-
- Version: 1
56-
Flags: 2
57-
VersionNdx: 2
58-
Hash: 108387921
51+
- VERSION_0
52+
## An entry with arbitrary values.
53+
- Flags: 2
54+
VersionNdx: 2
55+
Hash: 108387921
5956
Names:
6057
- VERSION_1
61-
- Version: 1
62-
Flags: 3
63-
VersionNdx: 3
64-
Hash: 108387922
58+
## Another entry with arbitrary values and version predecessors.
59+
- Flags: 3
60+
VersionNdx: 3
61+
Hash: 108387922
6562
Names:
6663
- VERSION_2
6764
- VERSION_3
68-
DynamicSymbols:
69-
- Name: foo
70-
Binding: STB_GLOBAL
71-
...
65+
- VERSION_4
66+
## Needed to emit the .dynstr section.
67+
DynamicSymbols: []
68+
69+
## Document that we are not able to dump a version definition which
70+
## has a version revision (vd_version) that is not equal to 1.
71+
72+
# RUN: yaml2obj %s -DVERSION=2 -o %t.version
73+
# RUN: not obj2yaml %t.version 2>&1 | \
74+
# RUN: FileCheck %s -DFILE=%t.version --check-prefix=VERSION-ERR
75+
76+
# VERSION-ERR: Error reading file: [[FILE]]: invalid SHT_GNU_verdef section version: 2

llvm/test/tools/yaml2obj/ELF/verdef-section.yaml

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
## Check we are able to handle SHT_GNU_verdef sections.
1+
## Test how we create SHT_GNU_verdef sections.
22

33
# RUN: yaml2obj --docnum=1 %s -o %t1
44
# RUN: llvm-readobj -V %t1 | FileCheck %s
55

66
# CHECK: VersionDefinitions [
77
# CHECK-NEXT: Definition {
88
# CHECK-NEXT: Version: 1
9+
# CHECK-NEXT: Flags [ (0x0)
10+
# CHECK-NEXT: ]
11+
# CHECK-NEXT: Index: 0
12+
# CHECK-NEXT: Hash: 0
13+
# CHECK-NEXT: Name:
14+
# CHECK-NEXT: Predecessors: []
15+
# CHECK-NEXT: }
16+
# CHECK-NEXT: Definition {
17+
# CHECK-NEXT: Version: 1
918
# CHECK-NEXT: Flags [ (0x1)
1019
# CHECK-NEXT: Base (0x1)
1120
# CHECK-NEXT: ]
@@ -26,14 +35,15 @@
2635
# CHECK-NEXT: }
2736
# CHECK-NEXT: Definition {
2837
# CHECK-NEXT: Version: 1
29-
# CHECK-NEXT: Flags [ (0x3)
38+
# CHECK-NEXT: Flags [ (0xFFFF)
3039
# CHECK-NEXT: Base (0x1)
40+
# CHECK-NEXT: Info (0x4)
3141
# CHECK-NEXT: Weak (0x2)
3242
# CHECK-NEXT: ]
3343
# CHECK-NEXT: Index: 3
3444
# CHECK-NEXT: Hash: 108387922
3545
# CHECK-NEXT: Name: VERSION_2
36-
# CHECK-NEXT: Predecessors: [VERSION_3]
46+
# CHECK-NEXT: Predecessors: [VERSION_3, VERSION_4]
3747
# CHECK-NEXT: }
3848
# CHECK-NEXT: ]
3949

@@ -42,39 +52,54 @@ FileHeader:
4252
Class: ELFCLASS64
4353
Data: ELFDATA2LSB
4454
Type: ET_DYN
45-
Entry: 0x0000000000001000
4655
Sections:
47-
- Name: .gnu.version_d
48-
Type: SHT_GNU_verdef
49-
Flags: [ SHF_ALLOC ]
50-
Address: 0x0000000000000230
51-
Link: .dynstr
52-
AddressAlign: 0x0000000000000004
53-
Info: 0x0000000000000003
56+
- Name: .gnu.version_d
57+
Type: SHT_GNU_verdef
58+
Flags: [ SHF_ALLOC ]
59+
Link: .dynstr
60+
Info: 0x4
5461
Entries:
55-
- Version: 1
56-
Flags: 1
57-
VersionNdx: 1
58-
Hash: 170240160
62+
## Case 1: an entry that has no Version, Flags, VersionNdx or Hash fields set.
63+
## Used to check values that are written by default. Also shows
64+
## that we are able to use the "=<none>" syntax for these fields.
65+
- Version: [[VERSION=<none>]]
66+
Flags: [[FLAGS=<none>]]
67+
VersionNdx: [[VERNDX=<none>]]
68+
Hash: [[HASH=<none>]]
69+
Names: []
70+
## Case 2: an arbitrary entry.
71+
- Flags: 1
72+
VersionNdx: 1
73+
Hash: 170240160
5974
Names:
6075
- dso.so.0
61-
- Version: 1
62-
Flags: 2
63-
VersionNdx: 2
64-
Hash: 108387921
76+
## Case 3: one more arbitrary entry with different values.
77+
- Flags: 2
78+
VersionNdx: 2
79+
Hash: 108387921
6580
Names:
6681
- VERSION_1
67-
- Version: 1
68-
Flags: 3
69-
VersionNdx: 3
70-
Hash: 108387922
82+
## Case 4: an entry that has version predecessors. Also, it sets
83+
## all known flags as well as few unknown.
84+
- Flags: 0xffff
85+
VersionNdx: 3
86+
Hash: 108387922
7187
Names:
7288
- VERSION_2
7389
- VERSION_3
90+
- VERSION_4
7491
DynamicSymbols:
7592
- Name: foo
7693
Binding: STB_GLOBAL
7794

95+
## Check we are able to emit a version definition which has a version revision
96+
## (vd_version) field value that is not equal to 1.
97+
98+
# RUN: yaml2obj --docnum=1 -DVERSION=2 %s -o %t.version
99+
# RUN: llvm-readobj -V %t.version 2>&1 | FileCheck %s --check-prefix=VERSION-ERR
100+
101+
# VERSION-ERR: unable to dump SHT_GNU_verdef section with index 1: version 2 is not yet supported
102+
78103
## Check we can use "Content" to describe the content.
79104

80105
# RUN: yaml2obj --docnum=2 %s -o %t2

llvm/tools/obj2yaml/elf2yaml.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,10 +1315,19 @@ ELFDumper<ELFT>::dumpVerdefSection(const Elf_Shdr *Shdr) {
13151315
while (Buf) {
13161316
const Elf_Verdef *Verdef = reinterpret_cast<const Elf_Verdef *>(Buf);
13171317
ELFYAML::VerdefEntry Entry;
1318-
Entry.Version = Verdef->vd_version;
1319-
Entry.Flags = Verdef->vd_flags;
1320-
Entry.VersionNdx = Verdef->vd_ndx;
1321-
Entry.Hash = Verdef->vd_hash;
1318+
if (Verdef->vd_version != 1)
1319+
return createStringError(errc::invalid_argument,
1320+
"invalid SHT_GNU_verdef section version: " +
1321+
Twine(Verdef->vd_version));
1322+
1323+
if (Verdef->vd_flags != 0)
1324+
Entry.Flags = Verdef->vd_flags;
1325+
1326+
if (Verdef->vd_ndx != 0)
1327+
Entry.VersionNdx = Verdef->vd_ndx;
1328+
1329+
if (Verdef->vd_hash != 0)
1330+
Entry.Hash = Verdef->vd_hash;
13221331

13231332
const uint8_t *BufAux = Buf + Verdef->vd_aux;
13241333
while (BufAux) {

0 commit comments

Comments
 (0)