## Check how obj2yaml produces SHT_GNU_HASH section descriptions.

## Check that obj2yaml uses "Header", "BloomFilter", "HashBuckets" and "HashValues"
## tags to describe a SHT_GNU_HASH section when it has content of a correct size.

# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: obj2yaml %t1 | FileCheck %s --check-prefix=FIELDS

# FIELDS:      - Name:   .gnu.hash
# FIELDS-NEXT:     Type:   SHT_GNU_HASH
# FIELDS-NEXT:     Flags:  [ SHF_ALLOC ]
# FIELDS-NEXT:     Header:
# FIELDS-NEXT:       SymNdx: 0x1
# FIELDS-NEXT:       Shift2: 0x2
# FIELDS-NEXT:     BloomFilter: [ 0x3, 0x4 ]
# FIELDS-NEXT:     HashBuckets: [ 0x5, 0x6, 0x7 ]
# FIELDS-NEXT:     HashValues:  [ 0x8, 0x9, 0xA, 0xB ]

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH
    Flags: [ SHF_ALLOC ]
    Header:
      SymNdx: 0x1
      Shift2: 0x2
    BloomFilter: [0x3, 0x4]
    HashBuckets: [0x5, 0x6, 0x7]
    HashValues:  [0x8, 0x9, 0xA, 0xB]

## Check how we handle broken cases.

# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: obj2yaml %t2 | FileCheck %s --check-prefix=INVALID

# INVALID:      - Name:        .gnu.hash.tooshort
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Flags:       [ SHF_ALLOC ]
# INVALID-NEXT:   Content:     112233445566778899AABBCCDDEEFF
# INVALID-NEXT: - Name:        .gnu.hash.empty
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Flags:       [ SHF_ALLOC ]
# INVALID-NEXT:   Address:     0xF
# INVALID-NEXT:   Header:
# INVALID-NEXT:     SymNdx:      0x0
# INVALID-NEXT:     Shift2:      0x0
# INVALID-NEXT:   BloomFilter: [ ]
# INVALID-NEXT:   HashBuckets: [ ]
# INVALID-NEXT:   HashValues:  [ ]
# INVALID-NEXT: - Name:        .gnu.hash.broken.maskwords
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Content:     '00000000000000000100000000000000'
# INVALID-NEXT: - Name:        .gnu.hash.broken.nbuckets.a
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Content:     '01000000000000000000000000000000'
# INVALID-NEXT: - Name:        .gnu.hash.broken.nbuckets.b
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Content:     FFFFFFFF000000000100000000000000{{$}}
# INVALID-NEXT: - Name:        .gnu.hash.hashvalues.ok
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Header:
# INVALID-NEXT:     SymNdx:      0x0
# INVALID-NEXT:     Shift2:      0x0
# INVALID-NEXT:   BloomFilter: [ ]
# INVALID-NEXT:   HashBuckets: [ ]
# INVALID-NEXT:   HashValues:  [ 0x0 ]
# INVALID-NEXT: - Name:        .gnu.hash.hashvalues.fail
# INVALID-NEXT:   Type:        SHT_GNU_HASH
# INVALID-NEXT:   Content:     '000000000000000000000000000000000000000000'

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
## Case 1: Content is less than 16 bytes.
  - Name:   .gnu.hash.tooshort
    Type:   SHT_GNU_HASH
    Flags:  [ SHF_ALLOC ]
    Content: "112233445566778899AABBCCDDEEFF"
## Case2: Check how we handle a fully empty hash section.
## It is almost technically valid, but uncommon. Modern linkers
## create at least one entry in Bloom filter if they want to disable it.
## Also, the dynamic symbol table has a null entry and having SymNdx = 0
## here is at least strange.
  - Name:  .gnu.hash.empty
    Type:  SHT_GNU_HASH
    Flags: [ SHF_ALLOC ]
    Header:
      SymNdx: 0x0
      Shift2: 0x0
      MaskWords: 0x0
      NBuckets:  0x0
    BloomFilter: []
    HashBuckets: []
    HashValues:  []
## Case 3: MaskWords field is broken: it says that the number of entries
## in the Bloom filter is 1, but the Bloom filter is empty.
  - Name:  .gnu.hash.broken.maskwords
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0
      Shift2: 0x0
      MaskWords: 0x1
      NBuckets:  0x0
    BloomFilter: []
    HashBuckets: []
    HashValues:  []
## Case 4(a): NBuckets field is broken, it says that the number of entries
## in the hash buckets is 1, but it is empty.
  - Name:  .gnu.hash.broken.nbuckets.a
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0
      Shift2: 0x0
      MaskWords: 0x0
      NBuckets:  0x1
    BloomFilter: []
    HashBuckets: []
    HashValues:  []
## Case 4(b): NBuckets = 0xFFFFFFFF is incorrect. The result will cause 32-bit
## unsigned overflows if we keep intermediate expressions uint32_t.
  - Name:  .gnu.hash.broken.nbuckets.b
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0
      Shift2: 0x0
      MaskWords: 0x1
      NBuckets:  0xFFFFFFFF
    BloomFilter: []
    HashBuckets: []
    HashValues:  []
## Case 5: Check that we use the various properties to dump the data when it
## has a size that is a multiple of 4, but fallback to dumping the whole section
## using the "Content" property otherwise.
  - Name:  .gnu.hash.hashvalues.ok
    Type:  SHT_GNU_HASH
    Content: "0000000000000000000000000000000000000000"
  - Name:  .gnu.hash.hashvalues.fail
    Type:  SHT_GNU_HASH
    Content: "000000000000000000000000000000000000000000"
