1## Check how the GNU Hash section is dumped with --gnu-hash-table. 2 3# RUN: yaml2obj --docnum=1 -DBITS=64 %s -o %t.x64 4# RUN: yaml2obj --docnum=1 -DBITS=32 %s -o %t.x32 5 6# RUN: llvm-readobj --gnu-hash-table %t.x64 | FileCheck %s 7# RUN: llvm-readelf --gnu-hash-table %t.x64 | FileCheck %s 8 9# RUN: llvm-readobj --gnu-hash-table %t.x32 | FileCheck %s 10# RUN: llvm-readelf --gnu-hash-table %t.x32 | FileCheck %s 11 12# CHECK: GnuHashTable { 13# CHECK-NEXT: Num Buckets: 3 14# CHECK-NEXT: First Hashed Symbol Index: 1 15# CHECK-NEXT: Num Mask Words: 2 16# CHECK-NEXT: Shift Count: 2 17# CHECK-NEXT: Bloom Filter: [0x3, 0x4] 18# CHECK-NEXT: Buckets: [5, 6, 7] 19# CHECK-NEXT: Values: [0x8, 0x9, 0xA, 0xB] 20# CHECK-NEXT: } 21 22--- !ELF 23FileHeader: 24 Class: ELFCLASS[[BITS]] 25 Data: ELFDATA2LSB 26 Type: ET_DYN 27Sections: 28 - Name: .gnu.hash 29 Type: SHT_GNU_HASH 30 Flags: [ SHF_ALLOC ] 31 Header: 32 SymNdx: 0x1 33 Shift2: 0x2 34## The number of words in the Bloom filter. The value of 2 is no-op. 35 MaskWords: [[MASKWORDS=2]] 36## The number of hash buckets. The value of 3 is no-op. 37 NBuckets: [[NBUCKETS=3]] 38 BloomFilter: [0x3, 0x4] 39 HashBuckets: [0x5, 0x6, 0x7] 40 HashValues: [0x8, 0x9, 0xA, 0xB] 41 - Name: .dynamic 42 Type: SHT_DYNAMIC 43 Flags: [ SHF_ALLOC ] 44 Link: .dynstr 45 Entries: 46 - Tag: DT_GNU_HASH 47 Value: 0x0 48 - Tag: DT_NULL 49 Value: 0x0 50DynamicSymbols: 51 - Name: aaa 52 Binding: STB_GLOBAL 53 - Name: bbb 54 Binding: STB_GLOBAL 55 - Name: ccc 56 Binding: STB_GLOBAL 57 - Name: ddd 58 Binding: STB_GLOBAL 59ProgramHeaders: 60 - Type: PT_LOAD 61 Flags: [ PF_R, PF_X ] 62 FirstSec: .gnu.hash 63 LastSec: .dynamic 64 65## Check we report a warning if there is no dynamic symbol section in the object. 66 67# RUN: yaml2obj --docnum=2 %s -o %t.nodynsym 68# RUN: llvm-readobj --gnu-hash-table %t.nodynsym 2>&1 | FileCheck %s -DFILE=%t.nodynsym --check-prefix=NODYNSYM 69# RUN: llvm-readelf --gnu-hash-table %t.nodynsym 2>&1 | FileCheck %s -DFILE=%t.nodynsym --check-prefix=NODYNSYM 70 71# NODYNSYM: GnuHashTable { 72# NODYNSYM-NEXT: Num Buckets: 1 73# NODYNSYM-NEXT: First Hashed Symbol Index: 0 74# NODYNSYM-NEXT: Num Mask Words: 1 75# NODYNSYM-NEXT: Shift Count: 0 76# NODYNSYM-NEXT: Bloom Filter: [0x0] 77# NODYNSYM-NEXT: Buckets: [0] 78# NODYNSYM-NEXT: warning: '[[FILE]]': unable to dump 'Values' for the SHT_GNU_HASH section: no dynamic symbol table found 79# NODYNSYM-NEXT: } 80 81--- !ELF 82FileHeader: 83 Class: ELFCLASS64 84 Data: ELFDATA2LSB 85 Type: ET_DYN 86Sections: 87 - Name: .gnu.hash 88 Type: SHT_GNU_HASH 89 Flags: [ SHF_ALLOC ] 90 Header: 91 SymNdx: 0x0 92 Shift2: 0x0 93 BloomFilter: [ 0x0 ] 94 HashBuckets: [ 0x0 ] 95 HashValues: [ 0x0 ] 96 - Name: .dynamic 97 Type: SHT_DYNAMIC 98 Flags: [ SHF_ALLOC ] 99 Entries: 100 - Tag: DT_GNU_HASH 101 Value: 0x0 102 - Tag: DT_NULL 103 Value: 0x0 104ProgramHeaders: 105 - Type: PT_LOAD 106 Flags: [ PF_R, PF_X ] 107 FirstSec: .gnu.hash 108 LastSec: .dynamic 109 110## Check what we do when the index of the first symbol in the dynamic symbol table 111## included in the hash table is larger than the number of dynamic symbols. 112 113# RUN: yaml2obj --docnum=3 %s -o %t.brokensymndx 114# RUN: llvm-readobj --gnu-hash-table %t.brokensymndx 2>&1 \ 115# RUN: | FileCheck %s -DFILE=%t.brokensymndx --check-prefix=SYMNDX 116# RUN: llvm-readelf --gnu-hash-table %t.brokensymndx 2>&1 \ 117# RUN: | FileCheck %s -DFILE=%t.brokensymndx --check-prefix=SYMNDX 118 119# SYMNDX: GnuHashTable { 120# SYMNDX-NEXT: Num Buckets: 1 121# SYMNDX-NEXT: First Hashed Symbol Index: 2 122# SYMNDX-NEXT: Num Mask Words: 1 123# SYMNDX-NEXT: Shift Count: 0 124# SYMNDX-NEXT: Bloom Filter: [0x1] 125# SYMNDX-NEXT: Buckets: [2] 126# SYMNDX-NEXT: warning: '[[FILE]]': unable to dump '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) 127# SYMNDX-NEXT: } 128 129--- !ELF 130FileHeader: 131 Class: ELFCLASS64 132 Data: ELFDATA2LSB 133 Type: ET_DYN 134Sections: 135 - Name: .gnu.hash 136 Type: SHT_GNU_HASH 137 Flags: [ SHF_ALLOC ] 138 Header: 139 SymNdx: 0x2 140 Shift2: 0x0 141 BloomFilter: [ 0x1 ] 142 HashBuckets: [ 0x2 ] 143 HashValues: [ 0x3 ] 144 - Name: .dynamic 145 Type: SHT_DYNAMIC 146 Flags: [ SHF_ALLOC ] 147 Link: 0 148 Entries: 149 - Tag: DT_GNU_HASH 150 Value: 0x0 151 - Tag: DT_NULL 152 Value: 0x0 153DynamicSymbols: 154 - Name: aaa 155 Binding: STB_GLOBAL 156ProgramHeaders: 157 - Type: PT_LOAD 158 Flags: [ PF_R, PF_X ] 159 FirstSec: .gnu.hash 160 LastSec: .dynamic 161 162## Check we emit a warning when the dynamic symbol table is empty. 163## A valid dynamic symbol table should have at least one symbol: the symbol with index 0. 164 165# RUN: yaml2obj --docnum=4 %s -o %t.emptydynsym 166# RUN: llvm-readobj --gnu-hash-table %t.emptydynsym 2>&1 \ 167# RUN: | FileCheck %s -DFILE=%t.emptydynsym --check-prefix=EMPTY-DYNSYM 168# RUN: llvm-readelf --gnu-hash-table %t.emptydynsym 2>&1 \ 169# RUN: | FileCheck %s -DFILE=%t.emptydynsym --check-prefix=EMPTY-DYNSYM 170 171# EMPTY-DYNSYM: GnuHashTable { 172# EMPTY-DYNSYM-NEXT: Num Buckets: 1 173# EMPTY-DYNSYM-NEXT: First Hashed Symbol Index: 0 174# EMPTY-DYNSYM-NEXT: Num Mask Words: 1 175# EMPTY-DYNSYM-NEXT: Shift Count: 0 176# EMPTY-DYNSYM-NEXT: Bloom Filter: [0x0] 177# EMPTY-DYNSYM-NEXT: Buckets: [0] 178# EMPTY-DYNSYM-NEXT: warning: '[[FILE]]': unable to dump 'Values' for the SHT_GNU_HASH section: the dynamic symbol table is empty 179# EMPTY-DYNSYM-NEXT: } 180 181--- !ELF 182FileHeader: 183 Class: ELFCLASS64 184 Data: ELFDATA2LSB 185 Type: ET_DYN 186Sections: 187 - Name: .gnu.hash 188 Type: SHT_GNU_HASH 189 Flags: [ SHF_ALLOC ] 190 Header: 191 SymNdx: 0x0 192 Shift2: 0x0 193 BloomFilter: [ 0x0 ] 194 HashBuckets: [ 0x0 ] 195 HashValues: [ 0x0 ] 196 - Name: .dynamic 197 Type: SHT_DYNAMIC 198 Flags: [ SHF_ALLOC ] 199 Link: 0 200 Entries: 201 - Tag: DT_GNU_HASH 202 Value: 0x0 203 - Tag: DT_NULL 204 Value: 0x0 205 - Name: .dynsym 206 Type: SHT_DYNSYM 207 Size: 0 208ProgramHeaders: 209 - Type: PT_LOAD 210 Flags: [ PF_R, PF_X ] 211 FirstSec: .gnu.hash 212 LastSec: .dynamic 213 214## Linkers might produce an empty no-op SHT_GNU_HASH section when 215## there are no dynamic symbols or when all dynamic symbols are undefined. 216## Such sections normally have a single zero entry in the bloom 217## filter, a single zero entry in the hash bucket and no values. 218## 219## The index of the first symbol in the dynamic symbol table 220## included in the hash table can be set to the number of dynamic symbols, 221## which is one larger than the index of the last dynamic symbol. 222## For empty tables however, this value is unimportant and can be ignored. 223 224## Case A: set the index of the first symbol in the dynamic symbol table to 225## the number of dynamic symbols. 226# RUN: yaml2obj --docnum=5 -DSYMNDX=0x1 %s -o %t.empty.1 227# RUN: llvm-readobj --gnu-hash-table %t.empty.1 2>&1 \ 228# RUN: | FileCheck %s -DFILE=%t.empty.1 -DSYMNDX=1 --check-prefix=EMPTY --implicit-check-not="warning:" 229# RUN: llvm-readelf --gnu-hash-table %t.empty.1 2>&1 \ 230# RUN: | FileCheck %s -DFILE=%t.empty.1 -DSYMNDX=1 --check-prefix=EMPTY --implicit-check-not="warning:" 231 232## Case B: set the index of the first symbol in the dynamic symbol table to 233## an arbitrary value that is larger than the number of dynamic symbols. 234# RUN: yaml2obj --docnum=5 -DSYMNDX=0x2 %s -o %t.empty.2 235# RUN: llvm-readobj --gnu-hash-table %t.empty.2 2>&1 \ 236# RUN: | FileCheck %s -DFILE=%t.empty.2 -DSYMNDX=2 --check-prefix=EMPTY --implicit-check-not="warning:" 237# RUN: llvm-readelf --gnu-hash-table %t.empty.2 2>&1 \ 238# RUN: | FileCheck %s -DFILE=%t.empty.2 -DSYMNDX=2 --check-prefix=EMPTY --implicit-check-not="warning:" 239 240# EMPTY: GnuHashTable { 241# EMPTY-NEXT: Num Buckets: 1 242# EMPTY-NEXT: First Hashed Symbol Index: [[SYMNDX]] 243# EMPTY-NEXT: Num Mask Words: 1 244# EMPTY-NEXT: Shift Count: 0 245# EMPTY-NEXT: Bloom Filter: [0x0] 246# EMPTY-NEXT: Buckets: [0] 247# EMPTY-NEXT: Values: [] 248# EMPTY-NEXT: } 249 250--- !ELF 251FileHeader: 252 Class: ELFCLASS64 253 Data: ELFDATA2LSB 254 Type: ET_DYN 255Sections: 256 - Name: .gnu.hash 257 Type: SHT_GNU_HASH 258 Flags: [ SHF_ALLOC ] 259 Header: 260 SymNdx: [[SYMNDX]] 261 Shift2: 0x0 262 BloomFilter: [ 0x0 ] 263 HashBuckets: [ 0x0 ] 264 HashValues: [ ] 265 - Name: .dynamic 266 Type: SHT_DYNAMIC 267 Flags: [ SHF_ALLOC ] 268 Link: 0 269 Entries: 270 - Tag: DT_GNU_HASH 271 Value: 0x0 272 - Tag: DT_NULL 273 Value: 0x0 274DynamicSymbols: [] 275ProgramHeaders: 276 - Type: PT_LOAD 277 Flags: [ PF_R, PF_X ] 278 FirstSec: .gnu.hash 279 LastSec: .dynamic 280 281## Check we report a proper warning when a hash table goes past the end of the file. 282 283## Case A: the 'maskwords' field is set so that the table goes past the end of the file. 284# RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_X86_64 -D MASKWORDS=4294967295 %s -o %t.err.maskwords 285# RUN: llvm-readobj --gnu-hash-table %t.err.maskwords 2>&1 | \ 286# RUN: FileCheck %s -DFILE=%t.err.maskwords -DMASKWORDS=4294967295 -DNBUCKETS=3 --check-prefix=ERR 287# RUN: llvm-readelf --gnu-hash-table %t.err.maskwords 2>&1 | \ 288# RUN: FileCheck %s -DFILE=%t.err.maskwords -DMASKWORDS=4294967295 -DNBUCKETS=3 --check-prefix=ERR 289 290## Case B: the 'nbuckets' field is set so that the table goes past the end of the file. 291# RUN: yaml2obj --docnum=1 -DBITS=64 -DMACHINE=EM_X86_64 -D NBUCKETS=4294967295 %s -o %t.err.nbuckets 292# RUN: llvm-readobj --gnu-hash-table %t.err.nbuckets 2>&1 | \ 293# RUN: FileCheck %s -DFILE=%t.err.nbuckets -DMASKWORDS=2 -DNBUCKETS=4294967295 --check-prefix=ERR 294# RUN: llvm-readelf --gnu-hash-table %t.err.nbuckets 2>&1 | \ 295# RUN: FileCheck %s -DFILE=%t.err.nbuckets -DMASKWORDS=2 -DNBUCKETS=4294967295 --check-prefix=ERR 296 297# ERR: GnuHashTable { 298# ERR-NEXT: Num Buckets: [[NBUCKETS]] 299# ERR-NEXT: First Hashed Symbol Index: 1 300# ERR-NEXT: Num Mask Words: [[MASKWORDS]] 301# ERR-NEXT: Shift Count: 2 302# ERR-NEXT: warning: '[[FILE]]': unable to dump the SHT_GNU_HASH section at 0x78: it goes past the end of the file 303# ERR-NEXT: } 304 305## Check we report a single warning about the broken GNU hash table when both 306## --gnu-hash-table and --elf-hash-histogram options are requested. 307# RUN: llvm-readelf --gnu-hash-table --elf-hash-histogram %t.err.nbuckets 2>&1 | \ 308# RUN: FileCheck %s -DFILE=%t.err.nbuckets -DMASKWORDS=2 -DNBUCKETS=4294967295 --check-prefix=ERR --implicit-check-not=warning 309