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, 1) = (got_addr(macho_reloc.o, external_data)[32:12] - test_gotpage21[32:12]) 43# jitlink-check: decode_operand(test_gotpageoff12, 2) = got_addr(macho_reloc.o, external_data)[11:3] 44 .globl test_gotpage21 45 .p2align 2 46test_gotpage21: 47 adrp x0, external_data@GOTPAGE 48 .globl test_gotpageoff12 49test_gotpageoff12: 50 ldr x0, [x0, external_data@GOTPAGEOFF] 51 52# Check ARM64_RELOC_PAGE21 / ARM64_RELOC_PAGEOFF12 handling with a reference to 53# a local symbol. 54# 55# For the PAGE21/ADRP instruction we have the 21-bit delta to the 4k page 56# containing the global. 57# 58# For the GOTPAGEOFF12 relocation we test the ADD instruction, all LDR/GPR 59# variants and all LDR/Neon variants. 60# 61# jitlink-check: decode_operand(test_page21, 1) = (named_data[32:12] - test_page21[32:12]) 62# jitlink-check: decode_operand(test_pageoff12add, 2) = named_data[11:0] 63# jitlink-check: decode_operand(test_pageoff12gpr8, 2) = named_data[11:0] 64# jitlink-check: decode_operand(test_pageoff12gpr16, 2) = named_data[11:1] 65# jitlink-check: decode_operand(test_pageoff12gpr32, 2) = named_data[11:2] 66# jitlink-check: decode_operand(test_pageoff12gpr64, 2) = named_data[11:3] 67# jitlink-check: decode_operand(test_pageoff12neon8, 2) = named_data[11:0] 68# jitlink-check: decode_operand(test_pageoff12neon16, 2) = named_data[11:1] 69# jitlink-check: decode_operand(test_pageoff12neon32, 2) = named_data[11:2] 70# jitlink-check: decode_operand(test_pageoff12neon64, 2) = named_data[11:3] 71# jitlink-check: decode_operand(test_pageoff12neon128, 2) = named_data[11:4] 72 .globl test_page21 73 .p2align 2 74test_page21: 75 adrp x0, named_data@PAGE 76 77 .globl test_pageoff12add 78test_pageoff12add: 79 add x0, x0, named_data@PAGEOFF 80 81 .globl test_pageoff12gpr8 82test_pageoff12gpr8: 83 ldrb w0, [x0, named_data@PAGEOFF] 84 85 .globl test_pageoff12gpr16 86test_pageoff12gpr16: 87 ldrh w0, [x0, named_data@PAGEOFF] 88 89 .globl test_pageoff12gpr32 90test_pageoff12gpr32: 91 ldr w0, [x0, named_data@PAGEOFF] 92 93 .globl test_pageoff12gpr64 94test_pageoff12gpr64: 95 ldr x0, [x0, named_data@PAGEOFF] 96 97 .globl test_pageoff12neon8 98test_pageoff12neon8: 99 ldr b0, [x0, named_data@PAGEOFF] 100 101 .globl test_pageoff12neon16 102test_pageoff12neon16: 103 ldr h0, [x0, named_data@PAGEOFF] 104 105 .globl test_pageoff12neon32 106test_pageoff12neon32: 107 ldr s0, [x0, named_data@PAGEOFF] 108 109 .globl test_pageoff12neon64 110test_pageoff12neon64: 111 ldr d0, [x0, named_data@PAGEOFF] 112 113 .globl test_pageoff12neon128 114test_pageoff12neon128: 115 ldr q0, [x0, named_data@PAGEOFF] 116 117# Check that calls to external functions trigger the generation of stubs and GOT 118# entries. 119# 120# jitlink-check: decode_operand(test_external_call, 0) = (stub_addr(macho_reloc.o, external_func) - test_external_call)[27:2] 121# jitlink-check: *{8}(got_addr(macho_reloc.o, external_func)) = external_func 122 .globl test_external_call 123 .p2align 2 124test_external_call: 125 bl external_func 126 127 .section __DATA,__data 128 129# Storage target for non-extern ARM64_RELOC_SUBTRACTOR relocs. 130 .p2align 3 131Lanon_data: 132 .quad 0x1111111111111111 133 134# Check ARM64_RELOC_SUBTRACTOR Quad/Long in anonymous storage with anonymous 135# minuend: "LA: .quad LA - B + C". The anonymous subtrahend form 136# "LA: .quad B - LA + C" is not tested as subtrahends are not permitted to be 137# anonymous. 138# 139# Note: +8 offset in expression below to accounts for sizeof(Lanon_data). 140# jitlink-check: *{8}(section_addr(macho_reloc.o, __data) + 8) = (section_addr(macho_reloc.o, __data) + 8) - named_data + 2 141 .p2align 3 142Lanon_minuend_quad: 143 .quad Lanon_minuend_quad - named_data + 2 144 145# Note: +16 offset in expression below to accounts for sizeof(Lanon_data) + sizeof(Lanon_minuend_long). 146# jitlink-check: *{4}(section_addr(macho_reloc.o, __data) + 16) = ((section_addr(macho_reloc.o, __data) + 16) - named_data + 2)[31:0] 147 .p2align 2 148Lanon_minuend_long: 149 .long Lanon_minuend_long - named_data + 2 150 151# Named quad storage target (first named atom in __data). 152# Align to 16 for use as 128-bit load target. 153 .globl named_data 154 .p2align 4 155named_data: 156 .quad 0x2222222222222222 157 .quad 0x3333333333333333 158 159# An alt-entry point for named_data 160 .globl named_data_alt_entry 161 .p2align 3 162 .alt_entry named_data_alt_entry 163named_data_alt_entry: 164 .quad 0 165 166# Check ARM64_RELOC_UNSIGNED / quad / extern handling by putting the address of 167# a local named function into a quad symbol. 168# 169# jitlink-check: *{8}named_func_addr_quad = named_func 170 .globl named_func_addr_quad 171 .p2align 3 172named_func_addr_quad: 173 .quad named_func 174 175# Check ARM64_RELOC_UNSIGNED / quad / non-extern handling by putting the 176# address of a local anonymous function into a quad symbol. 177# 178# jitlink-check: *{8}anon_func_addr_quad = section_addr(macho_reloc.o, __text) 179 .globl anon_func_addr_quad 180 .p2align 3 181anon_func_addr_quad: 182 .quad Lanon_func 183 184# ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with anonymous minuend 185# 186# jitlink-check: *{8}anon_minuend_quad1 = section_addr(macho_reloc.o, __data) - anon_minuend_quad1 + 2 187# Only the form "B: .quad LA - B + C" is tested. The form "B: .quad B - LA + C" is 188# invalid because the subtrahend can not be local. 189 .globl anon_minuend_quad1 190 .p2align 3 191anon_minuend_quad1: 192 .quad Lanon_data - anon_minuend_quad1 + 2 193 194# jitlink-check: *{4}anon_minuend_long1 = (section_addr(macho_reloc.o, __data) - anon_minuend_long1 + 2)[31:0] 195 .globl anon_minuend_long1 196 .p2align 2 197anon_minuend_long1: 198 .long Lanon_data - anon_minuend_long1 + 2 199 200# Check ARM64_RELOC_SUBTRACTOR Quad/Long in named storage with minuend and subtrahend. 201# Both forms "A: .quad A - B + C" and "A: .quad B - A + C" are tested. 202# 203# Check "A: .quad B - A + C". 204# jitlink-check: *{8}subtrahend_quad2 = (named_data - subtrahend_quad2 - 2) 205 .globl subtrahend_quad2 206 .p2align 3 207subtrahend_quad2: 208 .quad named_data - subtrahend_quad2 - 2 209 210# Check "A: .long B - A + C". 211# jitlink-check: *{4}subtrahend_long2 = (named_data - subtrahend_long2 - 2)[31:0] 212 .globl subtrahend_long2 213 .p2align 2 214subtrahend_long2: 215 .long named_data - subtrahend_long2 - 2 216 217# Check "A: .quad A - B + C". 218# jitlink-check: *{8}minuend_quad3 = (minuend_quad3 - named_data - 2) 219 .globl minuend_quad3 220 .p2align 3 221minuend_quad3: 222 .quad minuend_quad3 - named_data - 2 223 224# Check "A: .long B - A + C". 225# jitlink-check: *{4}minuend_long3 = (minuend_long3 - named_data - 2)[31:0] 226 .globl minuend_long3 227 .p2align 2 228minuend_long3: 229 .long minuend_long3 - named_data - 2 230 231# Check ARM64_RELOC_SUBTRACTOR handling for exprs of the form 232# "A: .quad/long B - C + D", where 'B' or 'C' is at a fixed offset from 'A' 233# (i.e. is part of an alt_entry chain that includes 'A'). 234# 235# Check "A: .long B - C + D" where 'B' is an alt_entry for 'A'. 236# jitlink-check: *{4}subtractor_with_alt_entry_minuend_long = (subtractor_with_alt_entry_minuend_long_B - named_data + 2)[31:0] 237 .globl subtractor_with_alt_entry_minuend_long 238 .p2align 2 239subtractor_with_alt_entry_minuend_long: 240 .long subtractor_with_alt_entry_minuend_long_B - named_data + 2 241 242 .globl subtractor_with_alt_entry_minuend_long_B 243 .p2align 2 244 .alt_entry subtractor_with_alt_entry_minuend_long_B 245subtractor_with_alt_entry_minuend_long_B: 246 .long 0 247 248# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'. 249# jitlink-check: *{8}subtractor_with_alt_entry_minuend_quad = (subtractor_with_alt_entry_minuend_quad_B - named_data + 2) 250 .globl subtractor_with_alt_entry_minuend_quad 251 .p2align 3 252subtractor_with_alt_entry_minuend_quad: 253 .quad subtractor_with_alt_entry_minuend_quad_B - named_data + 2 254 255 .globl subtractor_with_alt_entry_minuend_quad_B 256 .p2align 3 257 .alt_entry subtractor_with_alt_entry_minuend_quad_B 258subtractor_with_alt_entry_minuend_quad_B: 259 .quad 0 260 261# Check "A: .long B - C + D" where 'C' is an alt_entry for 'A'. 262# jitlink-check: *{4}subtractor_with_alt_entry_subtrahend_long = (named_data - subtractor_with_alt_entry_subtrahend_long_B + 2)[31:0] 263 .globl subtractor_with_alt_entry_subtrahend_long 264 .p2align 2 265subtractor_with_alt_entry_subtrahend_long: 266 .long named_data - subtractor_with_alt_entry_subtrahend_long_B + 2 267 268 .globl subtractor_with_alt_entry_subtrahend_long_B 269 .p2align 2 270 .alt_entry subtractor_with_alt_entry_subtrahend_long_B 271subtractor_with_alt_entry_subtrahend_long_B: 272 .long 0 273 274# Check "A: .quad B - C + D" where 'B' is an alt_entry for 'A'. 275# jitlink-check: *{8}subtractor_with_alt_entry_subtrahend_quad = (named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2) 276 .globl subtractor_with_alt_entry_subtrahend_quad 277 .p2align 3 278subtractor_with_alt_entry_subtrahend_quad: 279 .quad named_data - subtractor_with_alt_entry_subtrahend_quad_B + 2 280 281 .globl subtractor_with_alt_entry_subtrahend_quad_B 282 .p2align 3 283 .alt_entry subtractor_with_alt_entry_subtrahend_quad_B 284subtractor_with_alt_entry_subtrahend_quad_B: 285 .quad 0 286 287# Check ARM64_POINTER_TO_GOT handling. 288# ARM64_POINTER_TO_GOT is a delta-32 to a GOT entry. 289# 290# jitlink-check: *{4}test_got = (got_addr(macho_reloc.o, external_data) - test_got)[31:0] 291 .globl test_got 292 .p2align 2 293test_got: 294 .long external_data@got - . 295 296# Check that unreferenced atoms in no-dead-strip sections are not dead stripped. 297# We need to use a local symbol for this as any named symbol will end up in the 298# ORC responsibility set, which is automatically marked live and would couse 299# spurious passes. 300# 301# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_sect) = 0 302 .section __DATA,__nds_test_sect,regular,no_dead_strip 303 .quad 0 304 305# Check that unreferenced local symbols that have been marked no-dead-strip are 306# not dead-striped. 307# 308# jitlink-check: *{8}section_addr(macho_reloc.o, __nds_test_nlst) = 0 309 .section __DATA,__nds_test_nlst,regular 310 .no_dead_strip no_dead_strip_test_symbol 311no_dead_strip_test_symbol: 312 .quad 0 313 314# Check that explicit zero-fill symbols are supported 315# jitlink-check: *{8}zero_fill_test = 0 316 .globl zero_fill_test 317.zerofill __DATA,__zero_fill_test,zero_fill_test,8,3 318 319# Check that section alignments are respected. 320# We test this by introducing two segments with alignment 8, each containing one 321# byte of data. We require both symbols to have an aligned address. 322# 323# jitlink-check: section_alignment_check1[2:0] = 0 324# jitlink-check: section_alignment_check2[2:0] = 0 325 .section __DATA,__sec_align_chk1 326 .p2align 3 327 328 .globl section_alignment_check1 329section_alignment_check1: 330 .byte 0 331 332 .section __DATA,__sec_align_chk2 333 .p2align 3 334 335 .globl section_alignment_check2 336section_alignment_check2: 337 .byte 0 338 339.subsections_via_symbols 340