## Show that when "DATA" is used with an address, it forces the found location
## to be symbolized as data, including the source information.

# RUN: yaml2obj %s -o %t.so

# RUN: llvm-symbolizer 'DATA 0x304d0' 'DATA 0x304d1' 'DATA 0x304d3' \
# RUN:   'DATA 0x304c0' 'DATA 0x304c8' 'DATA 0x304d4' 'DATA 0x304dc' \
# RUN:   'DATA 0x304d8' --obj=%t.so | FileCheck %s

# CHECK:      bss_global
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:1
# CHECK-EMPTY:

## Check that lookups in the middle of the symbol are also resolved correctly.
# CHECK:      bss_global
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:1
# CHECK-EMPTY:
# CHECK:      bss_global
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:1
# CHECK-EMPTY:

## Now, the remainder of the symbols.
# CHECK-NEXT: data_global
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:2
# CHECK-EMPTY:
# CHECK-NEXT: str
# CHECK-NEXT: {{[0-9]+}} 8
# CHECK-NEXT: /tmp/file.cpp:4
# CHECK-EMPTY:
# CHECK-NEXT: f()::function_global
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:8
# CHECK-EMPTY:

## Including the one that includes an addend.
# CHECK-NEXT: alpha
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:12
# CHECK-EMPTY:
# CHECK-NEXT: beta
# CHECK-NEXT: {{[0-9]+}} 4
# CHECK-NEXT: /tmp/file.cpp:13
# CHECK-EMPTY:

## Ensure there's still a global that's offset-based.
# RUN: llvm-dwarfdump --debug-info %t.so | FileCheck %s --check-prefix=OFFSET

# OFFSET: DW_AT_location (DW_OP_addrx 0x4, DW_OP_plus_uconst 0x4)

################################################################################
## File below was generated using:
##
##   $ clang++ -g -O3 /tmp/file.cpp -shared -fuse-ld=lld -nostdlib \
##     -target aarch64-linux-gnuabi -mllvm -global-merge-ignore-single-use \
##     -o /tmp/file.so
##
##  With /tmp/file.cpp as:
##    1: int bss_global;
##    2: int data_global = 2;
##    3:
##    4: const char* str =
##    5:     "12345678";
##    6:
##    7: int* f() {
##    8:   static int function_global;
##    9:   return &function_global;
##   10: }
##   11:
##   12: static int alpha;
##   13: static int beta;
##   14: int *f(bool b) { return beta ? &alpha : &beta; }
##   15:
##
## ... then, one can get the offsets using `nm`, like:
##   $ nm out.so | grep bss_global
##     00000000000038fc B bss_global
##
## Note the use of the aarch64 target (with -nostdlib in order to allow linkage
## without libraries for cross-compilation) as well as -O3 and
## -global-merge-ignore-single-use. This is a specific combination that makes
## the compiler emit the `alpha` global variable with a more complex
## DW_AT_location than just a DW_OP_addr/DW_OP_addrx. In this instance, it
## outputs a `DW_AT_location  (DW_OP_addrx 0x4, DW_OP_plus_uconst 0x4)`.
##
## Ideally, this would be tested by invoking clang directly on a C source file,
## but unfortunately there's no way to do that for LLVM tests. The other option
## is to compile IR to an objfile, but llvm-symbolizer doesn't understand that
## two symbols can have the same address in different sections. In the code
## above, for example, we'd have bss_global at .bss+0x0, and data_global at
## .data+0x0, and so the symbolizer would only print one of them. Hence, we have
## the ugly dso-to-yaml blob below.
##
## For now, constant strings don't have a debuginfo entry, and so can't be
## symbolized correctly. In future (if D123534 gets merged), this can be updated
## to include a check that llvm-symbolizer can also symbolize constant strings,
## like `str` above (basically that &"12345678" should be symbolizable)
## to the specific line. Then, you can find the address of the constant string
## from the relocation:
##
##   $ nm out.so | grep str
##     00000000000038c0 D str
##   $ llvm-objdump -R out.so | grep 38c0
##     00000000000038c0 R_X86_64_RELATIVE *ABS*+0x4f8 # <-- 0x4f8
################################################################################

