## Check how yaml2obj produces SHT_GNU_HASH sections.

## Check we can describe a SHT_GNU_HASH section using the "Content" tag.
## Check we set sh_link to index of the .dynsym by default.

# RUN: yaml2obj --docnum=1 %s -o %t1
# RUN: llvm-readobj --sections --section-data %t1 | FileCheck %s --check-prefix=CONTENT

# CONTENT:      Name: .gnu.hash
# CONTENT-NEXT: Type: SHT_GNU_HASH
# CONTENT-NEXT: Flags [
# CONTENT-NEXT: ]
# CONTENT-NEXT: Address: 0x0
# CONTENT-NEXT: Offset: 0x40
# CONTENT-NEXT: Size: 3
# CONTENT-NEXT: Link: 4
# CONTENT-NEXT: Info: 0
# CONTENT-NEXT: AddressAlignment: 0
# CONTENT-NEXT: EntrySize: 0
# CONTENT-NEXT: SectionData (
# CONTENT-NEXT:   0000: 001122 |
# CONTENT-NEXT: )

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH
    Content: "001122"
## Used to trigger .dynsym creation.
DynamicSymbols: []

## Check we can use "Header", "BloomFilter", "HashBuckets" and "HashValues" keys to describe
## the hash section. Check we can set sh_link to any arbitrary value. Check both ELFCLASS32 and 64 bit output.

# RUN: yaml2obj --docnum=2 %s -o %t2
# RUN: yaml2obj --docnum=3 %s -o %t3
# RUN: llvm-readobj --sections --section-data %t2 | FileCheck %s --check-prefix=CONTENT32
# RUN: llvm-readobj --sections --section-data %t3 | FileCheck %s --check-prefix=CONTENT64

# CONTENT32:      Name: .gnu.hash
# CONTENT32-NEXT: Type: SHT_GNU_HASH
# CONTENT32-NEXT: Flags [
# CONTENT32-NEXT:   SHF_ALLOC
# CONTENT32-NEXT: ]
# CONTENT32-NEXT: Address: 0x0
# CONTENT32-NEXT: Offset: 0x34
# CONTENT32-NEXT: Size: 52
# CONTENT32-NEXT: Link: 254
# CONTENT32-NEXT: Info: 0
# CONTENT32-NEXT: AddressAlignment: 0
# CONTENT32-NEXT: EntrySize: 0
# CONTENT32-NEXT: SectionData (
# CONTENT32-NEXT:   0000: 03000000 01000000 02000000 02000000 |
# CONTENT32-NEXT:   0010: 03000000 04000000 05000000 06000000 |
# CONTENT32-NEXT:   0020: 07000000 08000000 09000000 0A000000 |
# CONTENT32-NEXT:   0030: 0B000000                            |
# CONTENT32-NEXT: )

# CONTENT64:      Name: .gnu.hash
# CONTENT64-NEXT: Type: SHT_GNU_HASH
# CONTENT64-NEXT: Flags [
# CONTENT64-NEXT:   SHF_ALLOC
# CONTENT64-NEXT: ]
# CONTENT64-NEXT: Address: 0x0
# CONTENT64-NEXT: Offset: 0x40
# CONTENT64-NEXT: Size: 60
# CONTENT64-NEXT: Link: 254
# CONTENT64-NEXT: Info: 0
# CONTENT64-NEXT: AddressAlignment: 0
# CONTENT64-NEXT: EntrySize: 0
# CONTENT64-NEXT: SectionData (
# CONTENT64-NEXT:   0000: 03000000 01000000 02000000 02000000 |
# CONTENT64-NEXT:   0010: 03000000 00000000 04000000 00000000 |
# CONTENT64-NEXT:   0020: 05000000 06000000 07000000 08000000 |
# CONTENT64-NEXT:   0030: 09000000 0A000000 0B000000          |
# CONTENT64-NEXT: )

