## 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 %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 # 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: {{.}} --- !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: .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. PT_LOAD's p_offset = 0x1bc. DT_HASH value is 0x0. ## llvm-readelf will read .hash content from p_offset + (p_vaddr - DT_HASH value) = 0x1bc. ## 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. PT_LOAD's p_offset = 0x1bc. DT_GNU_HASH value is 0x2c (size of .hash = 0x2c). ## llvm-readelf will read .gnu.hash content from p_offset + (p_vaddr - DT_GNU_HASH value) = 0x1e8. ## 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 # RUN: yaml2obj --docnum=2 %s -o %t1-64.so # RUN: llvm-readelf --hash-symbols %t1-64.so | FileCheck %s --check-prefix HASH-64 # 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: ELFCLASS64 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: [ 0x00000000, 0x00000002, 0x00000004 ] HashValues: [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ] - Name: .dynamic Type: SHT_DYNAMIC Flags: [ SHF_ALLOC ] Link: .dynstr Entries: - Tag: DT_HASH ## PT_LOAD's p_vaddr is 0x0. PT_LOAD's p_offset = 0x2b8. DT_HASH value is 0x0. ## llvm-readelf will read .hash content from p_offset + (p_vaddr - DT_HASH value) = 0x2b8. ## This matches the file offset of the .hash section. Value: 0x0000000000000000 - Tag: DT_GNU_HASH ## PT_LOAD's p_vaddr is 0x0. PT_LOAD's p_offset = 0x2b8. DT_GNU_HASH value is 0x2c (size of .hash = 0x2c). ## llvm-readelf will read .gnu.hash content from p_offset + (p_vaddr - DT_GNU_HASH value) = 0x2e4. ## 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=3 %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=4 %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=5 %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 PAddr: 0x0 Sections: - Section: .dynsym - Section: .dynstr - Section: .dynamic - Section: .text.foo - Type: PT_DYNAMIC Flags: [ PF_R ] VAddr: 0x1000 PAddr: 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=6 %s -o %t6.so # RUN: llvm-readelf --hash-symbols %t6.so 2>&1 | FileCheck %s -DFILE=%t6.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