--- !ELF
FileHeader:
  Class:           ELFCLASS64
  Data:            ELFDATA2LSB
  Type:            ET_DYN
  Machine:         EM_AARCH64
ProgramHeaders:
  - Type:            PT_PHDR
    Flags:           [ PF_R ]
    VAddr:           0x40
    Align:           0x8
  - Type:            PT_LOAD
    Flags:           [ PF_R ]
    FirstSec:        .dynsym
    LastSec:         .eh_frame
    Align:           0x10000
  - Type:            PT_LOAD
    Flags:           [ PF_X, PF_R ]
    FirstSec:        .text
    LastSec:         .text
    VAddr:           0x103E4
    Align:           0x10000
  - Type:            PT_LOAD
    Flags:           [ PF_W, PF_R ]
    FirstSec:        .dynamic
    LastSec:         .dynamic
    VAddr:           0x20410
    Align:           0x10000
  - Type:            PT_LOAD
    Flags:           [ PF_W, PF_R ]
    FirstSec:        .data
    LastSec:         .bss
    VAddr:           0x304C0
    Align:           0x10000
  - Type:            PT_DYNAMIC
    Flags:           [ PF_W, PF_R ]
    FirstSec:        .dynamic
    LastSec:         .dynamic
    VAddr:           0x20410
    Align:           0x8
  - Type:            PT_GNU_RELRO
    Flags:           [ PF_R ]
    FirstSec:        .dynamic
    LastSec:         .dynamic
    VAddr:           0x20410
  - Type:            PT_GNU_EH_FRAME
    Flags:           [ PF_R ]
    FirstSec:        .eh_frame_hdr
    LastSec:         .eh_frame_hdr
    VAddr:           0x37C
    Align:           0x4
  - Type:            PT_GNU_STACK
    Flags:           [ PF_W, PF_R ]
    Align:           0x0
