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