1## Check llvm-readelf is able to dump the content of hash sections correctly. 2 3## Check the output when both .hash and .gnu.hash sections are present. 4 5# RUN: yaml2obj --docnum=1 -DBITS=32 %s -o %t1-32.so 6# RUN: llvm-readelf --hash-symbols %t1-32.so \ 7# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix HASH-32 8 9# RUN: yaml2obj --docnum=1 -DBITS=64 %s -o %t1-64.so 10# RUN: llvm-readelf --hash-symbols %t1-64.so | FileCheck %s --check-prefix HASH-64 11 12# HASH-32: Symbol table of .hash for image: 13# HASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 14# HASH-32-NEXT: 1 0: 00000000 0 NOTYPE GLOBAL DEFAULT UND ccc 15# HASH-32-NEXT: 5 0: 00001001 0 NOTYPE WEAK DEFAULT 1 bbb 16# HASH-32-NEXT: 3 0: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd 17# HASH-32-NEXT: 2 0: 00001000 0 NOTYPE GLOBAL DEFAULT 1 aaa 18# HASH-32-NEXT: 4 0: 00000000 0 NOTYPE GLOBAL DEFAULT 2 eee 19# HASH-32-EMPTY: 20# HASH-32: Symbol table of .gnu.hash for image: 21# HASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 22# HASH-32-NEXT: 2 1: 00001000 0 NOTYPE GLOBAL DEFAULT 1 aaa 23# HASH-32-NEXT: 3 1: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd 24# HASH-32-NEXT: 4 2: 00000000 0 NOTYPE GLOBAL DEFAULT 2 eee 25# HASH-32-NEXT: 5 2: 00001001 0 NOTYPE WEAK DEFAULT 1 bbb 26# HASH-32-NOT: {{.}} 27 28# HASH-64: Symbol table of .hash for image: 29# HASH-64-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 30# HASH-64-NEXT: 1 0: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND ccc 31# HASH-64-NEXT: 5 0: 0000000000001001 0 NOTYPE WEAK DEFAULT 1 bbb 32# HASH-64-NEXT: 3 0: 0000000000000001 0 NOTYPE GLOBAL DEFAULT ABS ddd 33# HASH-64-NEXT: 2 0: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aaa 34# HASH-64-NEXT: 4 0: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 2 eee 35# HASH-64-EMPTY: 36# HASH-64-NEXT: Symbol table of .gnu.hash for image: 37# HASH-64-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 38# HASH-64-NEXT: 2 1: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 1 aaa 39# HASH-64-NEXT: 3 1: 0000000000000001 0 NOTYPE GLOBAL DEFAULT ABS ddd 40# HASH-64-NEXT: 4 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT 2 eee 41# HASH-64-NEXT: 5 2: 0000000000001001 0 NOTYPE WEAK DEFAULT 1 bbb 42# HASH-64-NOT: {{.}} 43 44--- !ELF 45FileHeader: 46 Class: ELFCLASS[[BITS]] 47 Data: ELFDATA2LSB 48 Type: ET_DYN 49Sections: 50 - Name: .hash 51 Type: SHT_HASH 52 Flags: [ SHF_ALLOC ] 53 Link: .dynsym 54 Bucket: [ 1, 0, 0 ] 55 Chain: [ 0, 5, 4, 2, 0, 3 ] 56 - Name: .gnu.hash 57 Type: SHT_GNU_HASH 58 Flags: [ SHF_ALLOC ] 59 Link: .dynsym 60 Header: 61 SymNdx: 0x2 62 Shift2: 0x0 63 BloomFilter: [ 0x0 ] 64 HashBuckets: [ 0x0, 0x2, 0x4 ] 65 HashValues: [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ] 66 - Name: .dynamic 67 Type: SHT_DYNAMIC 68 Flags: [ SHF_ALLOC ] 69 Link: .dynstr 70 Entries: 71## PT_LOAD's p_vaddr is 0x0. DT_HASH value is 0x0. 72## llvm-readelf will read .hash content from PT_LOAD's p_offset + (DT_HASH value - p_vaddr). 73## This matches the file offset of the .hash section. 74 - Tag: DT_HASH 75 Value: 0x0000000000000000 76 - Tag: DT_GNU_HASH 77## PT_LOAD's p_vaddr is 0x0. DT_GNU_HASH value is 0x2c (size of .hash = 0x2c). 78## llvm-readelf will read .gnu.hash content from PT_LOAD's p_offset + (DT_GNU_HASH value - p_vaddr). 79## This matches the file offset of the .gnu.hash section. 80 Value: 0x000000000000002C 81 - Tag: DT_NULL 82 Value: 0x0000000000000000 83DynamicSymbols: 84 - Name: [[NAME=ccc]] 85 Binding: STB_GLOBAL 86 Type: [[TYPE=STT_NOTYPE]] 87 - Name: [[NAME=aaa]] 88 Section: .hash 89 Binding: STB_GLOBAL 90 Value: 0x0000000000001000 91 Type: [[TYPE=STT_NOTYPE]] 92 - Name: [[NAME=ddd]] 93 Index: SHN_ABS 94 Binding: STB_GLOBAL 95 Value: 0x0000000000000001 96 Type: [[TYPE=STT_NOTYPE]] 97 - Name: [[NAME=eee]] 98 Section: .gnu.hash 99 Binding: STB_GLOBAL 100 Type: [[TYPE=STT_NOTYPE]] 101 - Name: [[NAME=bbb]] 102 Section: .hash 103 Binding: STB_WEAK 104 Value: 0x0000000000001001 105 Type: [[TYPE=STT_NOTYPE]] 106ProgramHeaders: 107 - Type: PT_LOAD 108 Flags: [ PF_R, PF_X ] 109 FirstSec: .hash 110 LastSec: .dynamic 111 112## Check what we print for unnamed section symbols. 113# RUN: yaml2obj --docnum=1 -DBITS=64 -DTYPE=STT_SECTION -DNAME="''" %s -o %t1-sec-syms.so 114# RUN: llvm-readelf --hash-symbols %t1-sec-syms.so 2>&1 | \ 115# RUN: FileCheck %s -DFILE=%t1-sec-syms.so --check-prefix=UNNAMED-SEC-SYMS 116 117# UNNAMED-SEC-SYMS: Symbol table of .hash for image: 118# UNNAMED-SEC-SYMS-NEXT: Num {{.*}} Ndx Name 119# UNNAMED-SEC-SYMS-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF) 120# UNNAMED-SEC-SYMS-NEXT: 1 {{.*}} UND <?> 121# UNNAMED-SEC-SYMS-NEXT: 5 {{.*}} 1 .hash 122# UNNAMED-SEC-SYMS-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS) 123# UNNAMED-SEC-SYMS-NEXT: 3 {{.*}} ABS <?> 124# UNNAMED-SEC-SYMS-NEXT: 2 {{.*}} 1 .hash 125# UNNAMED-SEC-SYMS-NEXT: 4 {{.*}} 2 .gnu.hash 126# UNNAMED-SEC-SYMS-EMPTY: 127# UNNAMED-SEC-SYMS: Symbol table of .gnu.hash for image: 128# UNNAMED-SEC-SYMS-NEXT: Num {{.*}} Ndx Name 129# UNNAMED-SEC-SYMS-NEXT: 2 {{.*}} 1 .hash 130# UNNAMED-SEC-SYMS-NEXT: 3 {{.*}} ABS <?> 131# UNNAMED-SEC-SYMS-NEXT: 4 {{.*}} 2 .gnu.hash 132# UNNAMED-SEC-SYMS-NEXT: 5 {{.*}} 1 .hash 133 134## Check the output when only .hash section is present. 135 136# RUN: yaml2obj --docnum=2 %s -o %t2-32.so 137# RUN: llvm-readelf --hash-symbols %t2-32.so \ 138# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix ONLY-HASH-32 139 140# ONLY-HASH-32: Symbol table of .hash for image: 141# ONLY-HASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 142# ONLY-HASH-32-NEXT: 1 0: 00000000 0 NOTYPE GLOBAL DEFAULT UND ccc 143# ONLY-HASH-32-NEXT: 5 0: 00001001 0 NOTYPE WEAK DEFAULT 1 bbb 144# ONLY-HASH-32-NEXT: 3 0: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd 145# ONLY-HASH-32-NEXT: 2 0: 00001000 0 NOTYPE GLOBAL DEFAULT 1 aaa 146# ONLY-HASH-32-NEXT: 4 0: 00000000 0 NOTYPE GLOBAL DEFAULT 2 eee 147# ONLY-HASH-32-NOT: {{.}} 148 149--- !ELF 150FileHeader: 151 Class: ELFCLASS32 152 Data: ELFDATA2LSB 153 Type: ET_DYN 154Sections: 155 - Name: .hash 156 Type: SHT_HASH 157 Flags: [ SHF_ALLOC ] 158 Link: .dynsym 159 Bucket: [ 1, 0, 0 ] 160 Chain: [ 0, 5, 4, 2, 0, 3 ] 161 - Name: .dynamic 162 Type: SHT_DYNAMIC 163 Flags: [ SHF_ALLOC ] 164 Link: .dynstr 165 Entries: 166 - Tag: DT_HASH 167 Value: 0x0000000000000000 168 - Tag: DT_NULL 169 Value: 0x0000000000000000 170DynamicSymbols: 171 - Name: ccc 172 Binding: STB_GLOBAL 173 - Name: aaa 174 Section: .hash 175 Binding: STB_GLOBAL 176 Value: 0x0000000000001000 177 - Name: ddd 178 Index: SHN_ABS 179 Binding: STB_GLOBAL 180 Value: 0x0000000000000001 181 - Name: eee 182 Section: .dynamic 183 Binding: STB_GLOBAL 184 - Name: bbb 185 Section: .hash 186 Binding: STB_WEAK 187 Value: 0x0000000000001001 188ProgramHeaders: 189 - Type: PT_LOAD 190 Flags: [ PF_R, PF_X ] 191 FirstSec: .hash 192 LastSec: .dynamic 193 194## Check the output when only .gnu.hash section is present. 195 196# RUN: yaml2obj --docnum=3 %s -o %t3-32.so 197# RUN: llvm-readelf --hash-symbols %t3-32.so \ 198# RUN: | FileCheck %s --strict-whitespace --match-full-lines --check-prefix ONLY-GNUHASH-32 199 200# ONLY-GNUHASH-32: Symbol table of .gnu.hash for image: 201# ONLY-GNUHASH-32-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 202# ONLY-GNUHASH-32-NEXT: 2 1: 00001000 0 NOTYPE GLOBAL DEFAULT 2 aaa 203# ONLY-GNUHASH-32-NEXT: 3 1: 00000001 0 NOTYPE GLOBAL DEFAULT ABS ddd 204# ONLY-GNUHASH-32-NEXT: 4 2: 00000000 0 NOTYPE GLOBAL DEFAULT 1 eee 205# ONLY-GNUHASH-32-NEXT: 5 2: 00001001 0 NOTYPE WEAK DEFAULT 2 bbb 206# ONLY-GNUHASH-32-NOT: {{.}} 207 208--- !ELF 209FileHeader: 210 Class: ELFCLASS32 211 Data: ELFDATA2LSB 212 Type: ET_DYN 213Sections: 214 - Name: .gnu.hash 215 Type: SHT_GNU_HASH 216 Flags: [ SHF_ALLOC ] 217 Link: .dynsym 218 Header: 219 SymNdx: 0x2 220 Shift2: 0x0 221 BloomFilter: [ 0x0 ] 222 HashBuckets: [ 0x0, 0x2, 0x4 ] 223 HashValues: [ 0x0B885C68, 0x0B886991, 0x0B886DF4, 0x0B8860CB ] 224 - Name: .dynamic 225 Type: SHT_DYNAMIC 226 Flags: [ SHF_ALLOC ] 227 Link: .dynstr 228 Entries: 229 - Tag: DT_GNU_HASH 230 Value: 0x0000000000000000 231 - Tag: DT_NULL 232 Value: 0x0000000000000000 233DynamicSymbols: 234 - Name: ccc 235 Binding: STB_GLOBAL 236 - Name: aaa 237 Section: .dynamic 238 Binding: STB_GLOBAL 239 Value: 0x0000000000001000 240 - Name: ddd 241 Index: SHN_ABS 242 Binding: STB_GLOBAL 243 Value: 0x0000000000000001 244 - Name: eee 245 Section: .gnu.hash 246 Binding: STB_GLOBAL 247 - Name: bbb 248 Section: .dynamic 249 Binding: STB_WEAK 250 Value: 0x0000000000001001 251ProgramHeaders: 252 - Type: PT_LOAD 253 Flags: [ PF_R, PF_X ] 254 FirstSec: .gnu.hash 255 LastSec: .dynamic 256 257## Show that if there are no hash sections, we do not print anything. 258# RUN: yaml2obj --docnum=4 %s -o %t4.so 259# RUN: llvm-readelf --hash-symbols %t4.so \ 260# RUN: | FileCheck %s --check-prefix NO-HASH --allow-empty 261 262# NO-HASH-NOT: {{.}} 263 264## Check that we can still find the dynamic symbols (i.e. the above test 265## doesn't pass due to a mistake in the dynamic section). 266# RUN: llvm-readelf --dyn-symbols %t4.so | FileCheck %s --check-prefix DYNSYMS 267 268# DYNSYMS: Symbol table '.dynsym' contains 2 entries: 269 270--- !ELF 271FileHeader: 272 Class: ELFCLASS64 273 Data: ELFDATA2LSB 274 Type: ET_DYN 275Sections: 276 - Name: .dynstr 277 Type: SHT_STRTAB 278 Flags: [ SHF_ALLOC ] 279 AddressAlign: 0x100 280 EntSize: 0x1 281 - Name: .dynsym 282 Type: SHT_DYNSYM 283 Flags: [ SHF_ALLOC ] 284 Link: .dynstr 285 Address: 0x100 286 AddressAlign: 0x100 287 EntSize: 0x18 288 - Name: .dynamic 289 Type: SHT_DYNAMIC 290 Flags: [ SHF_ALLOC ] 291 Address: 0x0000000000001000 292 Link: .dynstr 293 AddressAlign: 0x0000000000001000 294 EntSize: 0x0000000000000010 295 Entries: 296 - Tag: DT_STRTAB 297 Value: 0x0000000000000000 298 - Tag: DT_STRSZ 299 Value: 0x0000000000000009 300 - Tag: DT_SYMTAB 301 Value: 0x0000000000000100 302 - Tag: DT_SYMENT 303 Value: 0x0000000000000018 304 - Tag: DT_NULL 305 Value: 0x0000000000000000 306 - Name: .text.foo 307 Type: SHT_PROGBITS 308 Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ] 309 Size: 0x40 310 Address: 0x2000 311 AddressAlign: 0x2000 312DynamicSymbols: 313 - Name: _Z3fooi 314 Binding: STB_GLOBAL 315ProgramHeaders: 316 - Type: PT_LOAD 317 Flags: [ PF_R, PF_X ] 318 VAddr: 0x0 319 FirstSec: .dynstr 320 LastSec: .text.foo 321 - Type: PT_DYNAMIC 322 Flags: [ PF_R ] 323 VAddr: 0x1000 324 FirstSec: .dynamic 325 LastSec: .dynamic 326 327## Show that we report a warning for a hash table which contains an entry of 328## the bucket array pointing to a cycle. 329 330# RUN: yaml2obj --docnum=5 %s -o %t5.so 331# RUN: llvm-readelf --hash-symbols %t5.so 2>&1 | \ 332# RUN: FileCheck %s -DFILE=%t5.so --check-prefix=BROKEN --implicit-check-not=warning: 333 334# BROKEN: Symbol table of .hash for image: 335# BROKEN-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 336# BROKEN-NEXT: 1 0: 00000000 0 NOTYPE LOCAL DEFAULT UND aaa 337# BROKEN: warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain 338# BROKEN-NEXT: 1 1: 00000000 0 NOTYPE LOCAL DEFAULT UND aaa 339# BROKEN-NOT: {{.}} 340 341--- !ELF 342FileHeader: 343 Class: ELFCLASS32 344 Data: ELFDATA2LSB 345 Type: ET_DYN 346Sections: 347 - Name: .hash 348 Type: SHT_HASH 349 Link: .dynsym 350 Bucket: [ 1, 1 ] 351 Chain: [ 1, 1 ] 352 - Name: .dynamic 353 Type: SHT_DYNAMIC 354 Entries: 355## llvm-readelf will read the hash table from the file offset 356## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset, 357## which is the start of PT_LOAD, i.e. the file offset of .hash. 358 - Tag: DT_HASH 359 Value: 0x0 360DynamicSymbols: 361 - Name: aaa 362ProgramHeaders: 363 - Type: PT_LOAD 364 FirstSec: .hash 365 LastSec: .dynamic 366 367## Each SHT_HASH section starts with two 32-bit fields: nbucket and nchain. 368## Check we report an error when a DT_HASH value points to data that has size less than 8 bytes. 369 370# RUN: yaml2obj --docnum=6 %s -o %t6.o 371# RUN: llvm-readelf --hash-symbols %t6.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t6.o 372 373# ERR1: warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8){{$}} 374 375--- !ELF 376FileHeader: 377 Class: ELFCLASS64 378 Data: ELFDATA2LSB 379 Type: ET_DYN 380Sections: 381 - Name: .hash 382 Type: SHT_HASH 383 Flags: [ SHF_ALLOC ] 384 Bucket: [ 0 ] 385 Chain: [ 0 ] 386 - Name: .dynamic 387 Type: SHT_DYNAMIC 388 Flags: [ SHF_WRITE, SHF_ALLOC ] 389 Entries: 390 - Tag: DT_HASH 391 Value: 0x239 392 - Tag: DT_NULL 393 Value: 0x0 394DynamicSymbols: [] 395ProgramHeaders: 396 - Type: PT_LOAD 397 FileSize: 0x23a 398 FirstSec: .hash 399 LastSec: .dynamic 400 401## Check we report a warning when the hash table goes past the end of the file. 402 403## Case A.1: the hash table ends right before the EOF. We have a broken nbucket 404## field that has a value larger than the number of buckets. 405# RUN: yaml2obj --docnum=7 %s -o %t7.1.o -DNBUCKET=0x5d 406# RUN: llvm-readelf --hash-symbols %t7.1.o 2>&1 | FileCheck %s --check-prefix=NOERR1 407# NOERR1: Symbol table of .hash for image: 408# NOERR1-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 409# NOERR1-NEXT-EMPTY: 410 411## Case A.2: the hash table ends 1 byte past the EOF. We have a broken nbucket 412## field that has a value larger than the number of buckets. 413# RUN: yaml2obj --docnum=7 %s -o %t7.2.o -DNBUCKET=0x5e 414# RUN: llvm-readelf --hash-symbols %t7.2.o 2>&1 | FileCheck %s --check-prefix=ERR2 -DFILE=%t7.2.o 415# ERR2: Symbol table of .hash for image: 416# ERR2-NEXT: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 94, nchain = 1{{$}} 417# ERR2-NOT: {{.}} 418 419## Case B.1: the hash table ends right before the EOF. We have a broken nchain 420## field that has a value larger than the number of chains. 421# RUN: yaml2obj --docnum=7 %s -o %t7.3.o -DNCHAIN=0x5d 422# RUN: llvm-readelf --hash-symbols %t7.3.o 2>&1 | \ 423# RUN: FileCheck %s --implicit-check-not="warning:" --check-prefix=NOERR2 -DFILE=%t7.3.o 424# NOERR2: warning: '[[FILE]]': hash table nchain (93) differs from symbol count derived from SHT_DYNSYM section header (1) 425# 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 426# NOERR2: Symbol table of .hash for image: 427# NOERR2-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 428# NOERR2-NOT: {{.}} 429 430## Case B.2: the hash table ends 1 byte past the EOF. We have a broken nchain 431## field that has a value larger than the number of chains. 432# RUN: yaml2obj --docnum=7 %s -o %t7.4.o -DNCHAIN=0x5e 433# RUN: llvm-readelf --hash-symbols %t7.4.o 2>&1 | FileCheck %s --check-prefix=ERR3 -DFILE=%t7.4.o 434# ERR3: Symbol table of .hash for image: 435# ERR3-NEXT: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 1, nchain = 94{{$}} 436# ERR3-NOT: {{.}} 437 438--- !ELF 439FileHeader: 440 Class: ELFCLASS32 441 Data: ELFDATA2LSB 442 Type: ET_DYN 443Sections: 444 - Name: .hash 445 Type: SHT_HASH 446 Flags: [ SHF_ALLOC ] 447 Bucket: [ 0 ] 448 NBucket: [[NBUCKET=1]] 449 Chain: [ 0 ] 450 NChain: [[NCHAIN=1]] 451 - Name: .dynamic 452 Type: SHT_DYNAMIC 453 Flags: [ SHF_WRITE, SHF_ALLOC ] 454 Entries: 455 - Tag: DT_HASH 456 Value: 0x0 457 - Tag: DT_NULL 458 Value: 0x0 459DynamicSymbols: [] 460ProgramHeaders: 461 - Type: PT_LOAD 462 FirstSec: .hash 463 LastSec: .dynamic 464 465## Check we report a proper warning when a GNU hash table goes past the end of the file. 466 467## Case A: the 'maskwords' field is set so that the table goes past the end of the file. 468# RUN: yaml2obj --docnum=8 -D MASKWORDS=4294967295 %s -o %t.err.maskwords 469# RUN: llvm-readelf --hash-symbols %t.err.maskwords 2>&1 | \ 470# RUN: FileCheck %s -DFILE=%t.err.maskwords --check-prefix=ERR4 471 472# ERR4: Symbol table of .gnu.hash for image: 473# ERR4-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 474# ERR4-NEXT: warning: '[[FILE]]': unable to dump the SHT_GNU_HASH section at 0x78: it goes past the end of the file 475 476## Case B: the 'nbuckets' field is set so that the table goes past the end of the file. 477# RUN: yaml2obj --docnum=8 -D NBUCKETS=4294967295 %s -o %t.err.nbuckets 478# RUN: llvm-readelf --hash-symbols %t.err.nbuckets 2>&1 | \ 479# RUN: FileCheck %s -DFILE=%t.err.nbuckets --check-prefix=ERR4 480 481--- !ELF 482FileHeader: 483 Class: ELFCLASS64 484 Data: ELFDATA2LSB 485 Type: ET_DYN 486Sections: 487 - Name: .gnu.hash 488 Type: SHT_GNU_HASH 489 Flags: [ SHF_ALLOC ] 490 Header: 491 SymNdx: 0x1 492 Shift2: 0x2 493## The number of words in the Bloom filter. The value of 2 is no-op. 494 MaskWords: [[MASKWORDS=2]] 495## The number of hash buckets. The value of 3 is no-op. 496 NBuckets: [[NBUCKETS=3]] 497 BloomFilter: [0x3, 0x4] 498 HashBuckets: [0x5, 0x6, 0x7] 499 HashValues: [0x8, 0x9, 0xA, 0xB] 500 - Name: .dynamic 501 Type: SHT_DYNAMIC 502 Flags: [ SHF_ALLOC ] 503 Link: .dynstr 504 Entries: 505 - Tag: DT_GNU_HASH 506 Value: 0x0 507 - Tag: DT_NULL 508 Value: 0x0 509DynamicSymbols: 510 - Name: aaa 511 Binding: STB_GLOBAL 512 - Name: bbb 513 Binding: STB_GLOBAL 514 - Name: ccc 515 Binding: STB_GLOBAL 516 - Name: ddd 517 Binding: STB_GLOBAL 518ProgramHeaders: 519 - Type: PT_LOAD 520 Flags: [ PF_R, PF_X ] 521 FirstSec: .gnu.hash 522 LastSec: .dynamic 523 524## Check the behavior when the dynamic symbol table is empty or not found. 525 526## Case A.1: Check we report a warning when the dynamic symbol table is empty and we attempt to print hash symbols 527## from the .hash table. The number of symbols in the dynamic symbol table can be calculated from its size 528## or derived from the Chain vector of the .hash table. Make both ways to return a zero to do the check. 529# RUN: yaml2obj --docnum=9 %s -o %t9.1.so 530# RUN: llvm-readelf --hash-symbols %t9.1.so 2>&1 | FileCheck %s -DFILE=%t9.1.so --check-prefix=DYNSYM-EMPTY-HASH 531 532# DYNSYM-EMPTY-HASH: Symbol table of .hash for image: 533# DYNSYM-EMPTY-HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 534# DYNSYM-EMPTY-HASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .hash table: the dynamic symbol table is empty 535# DYNSYM-EMPTY-HASH-NOT: {{.}} 536 537--- !ELF 538FileHeader: 539 Class: ELFCLASS32 540 Data: ELFDATA2LSB 541 Type: ET_DYN 542Sections: 543 - Name: .hash 544 Type: SHT_HASH 545 Flags: [ SHF_ALLOC ] 546 Bucket: [ 0 ] 547 Chain: [ ] 548 - Name: .dynamic 549 Type: SHT_DYNAMIC 550 Flags: [ SHF_ALLOC ] 551 Entries: 552 - Tag: DT_HASH 553 Value: 0x0 554 - Tag: DT_STRTAB 555## PT_LOAD p_offset == .hash offset == 0x54. 556## 0x54 + 0x2c == 0x80 == .dynstr offset. 557 Value: 0x2c 558 - Tag: DT_STRSZ 559 Value: 0x1 560 - Tag: DT_NULL 561 Value: 0x0 562 - Name: .dynstr 563 Type: SHT_STRTAB 564 Flags: [ SHF_ALLOC ] 565 - Name: .dynsym 566 Type: [[DYNSYMTYPE=SHT_DYNSYM]] 567 Flags: [ SHF_ALLOC ] 568 Size: 0 569ProgramHeaders: 570 - Type: PT_LOAD 571 Flags: [ PF_R, PF_X ] 572 FirstSec: .hash 573 LastSec: .dynstr 574 575## Case A.2: similar to A.1, but now check that we report a warning when the dynamic symbol table was not found. 576## To do that, set the type of the .dynsym to SHT_PROGBITS to hide it. 577# RUN: yaml2obj --docnum=9 -DDYNSYMTYPE=SHT_PROGBITS %s -o %t9.2.so 578# RUN: llvm-readelf --hash-symbols %t9.2.so 2>&1 | FileCheck %s -DFILE=%t9.2.so --check-prefix=DYNSYM-NOTFOUND-HASH 579 580# DYNSYM-NOTFOUND-HASH: Symbol table of .hash for image: 581# DYNSYM-NOTFOUND-HASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 582# DYNSYM-NOTFOUND-HASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .hash table: the dynamic symbol table was not found 583# DYNSYM-NOTFOUND-HASH-NOT: {{.}} 584 585## Case B.1: Check we report a warning when the dynamic symbol table is empty and we attempt to print 586## hash symbols from the .gnu.hash table. 587# RUN: yaml2obj --docnum=10 %s -o %t10.1.so 588# RUN: llvm-readelf --hash-symbols %t10.1.so 2>&1 | FileCheck %s -DFILE=%t10.1.so --check-prefix=DYNSYM-EMPTY-GNUHASH 589 590# DYNSYM-EMPTY-GNUHASH: Symbol table of .gnu.hash for image: 591# DYNSYM-EMPTY-GNUHASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 592# DYNSYM-EMPTY-GNUHASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .gnu.hash table: the dynamic symbol table is empty 593# DYNSYM-EMPTY-GNUHASH-NOT: {{.}} 594 595## Case B.2: similar to B.1, but now check that we report a warning when the dynamic symbol table was not found. 596## To do that, set the type of the .dynsym to SHT_PROGBITS to hide it. 597# RUN: yaml2obj --docnum=10 -DDYNSYMTYPE=SHT_PROGBITS %s -o %t10.2.so 598# RUN: llvm-readelf --hash-symbols %t10.2.so 2>&1 | FileCheck %s -DFILE=%t10.2.so --check-prefix=DYNSYM-NOTFOUND-GNUHASH 599 600# DYNSYM-NOTFOUND-GNUHASH: Symbol table of .gnu.hash for image: 601# DYNSYM-NOTFOUND-GNUHASH-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 602# DYNSYM-NOTFOUND-GNUHASH-NEXT: warning: '[[FILE]]': unable to print symbols for the .gnu.hash table: the dynamic symbol table was not found 603# DYNSYM-NOTFOUND-GNUHASH-NOT: {{.}} 604 605--- !ELF 606FileHeader: 607 Class: ELFCLASS32 608 Data: ELFDATA2LSB 609 Type: ET_DYN 610Sections: 611 - Name: .gnu.hash 612 Type: SHT_GNU_HASH 613 Flags: [ SHF_ALLOC ] 614 Header: 615 SymNdx: 0x0 616 Shift2: 0x0 617 BloomFilter: [ 0x0 ] 618 HashBuckets: [ 0x1 ] 619 HashValues: [ 0x0 ] 620 - Name: .dynamic 621 Type: SHT_DYNAMIC 622 Flags: [ SHF_ALLOC ] 623 Entries: 624 - Tag: DT_GNU_HASH 625 Value: 0x0 626 - Tag: DT_STRTAB 627## PT_LOAD p_offset == .hash offset == 0x54. 628## 0x54 + 0x3c == 0x80 == .dynstr offset. 629 Value: 0x3c 630 - Tag: DT_STRSZ 631 Value: 0x1 632 - Tag: DT_NULL 633 Value: 0x0 634 - Name: .dynstr 635 Type: SHT_STRTAB 636 - Name: .dynsym 637 Type: [[DYNSYMTYPE=SHT_DYNSYM]] 638 Flags: [ SHF_ALLOC ] 639 Size: 0 640ProgramHeaders: 641 - Type: PT_LOAD 642 Flags: [ PF_R, PF_X ] 643 FirstSec: .gnu.hash 644 LastSec: .dynstr 645 646## In this case we have a broken value in the hash buckets array. Normally it contains an 647## index into the dynamic symbol table and also is used to get a hash value from the hash values array. 648## llvm-readelf attempts to read a symbol that is past the end of the dynamic symbol table. 649 650# RUN: yaml2obj --docnum=11 -DVALUE=0x2 %s -o %t11.past.dynsym.so 651# RUN: llvm-readelf --hash-symbols %t11.past.dynsym.so 2>&1 | \ 652# RUN: FileCheck %s -DFILE=%t11.past.dynsym.so --check-prefix=BUCKET-PAST-DYNSYM 653 654# BUCKET-PAST-DYNSYM: Symbol table of .gnu.hash for image: 655# BUCKET-PAST-DYNSYM-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 656# 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) 657# BUCKET-PAST-DYNSYM-NEXT: 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo 658# BUCKET-PAST-DYNSYM-NOT: {{.}} 659 660--- !ELF 661FileHeader: 662 Class: ELFCLASS64 663 Data: ELFDATA2LSB 664 Type: ET_DYN 665Sections: 666 - Name: .gnu.hash 667 Type: SHT_GNU_HASH 668 Flags: [ SHF_ALLOC ] 669 Link: .dynsym 670 Header: 671 SymNdx: [[SYMNDX=0x0]] 672 Shift2: 0x0 673 BloomFilter: [ 0x0 ] 674 HashBuckets: [ 0x0, [[VALUE]], 0x1 ] 675 HashValues: [ 0x0 ] 676 - Name: .dynamic 677 Type: SHT_DYNAMIC 678 Flags: [ SHF_ALLOC ] 679 Link: .dynstr 680 Entries: 681 - Tag: DT_GNU_HASH 682 Value: 0x0 683 - Tag: DT_NULL 684 Value: 0x0 685DynamicSymbols: 686 - Name: foo 687 Binding: STB_GLOBAL 688ProgramHeaders: 689 - Type: PT_LOAD 690 Flags: [ PF_R, PF_X ] 691 FirstSec: .gnu.hash 692 LastSec: .dynamic 693 694## In this case we are unable to read a hash value for a symbol with 695## an index that is less than the index of the first hashed symbol. 696 697# RUN: yaml2obj --docnum=11 -DSYMNDX=0x2 -DVALUE=0x1 %s -o %t11.first.hashed.so 698# RUN: llvm-readelf --hash-symbols %t11.first.hashed.so 2>&1 | \ 699# RUN: FileCheck %s -DFILE=%t11.first.hashed.so --check-prefix=FIRST-HASHED 700 701# FIRST-HASHED: Symbol table of .gnu.hash for image: 702# FIRST-HASHED-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 703# 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) 704# FIRST-HASHED-NEXT: 1 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo 705# 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) 706# FIRST-HASHED-NEXT: 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo 707# FIRST-HASHED-NOT: {{.}} 708 709## In this case one of the chain values doesn't end with a stopper bit and llvm-readelf attempts to read 710## a dynamic symbol with an index that is equal to the number of dynamic symbols. 711 712# RUN: yaml2obj --docnum=11 -DSYMNDX=0x1 -DVALUE=0x1 %s -o %t11.chain.bit.so 713# RUN: llvm-readelf --hash-symbols %t11.chain.bit.so 2>&1 | \ 714# RUN: FileCheck %s -DFILE=%t11.chain.bit.so --check-prefix=CHAIN-BIT 715 716# CHAIN-BIT: Symbol table of .gnu.hash for image: 717# CHAIN-BIT-NEXT: Num Buc: Value Size Type Bind Vis Ndx Name 718# CHAIN-BIT-NEXT: 1 1: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo 719# 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) 720# CHAIN-BIT-NEXT: 1 2: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND foo 721# CHAIN-BIT-NOT: {{.}} 722