Sections:
  - Name:            .dynsym
    Type:            SHT_DYNSYM
    Flags:           [ SHF_ALLOC ]
    Address:         0x238
    Link:            .dynstr
    AddressAlign:    0x8
  - Name:            .gnu.hash
    Type:            SHT_GNU_HASH
    Flags:           [ SHF_ALLOC ]
    Address:         0x2C8
    Link:            .dynsym
    AddressAlign:    0x8
    Header:
      SymNdx:          0x1
      Shift2:          0x1A
    BloomFilter:     [ 0x400188002180000C ]
    HashBuckets:     [ 0x1 ]
    HashValues:      [ 0xEE8502A, 0xEE85016, 0xC033991C, 0x61F7372E, 0xB88AB7F ]
  - Name:            .hash
    Type:            SHT_HASH
    Flags:           [ SHF_ALLOC ]
    Address:         0x2F8
    Link:            .dynsym
    AddressAlign:    0x4
    Bucket:          [ 5, 0, 4, 0, 3, 0 ]
    Chain:           [ 0, 0, 0, 1, 2, 0 ]
  - Name:            .dynstr
    Type:            SHT_STRTAB
    Flags:           [ SHF_ALLOC ]
    Address:         0x330
    AddressAlign:    0x1
  - Name:            .rela.dyn
    Type:            SHT_RELA
    Flags:           [ SHF_ALLOC ]
    Address:         0x358
    Link:            .dynsym
    AddressAlign:    0x8
    Relocations:
      - Offset:          0x304C8
        Type:            R_AARCH64_RELATIVE
        Addend:          880
  - Name:            .rodata
    Type:            SHT_PROGBITS
    Flags:           [ SHF_ALLOC, SHF_MERGE, SHF_STRINGS ]
    Address:         0x370
    AddressAlign:    0x1
    EntSize:         0x1
    Content:         '313233343536373800'
  - Name:            .eh_frame_hdr
    Type:            SHT_PROGBITS
    Flags:           [ SHF_ALLOC ]
    Address:         0x37C
    AddressAlign:    0x4
    Content:         011B033B18000000020000006800010034000000740001004C000000
  - Name:            .eh_frame
    Type:            SHT_PROGBITS
    Flags:           [ SHF_ALLOC ]
    Address:         0x398
    AddressAlign:    0x8
    Content:         1400000000000000017A5200017C1E011B0C1F0000000000140000001C0000002C0001000C00000000000000000000001400000034000000200001001C000000000000000000000000000000
  - Name:            .text
    Type:            SHT_PROGBITS
    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
    Address:         0x103E4
    AddressAlign:    0x4
    Content:         0001009000501391C0035FD60801009008611391E90308AA2A4540B85F0100710001899AC0035FD6
  - Name:            .dynamic
    Type:            SHT_DYNAMIC
    Flags:           [ SHF_WRITE, SHF_ALLOC ]
    Address:         0x20410
    Link:            .dynstr
    AddressAlign:    0x8
    Entries:
      - Tag:             DT_RELA
        Value:           0x358
      - Tag:             DT_RELASZ
        Value:           0x18
      - Tag:             DT_RELAENT
        Value:           0x18
      - Tag:             DT_RELACOUNT
        Value:           0x1
      - Tag:             DT_SYMTAB
        Value:           0x238
      - Tag:             DT_SYMENT
        Value:           0x18
      - Tag:             DT_STRTAB
        Value:           0x330
      - Tag:             DT_STRSZ
        Value:           0x28
      - Tag:             DT_GNU_HASH
        Value:           0x2C8
      - Tag:             DT_HASH
        Value:           0x2F8
      - Tag:             DT_NULL
        Value:           0x0
  - Name:            .data
    Type:            SHT_PROGBITS
    Flags:           [ SHF_WRITE, SHF_ALLOC ]
    Address:         0x304C0
    AddressAlign:    0x8
    Content:         '02000000000000000000000000000000'
  - Name:            .bss
    Type:            SHT_NOBITS
    Flags:           [ SHF_WRITE, SHF_ALLOC ]
    Address:         0x304D0
    AddressAlign:    0x4
    Size:            0x10
  - Name:            .debug_abbrev
    Type:            SHT_PROGBITS
    AddressAlign:    0x1
    Content:         011101252513050325721710171B25111B120673170000023400032549133F193A0B3B0B0218000003240003253E0B0B0B0000040F004913000005260049130000062E01111B120640187A196E2503253A0B3B0B49133F190000073400032549133A0B3B0B02180000083400032549133A0B3B0B02186E25000009050003253A0B3B0B4913000000
  - Name:            .debug_info
    Type:            SHT_PROGBITS
    AddressAlign:    0x1
    Content:         AB0000000500010800000000010021000108000000000000000205280000000800000002032E000000000102A1000304050402052E000000000202A101020648000000000402A102044D00000005520000000307080106050C000000016F0D0E0007A500000007082E000000000802A1030008092E000000000D02A1040A080B2E000000000C04A10423040C06061C000000016F0F0E000EA50000000910000EAA00000000042E0000000311020100
  - Name:            .debug_str_offsets
    Type:            SHT_PROGBITS
    AddressAlign:    0x1
    Content:         4C00000005000000A2000000000000002C00000059000000280000001C00000072000000640000008C0000008700000069000000140000007B0000009C0000001A0000000E0000008500000076000000
  - Name:            .comment
    Type:            SHT_PROGBITS
    Flags:           [ SHF_MERGE, SHF_STRINGS ]
    AddressAlign:    0x1
    EntSize:         0x1
    Content:         4C696E6B65723A204C4C442031352E302E300000636C616E672076657273696F6E2031352E302E30202868747470733A2F2F6769746875622E636F6D2F6C6C766D2F6C6C766D2D70726F6A6563742E67697420306462616566363162353666306566306162306366333865613932666663316633356265653366662900
  - Name:            .debug_line
    Type:            SHT_PROGBITS
    AddressAlign:    0x1
    Content:         620000000500080037000000010101FB0E0D00010101010000000100000101011F010E00000003011F020F051E0100000000006C97BBE59F7DC6A9EA956633431DA63E0400000902E4030100000000001805030A140500BF05190A0105120608740204000101
  - Name:            .debug_line_str
    Type:            SHT_PROGBITS
    Flags:           [ SHF_MERGE, SHF_STRINGS ]
    AddressAlign:    0x1
    EntSize:         0x1
    Content:         2F746D702F66696C652E637070002F7573722F6C6F63616C2F676F6F676C652F686F6D652F6D69746368702F6C6C766D2D6275696C642F6F707400
