xref: /llvm-project/llvm/test/tools/llvm-readobj/ELF/hash-symbols.test (revision 7f7dac712694ed661b2e774573b9ee1f99208882)
1## Check llvm-readelf is able to dump the content of hash sections correctly.
2
3## Check the output when both .hash and .gnu.hash sections are present.
4
5# RUN: yaml2obj --docnum=1 -DBITS=32 %s -o %t1-32.so
6# RUN: llvm-readelf --hash-symbols %t1-32.so \
7# RUN:   | FileCheck %s --strict-whitespace --match-full-lines --check-prefix HASH-32
8
9# RUN: yaml2obj --docnum=1 -DBITS=64 %s -o %t1-64.so
10# RUN: llvm-readelf --hash-symbols %t1-64.so | FileCheck %s --check-prefix HASH-64
11
12# HASH-32: Symbol table of .hash for image:
13# HASH-32-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
14# HASH-32-NEXT:    1   0: 00000000     0 NOTYPE  GLOBAL DEFAULT UND ccc
15# HASH-32-NEXT:    5   0: 00001001     0 NOTYPE  WEAK   DEFAULT   1 bbb
16# HASH-32-NEXT:    3   0: 00000001     0 NOTYPE  GLOBAL DEFAULT ABS ddd
17# HASH-32-NEXT:    2   0: 00001000     0 NOTYPE  GLOBAL DEFAULT   1 aaa
18# HASH-32-NEXT:    4   0: 00000000     0 NOTYPE  GLOBAL DEFAULT   2 eee
19# HASH-32-EMPTY:
20# HASH-32: Symbol table of .gnu.hash for image:
21# HASH-32-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
22# HASH-32-NEXT:    2   1: 00001000     0 NOTYPE  GLOBAL DEFAULT   1 aaa
23# HASH-32-NEXT:    3   1: 00000001     0 NOTYPE  GLOBAL DEFAULT ABS ddd
24# HASH-32-NEXT:    4   2: 00000000     0 NOTYPE  GLOBAL DEFAULT   2 eee
25# HASH-32-NEXT:    5   2: 00001001     0 NOTYPE  WEAK   DEFAULT   1 bbb
26# HASH-32-NOT: {{.}}
27
28# HASH-64:      Symbol table of .hash for image:
29# HASH-64-NEXT:  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name
30# HASH-64-NEXT:    1   0: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT UND ccc
31# HASH-64-NEXT:    5   0: 0000000000001001     0 NOTYPE  WEAK   DEFAULT   1 bbb
32# HASH-64-NEXT:    3   0: 0000000000000001     0 NOTYPE  GLOBAL DEFAULT ABS ddd
33# HASH-64-NEXT:    2   0: 0000000000001000     0 NOTYPE  GLOBAL DEFAULT   1 aaa
34# HASH-64-NEXT:    4   0: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT   2 eee
35# HASH-64-EMPTY:
36# HASH-64-NEXT: Symbol table of .gnu.hash for image:
37# HASH-64-NEXT:  Num Buc:    Value          Size   Type   Bind Vis      Ndx Name
38# HASH-64-NEXT:    2   1: 0000000000001000     0 NOTYPE  GLOBAL DEFAULT   1 aaa
39# HASH-64-NEXT:    3   1: 0000000000000001     0 NOTYPE  GLOBAL DEFAULT ABS ddd
40# HASH-64-NEXT:    4   2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT   2 eee
41# HASH-64-NEXT:    5   2: 0000000000001001     0 NOTYPE  WEAK   DEFAULT   1 bbb
42# HASH-64-NOT: {{.}}
43
44--- !ELF
45FileHeader:
46  Class: ELFCLASS[[BITS]]
47  Data:  ELFDATA2LSB
48  Type:  ET_DYN
49Sections:
50  - Name:    .hash
51    Type:    SHT_HASH
52    Flags:   [ SHF_ALLOC ]
53    Link:    .dynsym
54    Bucket:  [ 1, 0, 0 ]
55    Chain:   [ 0, 5, 4, 2, 0, 3 ]
56  - Name:    .gnu.hash
57    Type:    SHT_GNU_HASH
58    Flags:   [ SHF_ALLOC ]
59    Link:    .dynsym
60    Header:
61      SymNdx: 0x2
62      Shift2: 0x0
63    BloomFilter: [ 0x0 ]
64    HashBuckets: [ 0x0, 0x2, 0x4 ]
65    HashValues:  [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ]
66  - Name:  .dynamic
67    Type:  SHT_DYNAMIC
68    Flags: [ SHF_ALLOC ]
69    Link:  .dynstr
70    Entries:
71## PT_LOAD's p_vaddr is 0x0. DT_HASH value is 0x0.
72## llvm-readelf will read .hash content from PT_LOAD's p_offset + (DT_HASH value - p_vaddr).
73## This matches the file offset of the .hash section.
74      - Tag:   DT_HASH
75        Value: 0x0000000000000000
76      - Tag:   DT_GNU_HASH
77## PT_LOAD's p_vaddr is 0x0. DT_GNU_HASH value is 0x2c (size of .hash = 0x2c).
78## llvm-readelf will read .gnu.hash content from PT_LOAD's p_offset + (DT_GNU_HASH value - p_vaddr).
79## This matches the file offset of the .gnu.hash section.
80        Value: 0x000000000000002C
81      - Tag:   DT_NULL
82        Value: 0x0000000000000000
83DynamicSymbols:
84  - Name:    [[NAME=ccc]]
85    Binding: STB_GLOBAL
86    Type:    [[TYPE=STT_NOTYPE]]
87  - Name:    [[NAME=aaa]]
88    Section: .hash
89    Binding: STB_GLOBAL
90    Value:   0x0000000000001000
91    Type:    [[TYPE=STT_NOTYPE]]
92  - Name:    [[NAME=ddd]]
93    Index:   SHN_ABS
94    Binding: STB_GLOBAL
95    Value:   0x0000000000000001
96    Type:    [[TYPE=STT_NOTYPE]]
97  - Name:    [[NAME=eee]]
98    Section: .gnu.hash
99    Binding: STB_GLOBAL
100    Type:    [[TYPE=STT_NOTYPE]]
101  - Name:    [[NAME=bbb]]
102    Section: .hash
103    Binding: STB_WEAK
104    Value:   0x0000000000001001
105    Type:    [[TYPE=STT_NOTYPE]]
106ProgramHeaders:
107  - Type:      PT_LOAD
108    Flags:     [ PF_R, PF_X ]
109    FirstSec:  .hash
110    LastSec:   .dynamic
111
112## Check what we print for unnamed section symbols.
113# RUN: yaml2obj --docnum=1 -DBITS=64 -DTYPE=STT_SECTION -DNAME="''" %s -o %t1-sec-syms.so
114# RUN: llvm-readelf --hash-symbols %t1-sec-syms.so 2>&1 | \
115# RUN:   FileCheck %s -DFILE=%t1-sec-syms.so --check-prefix=UNNAMED-SEC-SYMS
116
117# UNNAMED-SEC-SYMS:      Symbol table of .hash for image:
118# UNNAMED-SEC-SYMS-NEXT:  Num   {{.*}} Ndx Name
119# UNNAMED-SEC-SYMS-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF)
120# UNNAMED-SEC-SYMS-NEXT:    1   {{.*}} UND <?>
121# UNNAMED-SEC-SYMS-NEXT:    5   {{.*}}   1 .hash
122# UNNAMED-SEC-SYMS-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS)
123# UNNAMED-SEC-SYMS-NEXT:    3   {{.*}} ABS <?>
124# UNNAMED-SEC-SYMS-NEXT:    2   {{.*}}   1 .hash
125# UNNAMED-SEC-SYMS-NEXT:    4   {{.*}}   2 .gnu.hash
126# UNNAMED-SEC-SYMS-EMPTY:
127# UNNAMED-SEC-SYMS:      Symbol table of .gnu.hash for image:
128# UNNAMED-SEC-SYMS-NEXT:  Num {{.*}} Ndx Name
129# UNNAMED-SEC-SYMS-NEXT:    2 {{.*}}   1 .hash
130# UNNAMED-SEC-SYMS-NEXT:    3 {{.*}} ABS <?>
131# UNNAMED-SEC-SYMS-NEXT:    4 {{.*}}   2 .gnu.hash
132# UNNAMED-SEC-SYMS-NEXT:    5 {{.*}}   1 .hash
133
134## Check the output when only .hash section is present.
135
136# RUN: yaml2obj --docnum=2 %s -o %t2-32.so
137# RUN: llvm-readelf --hash-symbols %t2-32.so \
138# RUN:   | FileCheck %s --strict-whitespace --match-full-lines --check-prefix ONLY-HASH-32
139
140# ONLY-HASH-32: Symbol table of .hash for image:
141# ONLY-HASH-32-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
142# ONLY-HASH-32-NEXT:    1   0: 00000000     0 NOTYPE  GLOBAL DEFAULT UND ccc
143# ONLY-HASH-32-NEXT:    5   0: 00001001     0 NOTYPE  WEAK   DEFAULT   1 bbb
144# ONLY-HASH-32-NEXT:    3   0: 00000001     0 NOTYPE  GLOBAL DEFAULT ABS ddd
145# ONLY-HASH-32-NEXT:    2   0: 00001000     0 NOTYPE  GLOBAL DEFAULT   1 aaa
146# ONLY-HASH-32-NEXT:    4   0: 00000000     0 NOTYPE  GLOBAL DEFAULT   2 eee
147# ONLY-HASH-32-NOT: {{.}}
148
149--- !ELF
150FileHeader:
151  Class: ELFCLASS32
152  Data:  ELFDATA2LSB
153  Type:  ET_DYN
154Sections:
155  - Name:    .hash
156    Type:    SHT_HASH
157    Flags:   [ SHF_ALLOC ]
158    Link:    .dynsym
159    Bucket: [ 1, 0, 0 ]
160    Chain:  [ 0, 5, 4, 2, 0, 3 ]
161  - Name:  .dynamic
162    Type:  SHT_DYNAMIC
163    Flags: [ SHF_ALLOC ]
164    Link:  .dynstr
165    Entries:
166      - Tag:   DT_HASH
167        Value: 0x0000000000000000
168      - Tag:   DT_NULL
169        Value: 0x0000000000000000
170DynamicSymbols:
171  - Name:    ccc
172    Binding: STB_GLOBAL
173  - Name:    aaa
174    Section: .hash
175    Binding: STB_GLOBAL
176    Value:   0x0000000000001000
177  - Name:    ddd
178    Index:   SHN_ABS
179    Binding: STB_GLOBAL
180    Value:   0x0000000000000001
181  - Name:    eee
182    Section: .dynamic
183    Binding: STB_GLOBAL
184  - Name:    bbb
185    Section: .hash
186    Binding: STB_WEAK
187    Value:   0x0000000000001001
188ProgramHeaders:
189  - Type:     PT_LOAD
190    Flags:    [ PF_R, PF_X ]
191    FirstSec: .hash
192    LastSec:  .dynamic
193
194## Check the output when only .gnu.hash section is present.
195
196# RUN: yaml2obj --docnum=3 %s -o %t3-32.so
197# RUN: llvm-readelf --hash-symbols %t3-32.so \
198# RUN:   | FileCheck %s --strict-whitespace --match-full-lines --check-prefix ONLY-GNUHASH-32
199
200# ONLY-GNUHASH-32: Symbol table of .gnu.hash for image:
201# ONLY-GNUHASH-32-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
202# ONLY-GNUHASH-32-NEXT:    2   1: 00001000     0 NOTYPE  GLOBAL DEFAULT   2 aaa
203# ONLY-GNUHASH-32-NEXT:    3   1: 00000001     0 NOTYPE  GLOBAL DEFAULT ABS ddd
204# ONLY-GNUHASH-32-NEXT:    4   2: 00000000     0 NOTYPE  GLOBAL DEFAULT   1 eee
205# ONLY-GNUHASH-32-NEXT:    5   2: 00001001     0 NOTYPE  WEAK   DEFAULT   2 bbb
206# ONLY-GNUHASH-32-NOT: {{.}}
207
208--- !ELF
209FileHeader:
210  Class: ELFCLASS32
211  Data:  ELFDATA2LSB
212  Type:  ET_DYN
213Sections:
214  - Name:    .gnu.hash
215    Type:    SHT_GNU_HASH
216    Flags:   [ SHF_ALLOC ]
217    Link:    .dynsym
218    Header:
219      SymNdx: 0x2
220      Shift2: 0x0
221    BloomFilter: [ 0x0 ]
222    HashBuckets: [ 0x0, 0x2, 0x4 ]
223    HashValues:  [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ]
224  - Name:  .dynamic
225    Type:  SHT_DYNAMIC
226    Flags: [ SHF_ALLOC ]
227    Link:  .dynstr
228    Entries:
229      - Tag:   DT_GNU_HASH
230        Value: 0x0000000000000000
231      - Tag:   DT_NULL
232        Value: 0x0000000000000000
233DynamicSymbols:
234  - Name:    ccc
235    Binding: STB_GLOBAL
236  - Name:    aaa
237    Section: .dynamic
238    Binding: STB_GLOBAL
239    Value:   0x0000000000001000
240  - Name:    ddd
241    Index:   SHN_ABS
242    Binding: STB_GLOBAL
243    Value:   0x0000000000000001
244  - Name:    eee
245    Section: .gnu.hash
246    Binding: STB_GLOBAL
247  - Name:    bbb
248    Section: .dynamic
249    Binding: STB_WEAK
250    Value:   0x0000000000001001
251ProgramHeaders:
252  - Type:     PT_LOAD
253    Flags:    [ PF_R, PF_X ]
254    FirstSec: .gnu.hash
255    LastSec:  .dynamic
256
257## Show that if there are no hash sections, we do not print anything.
258# RUN: yaml2obj --docnum=4 %s -o %t4.so
259# RUN: llvm-readelf --hash-symbols %t4.so \
260# RUN:   | FileCheck %s --check-prefix NO-HASH --allow-empty
261
262# NO-HASH-NOT: {{.}}
263
264## Check that we can still find the dynamic symbols (i.e. the above test
265## doesn't pass due to a mistake in the dynamic section).
266# RUN: llvm-readelf --dyn-symbols %t4.so | FileCheck %s --check-prefix DYNSYMS
267
268# DYNSYMS: Symbol table '.dynsym' contains 2 entries:
269
270--- !ELF
271FileHeader:
272  Class: ELFCLASS64
273  Data:  ELFDATA2LSB
274  Type:  ET_DYN
275Sections:
276  - Name:         .dynstr
277    Type:         SHT_STRTAB
278    Flags:        [ SHF_ALLOC ]
279    AddressAlign: 0x100
280    EntSize:      0x1
281  - Name:         .dynsym
282    Type:         SHT_DYNSYM
283    Flags:        [ SHF_ALLOC ]
284    Link:         .dynstr
285    Address:      0x100
286    AddressAlign: 0x100
287    EntSize:      0x18
288  - Name:         .dynamic
289    Type:         SHT_DYNAMIC
290    Flags:        [ SHF_ALLOC ]
291    Address:      0x0000000000001000
292    Link:         .dynstr
293    AddressAlign: 0x0000000000001000
294    EntSize:      0x0000000000000010
295    Entries:
296      - Tag:   DT_STRTAB
297        Value: 0x0000000000000000
298      - Tag:   DT_STRSZ
299        Value: 0x0000000000000009
300      - Tag:   DT_SYMTAB
301        Value: 0x0000000000000100
302      - Tag:   DT_SYMENT
303        Value: 0x0000000000000018
304      - Tag:   DT_NULL
305        Value: 0x0000000000000000
306  - Name:  .text.foo
307    Type:  SHT_PROGBITS
308    Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
309    Size:  0x40
310    Address: 0x2000
311    AddressAlign: 0x2000
312DynamicSymbols:
313  - Name:    _Z3fooi
314    Binding: STB_GLOBAL
315ProgramHeaders:
316  - Type:     PT_LOAD
317    Flags:    [ PF_R, PF_X ]
318    VAddr:    0x0
319    FirstSec: .dynstr
320    LastSec:  .text.foo
321  - Type:     PT_DYNAMIC
322    Flags:    [ PF_R ]
323    VAddr:    0x1000
324    FirstSec: .dynamic
325    LastSec:  .dynamic
326
327## Show that we report a warning for a hash table which contains an entry of
328## the bucket array pointing to a cycle.
329
330# RUN: yaml2obj --docnum=5 %s -o %t5.so
331# RUN: llvm-readelf --hash-symbols %t5.so 2>&1 | \
332# RUN:   FileCheck %s -DFILE=%t5.so --check-prefix=BROKEN --implicit-check-not=warning:
333
334# BROKEN:      Symbol table of .hash for image:
335# BROKEN-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
336# BROKEN-NEXT:    1   0: 00000000     0 NOTYPE  LOCAL  DEFAULT UND aaa
337# BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain
338# BROKEN-NEXT:    1   1: 00000000     0 NOTYPE  LOCAL  DEFAULT UND aaa
339# BROKEN-NOT: {{.}}
340
341--- !ELF
342FileHeader:
343  Class: ELFCLASS32
344  Data:  ELFDATA2LSB
345  Type:  ET_DYN
346Sections:
347  - Name:    .hash
348    Type:    SHT_HASH
349    Link:    .dynsym
350    Bucket:  [ 1, 1 ]
351    Chain:   [ 1, 1 ]
352  - Name:  .dynamic
353    Type:  SHT_DYNAMIC
354    Entries:
355## llvm-readelf will read the hash table from the file offset
356## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset,
357## which is the start of PT_LOAD, i.e. the file offset of .hash.
358      - Tag:   DT_HASH
359        Value: 0x0
360DynamicSymbols:
361  - Name: aaa
362ProgramHeaders:
363  - Type:     PT_LOAD
364    FirstSec: .hash
365    LastSec:  .dynamic
366
367## Each SHT_HASH section starts with two 32-bit fields: nbucket and nchain.
368## Check we report an error when a DT_HASH value points to data that has size less than 8 bytes.
369
370# RUN: yaml2obj --docnum=6 %s -o %t6.o
371# RUN: llvm-readelf --hash-symbols %t6.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t6.o
372
373# ERR1: warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8){{$}}
374
375--- !ELF
376FileHeader:
377  Class: ELFCLASS64
378  Data:  ELFDATA2LSB
379  Type:  ET_DYN
380Sections:
381  - Name:   .hash
382    Type:   SHT_HASH
383    Flags:  [ SHF_ALLOC ]
384    Bucket: [ 0 ]
385    Chain:  [ 0 ]
386  - Name:  .dynamic
387    Type:  SHT_DYNAMIC
388    Flags: [ SHF_WRITE, SHF_ALLOC ]
389    Entries:
390      - Tag:   DT_HASH
391        Value: 0x239
392      - Tag:   DT_NULL
393        Value: 0x0
394DynamicSymbols: []
395ProgramHeaders:
396  - Type:     PT_LOAD
397    FileSize: 0x23a
398    FirstSec: .hash
399    LastSec:  .dynamic
400
401## Check we report a warning when the hash table goes past the end of the file.
402
403## Case A.1: the hash table ends right before the EOF. We have a broken nbucket
404##           field that has a value larger than the number of buckets.
405# RUN: yaml2obj --docnum=7 %s -o %t7.1.o -DNBUCKET=0x5d
406# RUN: llvm-readelf --hash-symbols %t7.1.o 2>&1 | FileCheck %s --check-prefix=NOERR1
407# NOERR1:            Symbol table of .hash for image:
408# NOERR1-NEXT:         Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
409# NOERR1-NEXT-EMPTY:
410
411## Case A.2: the hash table ends 1 byte past the EOF. We have a broken nbucket
412##           field that has a value larger than the number of buckets.
413# RUN: yaml2obj --docnum=7 %s -o %t7.2.o -DNBUCKET=0x5e
414# RUN: llvm-readelf --hash-symbols %t7.2.o 2>&1 | FileCheck %s --check-prefix=ERR2 -DFILE=%t7.2.o
415# ERR2:      Symbol table of .hash for image:
416# ERR2-NEXT: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 94, nchain = 1{{$}}
417# ERR2-NOT:  {{.}}
418
419## Case B.1: the hash table ends right before the EOF. We have a broken nchain
420##           field that has a value larger than the number of chains.
421# RUN: yaml2obj --docnum=7 %s -o %t7.3.o -DNCHAIN=0x5d
422# RUN: llvm-readelf --hash-symbols %t7.3.o 2>&1 | \
423# RUN:   FileCheck %s --implicit-check-not="warning:" --check-prefix=NOERR2 -DFILE=%t7.3.o
424# NOERR2:      warning: '[[FILE]]': hash table nchain (93) differs from symbol count derived from SHT_DYNSYM section header (1)
425# NOERR2:      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
426# NOERR2:      Symbol table of .hash for image:
427# NOERR2-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
428# NOERR2-NOT:  {{.}}
429
430## Case B.2: the hash table ends 1 byte past the EOF. We have a broken nchain
431##           field that has a value larger than the number of chains.
432# RUN: yaml2obj --docnum=7 %s -o %t7.4.o -DNCHAIN=0x5e
433# RUN: llvm-readelf --hash-symbols %t7.4.o 2>&1 | FileCheck %s --check-prefix=ERR3 -DFILE=%t7.4.o
434# ERR3:      Symbol table of .hash for image:
435# ERR3-NEXT: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 1, nchain = 94{{$}}
436# ERR3-NOT:  {{.}}
437
438--- !ELF
439FileHeader:
440  Class: ELFCLASS32
441  Data:  ELFDATA2LSB
442  Type:  ET_DYN
443Sections:
444  - Name:    .hash
445    Type:    SHT_HASH
446    Flags:   [ SHF_ALLOC ]
447    Bucket:  [ 0 ]
448    NBucket: [[NBUCKET=1]]
449    Chain:   [ 0 ]
450    NChain:  [[NCHAIN=1]]
451  - Name:  .dynamic
452    Type:  SHT_DYNAMIC
453    Flags: [ SHF_WRITE, SHF_ALLOC ]
454    Entries:
455      - Tag:   DT_HASH
456        Value: 0x0
457      - Tag:   DT_NULL
458        Value: 0x0
459DynamicSymbols: []
460ProgramHeaders:
461  - Type:     PT_LOAD
462    FirstSec: .hash
463    LastSec:  .dynamic
464
465## Check we report a proper warning when a GNU hash table goes past the end of the file.
466
467## Case A: the 'maskwords' field is set so that the table goes past the end of the file.
468# RUN: yaml2obj --docnum=8 -D MASKWORDS=4294967295 %s -o %t.err.maskwords
469# RUN: llvm-readelf --hash-symbols %t.err.maskwords 2>&1 | \
470# RUN:   FileCheck %s -DFILE=%t.err.maskwords --check-prefix=ERR4
471
472# ERR4:      Symbol table of .gnu.hash for image:
473# ERR4-NEXT:  Num Buc: Value Size Type Bind Vis Ndx Name
474# ERR4-NEXT: warning: '[[FILE]]': unable to dump the SHT_GNU_HASH section at 0x78: it goes past the end of the file
475
476## Case B: the 'nbuckets' field is set so that the table goes past the end of the file.
477# RUN: yaml2obj --docnum=8 -D NBUCKETS=4294967295 %s -o %t.err.nbuckets
478# RUN: llvm-readelf --hash-symbols %t.err.nbuckets 2>&1 | \
479# RUN:   FileCheck %s -DFILE=%t.err.nbuckets --check-prefix=ERR4
480
481--- !ELF
482FileHeader:
483  Class: ELFCLASS64
484  Data:  ELFDATA2LSB
485  Type:  ET_DYN
486Sections:
487  - Name:  .gnu.hash
488    Type:  SHT_GNU_HASH
489    Flags: [ SHF_ALLOC ]
490    Header:
491      SymNdx: 0x1
492      Shift2: 0x2
493## The number of words in the Bloom filter. The value of 2 is no-op.
494      MaskWords: [[MASKWORDS=2]]
495## The number of hash buckets. The value of 3 is no-op.
496      NBuckets:  [[NBUCKETS=3]]
497    BloomFilter: [0x3, 0x4]
498    HashBuckets: [0x5, 0x6, 0x7]
499    HashValues:  [0x8, 0x9, 0xA, 0xB]
500  - Name:  .dynamic
501    Type:  SHT_DYNAMIC
502    Flags: [ SHF_ALLOC ]
503    Link:  .dynstr
504    Entries:
505      - Tag:   DT_GNU_HASH
506        Value: 0x0
507      - Tag:   DT_NULL
508        Value: 0x0
509DynamicSymbols:
510  - Name:    aaa
511    Binding: STB_GLOBAL
512  - Name:    bbb
513    Binding: STB_GLOBAL
514  - Name:    ccc
515    Binding: STB_GLOBAL
516  - Name:    ddd
517    Binding: STB_GLOBAL
518ProgramHeaders:
519  - Type:     PT_LOAD
520    Flags:    [ PF_R, PF_X ]
521    FirstSec: .gnu.hash
522    LastSec:  .dynamic
523
524## Check the behavior when the dynamic symbol table is empty or not found.
525
526## Case A.1: Check we report a warning when the dynamic symbol table is empty and we attempt to print hash symbols
527##         from the .hash table. The number of symbols in the dynamic symbol table can be calculated from its size
528##         or derived from the Chain vector of the .hash table. Make both ways to return a zero to do the check.
529# RUN: yaml2obj --docnum=9 %s -o %t9.1.so
530# RUN: llvm-readelf --hash-symbols %t9.1.so 2>&1 | FileCheck %s -DFILE=%t9.1.so --check-prefix=DYNSYM-EMPTY-HASH
531
532# DYNSYM-EMPTY-HASH:      Symbol table of .hash for image:
533# DYNSYM-EMPTY-HASH-NEXT:   Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
534# DYNSYM-EMPTY-HASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .hash table: the dynamic symbol table is empty
535# DYNSYM-EMPTY-HASH-NOT:  {{.}}
536
537--- !ELF
538FileHeader:
539  Class: ELFCLASS32
540  Data:  ELFDATA2LSB
541  Type:  ET_DYN
542Sections:
543  - Name:   .hash
544    Type:   SHT_HASH
545    Flags:  [ SHF_ALLOC ]
546    Bucket: [ 0 ]
547    Chain:  [ ]
548  - Name:  .dynamic
549    Type:  SHT_DYNAMIC
550    Flags: [ SHF_ALLOC ]
551    Entries:
552      - Tag:   DT_HASH
553        Value: 0x0
554      - Tag:   DT_STRTAB
555## PT_LOAD p_offset == .hash offset == 0x54.
556## 0x54 + 0x2c == 0x80 == .dynstr offset.
557        Value: 0x2c
558      - Tag:   DT_STRSZ
559        Value: 0x1
560      - Tag:   DT_NULL
561        Value: 0x0
562  - Name:  .dynstr
563    Type:  SHT_STRTAB
564    Flags: [ SHF_ALLOC ]
565  - Name:  .dynsym
566    Type:  [[DYNSYMTYPE=SHT_DYNSYM]]
567    Flags: [ SHF_ALLOC ]
568    Size:  0
569ProgramHeaders:
570  - Type:     PT_LOAD
571    Flags:    [ PF_R, PF_X ]
572    FirstSec: .hash
573    LastSec:  .dynstr
574
575## Case A.2: similar to A.1, but now check that we report a warning when the dynamic symbol table was not found.
576##           To do that, set the type of the .dynsym to SHT_PROGBITS to hide it.
577# RUN: yaml2obj --docnum=9 -DDYNSYMTYPE=SHT_PROGBITS %s -o %t9.2.so
578# RUN: llvm-readelf --hash-symbols %t9.2.so 2>&1 | FileCheck %s -DFILE=%t9.2.so --check-prefix=DYNSYM-NOTFOUND-HASH
579
580# DYNSYM-NOTFOUND-HASH:      Symbol table of .hash for image:
581# DYNSYM-NOTFOUND-HASH-NEXT:   Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
582# DYNSYM-NOTFOUND-HASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .hash table: the dynamic symbol table was not found
583# DYNSYM-NOTFOUND-HASH-NOT:  {{.}}
584
585## Case B.1: Check we report a warning when the dynamic symbol table is empty and we attempt to print
586##           hash symbols from the .gnu.hash table.
587# RUN: yaml2obj --docnum=10 %s -o %t10.1.so
588# RUN: llvm-readelf --hash-symbols %t10.1.so 2>&1 | FileCheck %s -DFILE=%t10.1.so --check-prefix=DYNSYM-EMPTY-GNUHASH
589
590# DYNSYM-EMPTY-GNUHASH:      Symbol table of .gnu.hash for image:
591# DYNSYM-EMPTY-GNUHASH-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
592# DYNSYM-EMPTY-GNUHASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .gnu.hash table: the dynamic symbol table is empty
593# DYNSYM-EMPTY-GNUHASH-NOT:  {{.}}
594
595## Case B.2: similar to B.1, but now check that we report a warning when the dynamic symbol table was not found.
596##           To do that, set the type of the .dynsym to SHT_PROGBITS to hide it.
597# RUN: yaml2obj --docnum=10 -DDYNSYMTYPE=SHT_PROGBITS %s -o %t10.2.so
598# RUN: llvm-readelf --hash-symbols %t10.2.so 2>&1 | FileCheck %s -DFILE=%t10.2.so --check-prefix=DYNSYM-NOTFOUND-GNUHASH
599
600# DYNSYM-NOTFOUND-GNUHASH:      Symbol table of .gnu.hash for image:
601# DYNSYM-NOTFOUND-GNUHASH-NEXT:  Num Buc:    Value  Size   Type   Bind Vis      Ndx Name
602# DYNSYM-NOTFOUND-GNUHASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .gnu.hash table: the dynamic symbol table was not found
603# DYNSYM-NOTFOUND-GNUHASH-NOT:  {{.}}
604
605--- !ELF
606FileHeader:
607  Class: ELFCLASS32
608  Data:  ELFDATA2LSB
609  Type:  ET_DYN
610Sections:
611  - Name:  .gnu.hash
612    Type:  SHT_GNU_HASH
613    Flags: [ SHF_ALLOC ]
614    Header:
615      SymNdx: 0x0
616      Shift2: 0x0
617    BloomFilter: [ 0x0 ]
618    HashBuckets: [ 0x1 ]
619    HashValues:  [ 0x0 ]
620  - Name:  .dynamic
621    Type:  SHT_DYNAMIC
622    Flags: [ SHF_ALLOC ]
623    Entries:
624      - Tag:   DT_GNU_HASH
625        Value: 0x0
626      - Tag:   DT_STRTAB
627## PT_LOAD p_offset == .hash offset == 0x54.
628## 0x54 + 0x3c == 0x80 == .dynstr offset.
629        Value: 0x3c
630      - Tag:   DT_STRSZ
631        Value: 0x1
632      - Tag:   DT_NULL
633        Value: 0x0
634  - Name: .dynstr
635    Type: SHT_STRTAB
636  - Name:  .dynsym
637    Type:  [[DYNSYMTYPE=SHT_DYNSYM]]
638    Flags: [ SHF_ALLOC ]
639    Size:  0
640ProgramHeaders:
641  - Type:     PT_LOAD
642    Flags:    [ PF_R, PF_X ]
643    FirstSec: .gnu.hash
644    LastSec:  .dynstr
645
646## In this case we have a broken value in the hash buckets array. Normally it contains an
647## index into the dynamic symbol table and also is used to get a hash value from the hash values array.
648## llvm-readelf attempts to read a symbol that is past the end of the dynamic symbol table.
649
650# RUN: yaml2obj --docnum=11 -DVALUE=0x2 %s -o %t11.past.dynsym.so
651# RUN: llvm-readelf --hash-symbols %t11.past.dynsym.so 2>&1 | \
652# RUN:   FileCheck %s -DFILE=%t11.past.dynsym.so --check-prefix=BUCKET-PAST-DYNSYM
653
654# BUCKET-PAST-DYNSYM:      Symbol table of .gnu.hash for image:
655# BUCKET-PAST-DYNSYM-NEXT:   Num Buc:    Value          Size   Type   Bind Vis      Ndx Name
656# BUCKET-PAST-DYNSYM-NEXT: warning: '[[FILE]]': unable to print hashed symbol with index 2, which is greater than or equal to the number of dynamic symbols (2)
657# BUCKET-PAST-DYNSYM-NEXT:     1   2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT UND foo
658# BUCKET-PAST-DYNSYM-NOT:  {{.}}
659
660--- !ELF
661FileHeader:
662  Class: ELFCLASS64
663  Data:  ELFDATA2LSB
664  Type:  ET_DYN
665Sections:
666  - Name:  .gnu.hash
667    Type:  SHT_GNU_HASH
668    Flags: [ SHF_ALLOC ]
669    Link:  .dynsym
670    Header:
671      SymNdx: [[SYMNDX=0x0]]
672      Shift2: 0x0
673    BloomFilter: [ 0x0 ]
674    HashBuckets: [ 0x0, [[VALUE]], 0x1 ]
675    HashValues:  [ 0x0 ]
676  - Name:  .dynamic
677    Type:  SHT_DYNAMIC
678    Flags: [ SHF_ALLOC ]
679    Link:  .dynstr
680    Entries:
681      - Tag:   DT_GNU_HASH
682        Value: 0x0
683      - Tag:   DT_NULL
684        Value: 0x0
685DynamicSymbols:
686  - Name:    foo
687    Binding: STB_GLOBAL
688ProgramHeaders:
689  - Type:     PT_LOAD
690    Flags:    [ PF_R, PF_X ]
691    FirstSec: .gnu.hash
692    LastSec:  .dynamic
693
694## In this case we are unable to read a hash value for a symbol with
695## an index that is less than the index of the first hashed symbol.
696
697# RUN: yaml2obj --docnum=11 -DSYMNDX=0x2 -DVALUE=0x1 %s -o %t11.first.hashed.so
698# RUN: llvm-readelf --hash-symbols %t11.first.hashed.so 2>&1 | \
699# RUN:   FileCheck %s -DFILE=%t11.first.hashed.so --check-prefix=FIRST-HASHED
700
701# FIRST-HASHED:      Symbol table of .gnu.hash for image:
702# FIRST-HASHED-NEXT:   Num Buc:    Value          Size   Type   Bind Vis      Ndx Name
703# FIRST-HASHED-NEXT: warning: '[[FILE]]': unable to get hash values for the SHT_GNU_HASH section: the first hashed symbol index (2) is greater than or equal to the number of dynamic symbols (2)
704# FIRST-HASHED-NEXT:     1   1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT UND foo
705# FIRST-HASHED-NEXT: warning: '[[FILE]]': unable to read the hash value for symbol with index 1, which is less than the index of the first hashed symbol (2)
706# FIRST-HASHED-NEXT:     1   2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT UND foo
707# FIRST-HASHED-NOT:  {{.}}
708
709## In this case one of the chain values doesn't end with a stopper bit and llvm-readelf attempts to read
710## a dynamic symbol with an index that is equal to the number of dynamic symbols.
711
712# RUN: yaml2obj --docnum=11 -DSYMNDX=0x1 -DVALUE=0x1 %s -o %t11.chain.bit.so
713# RUN: llvm-readelf --hash-symbols %t11.chain.bit.so 2>&1 | \
714# RUN:   FileCheck %s -DFILE=%t11.chain.bit.so --check-prefix=CHAIN-BIT
715
716# CHAIN-BIT:      Symbol table of .gnu.hash for image:
717# CHAIN-BIT-NEXT:   Num Buc:    Value          Size   Type   Bind Vis      Ndx Name
718# CHAIN-BIT-NEXT:     1   1: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT UND foo
719# CHAIN-BIT-NEXT: warning: '[[FILE]]': unable to print hashed symbol with index 2, which is greater than or equal to the number of dynamic symbols (2)
720# CHAIN-BIT-NEXT:     1   2: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT UND foo
721# CHAIN-BIT-NOT:  {{.}}
722