forked from OSchip/llvm-project
451 lines
14 KiB
Plaintext
451 lines
14 KiB
Plaintext
## Check llvm-readelf is able to dump the content of hash sections correctly.
|
|
|
|
## Check the output when both .hash and .gnu.hash sections are present.
|
|
|
|
# RUN: yaml2obj --docnum=1 -DBITS=32 %s -o %t1-32.so
|
|
# RUN: llvm-readelf --hash-symbols %t1-32.so \
|
|
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix HASH-32
|
|
|
|
# RUN: yaml2obj --docnum=1 -DBITS=64 %s -o %t1-64.so
|
|
# RUN: llvm-readelf --hash-symbols %t1-64.so | FileCheck %s --check-prefix HASH-64
|
|
|
|
# HASH-32: Symbol table of .hash for image:
|
|
# HASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# HASH-32-NEXT: 1 0: 00000000 0 NOTYPE GLOBAL DEFAULT UND ccc
|
|
# HASH-32-NEXT: 5 0: 00001001 0 NOTYPE WEAK DEFAULT 1 bbb
|
|
# HASH-32-NEXT: 3 0: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd
|
|
# HASH-32-NEXT: 2 0: 00001000 0 NOTYPE GLOBAL DEFAULT 1 aaa
|
|
# HASH-32-NEXT: 4 0: 00000000 0 NOTYPE GLOBAL DEFAULT 2 eee
|
|
# HASH-32-EMPTY:
|
|
# HASH-32: Symbol table of .gnu.hash for image:
|
|
# HASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# HASH-32-NEXT: 2 1: 00001000 0 NOTYPE GLOBAL DEFAULT 1 aaa
|
|
# HASH-32-NEXT: 3 1: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd
|
|
# HASH-32-NEXT: 4 2: 00000000 0 NOTYPE GLOBAL DEFAULT 2 eee
|
|
# HASH-32-NEXT: 5 2: 00001001 0 NOTYPE WEAK DEFAULT 1 bbb
|
|
# HASH-32-NOT: {{.}}
|
|
|
|
# HASH-64: Symbol table of .hash for image:
|
|
# HASH-64-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# HASH-64-NEXT: 1 0: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND ccc
|
|
# HASH-64-NEXT: 5 0: 0000000000001001 0 NOTYPE WEAK DEFAULT 1 bbb
|
|
# HASH-64-NEXT: 3 0: 0000000000000001 0 NOTYPE GLOBAL DEFAULT ABS ddd
|
|
# HASH-64-NEXT: 2 0: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aaa
|
|
# HASH-64-NEXT: 4 0: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 2 eee
|
|
# HASH-64-EMPTY:
|
|
# HASH-64-NEXT: Symbol table of .gnu.hash for image:
|
|
# HASH-64-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# HASH-64-NEXT: 2 1: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aaa
|
|
# HASH-64-NEXT: 3 1: 0000000000000001 0 NOTYPE GLOBAL DEFAULT ABS ddd
|
|
# HASH-64-NEXT: 4 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 2 eee
|
|
# HASH-64-NEXT: 5 2: 0000000000001001 0 NOTYPE WEAK DEFAULT 1 bbb
|
|
# HASH-64-NOT: {{.}}
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS[[BITS]]
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .hash
|
|
Type: SHT_HASH
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynsym
|
|
Bucket: [ 1, 0, 0 ]
|
|
Chain: [ 0, 5, 4, 2, 0, 3 ]
|
|
- Name: .gnu.hash
|
|
Type: SHT_GNU_HASH
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynsym
|
|
Header:
|
|
SymNdx: 0x2
|
|
Shift2: 0x0
|
|
BloomFilter: [ 0x0 ]
|
|
HashBuckets: [ 0x0, 0x2, 0x4 ]
|
|
HashValues: [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ]
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynstr
|
|
Entries:
|
|
## PT_LOAD's p_vaddr is 0x0. DT_HASH value is 0x0.
|
|
## llvm-readelf will read .hash content from PT_LOAD's p_offset + (DT_HASH value - p_vaddr).
|
|
## This matches the file offset of the .hash section.
|
|
- Tag: DT_HASH
|
|
Value: 0x0000000000000000
|
|
- Tag: DT_GNU_HASH
|
|
## PT_LOAD's p_vaddr is 0x0. DT_GNU_HASH value is 0x2c (size of .hash = 0x2c).
|
|
## llvm-readelf will read .gnu.hash content from PT_LOAD's p_offset + (DT_GNU_HASH value - p_vaddr).
|
|
## This matches the file offset of the .gnu.hash section.
|
|
Value: 0x000000000000002C
|
|
- Tag: DT_NULL
|
|
Value: 0x0000000000000000
|
|
DynamicSymbols:
|
|
- Name: ccc
|
|
Binding: STB_GLOBAL
|
|
- Name: aaa
|
|
Section: .hash
|
|
Binding: STB_GLOBAL
|
|
Value: 0x0000000000001000
|
|
- Name: ddd
|
|
Index: SHN_ABS
|
|
Binding: STB_GLOBAL
|
|
Value: 0x0000000000000001
|
|
- Name: eee
|
|
Section: .gnu.hash
|
|
Binding: STB_GLOBAL
|
|
- Name: bbb
|
|
Section: .hash
|
|
Binding: STB_WEAK
|
|
Value: 0x0000000000001001
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
Flags: [ PF_R, PF_X ]
|
|
Sections:
|
|
- Section: .hash
|
|
- Section: .gnu.hash
|
|
- Section: .dynamic
|
|
|
|
## Check the output when only .hash section is present.
|
|
|
|
# RUN: yaml2obj --docnum=2 %s -o %t2-32.so
|
|
# RUN: llvm-readelf --hash-symbols %t2-32.so \
|
|
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix ONLY-HASH-32
|
|
|
|
# ONLY-HASH-32: Symbol table of .hash for image:
|
|
# ONLY-HASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# ONLY-HASH-32-NEXT: 1 0: 00000000 0 NOTYPE GLOBAL DEFAULT UND ccc
|
|
# ONLY-HASH-32-NEXT: 5 0: 00001001 0 NOTYPE WEAK DEFAULT 1 bbb
|
|
# ONLY-HASH-32-NEXT: 3 0: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd
|
|
# ONLY-HASH-32-NEXT: 2 0: 00001000 0 NOTYPE GLOBAL DEFAULT 1 aaa
|
|
# ONLY-HASH-32-NEXT: 4 0: 00000000 0 NOTYPE GLOBAL DEFAULT 2 eee
|
|
# ONLY-HASH-32-NOT: {{.}}
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS32
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_386
|
|
Sections:
|
|
- Name: .hash
|
|
Type: SHT_HASH
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynsym
|
|
Bucket: [ 1, 0, 0 ]
|
|
Chain: [ 0, 5, 4, 2, 0, 3 ]
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynstr
|
|
Entries:
|
|
- Tag: DT_HASH
|
|
Value: 0x0000000000000000
|
|
- Tag: DT_NULL
|
|
Value: 0x0000000000000000
|
|
DynamicSymbols:
|
|
- Name: ccc
|
|
Binding: STB_GLOBAL
|
|
- Name: aaa
|
|
Section: .hash
|
|
Binding: STB_GLOBAL
|
|
Value: 0x0000000000001000
|
|
- Name: ddd
|
|
Index: SHN_ABS
|
|
Binding: STB_GLOBAL
|
|
Value: 0x0000000000000001
|
|
- Name: eee
|
|
Section: .dynamic
|
|
Binding: STB_GLOBAL
|
|
- Name: bbb
|
|
Section: .hash
|
|
Binding: STB_WEAK
|
|
Value: 0x0000000000001001
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
Flags: [ PF_R, PF_X ]
|
|
Sections:
|
|
- Section: .hash
|
|
- Section: .dynamic
|
|
|
|
## Check the output when only .gnu.hash section is present.
|
|
|
|
# RUN: yaml2obj --docnum=3 %s -o %t3-32.so
|
|
# RUN: llvm-readelf --hash-symbols %t3-32.so \
|
|
# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix ONLY-GNUHASH-32
|
|
|
|
# ONLY-GNUHASH-32: Symbol table of .gnu.hash for image:
|
|
# ONLY-GNUHASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# ONLY-GNUHASH-32-NEXT: 2 1: 00001000 0 NOTYPE GLOBAL DEFAULT 2 aaa
|
|
# ONLY-GNUHASH-32-NEXT: 3 1: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd
|
|
# ONLY-GNUHASH-32-NEXT: 4 2: 00000000 0 NOTYPE GLOBAL DEFAULT 1 eee
|
|
# ONLY-GNUHASH-32-NEXT: 5 2: 00001001 0 NOTYPE WEAK DEFAULT 2 bbb
|
|
# ONLY-GNUHASH-32-NOT: {{.}}
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS32
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_386
|
|
Sections:
|
|
- Name: .gnu.hash
|
|
Type: SHT_GNU_HASH
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynsym
|
|
Header:
|
|
SymNdx: 0x2
|
|
Shift2: 0x0
|
|
BloomFilter: [ 0x0 ]
|
|
HashBuckets: [ 0x0, 0x2, 0x4 ]
|
|
HashValues: [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ]
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynstr
|
|
Entries:
|
|
- Tag: DT_GNU_HASH
|
|
Value: 0x0000000000000000
|
|
- Tag: DT_NULL
|
|
Value: 0x0000000000000000
|
|
DynamicSymbols:
|
|
- Name: ccc
|
|
Binding: STB_GLOBAL
|
|
- Name: aaa
|
|
Section: .dynamic
|
|
Binding: STB_GLOBAL
|
|
Value: 0x0000000000001000
|
|
- Name: ddd
|
|
Index: SHN_ABS
|
|
Binding: STB_GLOBAL
|
|
Value: 0x0000000000000001
|
|
- Name: eee
|
|
Section: .gnu.hash
|
|
Binding: STB_GLOBAL
|
|
- Name: bbb
|
|
Section: .dynamic
|
|
Binding: STB_WEAK
|
|
Value: 0x0000000000001001
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
Flags: [ PF_R, PF_X ]
|
|
Sections:
|
|
- Section: .gnu.hash
|
|
- Section: .dynamic
|
|
|
|
## Show that if there are no hash sections, we do not print anything.
|
|
# RUN: yaml2obj --docnum=4 %s -o %t4.so
|
|
# RUN: llvm-readelf --hash-symbols %t4.so \
|
|
# RUN: | FileCheck %s --check-prefix NO-HASH --allow-empty
|
|
|
|
# NO-HASH-NOT: {{.}}
|
|
|
|
## Sanity check that we can still find the dynamic symbols (i.e. the above test
|
|
## doesn't pass due to a mistake in the dynamic section).
|
|
# RUN: llvm-readelf --dyn-symbols %t4.so | FileCheck %s --check-prefix DYNSYMS
|
|
|
|
# DYNSYMS: Symbol table '.dynsym' contains 2 entries:
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS64
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .dynstr
|
|
Type: SHT_STRTAB
|
|
Flags: [ SHF_ALLOC ]
|
|
AddressAlign: 0x100
|
|
EntSize: 0x1
|
|
- Name: .dynsym
|
|
Type: SHT_DYNSYM
|
|
Flags: [ SHF_ALLOC ]
|
|
Link: .dynstr
|
|
Address: 0x100
|
|
AddressAlign: 0x100
|
|
EntSize: 0x18
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Flags: [ SHF_ALLOC ]
|
|
Address: 0x0000000000001000
|
|
Link: .dynstr
|
|
AddressAlign: 0x0000000000001000
|
|
EntSize: 0x0000000000000010
|
|
Entries:
|
|
- Tag: DT_STRTAB
|
|
Value: 0x0000000000000000
|
|
- Tag: DT_STRSZ
|
|
Value: 0x0000000000000009
|
|
- Tag: DT_SYMTAB
|
|
Value: 0x0000000000000100
|
|
- Tag: DT_SYMENT
|
|
Value: 0x0000000000000018
|
|
- Tag: DT_NULL
|
|
Value: 0x0000000000000000
|
|
- Name: .text.foo
|
|
Type: SHT_PROGBITS
|
|
Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
|
|
Size: 0x40
|
|
Address: 0x2000
|
|
AddressAlign: 0x2000
|
|
DynamicSymbols:
|
|
- Name: _Z3fooi
|
|
Binding: STB_GLOBAL
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
Flags: [ PF_R, PF_X ]
|
|
VAddr: 0x0
|
|
Sections:
|
|
- Section: .dynsym
|
|
- Section: .dynstr
|
|
- Section: .dynamic
|
|
- Section: .text.foo
|
|
- Type: PT_DYNAMIC
|
|
Flags: [ PF_R ]
|
|
VAddr: 0x1000
|
|
Sections:
|
|
- Section: .dynamic
|
|
|
|
## Show that we report a warning for a hash table which contains an entry of
|
|
## the bucket array pointing to a cycle.
|
|
|
|
# RUN: yaml2obj --docnum=5 %s -o %t5.so
|
|
# RUN: llvm-readelf --hash-symbols %t5.so 2>&1 | FileCheck %s -DFILE=%t5.so --check-prefix=BROKEN
|
|
|
|
# BROKEN: Symbol table of .hash for image:
|
|
# BROKEN-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# BROKEN-NEXT: 1 0: 00000000 0 NOTYPE LOCAL DEFAULT UND aaa
|
|
# BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS32
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_386
|
|
Sections:
|
|
- Name: .hash
|
|
Type: SHT_HASH
|
|
Link: .dynsym
|
|
Bucket: [ 1 ]
|
|
Chain: [ 1, 1 ]
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Entries:
|
|
## llvm-readelf will read the hash table from the file offset
|
|
## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset,
|
|
## which is the start of PT_LOAD, i.e. the file offset of .hash.
|
|
- Tag: DT_HASH
|
|
Value: 0x0
|
|
DynamicSymbols:
|
|
- Name: aaa
|
|
- Name: bbb
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
Sections:
|
|
- Section: .hash
|
|
- Section: .dynamic
|
|
|
|
## Each SHT_HASH section starts with two 32-bit fields: nbucket and nchain.
|
|
## Check we report an error when a DT_HASH value points to data that has size less than 8 bytes.
|
|
|
|
# RUN: yaml2obj --docnum=6 %s -o %t6.o
|
|
# RUN: llvm-readelf --hash-symbols %t6.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t6.o
|
|
|
|
# ERR1: warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8){{$}}
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS64
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .hash
|
|
Type: SHT_HASH
|
|
Flags: [ SHF_ALLOC ]
|
|
Bucket: [ 0 ]
|
|
Chain: [ 0 ]
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
|
Entries:
|
|
- Tag: DT_HASH
|
|
Value: 0x239
|
|
- Tag: DT_NULL
|
|
Value: 0x0
|
|
DynamicSymbols: []
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
FileSize: 0x23a
|
|
Sections:
|
|
- Section: .hash
|
|
- Section: .dynamic
|
|
|
|
## Check we report a warning when the hash table goes past the end of the file.
|
|
|
|
## Case A.1: the hash table ends right before the EOF. We have a broken nbucket
|
|
## field that has a value larger than the number of buckets.
|
|
# RUN: yaml2obj --docnum=7 %s -o %t7.1.o -DNBUCKET=0x5d -DNCHAIN=0x1
|
|
# RUN: llvm-readelf --hash-symbols %t7.1.o 2>&1 | FileCheck %s --check-prefix=NOERR1
|
|
# NOERR1: Symbol table of .hash for image:
|
|
# NOERR1-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# NOERR1-NEXT-EMPTY:
|
|
|
|
## Case A.2: the hash table ends 1 byte past the EOF. We have a broken nbucket
|
|
## field that has a value larger than the number of buckets.
|
|
# RUN: yaml2obj --docnum=7 %s -o %t7.2.o -DNBUCKET=0x5e -DNCHAIN=0x1
|
|
# RUN: llvm-readelf --hash-symbols %t7.2.o 2>&1 | FileCheck %s --check-prefix=ERR2 -DFILE=%t7.2.o
|
|
# ERR2: Symbol table of .hash for image:
|
|
# ERR2-NEXT: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 94, nchain = 1{{$}}
|
|
# ERR2-NOT: {{.}}
|
|
|
|
## Case B.1: the hash table ends right before the EOF. We have a broken nchain
|
|
## field that has a value larger than the number of chains.
|
|
# RUN: yaml2obj --docnum=7 %s -o %t7.3.o -DNBUCKET=0x1 -DNCHAIN=0x5d
|
|
# RUN: llvm-readelf --hash-symbols %t7.3.o 2>&1 | \
|
|
# RUN: FileCheck %s --implicit-check-not="warning:" --check-prefix=NOERR2 -DFILE=%t7.3.o
|
|
# NOERR2: warning: '[[FILE]]': hash table nchain (93) differs from symbol count derived from SHT_DYNSYM section header (1)
|
|
# NOERR2: Symbol table of .hash for image:
|
|
# NOERR2-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name
|
|
# NOERR2-NOT: {{.}}
|
|
|
|
## Case B.2: the hash table ends 1 byte past the EOF. We have a broken nchain
|
|
## field that has a value larger than the number of chains.
|
|
# RUN: yaml2obj --docnum=7 %s -o %t7.4.o -DNBUCKET=0x1 -DNCHAIN=0x5e
|
|
# RUN: llvm-readelf --hash-symbols %t7.4.o 2>&1 | FileCheck %s --check-prefix=ERR3 -DFILE=%t7.4.o
|
|
# ERR3: Symbol table of .hash for image:
|
|
# ERR3-NEXT: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 1, nchain = 94{{$}}
|
|
# ERR3-NOT: {{.}}
|
|
|
|
--- !ELF
|
|
FileHeader:
|
|
Class: ELFCLASS32
|
|
Data: ELFDATA2LSB
|
|
Type: ET_DYN
|
|
Machine: EM_X86_64
|
|
Sections:
|
|
- Name: .hash
|
|
Type: SHT_HASH
|
|
Flags: [ SHF_ALLOC ]
|
|
Bucket: [ 0 ]
|
|
NBucket: [[NBUCKET]]
|
|
Chain: [ 0 ]
|
|
NChain: [[NCHAIN]]
|
|
- Name: .dynamic
|
|
Type: SHT_DYNAMIC
|
|
Flags: [ SHF_WRITE, SHF_ALLOC ]
|
|
Entries:
|
|
- Tag: DT_HASH
|
|
Value: 0x0
|
|
- Tag: DT_NULL
|
|
Value: 0x0
|
|
DynamicSymbols: []
|
|
ProgramHeaders:
|
|
- Type: PT_LOAD
|
|
Sections:
|
|
- Section: .hash
|
|
- Section: .dynamic
|