Skip to content

Commit 9d4bbe8

Browse files
author
Georgii Rymar
committed
[llvm-readelf/llvm-readobj] - Improve dumping of broken versioning sections.
This updates the elf-invalid-versioning.test test case: makes a cleanup, adds llvm-readobj calls and fixes 2 crash/assert issues I've found (test cases are provided). Differential revision: https://reviews.llvm.org/D68705
1 parent b06305e commit 9d4bbe8

File tree

2 files changed

+333
-44
lines changed

2 files changed

+333
-44
lines changed
Lines changed: 302 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,311 @@
1-
# RUN: yaml2obj %s -o %t
2-
# RUN: llvm-readelf -V %t | FileCheck %s --check-prefix=INVALID
1+
## Here we test how llvm-readelf/llvm-readobj behave when inputs have
2+
## invalid versioning sections.
33

4-
# INVALID: Version symbols section '.gnu.version' contains 2 entries:
5-
# INVALID-NEXT: Addr: 0000000000200210 Offset: 0x000040 Link: 5 (.dynsym)
6-
# INVALID-NEXT: 000: 0 (*local*) 3 (*invalid*)
4+
## In the first case we have a SHT_GNU_versym section that refers to
5+
## a version listed in a SHT_GNU_verneed section. That version has an
6+
## empty name, making it invalid.
7+
8+
# RUN: yaml2obj --docnum=1 %s -o %t1
9+
# RUN: llvm-readelf -V %t1 | FileCheck %s --check-prefix=GNU-VERNEED-NAME
10+
# RUN: llvm-readobj -V %t1 | FileCheck %s --check-prefix=LLVM-VERNEED-NAME
11+
12+
# GNU-VERNEED-NAME: Version symbols section '.gnu.version' contains 2 entries:
13+
# GNU-VERNEED-NAME-NEXT: Addr: 0000000000200210 Offset: 0x000040 Link: 5 (.dynsym)
14+
# GNU-VERNEED-NAME-NEXT: 000: 0 (*local*) 2 (*invalid*)
15+
16+
# GNU-VERNEED-NAME: Version needs section '.gnu.version_r' contains 1 entries:
17+
# GNU-VERNEED-NAME-NEXT: Addr: 0000000000000000 Offset: 0x000044 Link: 6 (.dynstr)
18+
# GNU-VERNEED-NAME-NEXT: 0x0000: Version: 1 File: somefile Cnt: 1
19+
# GNU-VERNEED-NAME-NEXT: 0x0010: Name: Flags: none Version: 2
20+
21+
# LLVM-VERNEED-NAME: VersionSymbols [
22+
# LLVM-VERNEED-NAME: Symbol {
23+
# LLVM-VERNEED-NAME-NEXT: Version: 0
24+
# LLVM-VERNEED-NAME-NEXT: Name:
25+
# LLVM-VERNEED-NAME-NEXT: }
26+
# LLVM-VERNEED-NAME-NEXT: Symbol {
27+
# LLVM-VERNEED-NAME-NEXT: Version: 2
28+
# LLVM-VERNEED-NAME-NEXT: Name: foo
29+
# LLVM-VERNEED-NAME-NEXT: }
30+
# LLVM-VERNEED-NAME-NEXT: ]
31+
32+
# LLVM-VERNEED-NAME: VersionRequirements [
33+
# LLVM-VERNEED-NAME-NEXT: Dependency {
34+
# LLVM-VERNEED-NAME-NEXT: Version: 1
35+
# LLVM-VERNEED-NAME-NEXT: Count: 1
36+
# LLVM-VERNEED-NAME-NEXT: FileName: somefile
37+
# LLVM-VERNEED-NAME-NEXT: Entries [
38+
# LLVM-VERNEED-NAME-NEXT: Entry {
39+
# LLVM-VERNEED-NAME-NEXT: Hash: 0
40+
# LLVM-VERNEED-NAME-NEXT: Flags: 0x0
41+
# LLVM-VERNEED-NAME-NEXT: Index: 2
42+
# LLVM-VERNEED-NAME-NEXT: Name: {{$}}
43+
# LLVM-VERNEED-NAME-NEXT: }
44+
# LLVM-VERNEED-NAME-NEXT: ]
45+
# LLVM-VERNEED-NAME-NEXT: }
46+
# LLVM-VERNEED-NAME-NEXT: ]
747