--- !ELF
FileHeader:
  Class:   ELFCLASS32
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_386
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]
    Link: 0xFE

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
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]
    Link: 0xFE

## Check we only can use "Header", "BloomFilter", "HashBuckets" and "HashValues" together.

# RUN: not yaml2obj --docnum=4 %s -o %t4 2>&1 | FileCheck %s --check-prefix=ERR
# RUN: not yaml2obj --docnum=5 %s -o %t5 2>&1 | FileCheck %s --check-prefix=ERR
# RUN: not yaml2obj --docnum=6 %s -o %t6 2>&1 | FileCheck %s --check-prefix=ERR
# RUN: not yaml2obj --docnum=7 %s -o %t7 2>&1 | FileCheck %s --check-prefix=ERR

# ERR: error: "Header", "BloomFilter", "HashBuckets" and "HashValues" must be used together

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash.no.header
    Type:  SHT_GNU_HASH
    BloomFilter: []
    HashBuckets: []
    HashValues: []

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash.no.bloomfilter
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0
      Shift2: 0x0
    HashBuckets: []
    HashValues: []

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash.no.nobuckets
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0
      Shift2: 0x0
    BloomFilter: []
    HashValues: []

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash.no.novalues
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0
      Shift2: 0x0
    BloomFilter: []
    HashBuckets: []

## Check that "SymNdx" and "Shift2" fields are mandatory when we specify the "Header".

# RUN: not yaml2obj --docnum=8 %s -o %t8 2>&1 | FileCheck %s --check-prefix=ERR2
# ERR2: error: missing required key 'SymNdx'

# RUN: not yaml2obj --docnum=9 %s -o %t9 2>&1 | FileCheck %s --check-prefix=ERR3
# ERR3: error: missing required key 'Shift2'

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH
    Header:
      Shift2: 0x0

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH
    Header:
      SymNdx: 0x0

## Either "Content" or "Header", "BloomFilter", "HashBuckets" and "HashBuckets" must be
## specified when declaring a SHT_GNU_HASH section.

# RUN: not yaml2obj --docnum=10 %s -o %t10 2>&1 | FileCheck %s --check-prefix=NOKEYS

# NOKEYS: error: either "Content" or "Header", "BloomFilter", "HashBuckets" and "HashBuckets" must be specified

--- !ELF
FileHeader:
  Class:   ELFCLASS64
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_X86_64
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH

## Test that "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with "Content".

# RUN: not yaml2obj --docnum=11 %s -o %t11 2>&1 | FileCheck %s --check-prefix=TOGETHER

# TOGETHER: error: "Header", "BloomFilter", "HashBuckets" and "HashValues" can't be used together with "Content"

--- !ELF
FileHeader:
  Class:   ELFCLASS32
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_386
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH
    Content: ""
    Header:
      SymNdx: 0x0
      Shift2: 0x0
    BloomFilter: []
    HashBuckets: []
    HashValues:  []

## Test we can override the number of buckets and the number of words in the Bloom filter
## using the "NBuckets" and "Shift2" keys.

# RUN: yaml2obj --docnum=12 %s -o %t12
# RUN: llvm-readobj --sections --section-data %t12 | FileCheck %s --check-prefix=OVERRIDE-CONTENT

# OVERRIDE-CONTENT:      Name: .gnu.hash
# OVERRIDE-CONTENT:      SectionData (
# OVERRIDE-CONTENT-NEXT:   0000: 01000000 02000000 03000000 04000000  |
# OVERRIDE-CONTENT-NEXT: )

--- !ELF
FileHeader:
  Class:   ELFCLASS32
  Data:    ELFDATA2LSB
  Type:    ET_DYN
  Machine: EM_386
Sections:
Sections:
  - Name:  .gnu.hash
    Type:  SHT_GNU_HASH
    Header:
      NBuckets:  0x1
      SymNdx:    0x2
      MaskWords: 0x3
      Shift2:    0x4
    BloomFilter: []
    HashBuckets: []
    HashValues:  []
