llvm/llvm/test/tools/llvm-readobj/ELF/dyn-symbols.test

## In this test we test that dynamic symbols are dumped as expected.

## Case 1: Dynamic symbol table found via the DT_SYMTAB dynamic tag.
# RUN: yaml2obj --docnum=1 %s -o %t1.so
# RUN: llvm-readobj --dyn-symbols %t1.so 2>&1 \
# RUN:   | FileCheck %s --implicit-check-not="warning:" --check-prefix=DYNSYMS-LLVM
# RUN: llvm-readelf --dyn-symbols %t1.so 2>&1 \
# RUN:   | FileCheck %s --implicit-check-not="warning:" --check-prefix=DYNSYMS-GNU

# DYNSYMS-LLVM:      DynamicSymbols [
# DYNSYMS-LLVM-NEXT:   Symbol {
# DYNSYMS-LLVM-NEXT:     Name:  (0)
# DYNSYMS-LLVM-NEXT:     Value: 0x0
# DYNSYMS-LLVM-NEXT:     Size: 0
# DYNSYMS-LLVM-NEXT:     Binding: Local (0x0)
# DYNSYMS-LLVM-NEXT:     Type: None (0x0)
# DYNSYMS-LLVM-NEXT:     Other: 0
# DYNSYMS-LLVM-NEXT:     Section: Undefined (0x0)
# DYNSYMS-LLVM-NEXT:   }
# DYNSYMS-LLVM-NEXT:   Symbol {
# DYNSYMS-LLVM-NEXT:     Name: foo (5)
# DYNSYMS-LLVM-NEXT:     Value: 0x0
# DYNSYMS-LLVM-NEXT:     Size: 0
# DYNSYMS-LLVM-NEXT:     Binding: Local (0x0)
# DYNSYMS-LLVM-NEXT:     Type: None (0x0)
# DYNSYMS-LLVM-NEXT:     Other: 0
# DYNSYMS-LLVM-NEXT:     Section: Undefined (0x0)
# DYNSYMS-LLVM-NEXT:   }
# DYNSYMS-LLVM-NEXT:   Symbol {
# DYNSYMS-LLVM-NEXT:     Name: bar (1)
# DYNSYMS-LLVM-NEXT:     Value: 0x0
# DYNSYMS-LLVM-NEXT:     Size: 0
# DYNSYMS-LLVM-NEXT:     Binding: Local (0x0)
# DYNSYMS-LLVM-NEXT:     Type: None (0x0)
# DYNSYMS-LLVM-NEXT:     Other: 0
# DYNSYMS-LLVM-NEXT:     Section: Undefined (0x0)
# DYNSYMS-LLVM-NEXT:   }
# DYNSYMS-LLVM-NEXT: ]

# DYNSYMS-GNU:      Symbol table '.dynsym' contains 3 entries:
# DYNSYMS-GNU-NEXT:  Num:    Value          Size Type    Bind   Vis       Ndx Name
# DYNSYMS-GNU-NEXT:    0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
# DYNSYMS-GNU-NEXT:    1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND foo
# DYNSYMS-GNU-NEXT:    2: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND bar

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMTAB
        Value: 0x100
      - Tag:   DT_NULL
        Value: 0
  - Name:    .dynsym
    Type:    SHT_DYNSYM
    Address: 0x100
DynamicSymbols:
  - Name: foo
  - Name: bar
ProgramHeaders:
  - Type:     PT_LOAD
    VAddr:    0x100
    FirstSec: .dynsym
    LastSec:  .dynsym

## Case 2: Check the output for aliases.
## a) Check the two-letter alias --dt is equivalent to the --dyn-symbols
## full flag name.
# RUN: llvm-readobj --dt %t1.so > %t.readobj-dt-alias
# RUN: llvm-readobj --dyn-symbols %t1.so > %t.readobj-dt-no-alias
# RUN: cmp %t.readobj-dt-alias %t.readobj-dt-no-alias
## b) Check --dyn-syms equals --dyn-symbols, --dt for llvm-readobj.
# RUN: llvm-readobj --dyn-syms %t1.so > %t.readobj-dyn-syms
# RUN: cmp %t.readobj-dt-alias %t.readobj-dyn-syms
## c) Check --dyn-syms equals --dyn-symbols for llvm-readelf.
# RUN: llvm-readelf --dyn-syms %t1.so > %t.readelf-dyn-syms
# RUN: llvm-readelf --dyn-symbols %t1.so > %t.readelf-dyn-symbols
# RUN: cmp %t.readelf-dyn-symbols %t.readelf-dyn-syms

## Case 3.1: Check that we are able to dump the dynamic symbol table even when we have no program headers.
## In this case we find the table by it's type (SHT_DYNSYM) and ignore the DT_SYMTAB value.
# RUN: yaml2obj --docnum=2 %s -o %t2.so
# RUN: llvm-readobj %t2.so --dyn-symbols 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t2.so --implicit-check-not=warning: --check-prefix=NOPHDRS-LLVM
# RUN: llvm-readelf %t2.so --dyn-symbols 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t2.so --implicit-check-not=warning: -DNAME=.dynsym --check-prefix=NOPHDRS-GNU