848
--- !ELF
949
FileHeader:
10-
Class: ELFCLASS64
11-
Data: ELFDATA2LSB
12-
Type: ET_EXEC
13-
Machine: EM_X86_64
14-
Entry: 0x0000000000201000
50+
Class: ELFCLASS64
51+
Data: ELFDATA2LSB
52+
Type: ET_EXEC
53+
Machine: EM_X86_64
1554
Sections:
16-
- Name: .gnu.version
17-
Type: SHT_GNU_versym
18-
Flags: [ SHF_ALLOC ]
19-
Address: 0x0000000000200210
20-
Link: .dynsym
21-
AddressAlign: 0x0000000000000002
22-
EntSize: 0x0000000000000002
23-
Entries: [ 0, 3 ]
24-
- Name: .gnu.version_r
25-
Type: SHT_GNU_verneed
26-
Flags: [ SHF_ALLOC ]
27-
Address: 0x0000000000200250
28-
Link: .dynstr
29-
AddressAlign: 0x0000000000000004
30-
Info: 0x0000000000000001
55+
- Name: .gnu.version
56+
Type: SHT_GNU_versym
57+
Flags: [ SHF_ALLOC ]
58+
Address: 0x200210
59+
Link: .dynsym
60+
Entries: [ 0, 2 ]
61+
- Name: .gnu.version_r
62+
Type: SHT_GNU_verneed
63+
Flags: [ SHF_ALLOC ]
64+
Link: .dynstr
65+
Info: 1
66+
AddressAlign: 4
3167
Dependencies:
32-
- Version: 1
33-
File: somefile
68+
- Version: 1
69+
File: somefile
3470
Entries:
35-
- Name: '' # invalid name
36-
Hash: 1937
37-
Flags: 233
38-
Other: 3
71+
- Name: '' ## invalid name
72+
Hash: 0
73+
Flags: 0
74+
Other: 2
3975
DynamicSymbols:
40-
- Name: f
41-
Binding: STB_GLOBAL
76+
- Name: foo
77+
Binding: STB_GLOBAL
4278
...
79+
80+
## In this case SHT_GNU_verneed is not linked to a dynamic string table. We check we handle
81+
## this situation properly.
82+
83+
# RUN: yaml2obj --docnum=2 %s -o %t2
84+
# RUN: llvm-readelf -V %t2 | FileCheck %s --check-prefix=GNU-NOLINK
85+
# RUN: llvm-readobj -V %t2 | FileCheck %s --check-prefix=LLVM-NOLINK
86+
87+
# GNU-NOLINK: Version symbols section '.gnu.version' contains 2 entries:
88+
# GNU-NOLINK-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 5 (.dynsym)
89+
# GNU-NOLINK-NEXT: 000: 0 (*local*) 2 (bar)
90+
# GNU-NOLINK: Version needs section '.gnu.version_r' contains 1 entries:
91+
# GNU-NOLINK-NEXT: Addr: 0000000000000000 Offset: 0x000044 Link: 0 ()
92+
# GNU-NOLINK-NEXT: 0x0000: Version: 1 File: <invalid> Cnt: 1
93+
# GNU-NOLINK-NEXT: 0x0010: Name: <invalid> Flags: none Version: 2
94+
95+
# LLVM-NOLINK: VersionSymbols [
96+
# LLVM-NOLINK: Symbol {
97+
# LLVM-NOLINK-NEXT: Version: 0
98+
# LLVM-NOLINK-NEXT: Name:
99+
# LLVM-NOLINK-NEXT: }
100+
# LLVM-NOLINK-NEXT: Symbol {
101+
# LLVM-NOLINK-NEXT: Version: 2
102+
# LLVM-NOLINK-NEXT: Name: foo@bar
103+
# LLVM-NOLINK-NEXT: }
104+
# LLVM-NOLINK-NEXT: ]
105+
106+
# LLVM-NOLINK: VersionRequirements [
107+
# LLVM-NOLINK-NEXT: Dependency {
108+
# LLVM-NOLINK-NEXT: Version: 1
109+
# LLVM-NOLINK-NEXT: Count: 1
110+
# LLVM-NOLINK-NEXT: FileName: <invalid>
111+
# LLVM-NOLINK-NEXT: Entries [
112+
# LLVM-NOLINK-NEXT: Entry {
113+
# LLVM-NOLINK-NEXT: Hash: 0
114+
# LLVM-NOLINK-NEXT: Flags: 0
115+
# LLVM-NOLINK-NEXT: Index: 2
116+
# LLVM-NOLINK-NEXT: Name: <invalid>
117+
# LLVM-NOLINK-NEXT: }
118+
# LLVM-NOLINK-NEXT: ]
119+
# LLVM-NOLINK-NEXT: }
120+
# LLVM-NOLINK-NEXT: ]
121+
122+
--- !ELF
123+
FileHeader:
124+
Class: ELFCLASS64
125+
Data: ELFDATA2LSB
126+
Type: ET_EXEC
127+
Machine: EM_X86_64
128+
Sections:
129+
- Name: .gnu.version
130+
Type: SHT_GNU_versym
131+
Flags: [ SHF_ALLOC ]
132+
Link: .dynsym
133+
Entries: [ 0, 2 ]
134+
- Name: .gnu.version_r
135+
Type: SHT_GNU_verneed
136+
Flags: [ SHF_ALLOC ]
137+
Link: 0
138+
Info: 1
139+
AddressAlign: 4
140+
Dependencies:
141+
- Version: 1
142+
File: somefile
143+
Entries:
144+
- Name: 'bar'
145+
Hash: 0
146+
Flags: 0
147+
Other: 2
148+
DynamicSymbols:
149+
- Name: foo
150+
Binding: STB_GLOBAL
151+
152+
## We can't parse misaligned auxiliary version records.
153+
## Here we have a SHT_GNU_verneed section aligned by 1 byte.
154+
## This makes the first auxiliary record offset % 4 be non-zero.
155+
156+
# RUN: yaml2obj --docnum=3 %s -o %t3
157+
# RUN: not llvm-readelf -V %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=BROKEN-AUX
158+
# RUN: not llvm-readobj -V %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=BROKEN-AUX
159+
160+
# BROKEN-AUX: error: '[[FILE]]': SHT_GNU_verneed: the vn_aux field of the entry with index 0 references a misaligned auxiliary record
161+
162+
--- !ELF
163+
FileHeader:
164+
Class: ELFCLASS64
165+
Data: ELFDATA2LSB
166+
Type: ET_EXEC
167+
Machine: EM_X86_64
168+
Sections:
169+
- Name: .gnu.version
170+
Type: SHT_GNU_versym
171+
Flags: [ SHF_ALLOC ]
172+
Link: .dynsym
173+
Entries: [ 2 ]
174+
- Name: .gnu.version_r
175+
Type: SHT_GNU_verneed
176+
Flags: [ SHF_ALLOC ]
177+
Info: 1
178+
AddressAlign: 1
179+
Dependencies:
180+
- Version: 1
181+
File: somefile
182+
Entries:
183+
- Name: 'bar'
184+
Hash: 0
185+
Flags: 0
186+
Other: 2
187+
DynamicSymbols:
188+
- Name: foo
189+
190+
## Here we check that we can properly dump the case when a dependency file name
191+
## and/or a dependency name string offset is equal to the string table size.
192+
##
193+
## We set the version dependency vn_file field to the offset of string 'foo' in
194+
## the .dynstr, which is 1. We create a custom string table .mystrtab of size 1
195+
## and link it with the .gnu.version_r section. For the vna_name we use the same trick.
196+
197+
# RUN: yaml2obj --docnum=4 %s -o %t4
198+
# RUN: llvm-readobj --sections --section-data -V %t4 | FileCheck %s --check-prefix=LLVM-OFFSET-EQ
199+
# RUN: llvm-readelf --sections -V %t4 | FileCheck %s --check-prefix=GNU-OFFSET-EQ
200+
201+
# LLVM-OFFSET-EQ: Name: .mystrtab
202+
# LLVM-OFFSET-EQ: Size:
203+
# LLVM-OFFSET-EQ-SAME: 1
204+
205+
# LLVM-OFFSET-EQ: Name: .dynstr
206+
# LLVM-OFFSET-EQ: SectionData (
207+
# LLVM-OFFSET-EQ-NEXT: 0000: 00666F6F 00 |.foo.|
208+
# LLVM-OFFSET-EQ-NEXT: )
209+
210+
# LLVM-OFFSET-EQ: VersionRequirements [
211+
# LLVM-OFFSET-EQ-NEXT: Dependency {
212+
# LLVM-OFFSET-EQ-NEXT: Version: 1
213+
# LLVM-OFFSET-EQ-NEXT: Count: 1
214+
# LLVM-OFFSET-EQ-NEXT: FileName: <invalid>
215+
# LLVM-OFFSET-EQ-NEXT: Entries [
216+
# LLVM-OFFSET-EQ-NEXT: Entry {
217+
# LLVM-OFFSET-EQ-NEXT: Hash: 0
218+
# LLVM-OFFSET-EQ-NEXT: Flags: 0x0
219+
# LLVM-OFFSET-EQ-NEXT: Index: 0
220+
# LLVM-OFFSET-EQ-NEXT: Name: <invalid>
221+
# LLVM-OFFSET-EQ-NEXT: }
222+
# LLVM-OFFSET-EQ-NEXT: ]
223+
# LLVM-OFFSET-EQ-NEXT: }
224+
# LLVM-OFFSET-EQ-NEXT: ]
225+
226+
# GNU-OFFSET-EQ: Version needs section '.gnu.version_r' contains 1 entries:
227+
# GNU-OFFSET-EQ-NEXT: Addr: 0000000000000000 Offset: 0x000044 Link: 1 (.mystrtab)
228+
# GNU-OFFSET-EQ-NEXT: 0x0000: Version: 1 File: <invalid> Cnt: 1
229+
# GNU-OFFSET-EQ-NEXT: 0x0010: Name: <invalid> Flags: none Version: 0
230+
231+
--- !ELF
232+
FileHeader:
233+
Class: ELFCLASS64
234+
Data: ELFDATA2LSB
235+
Type: ET_EXEC
236+
Machine: EM_X86_64
237+
Sections:
238+
- Name: .mystrtab
239+
Type: SHT_STRTAB
240+
Content: "00"
241+
- Name: .gnu.version_r
242+
Type: SHT_GNU_verneed
243+
Flags: [ SHF_ALLOC ]
244+
Info: 1
245+
Link: .mystrtab
246+
AddressAlign: 4
247+
Dependencies:
248+
- Version: 1
249+
File: foo
250+
Entries:
251+
- Name: 'foo'
252+
Hash: 0
253+
Flags: 0
254+
Other: 0
255+
DynamicSymbols:
256+
- Name: foo
257+
258+
## Here we check that we can properly dump the case when a dependency file name
259+
## and/or a dependency name string offset is greater than the string table size.
260+
##
261+
# RUN: yaml2obj --docnum=5 %s -o %t5
262+
# RUN: llvm-readobj --sections -V %t5 | FileCheck %s --check-prefix=LLVM-OFFSET-GR
263+
# RUN: llvm-readelf --sections -V %t5 | FileCheck %s --check-prefix=GNU-OFFSET-GR
264+
265+
# LLVM-OFFSET-GR: VersionRequirements [
266+
# LLVM-OFFSET-GR-NEXT: Dependency {
267+
# LLVM-OFFSET-GR-NEXT: Version: 1
268+
# LLVM-OFFSET-GR-NEXT: Count: 1
269+
# LLVM-OFFSET-GR-NEXT: FileName: <invalid>
270+
# LLVM-OFFSET-GR-NEXT: Entries [
271+
# LLVM-OFFSET-GR-NEXT: Entry {
272+
# LLVM-OFFSET-GR-NEXT: Hash: 0
273+
# LLVM-OFFSET-GR-NEXT: Flags: 0x0
274+
# LLVM-OFFSET-GR-NEXT: Index: 0
275+
# LLVM-OFFSET-GR-NEXT: Name: <invalid>
276+
# LLVM-OFFSET-GR-NEXT: }
277+
# LLVM-OFFSET-GR-NEXT: ]
278+
# LLVM-OFFSET-GR-NEXT: }
279+
# LLVM-OFFSET-GR-NEXT: ]
280+
281+
# GNU-OFFSET-GR: Version needs section '.gnu.version_r' contains 1 entries:
282+
# GNU-OFFSET-GR-NEXT: Addr: 0000000000000000 Offset: 0x000040 Link: 1 (.mystrtab)
283+
# GNU-OFFSET-GR-NEXT: 0x0000: Version: 1 File: <invalid> Cnt: 1
284+
# GNU-OFFSET-GR-NEXT: 0x0010: Name: <invalid> Flags: none Version: 0
285+
286+
--- !ELF
287+
FileHeader:
288+
Class: ELFCLASS64
289+
Data: ELFDATA2LSB
290+
Type: ET_EXEC
291+
Machine: EM_X86_64
292+
Sections:
293+
- Name: .mystrtab
294+
Type: SHT_STRTAB
295+
Content: ""
296+
- Name: .gnu.version_r
297+
Type: SHT_GNU_verneed
298+
Flags: [ SHF_ALLOC ]
299+
Info: 1
300+
Link: .mystrtab
301+
AddressAlign: 4
302+
Dependencies:
303+
- Version: 1
304+
File: foo
305+
Entries:
306+
- Name: 'foo'
307+
Hash: 0
308+
Flags: 0
309+
Other: 0
310+
DynamicSymbols:
311+
- Name: foo

0 commit comments

Comments
 (0)