
# RUN: ld64.lld -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s \
# RUN: && ld64.lld -arch x86_64 %t -r -print_atoms -o %t2  | FileCheck %s
#
# Test parsing and writing of x86_64 data relocations.
#
# The first step tests if the supplied mach-o file is parsed into the correct
# set of references.  The second step verifies relocations can be round-tripped
# by writing to a new .o file, then parsing that file which should result in
# the same references.
#
#_foo:
#  ret
#
#_bar:
#  ret
#
#  .section __DATA,__custom
#L1:
#  .quad 0
#
#  .data
#_d:
#  .quad   _foo
#  .quad   _foo+4
#  .quad   _foo - .
#  .quad   L1
#  .quad   L1 + 2
#  .quad   _foo - .
#  .quad   _foo + 4 - .
#  .quad   L1 - .
#  .long   _foo - .
#  .long   _foo + 4 - .
#  .long   L1 - .
#

--- !mach-o
arch:            x86_64
file-type:       MH_OBJECT
flags:           [  ]
compat-version:  0.0
current-version: 0.0
has-UUID:        false
OS:              unknown
sections:
  - segment:         __TEXT
    section:         __text
    type:            S_REGULAR
    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
    address:         0x0000000000000000
    content:         [ 0xC3, 0xC3 ]
  - segment:         __DATA
    section:         __custom
    type:            S_REGULAR
    attributes:      [  ]
    address:         0x0000000000000002
    content:         [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
  - segment:         __DATA
    section:         __data
    type:            S_REGULAR
    attributes:      [  ]
    address:         0x000000000000000A
    content:         [
#  .quad   _foo
# No addend is needed here as we are referencing _foo directly and that is
# encoded entirely in the X86_64_RELOC_UNSIGNED
                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#  .quad   _foo+4
# Addend of 4 is needed here as we are referencing _foo from the
# X86_64_RELOC_UNSIGNED, then the addend gives us 4 more.
                       0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#  .quad   _foo - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -16 because that is the offset from here back
# to _d.
                       0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
#  .quad   . - _foo
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -16 because that is the offset from here back
# to _d.
                       0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#  .quad   L1
# This is a X86_64_RELOC_UNSIGNED without extern set.
# In this case, we encode the section number for L1 in the relocation, and
# the addend here is the absolute address of the location in that section
# we want to reference.
                       0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#  .quad   L1 + 2
# This is a X86_64_RELOC_UNSIGNED without extern set.
# In this case, we encode the section number for L1 in the relocation, and
# the addend here is the absolute address of the location in that section
# we want to reference.  We have a 4 because the section is at address 2
# and we want an offset of 2 from there.
                       0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#  .quad   _foo - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -40 because that is the offset from here back
# to _d.
                       0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
#  .quad   _foo + 4 - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -52.  It would have been -56 because that
# would take us from the address of this relocation back to _d.  But as
# we also add 4 for the offset, we get -52.
                       0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
#  .quad   L1 - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned does not have extern set, so the relocation
# number is the section number for L1.
# Note the addend here is -62. Of that, -64 would be the offset from
# this location from _d.  The remaining 2 is the absolute address
# of L1.
                       0xC2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
#  .long   _foo - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -72 because that is the offset from here back
# to _d.
                       0xB8, 0xFF, 0xFF, 0xFF,
#  .long   . - _foo
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -76 because that is the offset from here back
# to _d.
                       0xB4, 0xFF, 0xFF, 0xFF,
#  .long   _foo + 4 - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned references _foo.
# Note the addend here is -76.  It would have been -80 because that
# would take us from the address of this relocation back to _d.  But as
# we also add 4 for the offset, we get -76.
                       0xB4, 0xFF, 0xFF, 0xFF,
#  .long   L1 - .
# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
# The subtractor references _d which is the first nonlocal label in this
# section.  The unsigned does not have extern set, so the relocation
# number is the section number for L1.
# Note the addend here is -82. Of that, -84 would be the offset from
# this location from _d.  The remaining 2 is the absolute address
# of L1.
                       0xAE, 0xFF, 0xFF, 0xFF ]
    relocations:
      - offset:          0x00000054
        type:            X86_64_RELOC_SUBTRACTOR
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000054
        type:            X86_64_RELOC_UNSIGNED
        length:          2
        pc-rel:          false
        extern:          false
        symbol:          2
      - offset:          0x00000050
        type:            X86_64_RELOC_SUBTRACTOR
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000050
        type:            X86_64_RELOC_UNSIGNED
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x0000004C
        type:            X86_64_RELOC_SUBTRACTOR
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x0000004C
        type:            X86_64_RELOC_UNSIGNED
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000048
        type:            X86_64_RELOC_SUBTRACTOR
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000048
        type:            X86_64_RELOC_UNSIGNED
        length:          2
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x00000040
        type:            X86_64_RELOC_SUBTRACTOR
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000040
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          false
        symbol:          2
      - offset:          0x00000038
        type:            X86_64_RELOC_SUBTRACTOR
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000038
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x00000030
        type:            X86_64_RELOC_SUBTRACTOR
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000030
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x00000028
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          false
        symbol:          2
      - offset:          0x00000020
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          false
        symbol:          2
      - offset:          0x00000018
        type:            X86_64_RELOC_SUBTRACTOR
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x00000018
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000010
        type:            X86_64_RELOC_SUBTRACTOR
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          2
      - offset:          0x00000010
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x00000008
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          0
      - offset:          0x00000000
        type:            X86_64_RELOC_UNSIGNED
        length:          3
        pc-rel:          false
        extern:          true
        symbol:          0
local-symbols:
  - name:            _foo
    type:            N_SECT
    sect:            1
    value:           0x0000000000000000
  - name:            _bar
    type:            N_SECT
    sect:            1
    value:           0x0000000000000001
  - name:            _d
    type:            N_SECT
    sect:            3
    value:           0x000000000000000A
page-size:       0x00000000
...


# CHECK:defined-atoms:
# CHECK:  - name:            _d
# CHECK:    type:            data
# CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00, 04, 00, 00, 00,
# CHECK:                       00, 00, 00, 00, F0, FF, FF, FF, FF, FF, FF, FF,
# CHECK:                       18, 00, 00, 00, 00, 00, 00, 00, {{..}}, {{..}}, 00, 00,
# CHECK:                       00, 00, 00, 00, {{..}}, {{..}}, 00, 00, 00, 00, 00, 00,
# CHECK:                       D0, FF, FF, FF, FF, FF, FF, FF, CC, FF, FF, FF,
# CHECK:                       FF, FF, FF, FF, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}},
# CHECK:                       B8, FF, FF, FF, B4, FF, FF, FF, B4, FF, FF, FF,
# CHECK:                       {{..}}, {{..}}, {{..}}, {{..}} ]
# CHECK:    dead-strip:      never
# CHECK:    references:
# CHECK:      - kind:            pointer64
# CHECK:        offset:          0
# CHECK:        target:          _foo
# CHECK:      - kind:            pointer64
# CHECK:        offset:          8
# CHECK:        target:          _foo
# CHECK:        addend:          4
# CHECK:      - kind:            delta64
# CHECK:        offset:          16
# CHECK:        target:          _foo
# CHECK:      - kind:            negDelta64
# CHECK:        offset:          24
# CHECK:        target:          _foo
# CHECK:      - kind:            pointer64Anon
# CHECK:        offset:          32
# CHECK:        target:          L003
# CHECK:      - kind:            pointer64Anon
# CHECK:        offset:          40
# CHECK:        target:          L003
# CHECK:        addend:          2
# CHECK:      - kind:            delta64
# CHECK:        offset:          48
# CHECK:        target:          _foo
# CHECK:      - kind:            delta64
# CHECK:        offset:          56
# CHECK:        target:          _foo
# CHECK:        addend:          4
# CHECK:      - kind:            delta64Anon
# CHECK:        offset:          64
# CHECK:        target:          L003
# CHECK:      - kind:            delta32
# CHECK:        offset:          72
# CHECK:        target:          _foo
# CHECK:      - kind:            negDelta32
# CHECK:        offset:          76
# CHECK:        target:          _foo
# CHECK:      - kind:            delta32
# CHECK:        offset:          80
# CHECK:        target:          _foo
# CHECK:        addend:          4
# CHECK:      - kind:            delta32Anon
# CHECK:        offset:          84
# CHECK:        target:          L003
# CHECK:  - name:            _foo
# CHECK:    content:         [ C3 ]
# CHECK:    dead-strip:      never
# CHECK:  - name:            _bar
# CHECK:    content:         [ C3 ]
# CHECK:    dead-strip:      never
# CHECK:  - ref-name:        L003
# CHECK:    type:            unknown
# CHECK:    content:         [ 00, 00, 00, 00, 00, 00, 00, 00 ]
# CHECK:    section-choice:  custom-required
# CHECK:    section-name:    '__DATA/__custom'
# CHECK:    dead-strip:      never