# NOPHDRS-LLVM: warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234
# NOPHDRS-LLVM:      DynamicSymbols [
# NOPHDRS-LLVM-NEXT:   Symbol {
# NOPHDRS-LLVM-NEXT:     Name:  (0)
# NOPHDRS-LLVM-NEXT:     Value: 0x0
# NOPHDRS-LLVM-NEXT:     Size: 0
# NOPHDRS-LLVM-NEXT:     Binding: Local (0x0)
# NOPHDRS-LLVM-NEXT:     Type: None (0x0)
# NOPHDRS-LLVM-NEXT:     Other: 0
# NOPHDRS-LLVM-NEXT:     Section: Undefined (0x0)
# NOPHDRS-LLVM-NEXT:   }
# NOPHDRS-LLVM-NEXT:   Symbol {
# NOPHDRS-LLVM-NEXT:     Name: foo (1)
# NOPHDRS-LLVM-NEXT:     Value: 0x0
# NOPHDRS-LLVM-NEXT:     Size: 0
# NOPHDRS-LLVM-NEXT:     Binding: Local (0x0)
# NOPHDRS-LLVM-NEXT:     Type: None (0x0)
# NOPHDRS-LLVM-NEXT:     Other: 0
# NOPHDRS-LLVM-NEXT:     Section: Undefined (0x0)
# NOPHDRS-LLVM-NEXT:   }
# NOPHDRS-LLVM-NEXT: ]

# NOPHDRS-GNU:      warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234
# NOPHDRS-NAMEWARN: warning: '[[FILE]]': unable to get the name of SHT_DYNSYM section with index 2: a section [index 2] has an invalid sh_name (0xffffffff) offset which goes past the end of the section name string table
# NOPHDRS-GNU:      Symbol table '[[NAME]]' contains 2 entries:
# NOPHDRS-GNU-NEXT:  Num:    Value          Size Type    Bind   Vis       Ndx Name
# NOPHDRS-GNU-NEXT:    0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
# NOPHDRS-GNU-NEXT:    1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND foo

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMTAB
        Value: 0xffff1234
      - Tag:   DT_NULL
        Value: 0
  - Name:   .dynsym
    Type:   SHT_DYNSYM
    ShName: [[DYNSYMNAME=<none>]]
DynamicSymbols:
  - Name: foo

## Case 3.2: the same as 3.1, but the sh_name field of the SHT_DYNSYM section is invalid.
##           Check we are still able to dump symbols.
# RUN: yaml2obj --docnum=2 -DDYNSYMNAME=0xffffffff %s -o %t2.broken.name
# RUN: llvm-readobj %t2.broken.name --dyn-symbols 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t2.broken.name --check-prefix=NOPHDRS-LLVM --implicit-check-not=warning:
# RUN: llvm-readelf %t2.broken.name --dyn-symbols 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t2.broken.name -DNAME="<?>" \
# RUN:     --check-prefixes=NOPHDRS-GNU,NOPHDRS-NAMEWARN --implicit-check-not=warning:

## Case 4: Check we report a warning when there is no SHT_DYNSYM section and we can't map the DT_SYMTAB value
## to an address because of the absence of a corresponding PT_LOAD program header.
# RUN: yaml2obj --docnum=3 %s -o %t3.so
# RUN: llvm-readobj %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefixes=NOSHT-DYNSYM,NOSHT-DYNSYM-LLVM
# RUN: llvm-readelf %t3.so --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t3.so --check-prefix=NOSHT-DYNSYM

# NOSHT-DYNSYM:           warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0x0
# NOSHT-DYNSYM-LLVM:      DynamicSymbols [
# NOSHT-DYNSYM-LLVM-NEXT: ]

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynsym
    Type:    SHT_PROGBITS
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMTAB
        Value: 0
      - Tag:   DT_NULL
        Value: 0
DynamicSymbols:
  - Name: foo

## Case 5: Check that when we can't map the value of the DT_SYMTAB tag to an address, we report a warning and
## use the information in the section header table to locate the dynamic symbol table.
# RUN: yaml2obj --docnum=4 %s -o %t4.so
# RUN: llvm-readobj %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-LLVM
# RUN: llvm-readelf %t4.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t4.so %s --check-prefixes=BROKEN-DTSYMTAB,BROKEN-DTSYMTAB-GNU

# BROKEN-DTSYMTAB:      warning: '[[FILE]]': unable to parse DT_SYMTAB: virtual address is not in any segment: 0xffff1234
# BROKEN-DTSYMTAB-LLVM: Name: foo
# BROKEN-DTSYMTAB-GNU:  1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND foo

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMTAB
        Value: 0xffff1234
      - Tag:   DT_NULL
        Value: 0
DynamicSymbols:
  - Name: foo
ProgramHeaders:
  - Type:     PT_LOAD
    VAddr:    0x0000
    FirstSec: .dynsym
    LastSec:  .dynsym

## Case 6: Check that if we can get the location of the dynamic symbol table using both the DT_SYMTAB value
## and the section headers table then we prefer the former and report a warning.
# RUN: yaml2obj --docnum=5 %s -o %t5.so
# RUN: llvm-readobj %t5.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefixes=PREFER-DTSYMTAB,PREFER-DTSYMTAB-LLVM
# RUN: llvm-readelf %t5.so --dyn-symbols 2>&1 | FileCheck -DFILE=%t5.so %s --check-prefixes=PREFER-DTSYMTAB,PREFER-DTSYMTAB-GNU

# PREFER-DTSYMTAB:      warning: '[[FILE]]': SHT_DYNSYM section header and DT_SYMTAB disagree about the location of the dynamic symbol table
# PREFER-DTSYMTAB-LLVM: Name: o
# PREFER-DTSYMTAB-GNU:  1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND o

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMTAB
        Value: 0x0
      - Tag:   DT_NULL
        Value: 0
  - Name: .dynsym
    Type: SHT_DYNSYM
  - Name: .mydynsym
    Type: SHT_DYNSYM
