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%
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
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
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
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
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
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
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
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
94 Class: ELFCLASS[[BITS]]
102 Chain: [ 0, 0, 1, 0, 2 ]
110 HashBuckets: [ 0x00000001, 0x00000004, 0x00000000 ]
111 HashValues: [ 0x0B887388, 0xECD54542, 0x7C92E3BB, 0x1C5871D9 ]
114 Flags: [ SHF_WRITE, SHF_ALLOC ]
119 ## sizeof(.hash) == 0x28.
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%
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.
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){{$}}
196 Flags: [ SHF_WRITE, SHF_ALLOC ]
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{{$}}
256 Flags: [ SHF_WRITE, SHF_ALLOC ]
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)
294 ## 0x2 is a no-op: it does not change the number of buckets described by the "Bucket" key
295 NBucket: [[NBUCKET=0x2]]
304 HashBuckets: [ 0x00000001, 0x00000004, 0x00000000 ]
305 HashValues: [ 0x0B887388 ]
308 Flags: [ SHF_WRITE, SHF_ALLOC ]
313 ## sizeof(.hash) == 0x14.
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"
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]]
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"
415 HashBuckets: [ [[VAL]] ]
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