brintos

brintos / llvm-project-archived public Read only

0
0
Text · 15.9 KiB · 10f8652 Raw
477 lines · plain
1## Here we test the --elf-hash-histogram command line option.2 3## This test case checks how we built histograms for hash sections.4 5# RUN: yaml2obj --docnum=1 -D BITS=32 %s -o %t1-32.o6# RUN: llvm-readelf --elf-hash-histogram %t1-32.o | FileCheck %s --check-prefix=HIST7 8## Test --histogram and -I aliases.9# RUN: llvm-readelf --histogram %t1-32.o | FileCheck %s --check-prefix=HIST10# RUN: llvm-readelf -I %t1-32.o | FileCheck %s --check-prefix=HIST11 12# RUN: yaml2obj --docnum=1 -D BITS=64 %s -o %t1-64.o13# RUN: llvm-readelf --elf-hash-histogram %t1-64.o | FileCheck %s --check-prefix=HIST14 15## Check that LLVM output has the expected format.16# RUN: llvm-readobj --elf-hash-histogram %t1-32.o | FileCheck %s --check-prefix=LLVM-HIST17# RUN: llvm-readobj --elf-hash-histogram %t1-64.o | FileCheck %s --check-prefix=LLVM-HIST18 19# HIST:      Histogram for bucket list length (total of 3 buckets)20# HIST-NEXT:  Length  Number     % of total  Coverage21# HIST-NEXT:       0  2          ( 66.7%)       0.0%22# HIST-NEXT:       1  0          (  0.0%)       0.0%23# HIST-NEXT:       2  0          (  0.0%)       0.0%24# HIST-NEXT:       3  1          ( 33.3%)     100.0%25# HIST-NEXT: Histogram for `.gnu.hash' bucket list length (total of 3 buckets)26# HIST-NEXT:  Length  Number     % of total  Coverage27# HIST-NEXT:       0  1          ( 33.3%)       0.0%28# HIST-NEXT:       1  1          ( 33.3%)      25.0%29# HIST-NEXT:       2  0          (  0.0%)      25.0%30# HIST-NEXT:       3  1          ( 33.3%)     100.0%31# HIST-NOT:  {{.}}32 33#      LLVM-HIST: HashHistogram {34# LLVM-HIST-NEXT:   TotalBuckets: 335# LLVM-HIST-NEXT:   Chains [36# LLVM-HIST-NEXT:     Chain {37# LLVM-HIST-NEXT:       Length: 038# LLVM-HIST-NEXT:       Count: 239# LLVM-HIST-NEXT:       Percentage:  66.740# LLVM-HIST-NEXT:       Coverage:   0.041# LLVM-HIST-NEXT:     }42# LLVM-HIST-NEXT:     Chain {43# LLVM-HIST-NEXT:       Length: 144# LLVM-HIST-NEXT:       Count: 045# LLVM-HIST-NEXT:       Percentage:   0.046# LLVM-HIST-NEXT:       Coverage:   0.047# LLVM-HIST-NEXT:     }48# LLVM-HIST-NEXT:     Chain {49# LLVM-HIST-NEXT:       Length: 250# LLVM-HIST-NEXT:       Count: 051# LLVM-HIST-NEXT:       Percentage:   0.052# LLVM-HIST-NEXT:       Coverage:   0.053# LLVM-HIST-NEXT:     }54# LLVM-HIST-NEXT:     Chain {55# LLVM-HIST-NEXT:       Length: 356# LLVM-HIST-NEXT:       Count: 157# LLVM-HIST-NEXT:       Percentage:  33.358# LLVM-HIST-NEXT:       Coverage: 100.059# LLVM-HIST-NEXT:     }60# LLVM-HIST-NEXT:   ]61# LLVM-HIST-NEXT: }62# LLVM-HIST-NEXT: GnuHashHistogram {63# LLVM-HIST-NEXT:   TotalBuckets: 364# LLVM-HIST-NEXT:   Buckets [65# LLVM-HIST-NEXT:     Bucket {66# LLVM-HIST-NEXT:       Length: 067# LLVM-HIST-NEXT:       Count: 168# LLVM-HIST-NEXT:       Percentage:  33.369# LLVM-HIST-NEXT:       Coverage:   0.070# LLVM-HIST-NEXT:     }71# LLVM-HIST-NEXT:     Bucket {72# LLVM-HIST-NEXT:       Length: 173# LLVM-HIST-NEXT:       Count: 174# LLVM-HIST-NEXT:       Percentage:  33.375# LLVM-HIST-NEXT:       Coverage:  25.076# LLVM-HIST-NEXT:     }77# LLVM-HIST-NEXT:     Bucket {78# LLVM-HIST-NEXT:       Length: 279# LLVM-HIST-NEXT:       Count: 080# LLVM-HIST-NEXT:       Percentage:   0.081# LLVM-HIST-NEXT:       Coverage:  25.082# LLVM-HIST-NEXT:     }83# LLVM-HIST-NEXT:     Bucket {84# LLVM-HIST-NEXT:       Length: 385# LLVM-HIST-NEXT:       Count: 186# LLVM-HIST-NEXT:       Percentage:  33.387# LLVM-HIST-NEXT:       Coverage: 100.088# LLVM-HIST-NEXT:     }89# LLVM-HIST-NEXT:   ]90# LLVM-HIST-NEXT: }91 92--- !ELF93FileHeader:94  Class: ELFCLASS[[BITS]]95  Data:  ELFDATA2LSB96  Type:  ET_DYN97Sections:98  - Name:   .hash99    Type:   SHT_HASH100    Flags:  [ SHF_ALLOC ]101    Bucket: [ 6, 4, 5 ]102    Chain:  [ 0, 0, 1, 0, 2 ]103  - Name:  .gnu.hash104    Type:  SHT_GNU_HASH105    Flags: [ SHF_ALLOC ]106    Header:107      SymNdx: 0x1108      Shift2: 0x0109    BloomFilter: [ 0x0 ]110    HashBuckets: [ 0x00000001, 0x00000004, 0x00000000 ]111    HashValues:  [ 0x0B887388, 0xECD54542, 0x7C92E3BB, 0x1C5871D9 ]112  - Name:  .dynamic113    Type:  SHT_DYNAMIC114    Flags: [ SHF_WRITE, SHF_ALLOC ]115    Entries:116      - Tag:   DT_HASH117        Value: 0x0118      - Tag:   DT_GNU_HASH119## sizeof(.hash) == 0x28.120        Value: 0x28121      - Tag:   DT_NULL122        Value: 0x0123DynamicSymbols:124  - Name: a125  - Name: b126  - Name: c127  - Name: d128ProgramHeaders:129  - Type:     PT_LOAD130    FirstSec: .hash131    LastSec:  .dynamic132 133## Show that we report a warning for a hash table which contains an entry of134## the bucket array pointing to a cycle.135 136# RUN: yaml2obj --docnum=2 %s -o %t2.o137# RUN: llvm-readelf --elf-hash-histogram 2>&1 %t2.o | \138# RUN:   FileCheck -DFILE=%t2.o %s --check-prefix=BROKEN --implicit-check-not=warning:139 140# BROKEN:       warning: '[[FILE]]': .hash section is invalid: bucket 1: a cycle was detected in the linked chain141# BROKEN:       Histogram for bucket list length (total of 2 buckets)142# BROKEN-NEXT:  Length  Number     % of total  Coverage143# BROKEN-NEXT:       0  0          (  0.0%)       0.0%144# BROKEN-NEXT:       1  2          (100.0%)     100.0%145 146--- !ELF147FileHeader:148  Class: ELFCLASS32149  Data:  ELFDATA2LSB150  Type:  ET_REL151Sections:152  - Name:   .hash153    Type:   SHT_HASH154    Link:   .dynsym155    Bucket: [ 1, 1 ]156    Chain:  [ 0, 1 ]157  - Name:  .dynamic158    Type:  SHT_DYNAMIC159    Flags: [ SHF_ALLOC ]160    Entries:161## llvm-readelf will read the hash table from the file offset162## p_offset + (p_vaddr - DT_HASH) = p_offset + (0 - 0) = p_offset,163## which is the start of PT_LOAD, i.e. the file offset of .hash.164      - Tag:   DT_HASH165        Value: 0x0166      - Tag:   DT_NULL167        Value: 0168DynamicSymbols:169  - Name: foo170ProgramHeaders:171  - Type:     PT_LOAD172    FirstSec: .hash173    LastSec:  .dynamic174 175## Each SHT_HASH section starts with two 32-bit fields: nbucket and nchain.176## Check we report an error when a DT_HASH value points to data that has size less than 8 bytes.177 178# RUN: yaml2obj --docnum=3 %s -o %t3.o179# RUN: llvm-readelf --elf-hash-histogram %t3.o 2>&1 | FileCheck %s --check-prefix=ERR1 -DFILE=%t3.o180 181# ERR1: warning: '[[FILE]]': the hash table at offset 0x2b1 goes past the end of the file (0x2b8){{$}}182 183--- !ELF184FileHeader:185  Class: ELFCLASS64186  Data:  ELFDATA2LSB187  Type:  ET_DYN188Sections:189  - Name:   .hash190    Type:   SHT_HASH191    Flags:  [ SHF_ALLOC ]192    Bucket: [ 0 ]193    Chain:  [ 0 ]194  - Name:  .dynamic195    Type:  SHT_DYNAMIC196    Flags: [ SHF_WRITE, SHF_ALLOC ]197    Entries:198      - Tag:   DT_HASH199        Value: 0x239200      - Tag:   DT_NULL201        Value: 0x0202DynamicSymbols: []203ProgramHeaders:204  - Type:     PT_LOAD205    FileSize: 0x23a206    FirstSec: .hash207    LastSec:  .dynamic208 209## Check we report a warning when the hash table goes past the end of the file.210 211## Case A.1: the hash table ends right before the EOF. We have a broken nbucket212##           field that has a value larger than the number of buckets.213# RUN: yaml2obj --docnum=4 %s -o %t4.1.o -DNBUCKET=0x5d -DNCHAIN=0x1214# RUN: llvm-readelf --elf-hash-histogram %t4.1.o 2>&1 | \215# RUN:   FileCheck %s --implicit-check-not={{.}} --allow-empty216 217## Case A.2: the hash table ends 1 byte past the EOF. We have a broken nbucket218##           field that has a value larger than the number of buckets.219# RUN: yaml2obj --docnum=4 %s -o %t4.2.o -DNBUCKET=0x5e -DNCHAIN=0x1220# RUN: llvm-readelf --elf-hash-histogram %t4.2.o 2>&1 | \221# RUN:   FileCheck %s --check-prefix=ERR2 -DFILE=%t4.2.o --implicit-check-not="warning:"222# ERR2: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 94, nchain = 1{{$}}223 224## Case B.1: the hash table ends right before the EOF. We have a broken nchain225##           field that has a value larger than the number of chains.226# RUN: yaml2obj --docnum=4 %s -o %t4.3.o -DNBUCKET=0x1 -DNCHAIN=0x5d227# RUN: llvm-readelf --elf-hash-histogram %t4.3.o 2>&1 | \228# RUN:   FileCheck %s --check-prefix=ERR3 -DFILE=%t4.3.o --implicit-check-not="warning:"229# ERR3: warning: '[[FILE]]': hash table nchain (93) differs from symbol count derived from SHT_DYNSYM section header (1){{$}}230# ERR3: 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 ignored231 232## Case B.2: the hash table ends 1 byte past the EOF. We have a broken nchain233##           field that has a value larger than the number of chains.234# RUN: yaml2obj --docnum=4 %s -o %t4.4.o -DNBUCKET=0x1 -DNCHAIN=0x5e235# RUN: llvm-readelf --elf-hash-histogram %t4.4.o 2>&1 | \236# RUN:   FileCheck %s --check-prefix=ERR4 -DFILE=%t4.4.o --implicit-check-not="warning:"237# ERR4: warning: '[[FILE]]': hash table nchain (94) differs from symbol count derived from SHT_DYNSYM section header (1){{$}}238# ERR4: warning: '[[FILE]]': the size (0x5e0) of the dynamic symbol table at 0x78, derived from the hash table, goes past the end of the file (0x1d4) and will be ignored239# ERR4: warning: '[[FILE]]': the hash table at offset 0x54 goes past the end of the file (0x1d4), nbucket = 1, nchain = 94{{$}}240 241--- !ELF242FileHeader:243  Class: ELFCLASS32244  Data:  ELFDATA2LSB245  Type:  ET_DYN246Sections:247  - Name:    .hash248    Type:    SHT_HASH249    Flags:   [ SHF_ALLOC ]250    Bucket:  [ 0 ]251    NBucket: [[NBUCKET]]252    Chain:   [ 0 ]253    NChain:  [[NCHAIN]]254  - Name:  .dynamic255    Type:  SHT_DYNAMIC256    Flags: [ SHF_WRITE, SHF_ALLOC ]257    Entries:258      - Tag:   DT_HASH259        Value: 0x0260      - Tag:   DT_NULL261        Value: 0x0262DynamicSymbols: []263ProgramHeaders:264  - Type:     PT_LOAD265    FirstSec: .hash266    LastSec:  .dynamic267 268## Check we dump a histogram for the .gnu.hash table even when the .hash table is skipped.269 270## Case A: the .hash table has no data to build histogram and it is skipped.271# RUN: yaml2obj --docnum=5 %s -o %t5.o272# RUN: llvm-readelf --elf-hash-histogram %t5.o 2>&1 | \273# RUN:   FileCheck %s --check-prefix=GNU-HASH --implicit-check-not="Histogram"274 275## Case B: the .hash table has a broken nbucket field. We report a warning276##         and skip dumping of the .hash table.277# RUN: yaml2obj --docnum=5 -DNBUCKET=0xffffffff %s -o %t6.o278# RUN: llvm-readelf --elf-hash-histogram %t6.o 2>&1 | \279# RUN:   FileCheck %s -DFILE=%t6.o --check-prefixes=WARN,GNU-HASH280 281# WARN:     warning: '[[FILE]]': the hash table at offset 0x78 goes past the end of the file (0x358), nbucket = 4294967295, nchain = 2282# GNU-HASH: Histogram for `.gnu.hash' bucket list length (total of 3 buckets)283 284--- !ELF285FileHeader:286  Class: ELFCLASS64287  Data:  ELFDATA2LSB288  Type:  ET_DYN289Sections:290  - Name:    .hash291    Type:    SHT_HASH292    Flags:   [ SHF_ALLOC ]293    Bucket:  [ 0 ]294## 0x2 is a no-op: it does not change the number of buckets described by the "Bucket" key295    NBucket: [[NBUCKET=0x2]]296    Chain:   [ 0, 0 ]297  - Name:  .gnu.hash298    Type:  SHT_GNU_HASH299    Flags: [ SHF_ALLOC ]300    Header:301      SymNdx: 0x1302      Shift2: 0x0303    BloomFilter: [ 0x0 ]304    HashBuckets: [ 0x00000001, 0x00000004, 0x00000000 ]305    HashValues:  [ 0x0B887388 ]306  - Name:  .dynamic307    Type:  SHT_DYNAMIC308    Flags: [ SHF_WRITE, SHF_ALLOC ]309    Entries:310      - Tag:   DT_HASH311        Value: 0x0312      - Tag:   DT_GNU_HASH313## sizeof(.hash) == 0x14.314        Value: 0x14315      - Tag:   DT_NULL316        Value: 0x0317DynamicSymbols:318  - Name: foo319ProgramHeaders:320  - Type:     PT_LOAD321    FirstSec: .hash322    LastSec:  .dynamic323 324## Check we report a proper warning when the GNU hash table goes past the end of the file.325 326## Case A: the 'maskwords' field is set so that the GNU hash table goes past the end of the file.327# RUN: yaml2obj --docnum=6 -D MASKWORDS=0x80000000 %s -o %t7328# RUN: llvm-readelf --elf-hash-histogram %t7 2>&1 | \329# RUN:   FileCheck %s -DFILE=%t7 --check-prefix=ERR5 --implicit-check-not="Histogram"330 331# ERR5: warning: '[[FILE]]': unable to dump the SHT_GNU_HASH section at 0x78: it goes past the end of the file332 333## Case B: the 'nbuckets' field is set so that the GNU hash table goes past the end of the file.334# RUN: yaml2obj --docnum=6 -D NBUCKETS=0x80000000 %s -o %t8335# RUN: llvm-readelf --elf-hash-histogram %t8 2>&1 | \336# RUN:   FileCheck %s -DFILE=%t8 --check-prefix=ERR5 --implicit-check-not="Histogram"337 338--- !ELF339FileHeader:340  Class: ELFCLASS64341  Data:  ELFDATA2LSB342  Type:  ET_DYN343Sections:344  - Name:  .gnu.hash345    Type:  SHT_GNU_HASH346    Flags: [ SHF_ALLOC ]347    Header:348      SymNdx: 0x0349      Shift2: 0x0350## The number of words in the Bloom filter. The value of 1 is no-op.351      MaskWords: [[MASKWORDS=1]]352## The number of hash buckets. The value of 1 is no-op.353      NBuckets:  [[NBUCKETS=1]]354    BloomFilter: [ 0x0 ]355    HashBuckets: [ 0x0 ]356    HashValues:  [ 0x0 ]357  - Name:  .dynamic358    Type:  SHT_DYNAMIC359    Flags: [ SHF_ALLOC ]360    Link:  .dynstr361    Entries:362      - Tag:   DT_GNU_HASH363        Value: 0x0364      - Tag:   DT_NULL365        Value: 0x0366DynamicSymbols: []367ProgramHeaders:368  - Type:     PT_LOAD369    FirstSec: .gnu.hash370    LastSec:  .dynamic371 372## Linkers might produce an empty no-op SHT_GNU_HASH section when373## there are no dynamic symbols or when all dynamic symbols are undefined.374## Such sections normally have a single zero entry in the bloom375## filter, a single zero entry in the hash bucket and no values.376##377## The index of the first symbol in the dynamic symbol table378## included in the hash table can be set to the number of dynamic symbols,379## which is one larger than the index of the last dynamic symbol.380## For empty tables however, this value is unimportant and can be ignored.381 382## Check the case when a 'symndx' index of the first symbol in the dynamic symbol383## table is larger than the number of dynamic symbols.384 385## Case A: when the buckets array is not empty and has a non-zero value we report a warning.386# RUN: yaml2obj --docnum=7 -DVAL=0x1 %s -o %t9387# RUN: llvm-readelf --elf-hash-histogram %t9 2>&1 | \388# RUN:   FileCheck %s -DFILE=%t9 --check-prefix=ERR6389 390# ERR6: warning: '[[FILE]]': unable to print the GNU hash table histogram: the first hashed symbol index (16) is greater than or equal to the number of dynamic symbols (1)391 392## Case B: we do not report a warning when the buckets array contains only zero values.393# RUN: yaml2obj --docnum=7 -DVAL=0x0 %s -o %t10394# RUN: llvm-readelf --elf-hash-histogram %t10 2>&1 | \395# RUN:   FileCheck %s --allow-empty --implicit-check-not="Histogram"396 397## Case C: we do not report a warning when the buckets array is empty.398# RUN: yaml2obj --docnum=7 -DVAL="" %s -o %t11399# RUN: llvm-readelf --elf-hash-histogram %t11 2>&1 | \400# RUN:   FileCheck %s --allow-empty --implicit-check-not="Histogram"401 402--- !ELF403FileHeader:404  Class: ELFCLASS64405  Data:  ELFDATA2LSB406  Type:  ET_DYN407Sections:408  - Name:  .gnu.hash409    Type:  SHT_GNU_HASH410    Flags: [ SHF_ALLOC ]411    Header:412      SymNdx: 0x10413      Shift2: 0x0414    BloomFilter: [ 0x0 ]415    HashBuckets: [ [[VAL]] ]416    HashValues:  [ 0x0 ]417  - Name:  .dynamic418    Type:  SHT_DYNAMIC419    Flags: [ SHF_ALLOC ]420    Link:  .dynstr421    Entries:422      - Tag:   DT_GNU_HASH423        Value: 0x0424      - Tag:   DT_NULL425        Value: 0x0426DynamicSymbols: []427ProgramHeaders:428  - Type:     PT_LOAD429    FirstSec: .gnu.hash430    LastSec:  .dynamic431 432## Check we report warnings when the dynamic symbol table is absent or empty.433 434## The code locates the dynamic symbol table by the section type. Use SHT_PROGBITS to hide it.435# RUN: yaml2obj --docnum=8 -DTYPE=SHT_PROGBITS %s -o %t12436# RUN: llvm-readelf --elf-hash-histogram %t12 2>&1 | \437# RUN:   FileCheck %s -DFILE=%t12 --check-prefix=ERR7438 439# ERR7: warning: '[[FILE]]': unable to print the GNU hash table histogram: no dynamic symbol table found440 441# RUN: yaml2obj --docnum=8 -DTYPE=SHT_DYNSYM %s -o %t13442# RUN: llvm-readelf --elf-hash-histogram %t13 2>&1 | \443# RUN:   FileCheck %s -DFILE=%t13 --check-prefix=ERR8444 445# ERR8: warning: '[[FILE]]': unable to print the GNU hash table histogram: the dynamic symbol table is empty446 447--- !ELF448FileHeader:449  Class: ELFCLASS64450  Data:  ELFDATA2LSB451  Type:  ET_DYN452Sections:453  - Name:  .gnu.hash454    Type:  SHT_GNU_HASH455    Flags: [ SHF_ALLOC ]456    Header:457      SymNdx: 0x0458      Shift2: 0x0459    BloomFilter: [ 0x0 ]460    HashBuckets: [ 0x0 ]461    HashValues:  [ 0x0 ]462  - Name:  .dynamic463    Type:  SHT_DYNAMIC464    Flags: [ SHF_ALLOC ]465    Entries:466      - Tag:   DT_GNU_HASH467        Value: 0x0468      - Tag:   DT_NULL469        Value: 0x0470  - Name: .dynsym471    Type: [[TYPE]]472    Size: 0473ProgramHeaders:474  - Type:     PT_LOAD475    FirstSec: .gnu.hash476    LastSec:  .gnu.hash477