Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / test / tools / llvm-readobj / ELF / hash-histogram.test
blob10f8652bb08556113eacd4df239c835120ef5afa
1 ## Here we test the --elf-hash-histogram command line option.
3 ## This test case checks how we built histograms for hash sections.
5 # RUN: yaml2obj --docnum=1 -D BITS=32 %s -o %t1-32.o
6 # RUN: llvm-readelf --elf-hash-histogram %t1-32.o | FileCheck %s --check-prefix=HIST
8 ## Test --histogram and -I aliases.
9 # RUN: llvm-readelf --histogram %t1-32.o | FileCheck %s --check-prefix=HIST
10 # RUN: llvm-readelf -I %t1-32.o | FileCheck %s --check-prefix=HIST
12 # RUN: yaml2obj --docnum=1 -D BITS=64 %s -o %t1-64.o
13 # RUN: llvm-readelf --elf-hash-histogram %t1-64.o | FileCheck %s --check-prefix=HIST
15 ## Check that LLVM output has the expected format.
16 # RUN: llvm-readobj --elf-hash-histogram %t1-32.o | FileCheck %s --check-prefix=LLVM-HIST
17 # RUN: llvm-readobj --elf-hash-histogram %t1-64.o | FileCheck %s --check-prefix=LLVM-HIST
19 # HIST:      Histogram for bucket list length (total of 3 buckets)
20 # HIST-NEXT:  Length  Number     % of total  Coverage
21 # HIST-NEXT:       0  2          ( 66.7%)       0.0%
22 # HIST-NEXT:       1  0          (  0.0%)       0.0%
23 # HIST-NEXT:       2  0          (  0.0%)       0.0%
24 # HIST-NEXT:       3  1          ( 33.3%)     100.0%
25 # HIST-NEXT: Histogram for `.gnu.hash' bucket list length (total of 3 buckets)
26 # HIST-NEXT:  Length  Number     % of total  Coverage
27 # HIST-NEXT:       0  1          ( 33.3%)       0.0%
28 # HIST-NEXT:       1  1          ( 33.3%)      25.0%
29 # HIST-NEXT:       2  0          (  0.0%)      25.0%
30 # HIST-NEXT:       3  1          ( 33.3%)     100.0%
31 # HIST-NOT:  {{.}}
33 #      LLVM-HIST: HashHistogram {
34 # LLVM-HIST-NEXT:   TotalBuckets: 3
35 # LLVM-HIST-NEXT:   Chains [
36 # LLVM-HIST-NEXT:     Chain {
37 # LLVM-HIST-NEXT:       Length: 0
38 # LLVM-HIST-NEXT:       Count: 2
39 # LLVM-HIST-NEXT:       Percentage:  66.7
40 # LLVM-HIST-NEXT:       Coverage:   0.0
41 # LLVM-HIST-NEXT:     }
42 # LLVM-HIST-NEXT:     Chain {
43 # LLVM-HIST-NEXT:       Length: 1
44 # LLVM-HIST-NEXT:       Count: 0
45 # LLVM-HIST-NEXT:       Percentage:   0.0
46 # LLVM-HIST-NEXT:       Coverage:   0.0
47 # LLVM-HIST-NEXT:     }
48 # LLVM-HIST-NEXT:     Chain {
49 # LLVM-HIST-NEXT:       Length: 2
50 # LLVM-HIST-NEXT:       Count: 0
51 # LLVM-HIST-NEXT:       Percentage:   0.0
52 # LLVM-HIST-NEXT:       Coverage:   0.0
53 # LLVM-HIST-NEXT:     }
54 # LLVM-HIST-NEXT:     Chain {
55 # LLVM-HIST-NEXT:       Length: 3
56 # LLVM-HIST-NEXT:       Count: 1
57 # LLVM-HIST-NEXT:       Percentage:  33.3
58 # LLVM-HIST-NEXT:       Coverage: 100.0
59 # LLVM-HIST-NEXT:     }
60 # LLVM-HIST-NEXT:   ]
61 # LLVM-HIST-NEXT: }
62 # LLVM-HIST-NEXT: GnuHashHistogram {
63 # LLVM-HIST-NEXT:   TotalBuckets: 3
64 # LLVM-HIST-NEXT:   Buckets [
65 # LLVM-HIST-NEXT:     Bucket {
66 # LLVM-HIST-NEXT:       Length: 0
67 # LLVM-HIST-NEXT:       Count: 1
68 # LLVM-HIST-NEXT:       Percentage:  33.3
69 # LLVM-HIST-NEXT:       Coverage:   0.0
70 # LLVM-HIST-NEXT:     }
71 # LLVM-HIST-NEXT:     Bucket {
72 # LLVM-HIST-NEXT:       Length: 1
73 # LLVM-HIST-NEXT:       Count: 1
74 # LLVM-HIST-NEXT:       Percentage:  33.3
75 # LLVM-HIST-NEXT:       Coverage:  25.0
76 # LLVM-HIST-NEXT:     }
77 # LLVM-HIST-NEXT:     Bucket {
78 # LLVM-HIST-NEXT:       Length: 2
79 # LLVM-HIST-NEXT:       Count: 0
80 # LLVM-HIST-NEXT:       Percentage:   0.0
81 # LLVM-HIST-NEXT:       Coverage:  25.0
82 # LLVM-HIST-NEXT:     }
83 # LLVM-HIST-NEXT:     Bucket {
84 # LLVM-HIST-NEXT:       Length: 3
85 # LLVM-HIST-NEXT:       Count: 1
86 # LLVM-HIST-NEXT:       Percentage:  33.3
87 # LLVM-HIST-NEXT:       Coverage: 100.0
88 # LLVM-HIST-NEXT:     }
89 # LLVM-HIST-NEXT:   ]
90 # LLVM-HIST-NEXT: }
92 --- !ELF
93 FileHeader:
94   Class: ELFCLASS[[BITS]]
95   Data:  ELFDATA2LSB
96   Type:  ET_DYN
97 Sections:
98   - Name:   .hash
99     Type:   SHT_HASH
100     Flags:  [ SHF_ALLOC ]
101     Bucket: [ 6, 4, 5 ]
102     Chain:  [ 0, 0, 1, 0, 2 ]
103   - Name:  .gnu.hash
104     Type:  SHT_GNU_HASH
105     Flags: [ SHF_ALLOC ]
106     Header:
107       SymNdx: 0x1
108       Shift2: 0x0
109     BloomFilter: [ 0x0 ]
110     HashBuckets: [ 0x00000001, 0x00000004, 0x00000000 ]
111     HashValues:  [ 0x0B887388, 0xECD54542, 0x7C92E3BB, 0x1C5871D9 ]
112   - Name:  .dynamic
113     Type:  SHT_DYNAMIC
114     Flags: [ SHF_WRITE, SHF_ALLOC ]
115     Entries:
116       - Tag:   DT_HASH
117         Value: 0x0
118       - Tag:   DT_GNU_HASH
119 ## sizeof(.hash) == 0x28.
120         Value: 0x28
121       - Tag:   DT_NULL
122         Value: 0x0
123 DynamicSymbols:
124   - Name: a
125   - Name: b
126   - Name: c
127   - Name: d
128 ProgramHeaders:
129   - Type:     PT_LOAD
130     FirstSec: .hash
131     LastSec:  .dynamic
133 ## Show that we report a warning for a hash table which contains an entry of
134 ## the bucket array pointing to a cycle.
136 # RUN: yaml2obj --docnum=2 %s -o %t2.o
137 # RUN: llvm-readelf --elf-hash-histogram 2>&1 %t2.o | \
138 # RUN:   FileCheck -DFILE=%t2.o %s --check-prefix=BROKEN --implicit-check-not=warning:
140 # BROKEN:       warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain
141 # BROKEN:       Histogram for bucket list length (total of 2 buckets)
142 # BROKEN-NEXT:  Length  Number     % of total  Coverage
143 # BROKEN-NEXT:       0  0          (  0.0%)       0.0%
144 # BROKEN-NEXT:       1  2          (100.0%)     100.0%
146 --- !ELF
147 FileHeader:
148   Class: ELFCLASS32
149   Data:  ELFDATA2LSB
150   Type:  ET_REL
151 Sections:
152   - Name:   .hash
153     Type:   SHT_HASH
154     Link:   .dynsym
155     Bucket: [ 1, 1 ]
156     Chain:  [ 0, 1 ]
157   - Name:  .dynamic
158     Type:  SHT_DYNAMIC
159     Flags: [ SHF_ALLOC ]
160     Entries:
161 ## llvm-readelf will read the hash table from the file offset
162 ## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset,
163 ## which is the start of PT_LOAD, i.e. the file offset of .hash.
164       - Tag:   DT_HASH
165         Value: 0x0
166       - Tag:   DT_NULL
167         Value: 0
168 DynamicSymbols:
169   - Name: foo
170 ProgramHeaders:
171   - Type:     PT_LOAD
172     FirstSec: .hash
173     LastSec:  .dynamic
175 ## Each SHT_HASH section starts with two 32-bit fields: nbucket and nchain.
176 ## Check we report an error when a DT_HASH value points to data that has size less than 8 bytes.
178 # RUN: yaml2obj --docnum=3 %s -o %t3.o
179 # RUN: llvm-readelf --elf-hash-histogram %t3.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t3.o
181 # ERR1: warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8){{$}}
183 --- !ELF
184 FileHeader:
185   Class: ELFCLASS64
186   Data:  ELFDATA2LSB
187   Type:  ET_DYN
188 Sections:
189   - Name:   .hash
190     Type:   SHT_HASH
191     Flags:  [ SHF_ALLOC ]
192     Bucket: [ 0 ]
193     Chain:  [ 0 ]
194   - Name:  .dynamic
195     Type:  SHT_DYNAMIC
196     Flags: [ SHF_WRITE, SHF_ALLOC ]
197     Entries:
198       - Tag:   DT_HASH
199         Value: 0x239
200       - Tag:   DT_NULL
201         Value: 0x0
202 DynamicSymbols: []
203 ProgramHeaders:
204   - Type:     PT_LOAD
205     FileSize: 0x23a
206     FirstSec: .hash
207     LastSec:  .dynamic
209 ## Check we report a warning when the hash table goes past the end of the file.
211 ## Case A.1: the hash table ends right before the EOF. We have a broken nbucket
212 ##           field that has a value larger than the number of buckets.
213 # RUN: yaml2obj --docnum=4 %s -o %t4.1.o -DNBUCKET=0x5d -DNCHAIN=0x1
214 # RUN: llvm-readelf --elf-hash-histogram %t4.1.o 2>&1 | \
215 # RUN:   FileCheck %s --implicit-check-not={{.}} --allow-empty
217 ## Case A.2: the hash table ends 1 byte past the EOF. We have a broken nbucket
218 ##           field that has a value larger than the number of buckets.
219 # RUN: yaml2obj --docnum=4 %s -o %t4.2.o -DNBUCKET=0x5e -DNCHAIN=0x1
220 # RUN: llvm-readelf --elf-hash-histogram %t4.2.o 2>&1 | \
221 # RUN:   FileCheck %s --check-prefix=ERR2 -DFILE=%t4.2.o --implicit-check-not="warning:"
222 # ERR2: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 94, nchain = 1{{$}}
224 ## Case B.1: the hash table ends right before the EOF. We have a broken nchain
225 ##           field that has a value larger than the number of chains.
226 # RUN: yaml2obj --docnum=4 %s -o %t4.3.o -DNBUCKET=0x1 -DNCHAIN=0x5d
227 # RUN: llvm-readelf --elf-hash-histogram %t4.3.o 2>&1 | \
228 # RUN:   FileCheck %s --check-prefix=ERR3 -DFILE=%t4.3.o --implicit-check-not="warning:"
229 # ERR3: warning: '[[FILE]]': hash table nchain (93) differs from symbol count derived from SHT_DYNSYM section header (1){{$}}
230 # ERR3: warning: '[[FILE]]': the size (0x5d0) of the dynamic symbol table at 0x78, derived from the hash table, goes past the end of the file (0x1d4) and will be ignored
232 ## Case B.2: the hash table ends 1 byte past the EOF. We have a broken nchain
233 ##           field that has a value larger than the number of chains.
234 # RUN: yaml2obj --docnum=4 %s -o %t4.4.o -DNBUCKET=0x1 -DNCHAIN=0x5e
235 # RUN: llvm-readelf --elf-hash-histogram %t4.4.o 2>&1 | \
236 # RUN:   FileCheck %s --check-prefix=ERR4 -DFILE=%t4.4.o --implicit-check-not="warning:"
237 # ERR4: warning: '[[FILE]]': hash table nchain (94) differs from symbol count derived from SHT_DYNSYM section header (1){{$}}
238 # ERR4: warning: '[[FILE]]': the size (0x5e0) of the dynamic symbol table at 0x78, derived from the hash table, goes past the end of the file (0x1d4) and will be ignored
239 # ERR4: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 1, nchain = 94{{$}}
241 --- !ELF
242 FileHeader:
243   Class: ELFCLASS32
244   Data:  ELFDATA2LSB
245   Type:  ET_DYN
246 Sections:
247   - Name:    .hash
248     Type:    SHT_HASH
249     Flags:   [ SHF_ALLOC ]
250     Bucket:  [ 0 ]
251     NBucket: [[NBUCKET]]
252     Chain:   [ 0 ]
253     NChain:  [[NCHAIN]]
254   - Name:  .dynamic
255     Type:  SHT_DYNAMIC
256     Flags: [ SHF_WRITE, SHF_ALLOC ]
257     Entries:
258       - Tag:   DT_HASH
259         Value: 0x0
260       - Tag:   DT_NULL
261         Value: 0x0
262 DynamicSymbols: []
263 ProgramHeaders:
264   - Type:     PT_LOAD
265     FirstSec: .hash
266     LastSec:  .dynamic
268 ## Check we dump a histogram for the .gnu.hash table even when the .hash table is skipped.
270 ## Case A: the .hash table has no data to build histogram and it is skipped.
271 # RUN: yaml2obj --docnum=5 %s -o %t5.o
272 # RUN: llvm-readelf --elf-hash-histogram %t5.o 2>&1 | \
273 # RUN:   FileCheck %s --check-prefix=GNU-HASH --implicit-check-not="Histogram"
275 ## Case B: the .hash table has a broken nbucket field. We report a warning
276 ##         and skip dumping of the .hash table.
277 # RUN: yaml2obj --docnum=5 -DNBUCKET=0xffffffff %s -o %t6.o
278 # RUN: llvm-readelf --elf-hash-histogram %t6.o 2>&1 | \
279 # RUN:   FileCheck %s -DFILE=%t6.o --check-prefixes=WARN,GNU-HASH
281 # WARN:     warning: '[[FILE]]': the hash table at offset 0x78 goes past the end of the file (0x358), nbucket = 4294967295, nchain = 2
282 # GNU-HASH: Histogram for `.gnu.hash' bucket list length (total of 3 buckets)
284 --- !ELF
285 FileHeader:
286   Class: ELFCLASS64
287   Data:  ELFDATA2LSB
288   Type:  ET_DYN
289 Sections:
290   - Name:    .hash
291     Type:    SHT_HASH
292     Flags:   [ SHF_ALLOC ]
293     Bucket:  [ 0 ]
294 ## 0x2 is a no-op: it does not change the number of buckets described by the "Bucket" key
295     NBucket: [[NBUCKET=0x2]]
296     Chain:   [ 0, 0 ]
297   - Name:  .gnu.hash
298     Type:  SHT_GNU_HASH
299     Flags: [ SHF_ALLOC ]
300     Header:
301       SymNdx: 0x1
302       Shift2: 0x0
303     BloomFilter: [ 0x0 ]
304     HashBuckets: [ 0x00000001, 0x00000004, 0x00000000 ]
305     HashValues:  [ 0x0B887388 ]
306   - Name:  .dynamic
307     Type:  SHT_DYNAMIC
308     Flags: [ SHF_WRITE, SHF_ALLOC ]
309     Entries:
310       - Tag:   DT_HASH
311         Value: 0x0
312       - Tag:   DT_GNU_HASH
313 ## sizeof(.hash) == 0x14.
314         Value: 0x14
315       - Tag:   DT_NULL
316         Value: 0x0
317 DynamicSymbols:
318   - Name: foo
319 ProgramHeaders:
320   - Type:     PT_LOAD
321     FirstSec: .hash
322     LastSec:  .dynamic
324 ## Check we report a proper warning when the GNU hash table goes past the end of the file.
326 ## Case A: the 'maskwords' field is set so that the GNU hash table goes past the end of the file.
327 # RUN: yaml2obj --docnum=6 -D MASKWORDS=0x80000000 %s -o %t7
328 # RUN: llvm-readelf --elf-hash-histogram %t7 2>&1 | \
329 # RUN:   FileCheck %s -DFILE=%t7 --check-prefix=ERR5 --implicit-check-not="Histogram"
331 # ERR5: warning: '[[FILE]]': unable to dump the SHT_GNU_HASH section at 0x78: it goes past the end of the file
333 ## Case B: the 'nbuckets' field is set so that the GNU hash table goes past the end of the file.
334 # RUN: yaml2obj --docnum=6 -D NBUCKETS=0x80000000 %s -o %t8
335 # RUN: llvm-readelf --elf-hash-histogram %t8 2>&1 | \
336 # RUN:   FileCheck %s -DFILE=%t8 --check-prefix=ERR5 --implicit-check-not="Histogram"
338 --- !ELF
339 FileHeader:
340   Class: ELFCLASS64
341   Data:  ELFDATA2LSB
342   Type:  ET_DYN
343 Sections:
344   - Name:  .gnu.hash
345     Type:  SHT_GNU_HASH
346     Flags: [ SHF_ALLOC ]
347     Header:
348       SymNdx: 0x0
349       Shift2: 0x0
350 ## The number of words in the Bloom filter. The value of 1 is no-op.
351       MaskWords: [[MASKWORDS=1]]
352 ## The number of hash buckets. The value of 1 is no-op.
353       NBuckets:  [[NBUCKETS=1]]
354     BloomFilter: [ 0x0 ]
355     HashBuckets: [ 0x0 ]
356     HashValues:  [ 0x0 ]
357   - Name:  .dynamic
358     Type:  SHT_DYNAMIC
359     Flags: [ SHF_ALLOC ]
360     Link:  .dynstr
361     Entries:
362       - Tag:   DT_GNU_HASH
363         Value: 0x0
364       - Tag:   DT_NULL
365         Value: 0x0
366 DynamicSymbols: []
367 ProgramHeaders:
368   - Type:     PT_LOAD
369     FirstSec: .gnu.hash
370     LastSec:  .dynamic
372 ## Linkers might produce an empty no-op SHT_GNU_HASH section when
373 ## there are no dynamic symbols or when all dynamic symbols are undefined.
374 ## Such sections normally have a single zero entry in the bloom
375 ## filter, a single zero entry in the hash bucket and no values.
377 ## The index of the first symbol in the dynamic symbol table
378 ## included in the hash table can be set to the number of dynamic symbols,
379 ## which is one larger than the index of the last dynamic symbol.
380 ## For empty tables however, this value is unimportant and can be ignored.
382 ## Check the case when a 'symndx' index of the first symbol in the dynamic symbol
383 ## table is larger than the number of dynamic symbols.
385 ## Case A: when the buckets array is not empty and has a non-zero value we report a warning.
386 # RUN: yaml2obj --docnum=7 -DVAL=0x1 %s -o %t9
387 # RUN: llvm-readelf --elf-hash-histogram %t9 2>&1 | \
388 # RUN:   FileCheck %s -DFILE=%t9 --check-prefix=ERR6
390 # ERR6: warning: '[[FILE]]': unable to print the GNU hash table histogram: the first hashed symbol index (16) is greater than or equal to the number of dynamic symbols (1)
392 ## Case B: we do not report a warning when the buckets array contains only zero values.
393 # RUN: yaml2obj --docnum=7 -DVAL=0x0 %s -o %t10
394 # RUN: llvm-readelf --elf-hash-histogram %t10 2>&1 | \
395 # RUN:   FileCheck %s --allow-empty --implicit-check-not="Histogram"
397 ## Case C: we do not report a warning when the buckets array is empty.
398 # RUN: yaml2obj --docnum=7 -DVAL="" %s -o %t11
399 # RUN: llvm-readelf --elf-hash-histogram %t11 2>&1 | \
400 # RUN:   FileCheck %s --allow-empty --implicit-check-not="Histogram"
402 --- !ELF
403 FileHeader:
404   Class: ELFCLASS64
405   Data:  ELFDATA2LSB
406   Type:  ET_DYN
407 Sections:
408   - Name:  .gnu.hash
409     Type:  SHT_GNU_HASH
410     Flags: [ SHF_ALLOC ]
411     Header:
412       SymNdx: 0x10
413       Shift2: 0x0
414     BloomFilter: [ 0x0 ]
415     HashBuckets: [ [[VAL]] ]
416     HashValues:  [ 0x0 ]
417   - Name:  .dynamic
418     Type:  SHT_DYNAMIC
419     Flags: [ SHF_ALLOC ]
420     Link:  .dynstr
421     Entries:
422       - Tag:   DT_GNU_HASH
423         Value: 0x0
424       - Tag:   DT_NULL
425         Value: 0x0
426 DynamicSymbols: []
427 ProgramHeaders:
428   - Type:     PT_LOAD
429     FirstSec: .gnu.hash
430     LastSec:  .dynamic
432 ## Check we report warnings when the dynamic symbol table is absent or empty.
434 ## The code locates the dynamic symbol table by the section type. Use SHT_PROGBITS to hide it.
435 # RUN: yaml2obj --docnum=8 -DTYPE=SHT_PROGBITS %s -o %t12
436 # RUN: llvm-readelf --elf-hash-histogram %t12 2>&1 | \
437 # RUN:   FileCheck %s -DFILE=%t12 --check-prefix=ERR7
439 # ERR7: warning: '[[FILE]]': unable to print the GNU hash table histogram: no dynamic symbol table found
441 # RUN: yaml2obj --docnum=8 -DTYPE=SHT_DYNSYM %s -o %t13
442 # RUN: llvm-readelf --elf-hash-histogram %t13 2>&1 | \
443 # RUN:   FileCheck %s -DFILE=%t13 --check-prefix=ERR8
445 # ERR8: warning: '[[FILE]]': unable to print the GNU hash table histogram: the dynamic symbol table is empty
447 --- !ELF
448 FileHeader:
449   Class: ELFCLASS64
450   Data:  ELFDATA2LSB
451   Type:  ET_DYN
452 Sections:
453   - Name:  .gnu.hash
454     Type:  SHT_GNU_HASH
455     Flags: [ SHF_ALLOC ]
456     Header:
457       SymNdx: 0x0
458       Shift2: 0x0
459     BloomFilter: [ 0x0 ]
460     HashBuckets: [ 0x0 ]
461     HashValues:  [ 0x0 ]
462   - Name:  .dynamic
463     Type:  SHT_DYNAMIC
464     Flags: [ SHF_ALLOC ]
465     Entries:
466       - Tag:   DT_GNU_HASH
467         Value: 0x0
468       - Tag:   DT_NULL
469         Value: 0x0
470   - Name: .dynsym
471     Type: [[TYPE]]
472     Size: 0
473 ProgramHeaders:
474   - Type:     PT_LOAD
475     FirstSec: .gnu.hash
476     LastSec:  .gnu.hash