408 lines · plain
1## This test shows how llvm-readobj uses the hash table section to derive the2## size of a dynamic symbol table. This allows dumping of the dynamic symbol3## table in the event of an object without section headers.4 5## Case 1a) Table size is derived from hash table, with DT_SYMTAB before DT_HASH.6# RUN: yaml2obj --docnum=1 %s -o %t1a-64 -DBITS=64 \7# RUN: -DTAG1=DT_SYMTAB -DTAG2=DT_HASH -DVAL1=0x400 -DVAL2=0x6008# RUN: llvm-strip --strip-sections %t1a-649# RUN: llvm-readobj --dyn-symbols %t1a-64 2>&1 | \10# RUN: FileCheck %s --check-prefixes=LLVM1,STRIP --implicit-check-not=warning:11# RUN: llvm-readelf --dyn-symbols %t1a-64 2>&1 | \12# RUN: FileCheck %s --check-prefixes=GNU1,GNU1-STRIP --implicit-check-not=warning:13# RUN: yaml2obj --docnum=1 %s -o %t1a-32 -DBITS=32 \14# RUN: -DTAG1=DT_SYMTAB -DTAG2=DT_HASH -DVAL1=0x400 -DVAL2=0x60015# RUN: llvm-strip --strip-sections %t1a-3216# RUN: llvm-readobj --dyn-symbols %t1a-32 2>&1 | \17# RUN: FileCheck %s --check-prefixes=LLVM1,STRIP --implicit-check-not=warning:18# RUN: llvm-readelf --dyn-symbols %t1a-32 2>&1 | \19# RUN: FileCheck %s --check-prefixes=GNU1,GNU1-STRIP --implicit-check-not=warning:20 21## 1b) Table size is derived from hash table, with DT_HASH before DT_SYMTAB.22## We don't bother testing 32 and 64-bit here. The above cases show that reading23## the nchain value is correct for all formats, and other tests show the basic24## printing behaviour.25# RUN: yaml2obj --docnum=1 %s -o %t1b-64 -DBITS=64 \26# RUN: -DTAG1=DT_HASH -DTAG2=DT_SYMTAB -DVAL1=0x600 -DVAL2=0x40027# RUN: llvm-strip --strip-sections %t1b-6428# RUN: llvm-readobj --dyn-symbols %t1b-64 2>&1 | \29# RUN: FileCheck %s --check-prefixes=LLVM1,STRIP --implicit-check-not=warning:30# RUN: llvm-readelf --dyn-symbols %t1b-64 2>&1 | \31# RUN: FileCheck %s --check-prefixes=GNU1,GNU1-STRIP --implicit-check-not=warning:32 33# LLVM1: DynamicSymbols [34# LLVM1-NEXT: Symbol {35# LLVM1-NEXT: Name: (0)36# LLVM1-NEXT: Value: 0x037# LLVM1-NEXT: Size: 038# LLVM1-NEXT: Binding: Local (0x0)39# LLVM1-NEXT: Type: None (0x0)40# LLVM1-NEXT: Other: 041# LLVM1-NEXT: Section: Undefined (0x0)42# LLVM1-NEXT: }43# LLVM1-NEXT: Symbol {44# LLVM1-NEXT: Name: foo (5)45# LLVM1-NEXT: Value: 0x10046# LLVM1-NEXT: Size: 047# LLVM1-NEXT: Binding: Local (0x0)48# LLVM1-NEXT: Type: Function (0x2)49# LLVM1-NEXT: Other: 050# STRIP-NEXT: Section: <?> (0x1)51# NOSTRIP-NEXT: Section: .text (0x1)52# LLVM1-NEXT: }53# LLVM1-NEXT: Symbol {54# LLVM1-NEXT: Name: bar (1)55# LLVM1-NEXT: Value: 0x20056# LLVM1-NEXT: Size: 057# LLVM1-NEXT: Binding: Local (0x0)58# LLVM1-NEXT: Type: Object (0x1)59# LLVM1-NEXT: Other: 060# STRIP-NEXT: Section: <?> (0x2)61# NOSTRIP-NEXT: Section: .data (0x2)62# LLVM1-NEXT: }63# LLVM1-NEXT: ]64 65# GNU1-STRIP: Symbol table for image contains 3 entries:66# GNU1-NOSTRIP: Symbol table '.dynsym' contains 3 entries:67# GNU1-NEXT: Num: Value Size Type Bind Vis Ndx Name68# GNU1-NEXT: 0: {{0*}}00000000 0 NOTYPE LOCAL DEFAULT UND69# GNU1-NEXT: 1: {{0*}}00000100 0 FUNC LOCAL DEFAULT 1 foo70# GNU1-NEXT: 2: {{0*}}00000200 0 OBJECT LOCAL DEFAULT 2 bar71# GNU1-EMPTY:72 73--- !ELF74FileHeader:75 Class: ELFCLASS[[BITS]]76 Data: ELFDATA2LSB77 Type: ET_DYN78Sections:79 - Name: .text80 Type: SHT_PROGBITS81 - Name: .data82 Type: SHT_PROGBITS83 - Name: .dynsym84 Type: SHT_DYNSYM85 Flags: [ SHF_ALLOC ]86 Address: 0x40087 AddressAlign: 0x40088 - Name: .hash89 Type: SHT_HASH90 Flags: [ SHF_ALLOC ]91 Address: 0x60092 AddressAlign: 0x20093 Bucket: [ 1 ]94 Chain: [ 1, 2, 3 ]95 - Name: .dynstr96 Type: SHT_STRTAB97 Flags: [ SHF_ALLOC ]98 Address: 0x80099 AddressAlign: 0x200100 - Name: .dynamic101 Type: SHT_DYNAMIC102 Flags: [ SHF_ALLOC ]103 Address: 0xA00104 AddressAlign: 0x200105 Entries:106 - Tag: DT_STRTAB107 Value: 0x800108 - Tag: DT_STRSZ109 Value: 9110 - Tag: [[TAG1]]111 Value: [[VAL1]]112 - Tag: [[TAG2]]113 Value: [[VAL2]]114 - Tag: DT_NULL115 Value: 0116DynamicSymbols:117 - Name: foo118 Type: STT_FUNC119 Section: .text120 Value: 0x100121 - Name: bar122 Type: STT_OBJECT123 Section: .data124 Value: 0x200125ProgramHeaders:126 - Type: PT_LOAD127 VAddr: 0128 FirstSec: .text129 LastSec: .data130 - Type: PT_LOAD131 VAddr: 0x400132 FirstSec: .dynsym133 LastSec: .dynamic134 - Type: PT_DYNAMIC135 VAddr: 0xA00136 FirstSec: .dynamic137 LastSec: .dynamic138 139## Case 2: Table size from DT_HASH does not match size from section header.140# RUN: yaml2obj --docnum=2 %s -o %t2-smaller -DCHAIN="[1, 2]"141# RUN: llvm-readobj --dyn-symbols %t2-smaller 2>&1 | \142# RUN: FileCheck %s --check-prefixes=LLVM2,WARN \143# RUN: --implicit-check-not=warning: -DNCHAIN=2144# RUN: llvm-readelf --dyn-symbols %t2-smaller 2>&1 | \145# RUN: FileCheck %s --check-prefixes=GNU2,WARN \146# RUN: --implicit-check-not=warning: -DNCHAIN=2147 148# RUN: yaml2obj --docnum=2 %s -o %t2-larger -DCHAIN="[1, 2, 3, 4]"149# RUN: llvm-readobj --dyn-symbols %t2-larger 2>&1 | \150# RUN: FileCheck %s --check-prefixes=LLVM2,LLVM2-MORE,LLVM2-ALL,WARN \151# RUN: --implicit-check-not=warning: -DNCHAIN=4152# RUN: llvm-readelf --dyn-symbols %t2-larger 2>&1 | \153# RUN: FileCheck %s --check-prefixes=GNU2,GNU2-MORE,GNU2-ALL,WARN \154# RUN: --implicit-check-not=warning: -DNCHAIN=4155 156# WARN: warning: '{{.*}}2-{{.*}}': hash table nchain ([[NCHAIN]]) differs from symbol count derived from SHT_DYNSYM section header (3)157 158## Show we report a warning when the sh_entsize of the SHT_DYNSYM section is zero and therefore we are unable159## to derive the number of dynamic symbols from SHT_DYNSYM section header.160# RUN: yaml2obj --docnum=2 %s -o %t2-zero-entsize -DCHAIN="[1, 2, 3, 4]" -DENTSIZE=0161# RUN: llvm-readobj --dyn-symbols %t2-zero-entsize 2>&1 | \162# RUN: FileCheck %s -DFILE=%t2-zero-entsize --check-prefixes=LLVM2,LLVM2-MORE,LLVM2-ALL,WARN-ENTSIZE \163# RUN: --implicit-check-not=warning:164# RUN: llvm-readelf --dyn-symbols %t2-zero-entsize 2>&1 | \165# RUN: FileCheck %s -DFILE=%t2-zero-entsize --check-prefixes=GNU2,GNU2-MORE,GNU2-ALL,WARN-ENTSIZE \166# RUN: --implicit-check-not=warning: -DNCHAIN=4167 168## WARN-ENTSIZE: warning: '[[FILE]]': SHT_DYNSYM section has sh_entsize == 0169 170## Show there's no warning if the sizes match171# RUN: yaml2obj --docnum=2 %s -o %t2-same -DCHAIN="[1, 2, 3]"172# RUN: llvm-readobj --dyn-symbols %t2-same 2>&1 | \173# RUN: FileCheck %s --check-prefixes=LLVM2,LLVM2-MORE --implicit-check-not=warning:174# RUN: llvm-readelf --dyn-symbols %t2-same 2>&1 | \175# RUN: FileCheck %s --check-prefixes=GNU2,GNU2-MORE \176# RUN: --implicit-check-not=warning: -DNCHAIN=3177 178# LLVM2: DynamicSymbols [179# LLVM2-NEXT: Symbol {180# LLVM2-NEXT: Name: (0)181# LLVM2-NEXT: Value: 0x0182# LLVM2-NEXT: Size: 0183# LLVM2-NEXT: Binding: Local (0x0)184# LLVM2-NEXT: Type: None (0x0)185# LLVM2-NEXT: Other: 0186# LLVM2-NEXT: Section: Undefined (0x0)187# LLVM2-NEXT: }188# LLVM2-NEXT: Symbol {189# LLVM2-NEXT: Name: foo (9)190# LLVM2-NEXT: Value: 0x100191# LLVM2-NEXT: Size: 0192# LLVM2-NEXT: Binding: Local (0x0)193# LLVM2-NEXT: Type: Function (0x2)194# LLVM2-NEXT: Other: 0195# LLVM2-NEXT: Section: .text (0x1)196# LLVM2-NEXT: }197# LLVM2-MORE-NEXT: Symbol {198# LLVM2-MORE-NEXT: Name: bar (5)199# LLVM2-MORE-NEXT: Value: 0x200200# LLVM2-MORE-NEXT: Size: 0201# LLVM2-MORE-NEXT: Binding: Local (0x0)202# LLVM2-MORE-NEXT: Type: Object (0x1)203# LLVM2-MORE-NEXT: Other: 0204# LLVM2-MORE-NEXT: Section: .data (0x2)205# LLVM2-MORE-NEXT: }206# LLVM2-ALL-NEXT: Symbol {207# LLVM2-ALL-NEXT: Name: baz (1)208# LLVM2-ALL-NEXT: Value: 0x300209# LLVM2-ALL-NEXT: Size: 0210# LLVM2-ALL-NEXT: Binding: Local (0x0)211# LLVM2-ALL-NEXT: Type: Object (0x1)212# LLVM2-ALL-NEXT: Other: 0213# LLVM2-ALL-NEXT: Section: .data (0x2)214# LLVM2-ALL-NEXT: }215# LLVM2-NEXT: ]216 217# GNU2: Symbol table '.dynsym' contains [[NCHAIN]] entries:218# GNU2-NEXT: Num: Value Size Type Bind Vis Ndx Name219# GNU2-NEXT: 0: {{0*}}00000000 0 NOTYPE LOCAL DEFAULT UND220# GNU2-NEXT: 1: {{0*}}00000100 0 FUNC LOCAL DEFAULT 1 foo221# GNU2-MORE-NEXT: 2: {{0*}}00000200 0 OBJECT LOCAL DEFAULT 2 bar222# GNU2-ALL-NEXT: 3: {{0*}}00000300 0 OBJECT LOCAL DEFAULT 2 baz223# GNU2-EMPTY:224 225## In this YAML, we define 4 dynamic symbols (including the null symbol), but226## constrain the .dynsym section header to say there are only 3. This means that227## when a size of 4 is derived from the hash table, we still have a valid symbol228## to dump.229--- !ELF230FileHeader:231 Class: ELFCLASS64232 Data: ELFDATA2LSB233 Type: ET_DYN234Sections:235 - Name: .text236 Type: SHT_PROGBITS237 - Name: .data238 Type: SHT_PROGBITS239 - Name: .dynsym240 Type: SHT_DYNSYM241 Flags: [ SHF_ALLOC ]242 ShSize: 0x48243 Address: 0x400244 AddressAlign: 0x400245## 0x18 is the standard entsize value.246 EntSize: [[ENTSIZE=0x18]]247 - Name: .hash248 Type: SHT_HASH249 Flags: [ SHF_ALLOC ]250 Address: 0x600251 AddressAlign: 0x200252 Bucket: [ 1 ]253 Chain: [[CHAIN]]254 - Name: .dynstr255 Type: SHT_STRTAB256 Flags: [ SHF_ALLOC ]257 Address: 0x800258 AddressAlign: 0x200259 - Name: .dynamic260 Type: SHT_DYNAMIC261 Flags: [ SHF_ALLOC ]262 Address: 0xA00263 AddressAlign: 0x200264 Entries:265 - Tag: DT_SYMTAB266 Value: 0x400267 - Tag: DT_HASH268 Value: 0x600269 - Tag: DT_STRTAB270 Value: 0x800271 - Tag: DT_STRSZ272 Value: 13273 - Tag: DT_NULL274 Value: 0275DynamicSymbols:276 - Name: foo277 Type: STT_FUNC278 Section: .text279 Value: 0x100280 - Name: bar281 Type: STT_OBJECT282 Section: .data283 Value: 0x200284 - Name: baz285 Type: STT_OBJECT286 Section: .data287 Value: 0x300288ProgramHeaders:289 - Type: PT_LOAD290 VAddr: 0291 FirstSec: .text292 LastSec: .data293 - Type: PT_LOAD294 VAddr: 0x400295 FirstSec: .dynsym296 LastSec: .dynamic297 - Type: PT_DYNAMIC298 VAddr: 0xA00299 FirstSec: .dynamic300 LastSec: .dynamic301 302## Case 3: DT_HASH is missing.303## Show that no warning occurs if there are section headers.304# RUN: yaml2obj --docnum=1 %s -o %t3 -DTAG1=DT_SYMTAB -DVAL1=0x400 -DTAG2=DT_NULL -DVAL2=0 -DBITS=64305# RUN: llvm-readobj --dyn-symbols %t3 2>&1 | \306# RUN: FileCheck %s --check-prefixes=LLVM1,NOSTRIP --implicit-check-not=warning:307# RUN: llvm-readelf --dyn-symbols %t3 2>&1 | \308# RUN: FileCheck %s --check-prefixes=GNU1,GNU1-NOSTRIP --implicit-check-not=warning:309 310## Show that size is treated as zero, if no section headers are present.311# RUN: llvm-strip --strip-sections %t3312# RUN: llvm-readobj --dyn-symbols %t3 2>&1 | \313# RUN: FileCheck %s --check-prefix=LLVM3 --implicit-check-not=warning:314# RUN: llvm-readelf --dyn-symbols %t3 2>&1 | \315# RUN: FileCheck %s --implicit-check-not={{.}} --allow-empty316 317# LLVM3: DynamicSymbols [318# LLVM3: ]319 320## Case 4: The size of the dynamic symbol table, inferred from the hash table, is broken.321## It is so large that symbol table goes past the end of the file. We have a dynamic322## relocation which refers to a symbol with an index that is also too large to be323## in the file. Check we report a warning when trying to dump this relocation.324 325# RUN: yaml2obj --docnum=3 %s -o %t4.1326 327## Remember the size of the output produced.328# RUN: wc -c %t4.1 > %t4.out.gnu.txt329# RUN: llvm-readelf --sections --dyn-relocations %t4.1 >> %t4.out.gnu.txt 2>&1330# RUN: FileCheck %s -DFILE=%t4.1 --input-file=%t4.out.gnu.txt --check-prefix=BROKEN-NCHAIN-GNU331 332# BROKEN-NCHAIN-GNU: [[#%u, FILESIZE:]]333# BROKEN-NCHAIN-GNU: warning: '[[FILE]]': the size (0x17ffffffe8) of the dynamic symbol table at 0x[[#%x, DYNSYMOFF:]], derived from the hash table, goes past the end of the file (0x[[#%x, FILESIZE]]) and will be ignored334 335# BROKEN-NCHAIN-GNU: [Nr] Name Type Address Off336# BROKEN-NCHAIN-GNU: [ 1] .rela.plt RELA 0000000000001000 0000[[#%x, RELAOFF:]]337# BROKEN-NCHAIN-GNU: [ 4] .dynsym DYNSYM 0000000000001078 0000[[#%x, DYNSYMOFF]]338 339# BROKEN-NCHAIN-GNU: 'PLT' relocation section at offset 0x[[#%x, RELAOFF]] contains 24 bytes:340# BROKEN-NCHAIN-GNU-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend341# BROKEN-NCHAIN-GNU-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 4292739037: index is greater than or equal to the number of dynamic symbols (1)342# BROKEN-NCHAIN-GNU-NEXT: 0000000000000000 ffddffdd00000000 R_X86_64_NONE <corrupt> + 0343 344# RUN: wc -c %t4.1 > %t4.out.llvm.txt345# RUN: llvm-readobj --sections --dyn-relocations %t4.1 2>&1 >> %t4.out.llvm.txt 2>&1346# RUN: FileCheck %s -DFILE=%t4.1 --input-file=%t4.out.llvm.txt --check-prefix=BROKEN-NCHAIN-LLVM347 348# BROKEN-NCHAIN-LLVM: [[#%u, FILESIZE:]]349# BROKEN-NCHAIN-LLVM: warning: '[[FILE]]': the size (0x17ffffffe8) of the dynamic symbol table at 0x[[#%x, DYNSYMOFF:]], derived from the hash table, goes past the end of the file (0x[[#%x, FILESIZE]]) and will be ignored350 351# BROKEN-NCHAIN-LLVM: Name: .dynsym352# BROKEN-NCHAIN-LLVM-NEXT: Type: SHT_DYNSYM353# BROKEN-NCHAIN-LLVM-NEXT: Flags [354# BROKEN-NCHAIN-LLVM-NEXT: SHF_ALLOC355# BROKEN-NCHAIN-LLVM-NEXT: ]356# BROKEN-NCHAIN-LLVM-NEXT: Address: 0x1078357# BROKEN-NCHAIN-LLVM-NEXT: Offset: 0x[[#%X, DYNSYMOFF]]358 359# BROKEN-NCHAIN-LLVM: Dynamic Relocations {360# BROKEN-NCHAIN-LLVM-NEXT: warning: '[[FILE]]': unable to get name of the dynamic symbol with index 4292739037: index is greater than or equal to the number of dynamic symbols (1)361# BROKEN-NCHAIN-LLVM-NEXT: 0x0 R_X86_64_NONE <corrupt> 0x0362# BROKEN-NCHAIN-LLVM-NEXT: }363 364--- !ELF365FileHeader:366 Class: ELFCLASS64367 Data: ELFDATA2LSB368 Type: ET_EXEC369 Machine: EM_X86_64370Sections:371 - Name: .rela.plt372 Type: SHT_RELA373 Flags: [ SHF_ALLOC ]374 Address: 0x1000375 Relocations:376 - Type: R_X86_64_NONE377 Symbol: 0xFFDDFFDD378 - Name: .dynamic379 Type: SHT_DYNAMIC380 Flags: [ SHF_ALLOC ]381 Entries:382 - Tag: DT_PLTRELSZ383 Value: 0x18384 - Tag: DT_JMPREL385## 0x1000 - PT_LOAD's p_vaddr (0x1000) == 0x0.386## 0x0 + PT_LOAD's p_offset (0x78) == .rela.plt section offset (0x78).387 Value: 0x1000388 - Tag: DT_PLTREL389 Value: 0x7 ## 7 == DT_RELA390 - Tag: DT_HASH391## 0x1068 - PT_LOAD's p_vaddr (0x1000) == 0x68.392## 0x68 + PT_LOAD's p_offset (0x78) == .hash section offset (0xE0).393 Value: 0x1068394 - Tag: DT_NULL395 Value: 0x0396 - Name: .hash397 Type: SHT_HASH398 Flags: [ SHF_ALLOC ]399 Bucket: [ 0 ]400 Chain: [ 0 ]401 NChain: 0xFFFFFFFF402DynamicSymbols: []403ProgramHeaders:404 - Type: PT_LOAD405 FirstSec: .rela.plt406 LastSec: .hash407 VAddr: 0x1000408