xref: /llvm-project/llvm/test/tools/llvm-readobj/ELF/hash-table.test (revision 9c89dcf80736a7c0710dc4c237ec35f0687e1efd)
1## Check how the SHT_HASH section is dumped with --hash-table.
2
3# RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_X86_64 %s -o %t.x64
4# RUN: yaml2obj --docnum=1 -DBITS=32 -DMACHINE=EM_386 %s -o %t.x32
5
6# RUN: llvm-readobj --hash-table %t.x64 | FileCheck %s --check-prefix=HASH
7# RUN: llvm-readelf --hash-table %t.x64 | FileCheck %s --check-prefix=HASH
8
9# RUN: llvm-readobj --hash-table %t.x32 | FileCheck %s --check-prefix=HASH
10# RUN: llvm-readelf --hash-table %t.x32 | FileCheck %s --check-prefix=HASH
11
12# HASH:      HashTable {
13# HASH-NEXT:   Num Buckets: 2
14# HASH-NEXT:   Num Chains: 3
15# HASH-NEXT:   Buckets: [1, 2]
16# HASH-NEXT:   Chains: [3, 4, 5]
17# HASH-NEXT: }
18
19--- !ELF
20FileHeader:
21  Class:   ELFCLASS[[BITS=64]]
22  Data:    ELFDATA2LSB
23  Type:    ET_DYN
24  Machine: [[MACHINE]]
25Sections:
26  - Name:    .hash
27    Type:    SHT_HASH
28    Flags:   [ SHF_ALLOC ]
29    Bucket:  [ 1, 2 ]
30    Chain:   [ 3, 4, 5 ]
31    EntSize: [[ENTSIZE=4]]
32  - Name:  .dynamic
33    Type:  SHT_DYNAMIC
34    Flags: [ SHF_ALLOC ]
35    Entries:
36      - Tag:   DT_HASH
37        Value: 0x0
38      - Tag:   DT_NULL
39        Value: 0x0
40ProgramHeaders:
41  - Type:     PT_LOAD
42    FirstSec: .hash
43    LastSec:  .dynamic
44
45## Document that we ignore the sh_entsize value when dumping the hash section.
46## Implementation assumes that the size of entries is 4, matching the ELF specification.
47
48# RUN: yaml2obj --docnum=1 -DENTSIZE=8 -DBITS=64 -DMACHINE=EM_X86_64 %s -o %t.x64.ent8
49# RUN: yaml2obj --docnum=1 -DENTSIZE=8 -DBITS=32 -DMACHINE=EM_386 %s -o %t.x32.ent8
50
51# RUN: llvm-readobj --hash-table %t.x64.ent8 | FileCheck %s --check-prefix=HASH
52# RUN: llvm-readelf --hash-table %t.x64.ent8 | FileCheck %s --check-prefix=HASH
53# RUN: llvm-readobj --hash-table %t.x32.ent8 | FileCheck %s --check-prefix=HASH
54# RUN: llvm-readelf --hash-table %t.x32.ent8 | FileCheck %s --check-prefix=HASH
55
56## We don't support dumping hash tables on EM_S390 and EM_ALPHA platforms and report a warning.
57## On these platforms the size of entries is 8, which violates the ELF specification, which says that the size
58## of hash entries in the hash table must be 4.
59
60# RUN: yaml2obj --docnum=1 -DMACHINE=EM_S390 %s -o %t.s390
61# RUN: llvm-readobj --hash-table %t.s390 2>&1 | FileCheck %s -DFILE=%t.s390 --check-prefixes=WARN-HASH -DNAME="IBM S/390"
62# RUN: llvm-readelf --hash-table %t.s390 2>&1 | FileCheck %s -DFILE=%t.s390 --check-prefixes=WARN-HASH -DNAME="IBM S/390"
63
64# WARN-HASH:      HashTable {
65# WARN-HASH-NEXT: warning: '[[FILE]]': the hash table at 0x78 is not supported: it contains non-standard 8 byte entries on [[NAME]] platform
66# WARN-HASH-NEXT: }
67
68# RUN: yaml2obj --docnum=1 -DMACHINE=EM_ALPHA %s -o %t.alpha
69# RUN: llvm-readobj --hash-table %t.alpha 2>&1 | FileCheck %s -DFILE=%t.alpha --check-prefixes=WARN-HASH -DNAME="EM_ALPHA"
70# RUN: llvm-readelf --hash-table %t.alpha 2>&1 | FileCheck %s -DFILE=%t.alpha --check-prefixes=WARN-HASH -DNAME="EM_ALPHA"
71
72## We don't report warnings about the unsupported hash table on EM_S390 and EM_ALPHA platforms
73## when --hash-table is not requested.
74
75# RUN: llvm-readobj %t.s390 2>&1 | FileCheck %s -DFILE=%t.s390 --allow-empty --implicit-check-not="warning:"
76# RUN: llvm-readelf %t.s390 2>&1 | FileCheck %s -DFILE=%t.s390 --allow-empty --implicit-check-not="warning:"
77# RUN: llvm-readobj %t.alpha 2>&1 | FileCheck %s -DFILE=%t.alpha --allow-empty --implicit-check-not="warning:"
78# RUN: llvm-readelf %t.alpha 2>&1 | FileCheck %s -DFILE=%t.alpha --allow-empty --implicit-check-not="warning:"
79
80## Check we can dump the SHT_HASH section even when an object
81## does not have the section header table.
82
83# RUN: yaml2obj --docnum=2 -DNOHEADERS=true %s -o %t.noshdr
84# RUN: llvm-readobj --hash-table %t.noshdr 2>&1 | \
85# RUN:   FileCheck %s -DFILE=%t.noshdr --check-prefix=NOSHDR --implicit-check-not=warning:
86# RUN: llvm-readelf --hash-table %t.noshdr 2>&1 | \
87# RUN:   FileCheck %s -DFILE=%t.noshdr --check-prefix=NOSHDR --implicit-check-not=warning:
88
89# NOSHDR:      HashTable {
90# NOSHDR-NEXT:   Num Buckets: 1
91# NOSHDR-NEXT:   Num Chains: 1
92# NOSHDR-NEXT:   Buckets: [0]
93# NOSHDR-NEXT:   Chains: [1]
94# NOSHDR-NEXT: }
95
96--- !ELF
97FileHeader:
98  Class: ELFCLASS64
99  Data:  ELFDATA2LSB
100  Type:  ET_DYN
101Sections:
102  - Name:   .hash
103    Type:   SHT_HASH
104    Flags:  [ SHF_ALLOC ]
105    Bucket: [ 0 ]
106    Chain:  [ 1 ]
107    EntSize: [[ENTSIZE=4]]
108  - Name:  .dynamic
109    Type:  SHT_DYNAMIC
110    Flags: [ SHF_ALLOC ]
111    Entries:
112      - Tag:   [[DYNTAG=DT_HASH]]
113        Value: 0x0
114      - Tag:   DT_NULL
115        Value: 0x0
116  - Type: SectionHeaderTable
117    NoHeaders: [[NOHEADERS=false]]
118ProgramHeaders:
119  - Type:     PT_LOAD
120    FirstSec: .hash
121    LastSec:  .dynamic
122  - Type:     PT_DYNAMIC
123    VAddr:    0x10
124    FirstSec: .dynamic
125    LastSec:  .dynamic
126
127## Document we don't report a warning when the value of the sh_entsize field of the SHT_HASH section is not 4.
128
129# RUN: yaml2obj --docnum=2 -DENTSIZE=0xff %s -o %t.ent.size
130# RUN: llvm-readobj --hash-table %t.ent.size 2>&1 | \
131# RUN:   FileCheck %s -DFILE=%t.ent.size --check-prefix=NOSHDR --implicit-check-not=warning:
132# RUN: llvm-readelf --hash-table %t.ent.size 2>&1 | \
133# RUN:   FileCheck %s -DFILE=%t.ent.size --check-prefix=NOSHDR --implicit-check-not=warning:
134
135## Document we need the DT_HASH dynamic tag to locate the hash table.
136
137# RUN: yaml2obj --docnum=2 -DDYNTAG=DT_NULL %s -o %t.no.dyntag
138# RUN: llvm-readobj --hash-table %t.no.dyntag 2>&1 | \
139# RUN:   FileCheck %s -DFILE=%t.no.dyntag --check-prefix=NODYNTAG --implicit-check-not=warning:
140# RUN: llvm-readelf --hash-table %t.no.dyntag 2>&1 | \
141# RUN:   FileCheck %s -DFILE=%t.no.dyntag --check-prefix=NODYNTAG --implicit-check-not=warning:
142
143# NODYNTAG:      HashTable {
144# NODYNTAG-NEXT: }
145
146## Each SHT_HASH section starts with two 32-bit fields: nbucket and nchain.
147## Check we report an error when a DT_HASH value points to data that has size less than 8 bytes.
148
149# RUN: yaml2obj --docnum=3 %s -o %t4.o
150# RUN: llvm-readelf --hash-table %t4.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t4.o
151# RUN: llvm-readobj --hash-table %t4.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t4.o
152
153# ERR1:      HashTable {
154# ERR1-NEXT:  warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8){{$}}
155# ERR1-NEXT: }
156
157--- !ELF
158FileHeader:
159  Class: ELFCLASS64
160  Data:  ELFDATA2LSB
161  Type:  ET_DYN
162Sections:
163  - Name:   .hash
164    Type:   SHT_HASH
165    Flags:  [ SHF_ALLOC ]
166    Bucket: [ 0 ]
167    Chain:  [ 0 ]
168  - Name:  .dynamic
169    Type:  SHT_DYNAMIC
170    Flags: [ SHF_WRITE, SHF_ALLOC ]
171    Entries:
172      - Tag:   DT_HASH
173        Value: 0x239
174      - Tag:   DT_NULL
175        Value: 0x0
176DynamicSymbols: []
177ProgramHeaders:
178  - Type:     PT_LOAD
179    FileSize: 0x23a
180    FirstSec: .hash
181    LastSec:  .dynamic
182
183## Check we report a warning when the hash table goes past the end of the file.
184
185## Case A.1: the hash table ends right before the EOF. We have a broken nbucket
186##           field that has a value larger than the number of buckets.
187# RUN: yaml2obj --docnum=4 %s -o %t5.1.o -DNBUCKET=0x5d -DNCHAIN=0x1
188# RUN: llvm-readelf --hash-table %t5.1.o 2>&1 | \
189# RUN:   FileCheck %s --check-prefix=NOERR1 --implicit-check-not="warning:"
190# RUN: llvm-readobj --hash-table %t5.1.o 2>&1 | \
191# RUN:   FileCheck %s --check-prefix=NOERR1 --implicit-check-not="warning:"
192
193# NOERR1:      HashTable {
194# NOERR1-NEXT:  Num Buckets: 93
195# NOERR1-NEXT:  Num Chains: 1
196## Here we would dump the rest of the file as buckets array because we have a broken nbucket field.
197## No need to check what we dump, we only want to test that we have no unexpected warnings/crashes.
198# NOERR1-NEXT:  Buckets:
199# NOERR1-NEXT:  Chains: [0]
200# NOERR1-NEXT: }
201
202## Case A.2: the hash table ends 1 byte past the EOF. We have a broken nbucket
203##           field that has a value larger than the number of buckets.
204# RUN: yaml2obj --docnum=4 %s -o %t5.2.o -DNBUCKET=0x5e -DNCHAIN=0x1
205# RUN: llvm-readelf --hash-table %t5.2.o 2>&1 | \
206# RUN:   FileCheck %s --check-prefix=ERR2 -DFILE=%t5.2.o --implicit-check-not="warning:"
207# RUN: llvm-readobj --hash-table %t5.2.o 2>&1 | \
208# RUN:   FileCheck %s --check-prefix=ERR2 -DFILE=%t5.2.o --implicit-check-not="warning:"
209
210# ERR2:      HashTable {
211# ERR2:       Num Buckets: 94
212# ERR2:       Num Chains: 1
213# ERR2-NEXT:  warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 94, nchain = 1{{$}}
214# ERR2-NEXT: }
215
216## Case B.1: the hash table ends right before the EOF. We have a broken nchain
217##           field that has a value larger than the number of chains.
218# RUN: yaml2obj --docnum=4 %s -o %t5.3.o -DNBUCKET=0x1 -DNCHAIN=0x5d
219# RUN: llvm-readelf --hash-table %t5.3.o 2>&1 | \
220# RUN:   FileCheck %s --check-prefix=NOERR2 -DFILE=%t5.3.o --implicit-check-not="warning:"
221# RUN: llvm-readobj --hash-table %t5.3.o 2>&1 | \
222# RUN:   FileCheck %s --check-prefix=NOERR2 -DFILE=%t5.3.o --implicit-check-not="warning:"
223
224# NOERR2:      warning: '[[FILE]]': hash table nchain (93) differs from symbol count derived from SHT_DYNSYM section header (1)
225# 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
226# NOERR2:      HashTable {
227# NOERR2-NEXT:   Num Buckets: 1
228# NOERR2-NEXT:   Num Chains: 93
229# NOERR2-NEXT:   Buckets: [0]
230## Here we would dump the rest of the file as chain array because we have a broken nchain field.
231## No need to check what we dump, we only want to test that we have no unexpected warnings/crashes.
232# NOERR2-NEXT:   Chains:
233# NOERR2-NEXT: }
234
235## Case B.2: the hash table ends 1 byte past the EOF. We have a broken nchain
236##           field that has a value larger than the number of chains.
237# RUN: yaml2obj --docnum=4 %s -o %t5.4.o -DNBUCKET=0x1 -DNCHAIN=0x5e
238# RUN: llvm-readelf --hash-table %t5.4.o 2>&1 | \
239# RUN:   FileCheck %s --check-prefix=ERR3 -DFILE=%t5.4.o --implicit-check-not="warning:"
240# RUN: llvm-readobj --hash-table %t5.4.o 2>&1 | \
241# RUN:   FileCheck %s --check-prefix=ERR3 -DFILE=%t5.4.o --implicit-check-not="warning:"
242
243# ERR3:      warning: '[[FILE]]': hash table nchain (94) differs from symbol count derived from SHT_DYNSYM section header (1)
244# ERR3:      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
245# ERR3:      HashTable {
246# ERR3-NEXT:  Num Buckets: 1
247# ERR3-NEXT:  Num Chains: 94
248# ERR3-NEXT:  warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 1, nchain = 94{{$}}
249# ERR3-NEXT: }
250
251--- !ELF
252FileHeader:
253  Class: ELFCLASS32
254  Data:  ELFDATA2LSB
255  Type:  ET_DYN
256Sections:
257  - Name:    .hash
258    Type:    SHT_HASH
259    Flags:   [ SHF_ALLOC ]
260    Bucket:  [ 0 ]
261    NBucket: [[NBUCKET]]
262    Chain:   [ 0 ]
263    NChain:  [[NCHAIN]]
264  - Name:  .dynamic
265    Type:  SHT_DYNAMIC
266    Flags: [ SHF_WRITE, SHF_ALLOC ]
267    Entries:
268      - Tag:   DT_HASH
269        Value: 0x0
270      - Tag:   DT_NULL
271        Value: 0x0
272DynamicSymbols: []
273ProgramHeaders:
274  - Type:     PT_LOAD
275    FirstSec: .hash
276    LastSec: .dynamic
277
278## Show we do not duplicate warnings when printing both the hash table and the hash histogram.
279## Note that --elf-hash-histogram is only implemented for llvm-readelf currently.
280# RUN: yaml2obj --docnum=3 %s -o %t4.o
281# RUN: llvm-readelf --hash-table --elf-hash-histogram %t4.o 2>&1 \
282# RUN:   | FileCheck %s --check-prefix=SINGLE-WARN -DFILE=%t4.o --implicit-check-not="warning:"
283
284# SINGLE-WARN:      warning: '[[FILE]]': hash table nchain (0) differs from symbol count derived from SHT_DYNSYM section header (1)
285# SINGLE-WARN-NEXT: HashTable {
286# SINGLE-WARN-NEXT: warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8)
287# SINGLE-WARN-NEXT: }
288