# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s \ # RUN: && lld -flavor darwin -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