Symbols:
  - Name:            file.cpp
    Type:            STT_FILE
    Index:           SHN_ABS
  - Name:            '$x.0'
    Section:         .text
    Value:           0x103E4
  - Name:            _ZZ1fvE15function_global
    Type:            STT_OBJECT
    Section:         .bss
    Value:           0x304D4
    Size:            0x4
  - Name:            '$d.1'
    Section:         .bss
    Value:           0x304D0
  - Name:            '$d.2'
    Section:         .data
    Value:           0x304C0
  - Name:            '$d.3'
    Section:         .rodata
    Value:           0x370
  - Name:            '$d.4'
    Section:         .debug_abbrev
  - Name:            '$d.5'
    Section:         .debug_info
  - Name:            '$d.6'
    Section:         .debug_str_offsets
  - Name:            '$d.7'
    Section:         .debug_str
    Value:           0xA2
  - Name:            '$d.8'
    Section:         .debug_addr
  - Name:            _ZL4beta
    Type:            STT_OBJECT
    Section:         .bss
    Value:           0x304D8
    Size:            0x4
  - Name:            _ZL5alpha
    Type:            STT_OBJECT
    Section:         .bss
    Value:           0x304DC
    Size:            0x4
  - Name:            '$d.9'
    Section:         .comment
    Value:           0x13
  - Name:            '$d.10'
    Section:         .eh_frame
    Value:           0x398
  - Name:            '$d.11'
    Section:         .debug_line
  - Name:            '$d.12'
    Section:         .debug_line_str
    Value:           0xE
  - Name:            _DYNAMIC
    Section:         .dynamic
    Value:           0x20410
    Other:           [ STV_HIDDEN ]
  - Name:            _Z1fv
    Type:            STT_FUNC
    Section:         .text
    Binding:         STB_GLOBAL
    Value:           0x103E4
    Size:            0xC
  - Name:            _Z1fb
    Type:            STT_FUNC
    Section:         .text
    Binding:         STB_GLOBAL
    Value:           0x103F0
    Size:            0x1C
  - Name:            bss_global
    Type:            STT_OBJECT
    Section:         .bss
    Binding:         STB_GLOBAL
    Value:           0x304D0
    Size:            0x4
  - Name:            data_global
    Type:            STT_OBJECT
    Section:         .data
    Binding:         STB_GLOBAL
    Value:           0x304C0
    Size:            0x4
  - Name:            str
    Type:            STT_OBJECT
    Section:         .data
    Binding:         STB_GLOBAL
    Value:           0x304C8
    Size:            0x8
DynamicSymbols:
  - Name:            _Z1fv
    Type:            STT_FUNC
    Section:         .text
    Binding:         STB_GLOBAL
    Value:           0x103E4
    Size:            0xC
  - Name:            _Z1fb
    Type:            STT_FUNC
    Section:         .text
    Binding:         STB_GLOBAL
    Value:           0x103F0
    Size:            0x1C
  - Name:            bss_global
    Type:            STT_OBJECT
    Section:         .bss
    Binding:         STB_GLOBAL
    Value:           0x304D0
    Size:            0x4
  - Name:            data_global
    Type:            STT_OBJECT
    Section:         .data
    Binding:         STB_GLOBAL
    Value:           0x304C0
    Size:            0x4
  - Name:            str
    Type:            STT_OBJECT
    Section:         .data
    Binding:         STB_GLOBAL
    Value:           0x304C8
    Size:            0x8
DWARF:
  debug_str:
    - '/tmp/file.cpp'
    - _Z1fb
    - alpha
    - f
    - data_global
    - int
    - '/usr/local/google/home/mitchp/llvm-build/opt'
    - bss_global
    - char
    - _ZL4beta
    - str
    - bool
    - _ZL5alpha
    - b
    - beta
    - function_global
    - _Z1fv
    - 'clang version 15.0.0 (https://github.com/llvm/llvm-project.git 0dbaef61b56f0ef0ab0cf38ea92ffc1f35bee3ff)'
  debug_addr:
    - Length:          0x3C
      Version:         0x5
      AddressSize:     0x8
      Entries:
        - Address:         0x304D0
        - Address:         0x304C0
        - Address:         0x304C8
        - Address:         0x304D4
        - Address:         0x304D8
        - Address:         0x103E4
        - Address:         0x103F0
...
