xref: /llvm-project/llvm/test/tools/llvm-readobj/ELF/symtab-shndx.test (revision eb81493e95c9f0e7feecd699758caa56b7d3514e)
1## In this file we have tests for the SHT_SYMTAB_SHNDX section
2## and the DT_SYMTAB_SHNDX dynamic tag.
3
4## Check that different SHT_SYMTAB_SHNDX sections can be used with different symbol tables.
5## In this test we check that we print different section indexes for regular and dynamic
6## symbol tables that are linked to different SHT_SYMTAB_SHNDX sections.
7
8# RUN: yaml2obj --docnum=1 %s -o %t1
9# RUN: llvm-readelf --symbols --dyn-syms %t1 2>&1 | FileCheck %s --check-prefix=GNU
10# RUN: llvm-readelf --symbols --dyn-syms --extra-sym-info %t1 2>&1 | FileCheck %s --check-prefix=GNUX
11# RUN: llvm-readobj --symbols --dyn-syms %t1 2>&1 | FileCheck %s --check-prefix=LLVM
12
13# GNU:      Symbol table '.dynsym' contains 3 entries:
14# GNU-NEXT:    Num:    Value  Size Type    Bind   Vis       Ndx Name
15# GNU-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND
16# GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT     3 dynsym1
17# GNU-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT     2 dynsym2
18# GNU:      Symbol table '.symtab' contains 3 entries:
19# GNU-NEXT:    Num:    Value  Size Type    Bind   Vis       Ndx Name
20# GNU-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND
21# GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT     2 sym1
22# GNU-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT     1 sym2
23
24# GNUX:      Symbol table '.dynsym' contains 3 entries:
25# GNUX-NEXT:    Num:    Value  Size Type    Bind   Vis+Other Ndx(SecName) Name [+ Version Info]
26# GNUX-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND
27# GNUX-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT     3 (.section3) dynsym1
28# GNUX-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT     2 (.section2) dynsym2
29# GNUX:      Symbol table '.symtab' contains 3 entries:
30# GNUX-NEXT:    Num:    Value  Size Type    Bind   Vis+Other Ndx(SecName) Name [+ Version Info]
31# GNUX-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND
32# GNUX-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT     2 (.section2) sym1
33# GNUX-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT     1 (.section1) sym2
34
35# LLVM:      Symbols [
36# LLVM-NEXT:   Symbol {
37# LLVM-NEXT:     Name:  (0)
38# LLVM:          Section: Undefined (0x0)
39# LLVM-NEXT:   }
40# LLVM-NEXT:   Symbol {
41# LLVM-NEXT:     Name: sym1 (6)
42# LLVM:          Section: .section2 (0x2)
43# LLVM-NEXT:   }
44# LLVM-NEXT:   Symbol {
45# LLVM-NEXT:     Name: sym2 (1)
46# LLVM:          Section: .section1 (0x1)
47# LLVM-NEXT:   }
48# LLVM-NEXT: ]
49# LLVM:      DynamicSymbols [
50# LLVM-NEXT:   Symbol {
51# LLVM-NEXT:     Name:  (0)
52# LLVM:          Section: Undefined (0x0)
53# LLVM-NEXT:   }
54# LLVM-NEXT:   Symbol {
55# LLVM-NEXT:     Name: dynsym1 (9)
56# LLVM:          Section: .section3 (0x3)
57# LLVM-NEXT:   }
58# LLVM-NEXT:   Symbol {
59# LLVM-NEXT:     Name: dynsym2 (1)
60# LLVM:          Section: .section2 (0x2)
61# LLVM-NEXT:   }
62# LLVM-NEXT: ]
63
64--- !ELF
65FileHeader:
66  Class: ELFCLASS32
67  Data:  ELFDATA2LSB
68  Type:  ET_REL
69Sections:
70  - Name: .section1
71    Type: SHT_PROGBITS
72  - Name: .section2
73    Type: SHT_PROGBITS
74  - Name: .section3
75    Type: SHT_PROGBITS
76  - Name:    .dynamic
77    Type:    SHT_DYNAMIC
78    Flags:   [ SHF_ALLOC ]
79    Address: 0x1000
80    Offset:  0x1000
81    Entries:
82      - Tag:   [[TAGNAME=DT_SYMTAB_SHNDX]]
83        Value: [[SYMTABSHNDX=0x2100]] ## Address of .bar section.
84      - Tag:   DT_NULL
85        Value: 0
86## By naming the SHT_SYMTAB_SHNDX sections to .foo and .bar we verify that we
87## don't use their names to locate them.
88  - Name:    .foo
89    Type:    SHT_SYMTAB_SHNDX
90    Flags:   [ SHF_ALLOC ]
91    Link:    [[SHNDXLINK=.symtab]]
92    Entries: [ 0, 2, 1 ]
93    Offset:  0x2000
94    Address: 0x2000
95  - Name:    .bar
96    Type:    SHT_SYMTAB_SHNDX
97    Flags:   [ SHF_ALLOC ]
98    Link:    .dynsym
99    Entries: [ 0, 3, 2 ]
100    Offset:  0x2100
101    Address: 0x2100
102Symbols:
103  - Name:  sym1
104    Index: SHN_XINDEX
105  - Name:  sym2
106    Index: SHN_XINDEX
107DynamicSymbols:
108  - Name:  dynsym1
109    Index: SHN_XINDEX
110  - Name:  dynsym2
111    Index: SHN_XINDEX
112ProgramHeaders:
113  - Type:     PT_LOAD
114    VAddr:    0x1000
115    FirstSec: .dynamic
116    LastSec:  .bar
117  - Type:     PT_DYNAMIC
118    VAddr:    0x1000
119    FirstSec: .dynamic
120    LastSec:  .dynamic
121
122## Check that we locate the SHT_SYMTAB_SHNDX section using the DT_SYMTAB_SHNDX
123## dynamic tag when dumping dynamic symbols. In this case we make the value of
124## DT_SYMTAB_SHNDX point to the SHT_SYMTAB_SHNDX section that is
125## linked with the static symbol table and check that we use it.
126
127# RUN: yaml2obj --docnum=1 -DSYMTABSHNDX=0x2000 %s -o %t2
128# RUN: llvm-readelf --dyn-syms %t2 2>&1 | FileCheck %s --check-prefix=DYNTAG-GNU
129# RUN: llvm-readobj --dyn-syms %t2 2>&1 | FileCheck %s --check-prefix=DYNTAG-LLVM
130
131# DYNTAG-GNU:      Symbol table '.dynsym' contains 3 entries:
132# DYNTAG-GNU-NEXT:    Num:    Value  Size Type    Bind   Vis     Ndx Name
133# DYNTAG-GNU-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT UND
134# DYNTAG-GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT   2 dynsym1
135# DYNTAG-GNU-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT   1 dynsym2
136
137# DYNTAG-LLVM:          Name: dynsym1 (9)
138# DYNTAG-LLVM:          Section: .section2 (0x2)
139# DYNTAG-LLVM-NEXT:   }
140# DYNTAG-LLVM-NEXT:   Symbol {
141# DYNTAG-LLVM-NEXT:     Name: dynsym2 (1)
142# DYNTAG-LLVM:          Section: .section1 (0x1)
143# DYNTAG-LLVM-NEXT:   }
144# DYNTAG-LLVM-NEXT: ]
145
146## Check that we report a warning when we dump a dynamic symbol table that
147## contains symbols with extended indices, but we don't have a DT_SYMTAB_SHNDX tag to locate
148## the corresponding extended indexes table.
149
150# RUN: yaml2obj --docnum=1 -DTAGNAME=0x0 -DSYMTABSHNDX=0x0 %s -o %t3
151# RUN: llvm-readelf --symbols --dyn-syms %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=NOTAG-GNU
152# RUN: llvm-readobj --symbols --dyn-syms %t3 2>&1 | FileCheck %s -DFILE=%t3 --check-prefix=NOTAG-LLVM
153
154# NOTAG-GNU:      Symbol table '.dynsym' contains 3 entries:
155# NOTAG-GNU-NEXT:    Num:    Value  Size Type    Bind   Vis       Ndx Name
156# NOTAG-GNU-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND
157# NOTAG-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table
158# NOTAG-GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT   RSV[0xffff] dynsym1
159# NOTAG-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table
160# NOTAG-GNU-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT   RSV[0xffff] dynsym2
161
162# NOTAG-LLVM:      Symbol {
163# NOTAG-LLVM:          Name: dynsym1 (9)
164# NOTAG-LLVM-NEXT:     Value: 0x0
165# NOTAG-LLVM-NEXT:     Size: 0
166# NOTAG-LLVM-NEXT:     Binding: Local (0x0)
167# NOTAG-LLVM-NEXT:     Type: None (0x0)
168# NOTAG-LLVM-NEXT:     Other: 0
169# NOTAG-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table
170# NOTAG-LLVM-NEXT:     Section: Reserved (0xFFFF)
171# NOTAG-LLVM-NEXT:   }
172# NOTAG-LLVM-NEXT:   Symbol {
173# NOTAG-LLVM-NEXT:     Name: dynsym2 (1)
174# NOTAG-LLVM-NEXT:     Value: 0x0
175# NOTAG-LLVM-NEXT:     Size: 0
176# NOTAG-LLVM-NEXT:     Binding: Local (0x0)
177# NOTAG-LLVM-NEXT:     Type: None (0x0)
178# NOTAG-LLVM-NEXT:     Other: 0
179# NOTAG-LLVM-NEXT: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table
180# NOTAG-LLVM-NEXT:     Section: Reserved (0xFFFF)
181# NOTAG-LLVM-NEXT:   }
182
183## In this case we have a SHT_SYMTAB_SHNDX section with a sh_link field that has a
184## value that is larger than the number of sections. Check we report a warning.
185
186# RUN: yaml2obj --docnum=1 -DSHNDXLINK=0xFF %s -o %t4
187# RUN: llvm-readelf --symbols --dyn-syms %t4 2>&1 | \
188# RUN:   FileCheck %s -DFILE=%t4 --check-prefixes=BROKENLINK,BROKENLINK-GNU --implicit-check-not=warning:
189# RUN: llvm-readobj --symbols --dyn-syms %t4 2>&1 | \
190# RUN:   FileCheck %s -DFILE=%t4 --check-prefixes=BROKENLINK,BROKENLINK-LLVM --implicit-check-not=warning:
191
192# BROKENLINK: warning: '[[FILE]]': unable to get the associated symbol table for SHT_SYMTAB_SHNDX section with index 5: sh_link (255) is greater than or equal to the total number of sections (12)
193
194# BROKENLINK-GNU:      warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table
195# BROKENLINK-GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT   RSV[0xffff] sym1
196# BROKENLINK-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table
197# BROKENLINK-GNU-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT   RSV[0xffff] sym2
198
199# BROKENLINK-LLVM:      Symbol {
200# BROKENLINK-LLVM:        Name: sym1 (6)
201# BROKENLINK-LLVM:      warning: '[[FILE]]': found an extended symbol index (1), but unable to locate the extended symbol index table
202# BROKENLINK-LLVM-NEXT:   Section: Reserved (0xFFFF)
203# BROKENLINK-LLVM-NEXT: }
204# BROKENLINK-LLVM-NEXT: Symbol {
205# BROKENLINK-LLVM-NEXT:   Name: sym2 (1)
206# BROKENLINK-LLVM:      warning: '[[FILE]]': found an extended symbol index (2), but unable to locate the extended symbol index table
207# BROKENLINK-LLVM-NEXT:   Section: Reserved (0xFFFF)
208# BROKENLINK-LLVM-NEXT: }
209
210## Check we report a warning when multiple SHT_SYMTAB_SHNDX sections are linked to a symbol table.
211## In this case, 2 sections are linked to the dynamic symbol table. Check it doesn't affect
212## anything, because the SHT_SYMTAB_SHNDX section specified by the DT_SYMTAB_SHNDX tag is still used.
213
214# RUN: yaml2obj --docnum=1 -DSHNDXLINK=.dynsym %s -o %t.multiple
215# RUN: llvm-readelf --symbols --dyn-syms %t.multiple 2>&1 | \
216# RUN:   FileCheck %s -DFILE=%t.multiple --check-prefix=MULTIPLE-GNU
217# RUN: llvm-readobj --symbols --dyn-syms %t.multiple 2>&1 | \
218# RUN:   FileCheck %s -DFILE=%t.multiple --check-prefix=MULTIPLE-LLVM
219
220# MULTIPLE-GNU:      warning: '[[FILE]]': multiple SHT_SYMTAB_SHNDX sections are linked to SHT_SYMTAB_SHNDX section with index 6
221# MULTIPLE-GNU:      Symbol table '.dynsym' contains 3 entries:
222# MULTIPLE-GNU-NEXT:    Num:    Value  Size Type    Bind   Vis     Ndx Name
223# MULTIPLE-GNU-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT UND
224# MULTIPLE-GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT   3 dynsym1
225# MULTIPLE-GNU-NEXT:      2: 00000000     0 NOTYPE  LOCAL  DEFAULT   2 dynsym2
226
227# MULTIPLE-LLVM:      Symbol {
228# MULTIPLE-LLVM:        Name: dynsym1 (9)
229# MULTIPLE-LLVM-NEXT:   Value: 0x0
230# MULTIPLE-LLVM-NEXT:   Size: 0
231# MULTIPLE-LLVM-NEXT:   Binding: Local (0x0)
232# MULTIPLE-LLVM-NEXT:   Type: None (0x0)
233# MULTIPLE-LLVM-NEXT:   Other: 0
234# MULTIPLE-LLVM-NEXT:   Section: .section3 (0x3)
235# MULTIPLE-LLVM-NEXT: }
236# MULTIPLE-LLVM-NEXT: Symbol {
237# MULTIPLE-LLVM-NEXT:   Name: dynsym2 (1)
238# MULTIPLE-LLVM-NEXT:   Value: 0x0
239# MULTIPLE-LLVM-NEXT:   Size: 0
240# MULTIPLE-LLVM-NEXT:   Binding: Local (0x0)
241# MULTIPLE-LLVM-NEXT:   Type: None (0x0)
242# MULTIPLE-LLVM-NEXT:   Other: 0
243# MULTIPLE-LLVM-NEXT:   Section: .section2 (0x2)
244# MULTIPLE-LLVM-NEXT: }
245
246## In this case we have a SHT_SYMTAB_SHNDX section placed right before
247## the end of the file. This table is broken: it contains fewer entries than
248## the number of dynamic symbols.
249## Check we report a warning when trying to read an extended symbol index past
250## the end of the file.
251
252# RUN: yaml2obj --docnum=2 %s -o %t.pastend
253# RUN: llvm-readelf --dyn-syms %t.pastend 2>&1 | \
254# RUN:   FileCheck %s -DFILE=%t.pastend --check-prefix=PASTEND-GNU --implicit-check-not=warning:
255# RUN: llvm-readobj --dyn-syms %t.pastend 2>&1 | \
256# RUN:   FileCheck %s -DFILE=%t.pastend --check-prefix=PASTEND-LLVM --implicit-check-not=warning:
257
258# PASTEND-GNU:      1: 00000000 0 NOTYPE  LOCAL  DEFAULT 1 dynsym1
259# PASTEND-GNU-NEXT: warning: '[[FILE]]': unable to read an extended symbol table at index 2: can't read past the end of the file
260# PASTEND-GNU-NEXT: 2: 00000000 0 NOTYPE  LOCAL  DEFAULT RSV[0xffff] dynsym2
261
262# PASTEND-LLVM:      Symbol {
263# PASTEND-LLVM:       Name: dynsym2 (1)
264# PASTEND-LLVM-NEXT:  Value: 0x0
265# PASTEND-LLVM-NEXT:  Size: 0
266# PASTEND-LLVM-NEXT:  Binding: Local (0x0)
267# PASTEND-LLVM-NEXT:  Type: None (0x0)
268# PASTEND-LLVM-NEXT:  Other: 0
269# PASTEND-LLVM-NEXT: warning: '[[FILE]]': unable to read an extended symbol table at index 2: can't read past the end of the file
270# PASTEND-LLVM-NEXT:  Section: Reserved (0xFFFF)
271# PASTEND-LLVM-NEXT: }
272
273--- !ELF
274FileHeader:
275  Class: ELFCLASS32
276  Data:  ELFDATA2LSB
277  Type:  ET_REL
278Sections:
279  - Name: .section1
280    Type: SHT_PROGBITS
281  - Name: .section2
282    Type: SHT_PROGBITS
283  - Name:    .dynamic
284    Type:    SHT_DYNAMIC
285    Flags:   [ SHF_ALLOC ]
286    Address: 0x1000
287    Offset:  0x1000
288    Entries:
289      - Tag:   DT_SYMTAB
290        Value: 0x1500
291      - Tag:   DT_HASH
292        Value: 0x1600
293      - Tag:   DT_STRTAB
294        Value: 0x1700
295      - Tag:   DT_STRSZ
296        Value: 17 ## ".dynsym1.dynsym2."
297      - Tag:   DT_SYMTAB_SHNDX
298        Value: 0x2000
299      - Tag:   DT_NULL
300        Value: 0
301  - Name:    .dynsym
302    Type:    SHT_DYNSYM
303    Flags:   [ SHF_ALLOC ]
304    Offset:  0x1500
305    Address: 0x1500
306## We need the .hash table to infer the number
307## of dynamic symbols.
308  - Name:    .hash
309    Type:    SHT_HASH
310    Flags:   [ SHF_ALLOC ]
311    Offset:  0x1600
312    Address: 0x1600
313    Bucket:  [ 1 ]
314    Chain:   [ 1, 2, 3 ]
315  - Name:    .dynstr
316    Type:    SHT_STRTAB
317    Flags:   [ SHF_ALLOC ]
318    Offset:  0x1700
319    Address: 0x1700
320  - Name: .strtab
321    Type: SHT_STRTAB
322  - Name:    .symtab_shndx
323    Type:    SHT_SYMTAB_SHNDX
324    Flags:   [ SHF_ALLOC ]
325    Entries: [ 0, 1 ]
326    Offset:  0x2000
327    Address: 0x2000
328  - Type:      SectionHeaderTable
329    NoHeaders: true
330DynamicSymbols:
331  - Name:  dynsym1
332    Index: SHN_XINDEX
333  - Name:  dynsym2
334    Index: SHN_XINDEX
335ProgramHeaders:
336  - Type:     PT_LOAD
337    VAddr:    0x1000
338    FirstSec: .dynamic
339    LastSec:  .symtab_shndx
340  - Type:     PT_DYNAMIC
341    VAddr:    0x1000
342    FirstSec: .dynamic
343    LastSec:  .dynamic
344