376 lines · plain
1# RUN: rm -rf %t && mkdir -p %t2# RUN: llvm-mc -triple=arm64-apple-darwin19 -filetype=obj -o %t/macho_reloc.o %s3# RUN: llvm-jitlink -noexec -abs external_data=0xdeadbeef -abs external_func=0xcafef00d -check=%s %t/macho_reloc.o4 5 .section __TEXT,__text,regular,pure_instructions6 7 .p2align 28Lanon_func:9 ret10 11 .globl named_func12 .p2align 213named_func:14 ret15 16# Check ARM64_RELOC_BRANCH26 handling with a call to a local function.17# The branch instruction only encodes 26 bits of the 28-bit possible branch18# range, since the low 2 bits will always be zero.19#20# jitlink-check: decode_operand(test_local_call, 0)[25:0] = (named_func - test_local_call)[27:2]21 .globl test_local_call22 .p2align 223test_local_call:24 bl named_func25 26 .globl _main27 .p2align 228_main:29 ret30 31# Check ARM64_RELOC_GOTPAGE21 / ARM64_RELOC_GOTPAGEOFF12 handling with a32# reference to an external symbol. Validate both the reference to the GOT entry,33# and also the content of the GOT entry.34#35# For the GOTPAGE21/ADRP instruction we have the 21-bit delta to the 4k page36# containing the GOT entry for external_data.37#38# For the GOTPAGEOFF/LDR instruction we have the 12-bit offset of the entry39# within the page.40#41# jitlink-check: *{8}(got_addr(macho_reloc.o, external_data)) = external_data42# jitlink-check: decode_operand(test_gotpage21_external, 1) = \43# jitlink-check: (got_addr(macho_reloc.o, external_data)[32:12] - \44# jitlink-check: test_gotpage21_external[32:12])45# jitlink-check: decode_operand(test_gotpageoff12_external, 2) = \46# jitlink-check: got_addr(macho_reloc.o, external_data)[11:3]47 .globl test_gotpage21_external48 .p2align 249test_gotpage21_external:50 adrp x0, external_data@GOTPAGE51 .globl test_gotpageoff12_external52test_gotpageoff12_external:53 ldr x0, [x0, external_data@GOTPAGEOFF]54 55# Check ARM64_RELOC_GOTPAGE21 / ARM64_RELOC_GOTPAGEOFF12 handling with a56# reference to a defined symbol. Validate both the reference to the GOT entry,57# and also the content of the GOT entry.58# jitlink-check: *{8}(got_addr(macho_reloc.o, named_data)) = named_data59# jitlink-check: decode_operand(test_gotpage21_defined, 1) = \60# jitlink-check: (got_addr(macho_reloc.o, named_data)[32:12] - \61# jitlink-check: test_gotpage21_defined[32:12])62# jitlink-check: decode_operand(test_gotpageoff12_defined, 2) = \63# jitlink-check: got_addr(macho_reloc.o, named_data)[11:3]64 .globl test_gotpage21_defined65 .p2align 266test_gotpage21_defined:67 adrp x0, named_data@GOTPAGE68 .globl test_gotpageoff12_defined69test_gotpageoff12_defined:70 ldr x0, [x0, named_data@GOTPAGEOFF]71 72# Check ARM64_RELOC_PAGE21 / ARM64_RELOC_PAGEOFF12 handling with a reference to73# a local symbol.74#75# For the PAGE21/ADRP instruction we have the 21-bit delta to the 4k page76# containing the global.77#78# For the GOTPAGEOFF12 relocation we test the ADD instruction, all LDR/GPR79# variants and all LDR/Neon variants.80#81# jitlink-check: decode_operand(test_page21, 1)[20:0] = \82# jitlink-check: ((named_data + 256) - test_page21)[32:12]83# jitlink-check: decode_operand(test_pageoff12add, 2) = (named_data + 256)[11:0]84# jitlink-check: decode_operand(test_pageoff12gpr8, 2) = (named_data + 256)[11:0]85# jitlink-cherk: decode_operand(test_pageoff12gpr8s, 2) = (named_data + 256)[11:0]86# jitlink-check: decode_operand(test_pageoff12gpr16, 2) = (named_data + 256)[11:1]87# jitlink-check: decode_operand(test_pageoff12gpr16s, 2) = (named_data + 256)[11:1]88# jitlink-check: decode_operand(test_pageoff12gpr32, 2) = (named_data + 256)[11:2]89# jitlink-check: decode_operand(test_pageoff12gpr64, 2) = (named_data + 256)[11:3]90# jitlink-check: decode_operand(test_pageoff12neon8, 2) = (named_data + 256)[11:0]91# jitlink-check: decode_operand(test_pageoff12neon16, 2) = (named_data + 256)[11:1]92# jitlink-check: decode_operand(test_pageoff12neon32, 2) = (named_data + 256)[11:2]93# jitlink-check: decode_operand(test_pageoff12neon64, 2) = (named_data + 256)[11:3]94# jitlink-check: decode_operand(test_pageoff12neon128, 2) = (named_data + 256)[11:4]95 .globl test_page2196 .p2align 297test_page21:98 adrp x0, named_data@PAGE + 25699 100 .globl test_pageoff12add101test_pageoff12add:102 add x0, x0, named_data@PAGEOFF + 256103 104 .globl test_pageoff12gpr8105test_pageoff12gpr8:106 ldrb w0, [x0, named_data@PAGEOFF + 256]107 108 .globl test_pageoff12gpr8s109test_pageoff12gpr8s:110 ldrsb w0, [x0, named_data@PAGEOFF + 256]111 112 .globl test_pageoff12gpr16113test_pageoff12gpr16:114 ldrh w0, [x0, named_data@PAGEOFF + 256]115 116 .globl test_pageoff12gpr16s117test_pageoff12gpr16s:118 ldrsh w0, [x0, named_data@PAGEOFF + 256]119 120 .globl test_pageoff12gpr32121test_pageoff12gpr32:122 ldr w0, [x0, named_data@PAGEOFF + 256]123 124 .globl test_pageoff12gpr64125test_pageoff12gpr64:126 ldr x0, [x0, named_data@PAGEOFF + 256]127 128 .globl test_pageoff12neon8129test_pageoff12neon8:130 ldr b0, [x0, named_data@PAGEOFF + 256]131 132 .globl test_pageoff12neon16133test_pageoff12neon16:134 ldr h0, [x0, named_data@PAGEOFF + 256]135 136 .globl test_pageoff12neon32137test_pageoff12neon32:138 ldr s0, [x0, named_data@PAGEOFF + 256]139 140 .globl test_pageoff12neon64141test_pageoff12neon64:142 ldr d0, [x0, named_data@PAGEOFF + 256]143 144 .globl test_pageoff12neon128145test_pageoff12neon128:146 ldr q0, [x0, named_data@PAGEOFF + 256]147 148# Check that calls to external functions trigger the generation of stubs and GOT149# entries.150#151# jitlink-check: decode_operand(test_external_call, 0) = (stub_addr(macho_reloc.o, external_func) - test_external_call)[27:2]152# jitlink-check: *{8}(got_addr(macho_reloc.o, external_func)) = external_func153 .globl test_external_call154 .p2align 2155test_external_call:156 bl external_func157 158 .section __DATA,__data159 160# Storage target for non-extern ARM64_RELOC_SUBTRACTOR relocs.161 .p2align 3162Lanon_data:163 .quad 0x1111111111111111164 165# Check ARM64_RELOC_SUBTRACTOR Quad/Long in anonymous storage with anonymous166# minuend: "LA: .quad LA - B + C". The anonymous subtrahend form167# "LA: .quad B - LA + C" is not tested as subtrahends are not permitted to be168# anonymous.169#170# Note: +8 offset in expression below to accounts for sizeof(Lanon_data).171# jitlink-check: *{8}(section_addr(macho_reloc.o, __DATA,__data) + 8) = \172# jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) + 8) - named_data + 2173 .p2align 3174Lanon_minuend_quad:175 .quad Lanon_minuend_quad - named_data + 2176 177# Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long).178# jitlink-check: *{4}(section_addr(macho_reloc.o, __DATA,__data) + 16) = \179# jitlink-check: ((section_addr(macho_reloc.o, __DATA,__data) + 16) - named_data + 2)[31:0]180 .p2align 2181Lanon_minuend_long:182 .long Lanon_minuend_long - named_data + 2183 184# Named quad storage target (first named atom in __data).185# Align to 16 for use as 128-bit load target.186 .globl named_data187 .p2align 4188named_data:189 .quad 0x2222222222222222190 .quad 0x3333333333333333191 192# An alt-entry point for named_data193 .globl named_data_alt_entry194 .p2align 3195 .alt_entry named_data_alt_entry196named_data_alt_entry:197 .quad 0198 199# Check ARM64_RELOC_UNSIGNED / quad / extern handling by putting the address of200# a local named function into a quad symbol.201#202# jitlink-check: *{8}named_func_addr_quad = named_func203 .globl named_func_addr_quad204 .p2align 3205named_func_addr_quad:206 .quad named_func207 208# Check ARM64_RELOC_UNSIGNED / quad / non-extern handling by putting the209# address of a local anonymous function into a quad symbol.210#211# jitlink-check: *{8}anon_func_addr_quad = \212# jitlink-check: section_addr(macho_reloc.o, __TEXT,__text)213 .globl anon_func_addr_quad214 .p2align 3215anon_func_addr_quad:216 .quad Lanon_func217 218# ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend219#220# jitlink-check: *{8}anon_minuend_quad1 = \221# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_quad1 + 2222# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is223# invalid because the subtrahend can not be local.224 .globl anon_minuend_quad1225 .p2align 3226anon_minuend_quad1:227 .quad Lanon_data - anon_minuend_quad1 + 2228 229# jitlink-check: *{4}anon_minuend_long1 = \230# jitlink-check: (section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_long1 + 2)[31:0]231 .globl anon_minuend_long1232 .p2align 2233anon_minuend_long1:234 .long Lanon_data - anon_minuend_long1 + 2235 236# Check ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with minuend and subtrahend.237# Both forms "A: .quad A - B + C" and "A: .quad B - A + C" are tested.238#239# Check "A: .quad B - A + C".240# jitlink-check: *{8}subtrahend_quad2 = (named_data - subtrahend_quad2 - 2)241 .globl subtrahend_quad2242 .p2align 3243subtrahend_quad2:244 .quad named_data - subtrahend_quad2 - 2245 246# Check "A: .long B - A + C".247# jitlink-check: *{4}subtrahend_long2 = (named_data - subtrahend_long2 - 2)[31:0]248 .globl subtrahend_long2249 .p2align 2250subtrahend_long2:251 .long named_data - subtrahend_long2 - 2252 253# Check "A: .quad A - B + C".254# jitlink-check: *{8}minuend_quad3 = (minuend_quad3 - named_data - 2)255 .globl minuend_quad3256 .p2align 3257minuend_quad3:258 .quad minuend_quad3 - named_data - 2259 260# Check "A: .long B - A + C".261# jitlink-check: *{4}minuend_long3 = (minuend_long3 - named_data - 2)[31:0]262 .globl minuend_long3263 .p2align 2264minuend_long3:265 .long minuend_long3 - named_data - 2266 267# Check ARM64_RELOC_SUBTRACTOR handling for exprs of the form268# "A: .quad/long B - C + D", where 'B' or 'C' is at a fixed offset from 'A'269# (i.e. is part of an alt_entry chain that includes 'A').270#271# Check "A: .long B - C + D" where 'B' is an alt_entry for 'A'.272# jitlink-check: *{4}subtractor_with_alt_entry_minuend_long = (subtractor_with_alt_entry_minuend_long_B - named_data + 2)[31:0]273 .globl subtractor_with_alt_entry_minuend_long274 .p2align 2275subtractor_with_alt_entry_minuend_long:276 .long subtractor_with_alt_entry_minuend_long_B - named_data + 2277 278 .globl subtractor_with_alt_entry_minuend_long_B279 .p2align 2280 .alt_entry subtractor_with_alt_entry_minuend_long_B281subtractor_with_alt_entry_minuend_long_B:282 .long 0283 284# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.285# jitlink-check: *{8}subtractor_with_alt_entry_minuend_quad = (subtractor_with_alt_entry_minuend_quad_B - named_data + 2)286 .globl subtractor_with_alt_entry_minuend_quad287 .p2align 3288subtractor_with_alt_entry_minuend_quad:289 .quad subtractor_with_alt_entry_minuend_quad_B - named_data + 2290 291 .globl subtractor_with_alt_entry_minuend_quad_B292 .p2align 3293 .alt_entry subtractor_with_alt_entry_minuend_quad_B294subtractor_with_alt_entry_minuend_quad_B:295 .quad 0296 297# Check "A: .long B - C + D" where 'C' is an alt_entry for 'A'.298# jitlink-check: *{4}subtractor_with_alt_entry_subtrahend_long = (named_data - subtractor_with_alt_entry_subtrahend_long_B + 2)[31:0]299 .globl subtractor_with_alt_entry_subtrahend_long300 .p2align 2301subtractor_with_alt_entry_subtrahend_long:302 .long named_data - subtractor_with_alt_entry_subtrahend_long_B + 2303 304 .globl subtractor_with_alt_entry_subtrahend_long_B305 .p2align 2306 .alt_entry subtractor_with_alt_entry_subtrahend_long_B307subtractor_with_alt_entry_subtrahend_long_B:308 .long 0309 310# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'.311# jitlink-check: *{8}subtractor_with_alt_entry_subtrahend_quad = (named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2)312 .globl subtractor_with_alt_entry_subtrahend_quad313 .p2align 3314subtractor_with_alt_entry_subtrahend_quad:315 .quad named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2316 317 .globl subtractor_with_alt_entry_subtrahend_quad_B318 .p2align 3319 .alt_entry subtractor_with_alt_entry_subtrahend_quad_B320subtractor_with_alt_entry_subtrahend_quad_B:321 .quad 0322 323# Check ARM64_POINTER_TO_GOT handling.324# ARM64_POINTER_TO_GOT is a delta-32 to a GOT entry.325#326# jitlink-check: *{4}test_got = (got_addr(macho_reloc.o, external_data) - test_got)[31:0]327 .globl test_got328 .p2align 2329test_got:330 .long external_data@got - .331 332# Check that unreferenced atoms in no-dead-strip sections are not dead stripped.333# We need to use a local symbol for this as any named symbol will end up in the334# ORC responsibility set, which is automatically marked live and would couse335# spurious passes.336#337# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_sect) = 0338 .section __DATA,__nds_test_sect,regular,no_dead_strip339 .quad 0340 341# Check that unreferenced local symbols that have been marked no-dead-strip are342# not dead-striped.343#344# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_nlst) = 0345 .section __DATA,__nds_test_nlst,regular346 .no_dead_strip no_dead_strip_test_symbol347no_dead_strip_test_symbol:348 .quad 0349 350# Check that explicit zero-fill symbols are supported351# jitlink-check: *{8}zero_fill_test = 0352 .globl zero_fill_test353.zerofill __DATA,__zero_fill_test,zero_fill_test,8,3354 355# Check that section alignments are respected.356# We test this by introducing two segments with alignment 8, each containing one357# byte of data. We require both symbols to have an aligned address.358#359# jitlink-check: section_alignment_check1[2:0] = 0360# jitlink-check: section_alignment_check2[2:0] = 0361 .section __DATA,__sec_align_chk1362 .p2align 3363 364 .globl section_alignment_check1365section_alignment_check1:366 .byte 0367 368 .section __DATA,__sec_align_chk2369 .p2align 3370 371 .globl section_alignment_check2372section_alignment_check2:373 .byte 0374 375.subsections_via_symbols376