## The Content describes 2 symbols: zero symbol and symbol with st_name == 3.
    Content: "000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000"
DynamicSymbols:
  - Name: foo
ProgramHeaders:
  - Type:     PT_LOAD
    VAddr:    0x0000
    FirstSec: .mydynsym
    LastSec:  .mydynsym

## Case 7: Check how we dump versioned symbols. Use both -V and --dyn-symbols
## to check that printed version is consistent.
## A default version is one that is contained in the version table (SHT_GNU_versym)
## and only available for defined symbols. We use the "@@" prefix to print it.

## Check how we dump undefined symbols.

# RUN: yaml2obj %s --docnum=6 -o %t6
# RUN: llvm-readobj -V --dyn-symbols %t6 | FileCheck %s --check-prefix=VERSIONED-UND-LLVM
# RUN: llvm-readelf -V --dyn-symbols %t6 | FileCheck %s --check-prefix=VERSIONED-UND-GNU

# VERSIONED-UND-LLVM:       DynamicSymbols [
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name:  (0)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name: localversym (28)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name: globalversym (40)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name: aaa@v2 (65)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name: bbb@v3hidden (61)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name: ccc@v4 (57)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT:   Symbol {
# VERSIONED-UND-LLVM-NEXT:     Name: ddd@v5hidden (53)
# VERSIONED-UND-LLVM-NEXT:     Value: 0x0
# VERSIONED-UND-LLVM-NEXT:     Size: 0
# VERSIONED-UND-LLVM-NEXT:     Binding: Local (0x0)
# VERSIONED-UND-LLVM-NEXT:     Type: None (0x0)
# VERSIONED-UND-LLVM-NEXT:     Other: 0
# VERSIONED-UND-LLVM-NEXT:     Section: Undefined (0x0)
# VERSIONED-UND-LLVM-NEXT:   }
# VERSIONED-UND-LLVM-NEXT: ]
# VERSIONED-UND-LLVM:      VersionSymbols [
# VERSIONED-UND-LLVM:          Name: localversym
# VERSIONED-UND-LLVM:          Name: globalversym
# VERSIONED-UND-LLVM:          Name: aaa@v2
# VERSIONED-UND-LLVM:          Name: bbb@v3hidden
# VERSIONED-UND-LLVM:          Name: ccc@v4
# VERSIONED-UND-LLVM:          Name: ddd@v5hidden

# VERSIONED-UND-GNU:      Num:    Value          Size Type    Bind   Vis     Ndx Name
# VERSIONED-UND-GNU:        1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND localversym
# VERSIONED-UND-GNU-NEXT:   2: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND globalversym
# VERSIONED-UND-GNU-NEXT:   3: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND aaa@v2
# VERSIONED-UND-GNU-NEXT:   4: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND bbb@v3hidden
# VERSIONED-UND-GNU-NEXT:   5: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND ccc@v4
# VERSIONED-UND-GNU-NEXT:   6: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT UND ddd@v5hidden
# VERSIONED-UND-GNU:      000:   0 (*local*)  0 (*local*) 1 (*global*) 2 (v2)
# VERSIONED-UND-GNU:      004:   3h(v3hidden) 4 (v4)      5h(v5hidden)

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:         .gnu.version
    Type:         SHT_GNU_versym
    Flags:        [ SHF_ALLOC ]
    Link:         .dynsym
    AddressAlign: 0x2
    EntSize:      0x2
## 0x8000 is a special VERSYM_HIDDEN bit.
## Here we have: VER_NDX_LOCAL (0), VER_NDX_GLOBAL (1), two versions
## from the SHT_GNU_verdef section (2, 0x8003) and two versions
## from the SHT_GNU_verneed section (4, 0x8005).
    Entries:      [ 0, 0, 1, 2, 0x8003, 4, 0x8005 ]
  - Name:         .gnu.version_d
    Type:         SHT_GNU_verdef
    Flags:        [ SHF_ALLOC ]
    AddressAlign: 0x4
    Entries:
      - VersionNdx: 2
        Names:
          - v2
      - VersionNdx: 3
        Names:
          - v3hidden
  - Name:  .gnu.version_r
    Type:  SHT_GNU_verneed
    Flags: [ SHF_ALLOC ]
    Dependencies:
      - Version: 1
        File:    file1.so
        Entries:
          - Name:  v4
            Other: 4
            Hash:  0
            Flags: 0
      - Version: 1
        File:    file2.0
        Entries:
          - Name:  v5hidden
            Other: 5
            Hash:  0
            Flags: 0
DynamicSymbols:
  - Name:  localversym
    Index: [[INDEX=<none>]]
  - Name:  globalversym
    Index: [[INDEX=<none>]]
  - Name:  aaa
    Index: [[INDEX=<none>]]
  - Name:  [[NAME=bbb]]
    Type:  [[TYPE=STT_NOTYPE]]
    Index: [[INDEX_BBB=<none>]]
  - Name:  [[NAME=ccc]]
    Type:  [[TYPE=STT_NOTYPE]]
    Index: [[INDEX=<none>]]
  - Name:  ddd
    Index: [[INDEX=<none>]]

## In this case all dynamic symbols are defined. Check that we print the
## "@@" prefix for default versions as expected.

# RUN: yaml2obj %s --docnum=6 -DINDEX=1 -DINDEX_BBB=1 -o %t6.def
# RUN: llvm-readobj -V --dyn-symbols %t6.def | FileCheck %s --check-prefix=VERSIONED-DEF-LLVM
# RUN: llvm-readelf -V --dyn-symbols %t6.def | FileCheck %s --check-prefix=VERSIONED-DEF-GNU

# VERSIONED-DEF-LLVM:      DynamicSymbols [
# VERSIONED-DEF-LLVM:        Symbol {
# VERSIONED-DEF-LLVM:          Name:    localversym (28)
# VERSIONED-DEF-LLVM:          Section: .gnu.version (0x1)
# VERSIONED-DEF-LLVM-NEXT:   }
# VERSIONED-DEF-LLVM-NEXT:   Symbol {
# VERSIONED-DEF-LLVM-NEXT:     Name:    globalversym (40)
# VERSIONED-DEF-LLVM:          Section: .gnu.version (0x1)
# VERSIONED-DEF-LLVM-NEXT:   }
# VERSIONED-DEF-LLVM-NEXT:   Symbol {
# VERSIONED-DEF-LLVM-NEXT:     Name:    aaa@@v2 (65)
# VERSIONED-DEF-LLVM:          Section: .gnu.version (0x1)
# VERSIONED-DEF-LLVM-NEXT:   }
# VERSIONED-DEF-LLVM-NEXT:   Symbol {
# VERSIONED-DEF-LLVM-NEXT:     Name:    bbb@v3hidden (61)
# VERSIONED-DEF-LLVM:          Section: .gnu.version (0x1)
# VERSIONED-DEF-LLVM-NEXT:   }
# VERSIONED-DEF-LLVM-NEXT:   Symbol {
# VERSIONED-DEF-LLVM-NEXT:     Name:    ccc@v4 (57)
# VERSIONED-DEF-LLVM:          Section: .gnu.version (0x1)
# VERSIONED-DEF-LLVM-NEXT:   }
# VERSIONED-DEF-LLVM-NEXT:   Symbol {
# VERSIONED-DEF-LLVM-NEXT:     Name:    ddd@v5hidden (53)
# VERSIONED-DEF-LLVM:          Section: .gnu.version (0x1)
# VERSIONED-DEF-LLVM-NEXT:   }
# VERSIONED-DEF-LLVM:      VersionSymbols [
# VERSIONED-DEF-LLVM:          Name: localversym
# VERSIONED-DEF-LLVM:          Name: globalversym
# VERSIONED-DEF-LLVM:          Name: aaa@@v2
# VERSIONED-DEF-LLVM:          Name: bbb@v3hidden
# VERSIONED-DEF-LLVM:          Name: ccc@v4
# VERSIONED-DEF-LLVM:          Name: ddd@v5hidden

# VERSIONED-DEF-GNU:      Num: {{.*}} Vis     Ndx Name
# VERSIONED-DEF-GNU:        1: {{.*}} DEFAULT   1 localversym
# VERSIONED-DEF-GNU-NEXT:   2: {{.*}} DEFAULT   1 globalversym
# VERSIONED-DEF-GNU-NEXT:   3: {{.*}} DEFAULT   1 aaa@@v2
# VERSIONED-DEF-GNU-NEXT:   4: {{.*}} DEFAULT   1 bbb@v3hidden
# VERSIONED-DEF-GNU-NEXT:   5: {{.*}} DEFAULT   1 ccc@v4
# VERSIONED-DEF-GNU-NEXT:   6: {{.*}} DEFAULT   1 ddd@v5hidden

## Check the behavior for unnamed versioned section symbols.
# RUN: yaml2obj %s -DTYPE=STT_SECTION -DNAME="''" -DINDEX_BBB=SHN_ABS --docnum=6 -o %t6.sec.sym
# RUN: llvm-readobj -V --dyn-symbols %t6.sec.sym 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t6.sec.sym --check-prefix=VERSIONED-SEC-SYM-LLVM
# RUN: llvm-readelf -V --dyn-symbols %t6.sec.sym 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t6.sec.sym --check-prefix=VERSIONED-SEC-SYM-GNU

# VERSIONED-SEC-SYM-LLVM: DynamicSymbols [
# VERSIONED-SEC-SYM-LLVM:  Name: localversym (28)
# VERSIONED-SEC-SYM-LLVM:  Name: globalversym (40)
# VERSIONED-SEC-SYM-LLVM:  Name: aaa@v2 (57)
# VERSIONED-SEC-SYM-LLVM: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS)
# VERSIONED-SEC-SYM-LLVM:  Name: <?> (0)
# VERSIONED-SEC-SYM-LLVM: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF)
# VERSIONED-SEC-SYM-LLVM:  Name: <?> (0)
# VERSIONED-SEC-SYM-LLVM:  Name: ddd@v5hidden (53)
# VERSIONED-SEC-SYM-LLVM: VersionSymbols [
# VERSIONED-SEC-SYM-LLVM:  Name: localversym
# VERSIONED-SEC-SYM-LLVM:  Name: globalversym
# VERSIONED-SEC-SYM-LLVM:  Name: aaa@v2
# VERSIONED-SEC-SYM-LLVM:  Name: <?>
# VERSIONED-SEC-SYM-LLVM:  Name: <?>
# VERSIONED-SEC-SYM-LLVM:  Name: ddd@v5hidden

# VERSIONED-SEC-SYM-GNU:     Symbol table '.dynsym' contains 7 entries:
# VERSIONED-SEC-SYM-GNU:        Num: {{.*}} Ndx Name
# VERSIONED-SEC-SYM-GNU:          1: {{.*}} UND localversym
# VERSIONED-SEC-SYM-GNU-NEXT:     2: {{.*}} UND globalversym
# VERSIONED-SEC-SYM-GNU-NEXT:     3: {{.*}} UND aaa@v2
# VERSIONED-SEC-SYM-GNU-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0xfff1 (SHN_ABS)
# VERSIONED-SEC-SYM-GNU-NEXT:     4: {{.*}} ABS <?>
# VERSIONED-SEC-SYM-GNU-NEXT: warning: '[[FILE]]': unable to get section index for symbol with st_shndx = 0x0 (SHN_UNDEF)
# VERSIONED-SEC-SYM-GNU-NEXT:     5: {{.*}} UND <?>
# VERSIONED-SEC-SYM-GNU-NEXT:     6: {{.*}} UND ddd@v5hidden

## Check we print a proper warning when an unnamed versioned section symbol has st_shndx = SHN_XINDEX, but there
## is no SHT_SYMTAB_SHNDX section in the object.
# RUN: yaml2obj %s -DTYPE=STT_SECTION -DNAME="''" -DINDEX_BBB=SHN_XINDEX --docnum=6 -o %t6.sec.xindex.sym
# RUN: llvm-readobj -V --dyn-symbols %t6.sec.xindex.sym 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t6.sec.xindex.sym --check-prefix=VERSIONED-SEC-SYM-XINDEX-LLVM
# RUN: llvm-readelf -V --dyn-symbols %t6.sec.xindex.sym 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t6.sec.xindex.sym --check-prefix=VERSIONED-SEC-SYM-XINDEX-GNU

# VERSIONED-SEC-SYM-XINDEX-LLVM:       Name: aaa@v2 (57)
# VERSIONED-SEC-SYM-XINDEX-LLVM:      warning: '[[FILE]]': found an extended symbol index (4), but unable to locate the extended symbol index table
# VERSIONED-SEC-SYM-XINDEX-LLVM-NEXT: Symbol {
# VERSIONED-SEC-SYM-XINDEX-LLVM-NEXT:  Name: <?> (0)

# VERSIONED-SEC-SYM-XINDEX-GNU:      3: {{.*}} UND aaa@v2
# VERSIONED-SEC-SYM-XINDEX-GNU-NEXT: warning: '[[FILE]]': found an extended symbol index (4), but unable to locate the extended symbol index table
# VERSIONED-SEC-SYM-XINDEX-GNU-NEXT: 4: {{.*}} RSV[0xffff] <?>

## Case 8: Check what we print when:
## a) The dynamic symbol table does not exist.
# RUN: yaml2obj %s --docnum=7 -o %t7
# RUN: llvm-readobj --dyn-symbols %t7 | FileCheck %s --check-prefix=NO-DYNSYM-LLVM
# RUN: llvm-readelf --dyn-symbols %t7 | count 0
## b) The dynamic symbol table has a size of 0.
# RUN: yaml2obj %s --docnum=8 -o %t8
# RUN: llvm-readobj --dyn-symbols %t8 | FileCheck %s --check-prefix=NO-DYNSYM-LLVM
# RUN: llvm-readelf --dyn-symbols %t8 | count 0
## c) The dynamic symbol table only contains the null symbol.
# RUN: yaml2obj %s --docnum=9 -o %t9
# RUN: llvm-readobj --dyn-symbols %t9 | FileCheck %s --check-prefix=DYNSYM-EMPTY-LLVM
# RUN: llvm-readelf --dyn-symbols %t9 | FileCheck %s --check-prefix=DYNSYM-EMPTY-GNU

# NO-DYNSYM-LLVM:      DynamicSymbols [
# NO-DYNSYM-LLVM-NEXT: ]

# DYNSYM-EMPTY-LLVM:      DynamicSymbols [
# DYNSYM-EMPTY-LLVM-NEXT:  Symbol {
# DYNSYM-EMPTY-LLVM-NEXT:  Name: (0)
# DYNSYM-EMPTY-LLVM-NEXT:  Value: 0x0
# DYNSYM-EMPTY-LLVM-NEXT:  Size: 0
# DYNSYM-EMPTY-LLVM-NEXT:  Binding: Local (0x0)
# DYNSYM-EMPTY-LLVM-NEXT:  Type: None (0x0)
# DYNSYM-EMPTY-LLVM-NEXT:  Other: 0
# DYNSYM-EMPTY-LLVM-NEXT:  Section: Undefined (0x0)
# DYNSYM-EMPTY-LLVM-NEXT:  }
# DYNSYM-EMPTY-LLVM-NEXT: ]

# DYNSYM-EMPTY-GNU:      Symbol table '.dynsym' contains 1 entries:
# DYNSYM-EMPTY-GNU-NEXT:   Num:    Value  Size Type    Bind   Vis       Ndx Name
# DYNSYM-EMPTY-GNU-NEXT:     0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name: .dynsym
    Type: SHT_DYNSYM
    Size: 0

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN
DynamicSymbols: []

## Case 9: Check what we print when:
## a) The size of the dynamic symbol table is not a multiple of its entry size.
# RUN: yaml2obj %s --docnum=10 -o %t10
# RUN: llvm-readobj --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1
# RUN: llvm-readelf --dyn-symbols %t10 2>&1 | FileCheck %s -DFILE=%t10 --check-prefix=DYNSYM-SIZE-INVALID1

# DYNSYM-SIZE-INVALID1: warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x1) or entry size (0x10)

## b) The same, but the DT_SYMTAB tag is present. In this case the dynamic tag has priority over the
##    information about a location and an entity size of the dynamic symbol table from the section header.
##    The code uses sizeof(Elf_Sym) for an entity size, so it can't be incorrect and
##    the message printed is a bit shorter.
# RUN: yaml2obj %s --docnum=11 -o %t11
# RUN: llvm-readobj --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2
# RUN: llvm-readelf --dyn-symbols %t11 2>&1 | FileCheck %s -DFILE=%t11 --check-prefix=DYNSYM-SIZE-INVALID2

# DYNSYM-SIZE-INVALID2: warning: '[[FILE]]': SHT_DYNSYM section with index 2 has invalid size (0x1){{$}}

## c) In the case when the DT_SYMENT tag is present, we report when it's value does not match the
#     value of the symbol size for the platform.
# RUN: yaml2obj %s -D BITS=32 --docnum=12 -o %t12
# RUN: llvm-readobj --dyn-symbols %t12 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID3
# RUN: llvm-readelf --dyn-symbols %t12 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t12 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID3
# RUN: yaml2obj %s -D BITS=64 --docnum=12 -o %t13
# RUN: llvm-readobj --dyn-symbols %t13 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t13 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID4
# RUN: llvm-readelf --dyn-symbols %t13 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t13 --implicit-check-not=warning: --check-prefix=DYNSYM-SIZE-INVALID4

# DYNSYM-SIZE-INVALID3: warning: '[[FILE]]': DT_SYMENT value of 0x123 is not the size of a symbol (0x10){{$}}
# DYNSYM-SIZE-INVALID4: warning: '[[FILE]]': DT_SYMENT value of 0x123 is not the size of a symbol (0x18){{$}}

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name: .dynsym
    Type: SHT_DYNSYM
    Size: 0x1

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMTAB
        Value: 0x100
      - Tag:   DT_NULL
        Value: 0
  - Name:    .dynsym
    Type:    SHT_DYNSYM
    Address: 0x100
    Size:    0x1
ProgramHeaders:
  - Type:     PT_LOAD
    VAddr:    0x100
    FirstSec: .dynsym
    LastSec:  .dynsym

--- !ELF
FileHeader:
  Class: ELFCLASS[[BITS]]
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:    .dynamic
    Type:    SHT_DYNAMIC
    Entries:
      - Tag:   DT_SYMENT
        Value: 0x123
      - Tag:   DT_SYMENT
        Value: 0x123
      - Tag:   DT_NULL
        Value: 0

## Case 10: Check we report a warning when the DT_STRSZ value is broken so that the dynamic string
##          table goes past the end of the file. Document we stop dumping symbols and report an error.

# RUN: yaml2obj %s --docnum=13 -o %t14
# RUN: llvm-readobj --dyn-symbols %t14 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-LLVM
# RUN: llvm-readelf --dyn-symbols %t14 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t14 --check-prefix=DYNSTR-INVALID-GNU

# DYNSTR-INVALID-LLVM: warning: '[[FILE]]': the dynamic string table at 0x78 goes past the end of the file (0x2a8) with DT_STRSZ = 0xffffffff
# DYNSTR-INVALID-LLVM:      DynamicSymbols [
# DYNSTR-INVALID-LLVM-NEXT:   Symbol {
# DYNSTR-INVALID-LLVM-NEXT:     Name:  (0)
# DYNSTR-INVALID-LLVM-NEXT:     Value: 0x0
# DYNSTR-INVALID-LLVM-NEXT:     Size: 0
# DYNSTR-INVALID-LLVM-NEXT:     Binding: Local (0x0)
# DYNSTR-INVALID-LLVM-NEXT:     Type: None (0x0)
# DYNSTR-INVALID-LLVM-NEXT:     Other: 0
# DYNSTR-INVALID-LLVM-NEXT:     Section: Undefined (0x0)
# DYNSTR-INVALID-LLVM-NEXT:   }
# DYNSTR-INVALID-LLVM-NEXT: warning: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6
# DYNSTR-INVALID-LLVM-NEXT:   Symbol {
# DYNSTR-INVALID-LLVM-NEXT:     Name: <?> (4294967040)
# DYNSTR-INVALID-LLVM-NEXT:     Value: 0x0
# DYNSTR-INVALID-LLVM-NEXT:     Size: 0
# DYNSTR-INVALID-LLVM-NEXT:     Binding: Local (0x0)
# DYNSTR-INVALID-LLVM-NEXT:     Type: None (0x0)
# DYNSTR-INVALID-LLVM-NEXT:     Other: 0
# DYNSTR-INVALID-LLVM-NEXT:     Section: Undefined (0x0)
# DYNSTR-INVALID-LLVM-NEXT:   }
# DYNSTR-INVALID-LLVM-NEXT:   Symbol {
# DYNSTR-INVALID-LLVM-NEXT:     Name: test (1)
# DYNSTR-INVALID-LLVM-NEXT:     Value: 0x0
# DYNSTR-INVALID-LLVM-NEXT:     Size: 0
# DYNSTR-INVALID-LLVM-NEXT:     Binding: Local (0x0)
# DYNSTR-INVALID-LLVM-NEXT:     Type: None (0x0)
# DYNSTR-INVALID-LLVM-NEXT:     Other: 0
# DYNSTR-INVALID-LLVM-NEXT:     Section: Undefined (0x0)
# DYNSTR-INVALID-LLVM-NEXT:   }
# DYNSTR-INVALID-LLVM-NEXT: ]

# DYNSTR-INVALID-GNU: warning: '[[FILE]]': the dynamic string table at 0x78 goes past the end of the file (0x2a8) with DT_STRSZ = 0xffffffff
# DYNSTR-INVALID-GNU:      Symbol table '.dynsym' contains 3 entries:
# DYNSTR-INVALID-GNU-NEXT:    Num:    Value          Size Type    Bind   Vis       Ndx Name
# DYNSTR-INVALID-GNU-NEXT:      0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND
# DYNSTR-INVALID-GNU-NEXT: warning: '[[FILE]]': st_name (0xffffff00) is past the end of the string table of size 0x6
# DYNSTR-INVALID-GNU-NEXT:      1: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND <?>
# DYNSTR-INVALID-GNU-NEXT:      2: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT   UND test

--- !ELF
FileHeader:
  Class: ELFCLASS64
  Data:  ELFDATA2LSB
  Type:  ET_EXEC
Sections:
  - Name:    .dynstr
    Type:    SHT_STRTAB
    Flags:   [ SHF_ALLOC ]
    Content: '007465737400' ## '\0', 'test', '\0'
  - Name:  .dynamic
    Type:  SHT_DYNAMIC
    Flags: [ SHF_ALLOC ]
    Link:  .dynstr
    Entries:
      - Tag:   DT_STRTAB
        Value: 0x0
      - Tag:   DT_STRSZ
        Value: 0xffffffff
      - Tag:   DT_NULL
        Value: 0x0
DynamicSymbols:
  - StName:  0xffffff00
## An arbitrary valid symbol to document we report an error before dumping it.
  - StName:  0x1
ProgramHeaders:
  - Type:     PT_LOAD
    Flags:    [ PF_R ]
    FirstSec: .dynstr
    LastSec:  .dynamic

## Case 11: check various warnings we report when fields of the SHT_DYNSYM section are broken.

## a) check we report a warning when the entry size of the dynamic symbol table is zero.
# RUN: yaml2obj %s --docnum=14 -DENTSIZE=0x0 -o %t15.entsize
# RUN: llvm-readobj --dyn-symbols %t15.entsize 2>&1 | FileCheck %s -DFILE=%t15.entsize --check-prefix=DYNSYM-ZERO-ENTSIZE-LLVM
# RUN: llvm-readelf --dyn-symbols %t15.entsize 2>&1 | \
# RUN:   FileCheck %s -DFILE=%t15.entsize --check-prefix=DYNSYM-ZERO-ENTSIZE-GNU --implicit-check-not="Symbol table"

# DYNSYM-ZERO-ENTSIZE-LLVM:      DynamicSymbols [
# DYNSYM-ZERO-ENTSIZE-LLVM-NEXT:  warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x20) or entry size (0x0)
# DYNSYM-ZERO-ENTSIZE-LLVM-NEXT: ]

# DYNSYM-ZERO-ENTSIZE-GNU:  warning: '[[FILE]]': SHT_DYNSYM section with index 1 has invalid size (0x20) or entry size (0x0)

--- !ELF
FileHeader:
  Class: ELFCLASS32
  Data:  ELFDATA2LSB
  Type:  ET_DYN
Sections:
  - Name:     .dynsym
    Type:     SHT_DYNSYM
    EntSize:  [[ENTSIZE=<none>]]
    Link:     [[LINK=<none>]]
    ShOffset: [[OFFSET=<none>]]
    ShSize:   [[SIZE=<none>]]
DynamicSymbols:
  - Name: foo

## b) check we report a warning when the sh_offset field of the SHT_DYNSYM section is
##    invalid (sh_offset + sh_size is greater than the file size). Check we don't dump
##    dynamic symbols in this case.
# RUN: yaml2obj --docnum=14 %s -DOFFSET=0xffffffff -o %t15.offset
# RUN: llvm-readobj %t15.offset --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.offset \
# RUN:   --check-prefixes=OFFSET-BROKEN,OFFSET-BROKEN-LLVM
# RUN: llvm-readelf %t15.offset --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.offset \
# RUN:   --implicit-check-not="Symbol table" --check-prefix=OFFSET-BROKEN

# OFFSET-BROKEN: warning: '[[FILE]]': unable to read dynamic symbols from SHT_DYNSYM section with index 1: offset (0xffffffff) + size (0x20) is greater than the file size (0x148)

# OFFSET-BROKEN-LLVM:      DynamicSymbols [
# OFFSET-BROKEN-LLVM-NEXT: ]

## c) check we report a warning when the sh_size field of the SHT_DYNSYM section is
##    invalid (sh_offset + sh_size is greater than the file size). Check we don't dump
##    dynamic symbols in this case.
# RUN: yaml2obj --docnum=14 %s -DSIZE=0xffffffff -o %t15.size
# RUN: llvm-readobj %t15.size --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.size \
# RUN:   --check-prefixes=SIZE-BROKEN,SIZE-BROKEN-LLVM
# RUN: llvm-readelf %t15.size --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t15.size \
# RUN:   --implicit-check-not="Symbol table" --check-prefix=SIZE-BROKEN

# SIZE-BROKEN: warning: '[[FILE]]': unable to read dynamic symbols from SHT_DYNSYM section with index 1: offset (0x34) + size (0xffffffff) is greater than the file size (0x148)

# SIZE-BROKEN-LLVM:      DynamicSymbols [
# SIZE-BROKEN-LLVM-NEXT: ]

## d) check we report a warning when the sh_link field of the SHT_DYNSYM section
##    is not a valid section index or is not an index of a valid string table.
# RUN: yaml2obj --docnum=14 %s -DLINK=0xffffffff -o %t16.link
# RUN: llvm-readobj %t16.link --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \
# RUN:   --check-prefixes=LINK-BROKEN1,LINK-BROKEN-LLVM --implicit-check-not=warning:
# RUN: llvm-readelf %t16.link --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \
# RUN:   --check-prefixes=LINK-BROKEN1,LINK-BROKEN-GNU --implicit-check-not=warning:

## Also test that we are able to dump section headers even if the .dynsym section's sh_link field is broken.
# RUN: llvm-readobj %t16.link --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \
# RUN:   --check-prefixes=LINK-BROKEN1,LINK-SEC-HDRS-LLVM,LINK-BROKEN-LLVM --implicit-check-not=warning:
# RUN: llvm-readelf %t16.link --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link \
# RUN:   --check-prefixes=LINK-BROKEN1,LINK-SEC-HDRS-GNU,LINK-BROKEN-GNU

# RUN: yaml2obj --docnum=14 %s -DLINK=0x0 -o %t16.link.0
# RUN: llvm-readobj %t16.link.0 --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \
# RUN:   --check-prefixes=LINK-BROKEN2,LINK-BROKEN-LLVM --implicit-check-not=warning:
# RUN: llvm-readelf %t16.link.0 --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \
# RUN:   --check-prefixes=LINK-BROKEN2,LINK-BROKEN-GNU --implicit-check-not=warning:

## Also test that we are able to dump section headers even if the .dynsym section's sh_link field is broken.
# RUN: llvm-readobj %t16.link.0 --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \
# RUN:   --check-prefixes=LINK-BROKEN2,LINK-SEC-HDRS-LLVM,LINK-BROKEN-LLVM --implicit-check-not=warning:
# RUN: llvm-readelf %t16.link.0 --section-headers --dyn-symbols 2>&1 | FileCheck %s -DFILE=%t16.link.0 \
# RUN:   --check-prefixes=LINK-BROKEN2,LINK-SEC-HDRS-GNU,LINK-BROKEN-GNU --implicit-check-not=warning:

# LINK-BROKEN1: warning: '[[FILE]]': unable to get the string table for the SHT_DYNSYM section with index 1: invalid section index: 4294967295
# LINK-BROKEN2: warning: '[[FILE]]': unable to get the string table for the SHT_DYNSYM section with index 1: invalid sh_type for string table section [index 0]: expected SHT_STRTAB, but got SHT_NULL

# LINK-SEC-HDRS-LLVM: Sections [
# LINK-SEC-HDRS-GNU:  There are 5 section headers, starting at offset 0x80:

# LINK-BROKEN-LLVM:      DynamicSymbols [
# LINK-BROKEN-LLVM-NEXT: warning: '[[FILE]]': st_name (0x0) is past the end of the string table of size 0x0
# LINK-BROKEN-LLVM-NEXT:   Symbol {
# LINK-BROKEN-LLVM-NEXT:     Name: <?> (0)
# LINK-BROKEN-LLVM-NEXT:     Value: 0x0
# LINK-BROKEN-LLVM-NEXT:     Size: 0
# LINK-BROKEN-LLVM-NEXT:     Binding: Local (0x0)
# LINK-BROKEN-LLVM-NEXT:     Type: None (0x0)
# LINK-BROKEN-LLVM-NEXT:     Other: 0
# LINK-BROKEN-LLVM-NEXT:     Section: Undefined (0x0)
# LINK-BROKEN-LLVM-NEXT:   }
# LINK-BROKEN-LLVM-NEXT: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x0
# LINK-BROKEN-LLVM-NEXT:   Symbol {
# LINK-BROKEN-LLVM-NEXT:     Name: <?> (1)
# LINK-BROKEN-LLVM-NEXT:     Value: 0x0
# LINK-BROKEN-LLVM-NEXT:     Size: 0
# LINK-BROKEN-LLVM-NEXT:     Binding: Local (0x0)
# LINK-BROKEN-LLVM-NEXT:     Type: None (0x0)
# LINK-BROKEN-LLVM-NEXT:     Other: 0
# LINK-BROKEN-LLVM-NEXT:     Section: Undefined (0x0)
# LINK-BROKEN-LLVM-NEXT:   }
# LINK-BROKEN-LLVM-NEXT: ]

# LINK-BROKEN-GNU:      Symbol table '.dynsym' contains 2 entries:
# LINK-BROKEN-GNU-NEXT:    Num:    Value  Size Type    Bind   Vis       Ndx Name
# LINK-BROKEN-GNU-NEXT: warning: '[[FILE]]': st_name (0x0) is past the end of the string table of size 0x0
# LINK-BROKEN-GNU-NEXT:      0: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND <?>
# LINK-BROKEN-GNU-NEXT: warning: '[[FILE]]': st_name (0x1) is past the end of the string table of size 0x0
# LINK-BROKEN-GNU-NEXT:      1: 00000000     0 NOTYPE  LOCAL  DEFAULT   UND <?>