1# RUN: rm -rf %t && mkdir -p %t 2# RUN: llvm-mc -triple=arm64-apple-darwin19 -filetype=obj -o %t/macho_reloc.o %s 3# RUN: llvm-jitlink -noexec -define-abs external_data=0xdeadbeef -define-abs external_func=0xcafef00d -check=%s %t/macho_reloc.o 4 5 .section __TEXT,__text,regular,pure_instructions 6 7 .p2align 2 8Lanon_func: 9 ret 10 11 .globl named_func 12 .p2align 2 13named_func: 14 ret 15 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 branch 18# 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_call 22 .p2align 2 23test_local_call: 24 bl named_func 25 26 .globl _main 27 .p2align 2 28_main: 29 ret 30 31# Check ARM64_RELOC_GOTPAGE21 / ARM64_RELOC_GOTPAGEOFF12 handling with a 32# 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 page 36# containing the GOT entry for external_data. 37# 38# For the GOTPAGEOFF/LDR instruction we have the 12-bit offset of the entry 39# within the page. 40# 41# jitlink-check: *{8}(got_addr(macho_reloc.o, external_data)) = external_data 42# 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_external 48 .p2align 2 49test_gotpage21_external: 50 adrp x0, external_data@GOTPAGE 51 .globl test_gotpageoff12_external 52test_gotpageoff12_external: 53 ldr x0, [x0, external_data@GOTPAGEOFF] 54 55# Check ARM64_RELOC_GOTPAGE21 / ARM64_RELOC_GOTPAGEOFF12 handling with a 56# 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_data 59# 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_defined 65 .p2align 2 66test_gotpage21_defined: 67 adrp x0, named_data@GOTPAGE 68 .globl test_gotpageoff12_defined 69test_gotpageoff12_defined: 70 ldr x0, [x0, named_data@GOTPAGEOFF] 71 72# Check ARM64_RELOC_PAGE21 / ARM64_RELOC_PAGEOFF12 handling with a reference to 73# a local symbol. 74# 75# For the PAGE21/ADRP instruction we have the 21-bit delta to the 4k page 76# containing the global. 77# 78# For the GOTPAGEOFF12 relocation we test the ADD instruction, all LDR/GPR 79# 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_page21 96 .p2align 2 97test_page21: 98 adrp x0, named_data@PAGE + 256 99 100 .globl test_pageoff12add 101test_pageoff12add: 102 add x0, x0, named_data@PAGEOFF + 256 103 104 .globl test_pageoff12gpr8 105test_pageoff12gpr8: 106 ldrb w0, [x0, named_data@PAGEOFF + 256] 107 108 .globl test_pageoff12gpr8s 109test_pageoff12gpr8s: 110 ldrsb w0, [x0, named_data@PAGEOFF + 256] 111 112 .globl test_pageoff12gpr16 113test_pageoff12gpr16: 114 ldrh w0, [x0, named_data@PAGEOFF + 256] 115 116 .globl test_pageoff12gpr16s 117test_pageoff12gpr16s: 118 ldrsh w0, [x0, named_data@PAGEOFF + 256] 119 120 .globl test_pageoff12gpr32 121test_pageoff12gpr32: 122 ldr w0, [x0, named_data@PAGEOFF + 256] 123 124 .globl test_pageoff12gpr64 125test_pageoff12gpr64: 126 ldr x0, [x0, named_data@PAGEOFF + 256] 127 128 .globl test_pageoff12neon8 129test_pageoff12neon8: 130 ldr b0, [x0, named_data@PAGEOFF + 256] 131 132 .globl test_pageoff12neon16 133test_pageoff12neon16: 134 ldr h0, [x0, named_data@PAGEOFF + 256] 135 136 .globl test_pageoff12neon32 137test_pageoff12neon32: 138 ldr s0, [x0, named_data@PAGEOFF + 256] 139 140 .globl test_pageoff12neon64 141test_pageoff12neon64: 142 ldr d0, [x0, named_data@PAGEOFF + 256] 143 144 .globl test_pageoff12neon128 145test_pageoff12neon128: 146 ldr q0, [x0, named_data@PAGEOFF + 256] 147 148# Check that calls to external functions trigger the generation of stubs and GOT 149# 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_func 153 .globl test_external_call 154 .p2align 2 155test_external_call: 156 bl external_func 157 158 .section __DATA,__data 159 160# Storage target for non-extern ARM64_RELOC_SUBTRACTOR relocs. 161 .p2align 3 162Lanon_data: 163 .quad 0x1111111111111111 164 165# Check ARM64_RELOC_SUBTRACTOR Quad/Long in anonymous storage with anonymous 166# minuend: "LA: .quad LA - B + C". The anonymous subtrahend form 167# "LA: .quad B - LA + C" is not tested as subtrahends are not permitted to be 168# 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 + 2 173 .p2align 3 174Lanon_minuend_quad: 175 .quad Lanon_minuend_quad - named_data + 2 176 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 2 181Lanon_minuend_long: 182 .long Lanon_minuend_long - named_data + 2 183 184# Named quad storage target (first named atom in __data). 185# Align to 16 for use as 128-bit load target. 186 .globl named_data 187 .p2align 4 188named_data: 189 .quad 0x2222222222222222 190 .quad 0x3333333333333333 191 192# An alt-entry point for named_data 193 .globl named_data_alt_entry 194 .p2align 3 195 .alt_entry named_data_alt_entry 196named_data_alt_entry: 197 .quad 0 198 199# Check ARM64_RELOC_UNSIGNED / quad / extern handling by putting the address of 200# a local named function into a quad symbol. 201# 202# jitlink-check: *{8}named_func_addr_quad = named_func 203 .globl named_func_addr_quad 204 .p2align 3 205named_func_addr_quad: 206 .quad named_func 207 208# Check ARM64_RELOC_UNSIGNED / quad / non-extern handling by putting the 209# 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_quad 214 .p2align 3 215anon_func_addr_quad: 216 .quad Lanon_func 217 218# ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend 219# 220# jitlink-check: *{8}anon_minuend_quad1 = \ 221# jitlink-check: section_addr(macho_reloc.o, __DATA,__data) - anon_minuend_quad1 + 2 222# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is 223# invalid because the subtrahend can not be local. 224 .globl anon_minuend_quad1 225 .p2align 3 226anon_minuend_quad1: 227 .quad Lanon_data - anon_minuend_quad1 + 2 228 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_long1 232 .p2align 2 233anon_minuend_long1: 234 .long Lanon_data - anon_minuend_long1 + 2 235 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_quad2 242 .p2align 3 243subtrahend_quad2: 244 .quad named_data - subtrahend_quad2 - 2 245 246# Check "A: .long B - A + C". 247# jitlink-check: *{4}subtrahend_long2 = (named_data - subtrahend_long2 - 2)[31:0] 248 .globl subtrahend_long2 249 .p2align 2 250subtrahend_long2: 251 .long named_data - subtrahend_long2 - 2 252 253# Check "A: .quad A - B + C". 254# jitlink-check: *{8}minuend_quad3 = (minuend_quad3 - named_data - 2) 255 .globl minuend_quad3 256 .p2align 3 257minuend_quad3: 258 .quad minuend_quad3 - named_data - 2 259 260# Check "A: .long B - A + C". 261# jitlink-check: *{4}minuend_long3 = (minuend_long3 - named_data - 2)[31:0] 262 .globl minuend_long3 263 .p2align 2 264minuend_long3: 265 .long minuend_long3 - named_data - 2 266 267# Check ARM64_RELOC_SUBTRACTOR handling for exprs of the form 268# "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_long 274 .p2align 2 275subtractor_with_alt_entry_minuend_long: 276 .long subtractor_with_alt_entry_minuend_long_B - named_data + 2 277 278 .globl subtractor_with_alt_entry_minuend_long_B 279 .p2align 2 280 .alt_entry subtractor_with_alt_entry_minuend_long_B 281subtractor_with_alt_entry_minuend_long_B: 282 .long 0 283 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_quad 287 .p2align 3 288subtractor_with_alt_entry_minuend_quad: 289 .quad subtractor_with_alt_entry_minuend_quad_B - named_data + 2 290 291 .globl subtractor_with_alt_entry_minuend_quad_B 292 .p2align 3 293 .alt_entry subtractor_with_alt_entry_minuend_quad_B 294subtractor_with_alt_entry_minuend_quad_B: 295 .quad 0 296 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_long 300 .p2align 2 301subtractor_with_alt_entry_subtrahend_long: 302 .long named_data - subtractor_with_alt_entry_subtrahend_long_B + 2 303 304 .globl subtractor_with_alt_entry_subtrahend_long_B 305 .p2align 2 306 .alt_entry subtractor_with_alt_entry_subtrahend_long_B 307subtractor_with_alt_entry_subtrahend_long_B: 308 .long 0 309 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_quad 313 .p2align 3 314subtractor_with_alt_entry_subtrahend_quad: 315 .quad named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2 316 317 .globl subtractor_with_alt_entry_subtrahend_quad_B 318 .p2align 3 319 .alt_entry subtractor_with_alt_entry_subtrahend_quad_B 320subtractor_with_alt_entry_subtrahend_quad_B: 321 .quad 0 322 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_got 328 .p2align 2 329test_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 the 334# ORC responsibility set, which is automatically marked live and would couse 335# spurious passes. 336# 337# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_sect) = 0 338 .section __DATA,__nds_test_sect,regular,no_dead_strip 339 .quad 0 340 341# Check that unreferenced local symbols that have been marked no-dead-strip are 342# not dead-striped. 343# 344# jitlink-check: *{8}section_addr(macho_reloc.o, __DATA,__nds_test_nlst) = 0 345 .section __DATA,__nds_test_nlst,regular 346 .no_dead_strip no_dead_strip_test_symbol 347no_dead_strip_test_symbol: 348 .quad 0 349 350# Check that explicit zero-fill symbols are supported 351# jitlink-check: *{8}zero_fill_test = 0 352 .globl zero_fill_test 353.zerofill __DATA,__zero_fill_test,zero_fill_test,8,3 354 355# Check that section alignments are respected. 356# We test this by introducing two segments with alignment 8, each containing one 357# byte of data. We require both symbols to have an aligned address. 358# 359# jitlink-check: section_alignment_check1[2:0] = 0 360# jitlink-check: section_alignment_check2[2:0] = 0 361 .section __DATA,__sec_align_chk1 362 .p2align 3 363 364 .globl section_alignment_check1 365section_alignment_check1: 366 .byte 0 367 368 .section __DATA,__sec_align_chk2 369 .p2align 3 370 371 .globl section_alignment_check2 372section_alignment_check2: 373 .byte 0 374 375.subsections_via_symbols 376