| ## 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 |
| 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: [[NAME=ccc]] |
| Binding: STB_GLOBAL |
| Type: [[TYPE=STT_NOTYPE]] |
| - Name: [[NAME=aaa]] |
| Section: .hash |
| Binding: STB_GLOBAL |
| Value: 0x0000000000001000 |
| Type: [[TYPE=STT_NOTYPE]] |
| - Name: [[NAME=ddd]] |
| Index: SHN_ABS |
| Binding: STB_GLOBAL |
| Value: 0x0000000000000001 |
| Type: [[TYPE=STT_NOTYPE]] |
| - Name: [[NAME=eee]] |
| Section: .gnu.hash |
| Binding: STB_GLOBAL |
| Type: [[TYPE=STT_NOTYPE]] |
| - Name: [[NAME=bbb]] |
| Section: .hash |
| Binding: STB_WEAK |
| Value: 0x0000000000001001 |
| Type: [[TYPE=STT_NOTYPE]] |
| ProgramHeaders: |
| - Type: PT_LOAD |
| Flags: [ PF_R, PF_X ] |
| FirstSec: .hash |
| LastSec: .dynamic |
| |
| ## Check what we print for unnamed section symbols. |
| # RUN: yaml2obj --docnum=1 -DBITS=64 -DTYPE=STT_SECTION -DNAME="''" %s -o %t1-sec-syms.so |
| # RUN: llvm-readelf --hash-symbols %t1-sec-syms.so 2>&1 | \ |
| # RUN: FileCheck %s -DFILE=%t1-sec-syms.so --check-prefix=UNNAMED-SEC-SYMS |
| |
| # UNNAMED-SEC-SYMS: Symbol table of .hash for image: |
| # UNNAMED-SEC-SYMS-NEXT: Num {{.*}} Ndx Name |
| # UNNAMED-SEC-SYMS-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF) |
| # UNNAMED-SEC-SYMS-NEXT: 1 {{.*}} UND <?> |
| # UNNAMED-SEC-SYMS-NEXT: 5 {{.*}} 1 .hash |
| # UNNAMED-SEC-SYMS-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS) |
| # UNNAMED-SEC-SYMS-NEXT: 3 {{.*}} ABS <?> |
| # UNNAMED-SEC-SYMS-NEXT: 2 {{.*}} 1 .hash |
| # UNNAMED-SEC-SYMS-NEXT: 4 {{.*}} 2 .gnu.hash |
| # UNNAMED-SEC-SYMS-EMPTY: |
| # UNNAMED-SEC-SYMS: Symbol table of .gnu.hash for image: |
| # UNNAMED-SEC-SYMS-NEXT: Num {{.*}} Ndx Name |
| # UNNAMED-SEC-SYMS-NEXT: 2 {{.*}} 1 .hash |
| # UNNAMED-SEC-SYMS-NEXT: 3 {{.*}} ABS <?> |
| # UNNAMED-SEC-SYMS-NEXT: 4 {{.*}} 2 .gnu.hash |
| # UNNAMED-SEC-SYMS-NEXT: 5 {{.*}} 1 .hash |
| |
| ## 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 |
| 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 ] |
| FirstSec: .hash |
| LastSec: .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 |
| 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 ] |
| FirstSec: .gnu.hash |
| LastSec: .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 |
| 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 |
| FirstSec: .dynstr |
| LastSec: .text.foo |
| - Type: PT_DYNAMIC |
| Flags: [ PF_R ] |
| VAddr: 0x1000 |
| FirstSec: .dynamic |
| LastSec: .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 | \ |
| # RUN: FileCheck %s -DFILE=%t5.so --check-prefix=BROKEN --implicit-check-not=warning: |
| |
| # 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 |
| # BROKEN-NEXT: 1 1: 00000000 0 NOTYPE LOCAL DEFAULT UND aaa |
| # BROKEN-NOT: {{.}} |
| |
| --- !ELF |
| FileHeader: |
| Class: ELFCLASS32 |
| Data: ELFDATA2LSB |
| Type: ET_DYN |
| Sections: |
| - Name: .hash |
| Type: SHT_HASH |
| Link: .dynsym |
| Bucket: [ 1, 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 |
| ProgramHeaders: |
| - Type: PT_LOAD |
| FirstSec: .hash |
| LastSec: .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 |
| 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 |
| FirstSec: .hash |
| LastSec: .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 |
| # 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 |
| # 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 -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: 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 |
| # 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 -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 |
| Sections: |
| - Name: .hash |
| Type: SHT_HASH |
| Flags: [ SHF_ALLOC ] |
| Bucket: [ 0 ] |
| NBucket: [[NBUCKET=1]] |
| Chain: [ 0 ] |
| NChain: [[NCHAIN=1]] |
| - 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 |
| FirstSec: .hash |
| LastSec: .dynamic |
| |
| ## Check we report a proper warning when a GNU hash table goes past the end of the file. |
| |
| ## Case A: the 'maskwords' field is set so that the table goes past the end of the file. |
| # RUN: yaml2obj --docnum=8 -D MASKWORDS=4294967295 %s -o %t.err.maskwords |
| # RUN: llvm-readelf --hash-symbols %t.err.maskwords 2>&1 | \ |
| # RUN: FileCheck %s -DFILE=%t.err.maskwords --check-prefix=ERR4 |
| |
| # ERR4: Symbol table of .gnu.hash for image: |
| # ERR4-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # ERR4-NEXT: warning: '[[FILE]]': unable to dump the SHT_GNU_HASH section at 0x78: it goes past the end of the file |
| |
| ## Case B: the 'nbuckets' field is set so that the table goes past the end of the file. |
| # RUN: yaml2obj --docnum=8 -D NBUCKETS=4294967295 %s -o %t.err.nbuckets |
| # RUN: llvm-readelf --hash-symbols %t.err.nbuckets 2>&1 | \ |
| # RUN: FileCheck %s -DFILE=%t.err.nbuckets --check-prefix=ERR4 |
| |
| --- !ELF |
| FileHeader: |
| Class: ELFCLASS64 |
| Data: ELFDATA2LSB |
| Type: ET_DYN |
| Sections: |
| - Name: .gnu.hash |
| Type: SHT_GNU_HASH |
| Flags: [ SHF_ALLOC ] |
| Header: |
| SymNdx: 0x1 |
| Shift2: 0x2 |
| ## The number of words in the Bloom filter. The value of 2 is no-op. |
| MaskWords: [[MASKWORDS=2]] |
| ## The number of hash buckets. The value of 3 is no-op. |
| NBuckets: [[NBUCKETS=3]] |
| BloomFilter: [0x3, 0x4] |
| HashBuckets: [0x5, 0x6, 0x7] |
| HashValues: [0x8, 0x9, 0xA, 0xB] |
| - Name: .dynamic |
| Type: SHT_DYNAMIC |
| Flags: [ SHF_ALLOC ] |
| Link: .dynstr |
| Entries: |
| - Tag: DT_GNU_HASH |
| Value: 0x0 |
| - Tag: DT_NULL |
| Value: 0x0 |
| DynamicSymbols: |
| - Name: aaa |
| Binding: STB_GLOBAL |
| - Name: bbb |
| Binding: STB_GLOBAL |
| - Name: ccc |
| Binding: STB_GLOBAL |
| - Name: ddd |
| Binding: STB_GLOBAL |
| ProgramHeaders: |
| - Type: PT_LOAD |
| Flags: [ PF_R, PF_X ] |
| FirstSec: .gnu.hash |
| LastSec: .dynamic |
| |
| ## Check the behavior when the dynamic symbol table is empty or not found. |
| |
| ## Case A.1: Check we report a warning when the dynamic symbol table is empty and we attempt to print hash symbols |
| ## from the .hash table. The number of symbols in the dynamic symbol table can be calculated from its size |
| ## or derived from the Chain vector of the .hash table. Make both ways to return a zero to do the check. |
| # RUN: yaml2obj --docnum=9 %s -o %t9.1.so |
| # RUN: llvm-readelf --hash-symbols %t9.1.so 2>&1 | FileCheck %s -DFILE=%t9.1.so --check-prefix=DYNSYM-EMPTY-HASH |
| |
| # DYNSYM-EMPTY-HASH: Symbol table of .hash for image: |
| # DYNSYM-EMPTY-HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # DYNSYM-EMPTY-HASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .hash table: the dynamic symbol table is empty |
| # DYNSYM-EMPTY-HASH-NOT: {{.}} |
| |
| --- !ELF |
| FileHeader: |
| Class: ELFCLASS32 |
| Data: ELFDATA2LSB |
| Type: ET_DYN |
| Sections: |
| - Name: .hash |
| Type: SHT_HASH |
| Flags: [ SHF_ALLOC ] |
| Bucket: [ 0 ] |
| Chain: [ ] |
| - Name: .dynamic |
| Type: SHT_DYNAMIC |
| Flags: [ SHF_ALLOC ] |
| Entries: |
| - Tag: DT_HASH |
| Value: 0x0 |
| - Tag: DT_STRTAB |
| ## PT_LOAD p_offset == .hash offset == 0x54. |
| ## 0x54 + 0x2c == 0x80 == .dynstr offset. |
| Value: 0x2c |
| - Tag: DT_STRSZ |
| Value: 0x1 |
| - Tag: DT_NULL |
| Value: 0x0 |
| - Name: .dynstr |
| Type: SHT_STRTAB |
| Flags: [ SHF_ALLOC ] |
| - Name: .dynsym |
| Type: [[DYNSYMTYPE=SHT_DYNSYM]] |
| Flags: [ SHF_ALLOC ] |
| Size: 0 |
| ProgramHeaders: |
| - Type: PT_LOAD |
| Flags: [ PF_R, PF_X ] |
| FirstSec: .hash |
| LastSec: .dynstr |
| |
| ## Case A.2: similar to A.1, but now check that we report a warning when the dynamic symbol table was not found. |
| ## To do that, set the type of the .dynsym to SHT_PROGBITS to hide it. |
| # RUN: yaml2obj --docnum=9 -DDYNSYMTYPE=SHT_PROGBITS %s -o %t9.2.so |
| # RUN: llvm-readelf --hash-symbols %t9.2.so 2>&1 | FileCheck %s -DFILE=%t9.2.so --check-prefix=DYNSYM-NOTFOUND-HASH |
| |
| # DYNSYM-NOTFOUND-HASH: Symbol table of .hash for image: |
| # DYNSYM-NOTFOUND-HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # DYNSYM-NOTFOUND-HASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .hash table: the dynamic symbol table was not found |
| # DYNSYM-NOTFOUND-HASH-NOT: {{.}} |
| |
| ## Case B.1: Check we report a warning when the dynamic symbol table is empty and we attempt to print |
| ## hash symbols from the .gnu.hash table. |
| # RUN: yaml2obj --docnum=10 %s -o %t10.1.so |
| # RUN: llvm-readelf --hash-symbols %t10.1.so 2>&1 | FileCheck %s -DFILE=%t10.1.so --check-prefix=DYNSYM-EMPTY-GNUHASH |
| |
| # DYNSYM-EMPTY-GNUHASH: Symbol table of .gnu.hash for image: |
| # DYNSYM-EMPTY-GNUHASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # DYNSYM-EMPTY-GNUHASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .gnu.hash table: the dynamic symbol table is empty |
| # DYNSYM-EMPTY-GNUHASH-NOT: {{.}} |
| |
| ## Case B.2: similar to B.1, but now check that we report a warning when the dynamic symbol table was not found. |
| ## To do that, set the type of the .dynsym to SHT_PROGBITS to hide it. |
| # RUN: yaml2obj --docnum=10 -DDYNSYMTYPE=SHT_PROGBITS %s -o %t10.2.so |
| # RUN: llvm-readelf --hash-symbols %t10.2.so 2>&1 | FileCheck %s -DFILE=%t10.2.so --check-prefix=DYNSYM-NOTFOUND-GNUHASH |
| |
| # DYNSYM-NOTFOUND-GNUHASH: Symbol table of .gnu.hash for image: |
| # DYNSYM-NOTFOUND-GNUHASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # DYNSYM-NOTFOUND-GNUHASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .gnu.hash table: the dynamic symbol table was not found |
| # DYNSYM-NOTFOUND-GNUHASH-NOT: {{.}} |
| |
| --- !ELF |
| FileHeader: |
| Class: ELFCLASS32 |
| Data: ELFDATA2LSB |
| Type: ET_DYN |
| Sections: |
| - Name: .gnu.hash |
| Type: SHT_GNU_HASH |
| Flags: [ SHF_ALLOC ] |
| Header: |
| SymNdx: 0x0 |
| Shift2: 0x0 |
| BloomFilter: [ 0x0 ] |
| HashBuckets: [ 0x1 ] |
| HashValues: [ 0x0 ] |
| - Name: .dynamic |
| Type: SHT_DYNAMIC |
| Flags: [ SHF_ALLOC ] |
| Entries: |
| - Tag: DT_GNU_HASH |
| Value: 0x0 |
| - Tag: DT_STRTAB |
| ## PT_LOAD p_offset == .hash offset == 0x54. |
| ## 0x54 + 0x3c == 0x80 == .dynstr offset. |
| Value: 0x3c |
| - Tag: DT_STRSZ |
| Value: 0x1 |
| - Tag: DT_NULL |
| Value: 0x0 |
| - Name: .dynstr |
| Type: SHT_STRTAB |
| - Name: .dynsym |
| Type: [[DYNSYMTYPE=SHT_DYNSYM]] |
| Flags: [ SHF_ALLOC ] |
| Size: 0 |
| ProgramHeaders: |
| - Type: PT_LOAD |
| Flags: [ PF_R, PF_X ] |
| FirstSec: .gnu.hash |
| LastSec: .dynstr |
| |
| ## In this case we have a broken value in the hash buckets array. Normally it contains an |
| ## index into the dynamic symbol table and also is used to get a hash value from the hash values array. |
| ## llvm-readelf attempts to read a symbol that is past the end of the dynamic symbol table. |
| |
| # RUN: yaml2obj --docnum=11 -DVALUE=0x2 %s -o %t11.past.dynsym.so |
| # RUN: llvm-readelf --hash-symbols %t11.past.dynsym.so 2>&1 | \ |
| # RUN: FileCheck %s -DFILE=%t11.past.dynsym.so --check-prefix=BUCKET-PAST-DYNSYM |
| |
| # BUCKET-PAST-DYNSYM: Symbol table of .gnu.hash for image: |
| # BUCKET-PAST-DYNSYM-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # 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) |
| # BUCKET-PAST-DYNSYM-NEXT: 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo |
| # BUCKET-PAST-DYNSYM-NOT: {{.}} |
| |
| --- !ELF |
| FileHeader: |
| Class: ELFCLASS64 |
| Data: ELFDATA2LSB |
| Type: ET_DYN |
| Sections: |
| - Name: .gnu.hash |
| Type: SHT_GNU_HASH |
| Flags: [ SHF_ALLOC ] |
| Link: .dynsym |
| Header: |
| SymNdx: [[SYMNDX=0x0]] |
| Shift2: 0x0 |
| BloomFilter: [ 0x0 ] |
| HashBuckets: [ 0x0, [[VALUE]], 0x1 ] |
| HashValues: [ 0x0 ] |
| - Name: .dynamic |
| Type: SHT_DYNAMIC |
| Flags: [ SHF_ALLOC ] |
| Link: .dynstr |
| Entries: |
| - Tag: DT_GNU_HASH |
| Value: 0x0 |
| - Tag: DT_NULL |
| Value: 0x0 |
| DynamicSymbols: |
| - Name: foo |
| Binding: STB_GLOBAL |
| ProgramHeaders: |
| - Type: PT_LOAD |
| Flags: [ PF_R, PF_X ] |
| FirstSec: .gnu.hash |
| LastSec: .dynamic |
| |
| ## In this case we are unable to read a hash value for a symbol with |
| ## an index that is less than the index of the first hashed symbol. |
| |
| # RUN: yaml2obj --docnum=11 -DSYMNDX=0x2 -DVALUE=0x1 %s -o %t11.first.hashed.so |
| # RUN: llvm-readelf --hash-symbols %t11.first.hashed.so 2>&1 | \ |
| # RUN: FileCheck %s -DFILE=%t11.first.hashed.so --check-prefix=FIRST-HASHED |
| |
| # FIRST-HASHED: Symbol table of .gnu.hash for image: |
| # FIRST-HASHED-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # 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) |
| # FIRST-HASHED-NEXT: 1 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo |
| # 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) |
| # FIRST-HASHED-NEXT: 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo |
| # FIRST-HASHED-NOT: {{.}} |
| |
| ## In this case one of the chain values doesn't end with a stopper bit and llvm-readelf attempts to read |
| ## a dynamic symbol with an index that is equal to the number of dynamic symbols. |
| |
| # RUN: yaml2obj --docnum=11 -DSYMNDX=0x1 -DVALUE=0x1 %s -o %t11.chain.bit.so |
| # RUN: llvm-readelf --hash-symbols %t11.chain.bit.so 2>&1 | \ |
| # RUN: FileCheck %s -DFILE=%t11.chain.bit.so --check-prefix=CHAIN-BIT |
| |
| # CHAIN-BIT: Symbol table of .gnu.hash for image: |
| # CHAIN-BIT-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name |
| # CHAIN-BIT-NEXT: 1 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo |
| # 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) |
| # CHAIN-BIT-NEXT: 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo |
| # CHAIN-BIT-NOT: {{.}} |