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 -slab-allocate 100Kb -slab-address 0xfff00000 \
4 # RUN: -define-abs external_data=0x1 -define-abs external_func=0x2 \
5 # RUN: -check=%s %t/macho_reloc.o
7 # Test standard MachO relocations. Simulates slab allocation in the top 1Mb of
8 # memory and places external symbols in the lowest page to prevent GOT and stub
11 .section __TEXT,__text,regular,pure_instructions
13 # Check that common symbols work.
14 # jitlink-check: *{4}common_symbol = 0
15 # jitlink-check: common_symbol[1:0] = 0
16 .comm common_symbol,4,2
28 # Check X86_64_RELOC_BRANCH handling with a call to a local function.
30 # jitlink-check: decode_operand(test_local_call, 0) = named_func - next_pc(test_local_call)
31 .globl test_local_call
42 # Check X86_64_RELOC_GOTPCREL handling with a load from an external symbol.
43 # Validate both the reference to the GOT entry, and also the content of the GOT
46 # jitlink-check: decode_operand(test_gotld, 4) = got_addr(macho_reloc.o, external_data) - next_pc(test_gotld)
47 # jitlink-check: *{8}(got_addr(macho_reloc.o, external_data)) = external_data
51 movq external_data@GOTPCREL
(%rip
), %rax
55 # Check X86_64_RELOC_GOTPCREL handling with cmp instructions, which have
58 # jitlink-check: decode_operand(test_gotcmpq, 3) = got_addr(macho_reloc.o, external_data) - next_pc(test_gotcmpq)
62 cmpq $
0, external_data@GOTPCREL
(%rip
)
65 # Check that calls to external functions trigger the generation of stubs and GOT
68 # jitlink-check: decode_operand(test_external_call, 0) = stub_addr(macho_reloc.o, external_func) - next_pc(test_external_call)
69 # jitlink-check: *{8}(got_addr(macho_reloc.o, external_func)) = external_func
70 .globl test_external_call
76 # Check signed relocation handling:
78 # X86_64_RELOC_SIGNED / Extern -- movq address of linker global
79 # X86_64_RELOC_SIGNED1 / Extern -- movb immediate byte to linker global
80 # X86_64_RELOC_SIGNED2 / Extern -- movw immediate word to linker global
81 # X86_64_RELOC_SIGNED4 / Extern -- movl immediate long to linker global
83 # X86_64_RELOC_SIGNED / Anon -- movq address of linker private into register
84 # X86_64_RELOC_SIGNED1 / Anon -- movb immediate byte to linker private
85 # X86_64_RELOC_SIGNED2 / Anon -- movw immediate word to linker private
86 # X86_64_RELOC_SIGNED4 / Anon -- movl immediate long to linker private
89 # jitlink-check: decode_operand(signed, 4) = named_data - next_pc(signed)
91 movq named_data
(%rip
), %rax
94 # jitlink-check: decode_operand(signed1, 3) = named_data - next_pc(signed1)
96 movb $
0xAA, named_data
(%rip
)
99 # jitlink-check: decode_operand(signed2, 3) = named_data - next_pc(signed2)
101 movw $
0xAAAA, named_data
(%rip
)
104 # jitlink-check: decode_operand(signed4, 3) = named_data - next_pc(signed4)
106 movl $
0xAAAAAAAA, named_data
(%rip
)
109 # jitlink-check: decode_operand(signedanon, 4) = \
110 # jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signedanon)
112 movq Lanon_data
(%rip
), %rax
115 # jitlink-check: decode_operand(signed1anon, 3) = \
116 # jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed1anon)
118 movb $
0xAA, Lanon_data
(%rip
)
121 # jitlink-check: decode_operand(signed2anon, 3) = \
122 # jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed2anon)
124 movw $
0xAAAA, Lanon_data
(%rip
)
127 # jitlink-check: decode_operand(signed4anon, 3) = \
128 # jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - next_pc(signed4anon)
130 movl $
0xAAAAAAAA, Lanon_data
(%rip
)
134 .section __DATA,__data
136 # Storage target for non-extern X86_64_RELOC_SIGNED_(1/2/4) relocs.
139 .quad 0x1111111111111111
141 # Check X86_64_RELOC_SUBTRACTOR Quad/Long in anonymous storage with anonymous
142 # minuend: "LA: .quad LA - B + C". The anonymous subtrahend form
143 # "LA: .quad B - LA + C" is not tested as subtrahends are not permitted to be
146 # Note: +8 offset in expression below to accounts for sizeof(Lanon_data).
147 # jitlink-check: *{8}(section_addr(macho_reloc.o, __DATA,__data) + 8) = \
148 # jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) + 8) - named_data - 2
151 .quad Lanon_minuend_quad - named_data - 2
153 # Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long).
154 # jitlink-check: *{4}(section_addr(macho_reloc.o, __DATA,__data) + 16) = \
155 # jitlink-check: ((section_addr(macho_reloc.o, __DATA,__data) + 16) - named_data - 2)[31:0]
158 .long Lanon_minuend_long - named_data - 2
160 # Named quad storage target (first named atom in __data).
164 .quad 0x2222222222222222
166 # An alt-entry point for named_data
167 .globl named_data_alt_entry
169 .alt_entry named_data_alt_entry
170 named_data_alt_entry
:
173 # Check X86_64_RELOC_UNSIGNED / quad / extern handling by putting the address of
174 # a local named function into a quad symbol.
176 # jitlink-check: *{8}named_func_addr_quad = named_func
177 .globl named_func_addr_quad
179 named_func_addr_quad
:
182 # Check X86_64_RELOC_UNSIGNED / long / extern handling by putting the address of
183 # an external function (defined to reside in the low 4Gb) into a long symbol.
185 # jitlink-check: *{4}named_func_addr_long = external_func
186 .globl named_func_addr_long
188 named_func_addr_long
:
191 # Check X86_64_RELOC_UNSIGNED / quad / non-extern handling by putting the
192 # address of a local anonymous function into a quad symbol.
194 # jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __TEXT,__text)
195 .globl anon_func_addr_quad
200 # X86_64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend
202 # jitlink-check: *{8}anon_minuend_quad1 = \
203 # jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_quad1 - 2
204 # Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is
205 # invalid because the subtrahend can not be local.
206 .globl anon_minuend_quad1
209 .quad Lanon_data - anon_minuend_quad1 - 2
211 # jitlink-check: *{4}anon_minuend_long1 = \
212 # jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_long1 - 2)[31:0]
213 .globl anon_minuend_long1
216 .long Lanon_data - anon_minuend_long1 - 2
218 # Check X86_64_RELOC_SUBTRACTOR Quad/Long in named storage with minuend and subtrahend.
219 # Both forms "A: .quad A - B + C" and "A: .quad B - A + C" are tested.
221 # Check "A: .quad B - A + C".
222 # jitlink-check: *{8}subtrahend_quad2 = (named_data - subtrahend_quad2 - 2)
223 .globl subtrahend_quad2
226 .quad named_data - subtrahend_quad2 - 2
228 # Check "A: .long B - A + C".
229 # jitlink-check: *{4}subtrahend_long2 = (named_data - subtrahend_long2 - 2)[31:0]
230 .globl subtrahend_long2
233 .long named_data - subtrahend_long2 - 2
235 # Check "A: .quad A - B + C".
236 # jitlink-check: *{8}minuend_quad3 = (minuend_quad3 - named_data - 2)
240 .quad minuend_quad3 - named_data - 2
242 # Check "A: .long B - A + C".
243 # jitlink-check: *{4}minuend_long3 = (minuend_long3 - named_data - 2)[31:0]
247 .long minuend_long3 - named_data - 2
249 # Check X86_64_RELOC_SUBTRACTOR handling for exprs of the form
250 # "A: .quad/long B - C + D", where 'B' or 'C' is at a fixed offset from 'A'
251 # (i.e. is part of an alt_entry chain that includes 'A').
253 # Check "A: .long B - C + D" where 'B' is an alt_entry for 'A'.
254 # jitlink-check: *{4}subtractor_with_alt_entry_minuend_long = (subtractor_with_alt_entry_minuend_long_B - named_data - 2)[31:0]
255 .globl subtractor_with_alt_entry_minuend_long
257 subtractor_with_alt_entry_minuend_long
:
258 .long subtractor_with_alt_entry_minuend_long_B - named_data - 2
260 .globl subtractor_with_alt_entry_minuend_long_B
262 .alt_entry subtractor_with_alt_entry_minuend_long_B
263 subtractor_with_alt_entry_minuend_long_B
:
266 # Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.
267 # jitlink-check: *{8}subtractor_with_alt_entry_minuend_quad = (subtractor_with_alt_entry_minuend_quad_B - named_data - 2)
268 .globl subtractor_with_alt_entry_minuend_quad
270 subtractor_with_alt_entry_minuend_quad
:
271 .quad subtractor_with_alt_entry_minuend_quad_B - named_data - 2
273 .globl subtractor_with_alt_entry_minuend_quad_B
275 .alt_entry subtractor_with_alt_entry_minuend_quad_B
276 subtractor_with_alt_entry_minuend_quad_B
:
279 # Check "A: .long B - C + D" where 'C' is an alt_entry for 'A'.
280 # jitlink-check: *{4}subtractor_with_alt_entry_subtrahend_long = (named_data - subtractor_with_alt_entry_subtrahend_long_B - 2)[31:0]
281 .globl subtractor_with_alt_entry_subtrahend_long
283 subtractor_with_alt_entry_subtrahend_long
:
284 .long named_data - subtractor_with_alt_entry_subtrahend_long_B - 2
286 .globl subtractor_with_alt_entry_subtrahend_long_B
288 .alt_entry subtractor_with_alt_entry_subtrahend_long_B
289 subtractor_with_alt_entry_subtrahend_long_B
:
292 # Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.
293 # jitlink-check: *{8}subtractor_with_alt_entry_subtrahend_quad = (named_data - subtractor_with_alt_entry_subtrahend_quad_B - 2)
294 .globl subtractor_with_alt_entry_subtrahend_quad
296 subtractor_with_alt_entry_subtrahend_quad
:
297 .quad named_data - subtractor_with_alt_entry_subtrahend_quad_B - 2
299 .globl subtractor_with_alt_entry_subtrahend_quad_B
301 .alt_entry subtractor_with_alt_entry_subtrahend_quad_B
302 subtractor_with_alt_entry_subtrahend_quad_B
:
305 # Check X86_64_RELOC_GOT handling.
306 # X86_64_RELOC_GOT is the data-section counterpart to X86_64_RELOC_GOTLD. It is
307 # handled exactly the same way, including having an implicit PC-rel offset of -4
308 # (despite this not making sense in a data section, and requiring an explicit
309 # +4 addend to cancel it out and get the correct result).
311 # jitlink-check: *{4}test_got = (got_addr(macho_reloc.o, external_data) - test_got)[31:0]
315 .long external_data@GOTPCREL + 4
317 # Check that unreferenced atoms in no-dead-strip sections are not dead stripped.
318 # We need to use a local symbol for this as any named symbol will end up in the
319 # ORC responsibility set, which is automatically marked live and would couse
322 # jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_sect) = 0
323 .section __DATA,__nds_test_sect,regular,no_dead_strip
326 # Check that unreferenced local symbols that have been marked no-dead-strip are
329 # jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_nlst) = 0
330 .section __DATA,__nds_test_nlst,regular
331 .no_dead_strip no_dead_strip_test_symbol
332 no_dead_strip_test_symbol
:
335 # Check that explicit zero-fill symbols are supported
336 # jitlink-check: *{8}zero_fill_test = 0
337 .globl zero_fill_test
338 .zerofill __DATA,__zero_fill_test,zero_fill_test,8,3
340 # Check that section alignments are respected.
341 # We test this by introducing two segments with alignment 8, each containing one
342 # byte of data. We require both symbols to have an aligned address.
344 # jitlink-check: section_alignment_check1[2:0] = 0
345 # jitlink-check: section_alignment_check2[2:0] = 0
346 .section __DATA,__sec_align_chk1
349 .globl section_alignment_check1
350 section_alignment_check1
:
353 .section __DATA,__sec_align_chk2
356 .globl section_alignment_check2
357 section_alignment_check2
:
360 .subsections_via_symbols