| |
| # 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 |
| |