xref: /llvm-project/llvm/test/ExecutionEngine/JITLink/x86-64/MachO_relocations.s (revision 8ad75c1037289b06bd1b95ff445797d380d93039)
1# RUN: rm -rf %t && mkdir -p %t
2# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj -o %t/macho_reloc.o %s
3# RUN: llvm-jitlink -noexec \
4# RUN:    -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
5# RUN:    -abs external_data=0x1 -abs external_func=0x2 \
6# RUN:    -check=%s %t/macho_reloc.o
7#
8# Test standard MachO relocations. Simulates slab allocation in the top 1Mb of
9# memory and places external symbols in the lowest page to prevent GOT and stub
10# elimination.
11
12        .section        __TEXT,__text,regular,pure_instructions
13
14# Check that common symbols work.
15# jitlink-check: *{4}common_symbol = 0
16# jitlink-check: common_symbol[1:0] = 0
17.comm   common_symbol,4,2
18
19        .align  4, 0x90
20Lanon_func:
21        retq
22
23        .globl  named_func
24        .align  4, 0x90
25named_func:
26        xorq    %rax, %rax
27        retq
28
29# Check X86_64_RELOC_BRANCH handling with a call to a local function.
30#
31# jitlink-check: decode_operand(test_local_call, 0) = named_func - next_pc(test_local_call)
32        .globl  test_local_call
33        .align  4, 0x90
34test_local_call:
35        callq   named_func
36        retq
37
38        .globl  _main
39        .align  4, 0x90
40_main:
41        retq
42
43# Check X86_64_RELOC_GOTPCREL handling with a load from an external symbol.
44# Validate both the reference to the GOT entry, and also the content of the GOT
45# entry.
46#
47# jitlink-check: decode_operand(test_gotld, 4) = got_addr(macho_reloc.o, external_data) - next_pc(test_gotld)
48# jitlink-check: *{8}(got_addr(macho_reloc.o, external_data)) = external_data
49        .globl  test_gotld
50        .align  4, 0x90
51test_gotld:
52        movq    external_data@GOTPCREL(%rip), %rax
53        retq
54
55
56# Check X86_64_RELOC_GOTPCREL handling with cmp instructions, which have
57# negative addends.
58#
59# jitlink-check: decode_operand(test_gotcmpq, 3) = got_addr(macho_reloc.o, external_data) - next_pc(test_gotcmpq)
60        .globl  test_gotcmpq
61        .align  4, 0x90
62test_gotcmpq:
63        cmpq    $0, external_data@GOTPCREL(%rip)
64        retq
65
66# Check that calls to external functions trigger the generation of stubs and GOT
67# entries.
68#
69# jitlink-check: decode_operand(test_external_call, 0) = stub_addr(macho_reloc.o, external_func) - next_pc(test_external_call)
70# jitlink-check: *{8}(got_addr(macho_reloc.o, external_func)) = external_func
71        .globl  test_external_call
72        .align  4, 0x90
73test_external_call:
74        callq   external_func
75        retq
76
77# Check signed relocation handling:
78#
79# X86_64_RELOC_SIGNED / Extern -- movq address of linker global
80# X86_64_RELOC_SIGNED1 / Extern -- movb immediate byte to linker global
81# X86_64_RELOC_SIGNED2 / Extern -- movw immediate word to linker global
82# X86_64_RELOC_SIGNED4 / Extern -- movl immediate long to linker global
83#
84# X86_64_RELOC_SIGNED / Anon -- movq address of linker private into register
85# X86_64_RELOC_SIGNED1 / Anon -- movb immediate byte to linker private
86# X86_64_RELOC_SIGNED2 / Anon -- movw immediate word to linker private
87# X86_64_RELOC_SIGNED4 / Anon -- movl immediate long to linker private
88signed_reloc_checks:
89        .globl signed
90# jitlink-check: decode_operand(signed, 4) = named_data - next_pc(signed)
91signed:
92        movq named_data(%rip), %rax
93
94        .globl signed1
95# jitlink-check: decode_operand(signed1, 3) = named_data - next_pc(signed1)
96signed1:
97        movb $0xAA, named_data(%rip)
98
99        .globl signed2
100# jitlink-check: decode_operand(signed2, 3) = named_data - next_pc(signed2)
101signed2:
102        movw $0xAAAA, named_data(%rip)
103
104        .globl signed4
105# jitlink-check: decode_operand(signed4, 3) = named_data - next_pc(signed4)
106signed4:
107        movl $0xAAAAAAAA, named_data(%rip)
108
109        .globl signedanon
110# jitlink-check: decode_operand(signedanon, 4) = \
111# jitlink-check:     section_addr(macho_reloc.o, __DATA,__data) - next_pc(signedanon)
112signedanon:
113        movq Lanon_data(%rip), %rax
114
115        .globl signed1anon
116# jitlink-check: decode_operand(signed1anon, 3) = \
117# jitlink-check:     section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed1anon)
118signed1anon:
119        movb $0xAA, Lanon_data(%rip)
120
121        .globl signed2anon
122# jitlink-check: decode_operand(signed2anon, 3) = \
123# jitlink-check:     section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed2anon)
124signed2anon:
125        movw $0xAAAA, Lanon_data(%rip)
126
127        .globl signed4anon
128# jitlink-check: decode_operand(signed4anon, 3) = \
129# jitlink-check:     section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed4anon)
130signed4anon:
131        movl $0xAAAAAAAA, Lanon_data(%rip)
132
133
134
135        .section        __DATA,__data
136
137# Storage target for non-extern X86_64_RELOC_SIGNED_(1/2/4) relocs.
138        .p2align  3
139Lanon_data:
140        .quad   0x1111111111111111
141
142# Check X86_64_RELOC_SUBTRACTOR Quad/Long in anonymous storage with anonymous
143# minuend: "LA: .quad LA - B + C". The anonymous subtrahend form
144# "LA: .quad B - LA + C" is not tested as subtrahends are not permitted to be
145# anonymous.
146#
147# Note: +8 offset in expression below to accounts for sizeof(Lanon_data).
148# jitlink-check: *{8}(section_addr(macho_reloc.o, __DATA,__data) + 8) = \
149# jitlink-check:     (section_addr(macho_reloc.o, __DATA,__data) + 8) - named_data - 2
150        .p2align  3
151Lanon_minuend_quad:
152        .quad Lanon_minuend_quad - named_data - 2
153
154# Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long).
155# jitlink-check: *{4}(section_addr(macho_reloc.o, __DATA,__data) + 16) = \
156# jitlink-check:     ((section_addr(macho_reloc.o, __DATA,__data) + 16) - named_data - 2)[31:0]
157        .p2align  2
158Lanon_minuend_long:
159        .long Lanon_minuend_long - named_data - 2
160
161# Named quad storage target (first named atom in __data).
162        .globl named_data
163        .p2align  3
164named_data:
165        .quad   0x2222222222222222
166
167# An alt-entry point for named_data
168        .globl named_data_alt_entry
169        .p2align  3
170        .alt_entry named_data_alt_entry
171named_data_alt_entry:
172        .quad   0
173
174# Check X86_64_RELOC_UNSIGNED / quad / extern handling by putting the address of
175# a local named function into a quad symbol.
176#
177# jitlink-check: *{8}named_func_addr_quad = named_func
178        .globl  named_func_addr_quad
179        .p2align  3
180named_func_addr_quad:
181        .quad   named_func
182
183# Check X86_64_RELOC_UNSIGNED / long / extern handling by putting the address of
184# an external function (defined to reside in the low 4Gb) into a long symbol.
185#
186# jitlink-check: *{4}named_func_addr_long = external_func
187        .globl  named_func_addr_long
188        .p2align  2
189named_func_addr_long:
190        .long   external_func
191
192# Check X86_64_RELOC_UNSIGNED / quad / non-extern handling by putting the
193# address of a local anonymous function into a quad symbol.
194#
195# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __TEXT,__text)
196        .globl  anon_func_addr_quad
197        .p2align  3
198anon_func_addr_quad:
199        .quad   Lanon_func
200
201# X86_64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend
202#
203# jitlink-check: *{8}anon_minuend_quad1 = \
204# jitlink-check:     section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_quad1 - 2
205# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is
206# invalid because the subtrahend can not be local.
207        .globl  anon_minuend_quad1
208        .p2align  3
209anon_minuend_quad1:
210        .quad Lanon_data - anon_minuend_quad1 - 2
211
212# jitlink-check: *{4}anon_minuend_long1 = \
213# jitlink-check:     (section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_long1 - 2)[31:0]
214        .globl  anon_minuend_long1
215        .p2align  2
216anon_minuend_long1:
217        .long Lanon_data - anon_minuend_long1 - 2
218
219# Check X86_64_RELOC_SUBTRACTOR Quad/Long in named storage with minuend and subtrahend.
220# Both forms "A: .quad A - B + C" and "A: .quad B - A + C" are tested.
221#
222# Check "A: .quad B - A + C".
223# jitlink-check: *{8}subtrahend_quad2 = (named_data - subtrahend_quad2 - 2)
224        .globl  subtrahend_quad2
225        .p2align  3
226subtrahend_quad2:
227        .quad named_data - subtrahend_quad2 - 2
228
229# Check "A: .long B - A + C".
230# jitlink-check: *{4}subtrahend_long2 = (named_data - subtrahend_long2 - 2)[31:0]
231        .globl  subtrahend_long2
232        .p2align  2
233subtrahend_long2:
234        .long named_data - subtrahend_long2 - 2
235
236# Check "A: .quad A - B + C".
237# jitlink-check: *{8}minuend_quad3 = (minuend_quad3 - named_data - 2)
238        .globl  minuend_quad3
239        .p2align  3
240minuend_quad3:
241        .quad minuend_quad3 - named_data - 2
242
243# Check "A: .long B - A + C".
244# jitlink-check: *{4}minuend_long3 = (minuend_long3 - named_data - 2)[31:0]
245        .globl  minuend_long3
246        .p2align  2
247minuend_long3:
248        .long minuend_long3 - named_data - 2
249
250# Check X86_64_RELOC_SUBTRACTOR handling for exprs of the form
251# "A: .quad/long B - C + D", where 'B' or 'C' is at a fixed offset from 'A'
252# (i.e. is part of an alt_entry chain that includes 'A').
253#
254# Check "A: .long B - C + D" where 'B' is an alt_entry for 'A'.
255# jitlink-check: *{4}subtractor_with_alt_entry_minuend_long = (subtractor_with_alt_entry_minuend_long_B - named_data - 2)[31:0]
256        .globl  subtractor_with_alt_entry_minuend_long
257        .p2align  2
258subtractor_with_alt_entry_minuend_long:
259        .long subtractor_with_alt_entry_minuend_long_B - named_data - 2
260
261        .globl  subtractor_with_alt_entry_minuend_long_B
262        .p2align  2
263        .alt_entry subtractor_with_alt_entry_minuend_long_B
264subtractor_with_alt_entry_minuend_long_B:
265        .long 0
266
267# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.
268# jitlink-check: *{8}subtractor_with_alt_entry_minuend_quad = (subtractor_with_alt_entry_minuend_quad_B - named_data - 2)
269        .globl  subtractor_with_alt_entry_minuend_quad
270        .p2align  3
271subtractor_with_alt_entry_minuend_quad:
272        .quad subtractor_with_alt_entry_minuend_quad_B - named_data - 2
273
274        .globl  subtractor_with_alt_entry_minuend_quad_B
275        .p2align  3
276        .alt_entry subtractor_with_alt_entry_minuend_quad_B
277subtractor_with_alt_entry_minuend_quad_B:
278        .quad 0
279
280# Check "A: .long B - C + D" where 'C' is an alt_entry for 'A'.
281# jitlink-check: *{4}subtractor_with_alt_entry_subtrahend_long = (named_data - subtractor_with_alt_entry_subtrahend_long_B - 2)[31:0]
282        .globl  subtractor_with_alt_entry_subtrahend_long
283        .p2align  2
284subtractor_with_alt_entry_subtrahend_long:
285        .long named_data - subtractor_with_alt_entry_subtrahend_long_B - 2
286
287        .globl  subtractor_with_alt_entry_subtrahend_long_B
288        .p2align  2
289        .alt_entry subtractor_with_alt_entry_subtrahend_long_B
290subtractor_with_alt_entry_subtrahend_long_B:
291        .long 0
292
293# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.
294# jitlink-check: *{8}subtractor_with_alt_entry_subtrahend_quad = (named_data - subtractor_with_alt_entry_subtrahend_quad_B - 2)
295        .globl  subtractor_with_alt_entry_subtrahend_quad
296        .p2align  3
297subtractor_with_alt_entry_subtrahend_quad:
298        .quad named_data - subtractor_with_alt_entry_subtrahend_quad_B - 2
299
300        .globl  subtractor_with_alt_entry_subtrahend_quad_B
301        .p2align  3
302        .alt_entry subtractor_with_alt_entry_subtrahend_quad_B
303subtractor_with_alt_entry_subtrahend_quad_B:
304        .quad 0
305
306# Check X86_64_RELOC_GOT handling.
307# X86_64_RELOC_GOT is the data-section counterpart to X86_64_RELOC_GOTLD. It is
308# handled exactly the same way, including having an implicit PC-rel offset of -4
309# (despite this not making sense in a data section, and requiring an explicit
310# +4 addend to cancel it out and get the correct result).
311#
312# jitlink-check: *{4}test_got = (got_addr(macho_reloc.o, external_data) - test_got)[31:0]
313        .globl test_got
314        .p2align  2
315test_got:
316        .long   external_data@GOTPCREL + 4
317
318# Check that unreferenced atoms in no-dead-strip sections are not dead stripped.
319# We need to use a local symbol for this as any named symbol will end up in the
320# ORC responsibility set, which is automatically marked live and would couse
321# spurious passes.
322#
323# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_sect) = 0
324        .section        __DATA,__nds_test_sect,regular,no_dead_strip
325        .quad 0
326
327# Check that unreferenced local symbols that have been marked no-dead-strip are
328# not dead-striped.
329#
330# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_nlst) = 0
331        .section       __DATA,__nds_test_nlst,regular
332        .no_dead_strip no_dead_strip_test_symbol
333no_dead_strip_test_symbol:
334        .quad 0
335
336# Check that explicit zero-fill symbols are supported
337# jitlink-check: *{8}zero_fill_test = 0
338        .globl zero_fill_test
339.zerofill __DATA,__zero_fill_test,zero_fill_test,8,3
340
341# Check that section alignments are respected.
342# We test this by introducing two segments with alignment 8, each containing one
343# byte of data. We require both symbols to have an aligned address.
344#
345# jitlink-check: section_alignment_check1[2:0] = 0
346# jitlink-check: section_alignment_check2[2:0] = 0
347        .section        __DATA,__sec_align_chk1
348        .p2align 3
349
350        .globl section_alignment_check1
351section_alignment_check1:
352        .byte 0
353
354        .section        __DATA,__sec_align_chk2
355        .p2align 3
356
357        .globl section_alignment_check2
358section_alignment_check2:
359        .byte 0
360
361.subsections_via_symbols
362