1# RUN: rm -rf %t && mkdir -p %t 2# RUN: llvm-mc -triple=aarch64-unknown-linux-gnu -x86-relax-relocations=false \ 3# RUN: -position-independent -filetype=obj -o %t/elf_reloc.o %s 4# RUN: llvm-jitlink -noexec \ 5# RUN: -abs external_data=0xdeadbeef \ 6# RUN: -abs external_func=0xcafef00d \ 7# RUN: -check %s %t/elf_reloc.o 8 9 .text 10 11 .globl main 12 .p2align 2 13 .type main,@function 14main: 15 ret 16 17 .size main, .-main 18 19# Check R_AARCH64_CALL26 / R_AARCH64_JUMP26 relocation of a local function call 20# 21# jitlink-check: decode_operand(local_func_call26, 0)[25:0] = (local_func - local_func_call26)[27:2] 22# jitlink-check: decode_operand(local_func_jump26, 0)[25:0] = (local_func - local_func_jump26)[27:2] 23 .globl local_func 24 .p2align 2 25 .type local_func,@function 26local_func: 27 ret 28 .size local_func, .-local_func 29 30 .globl local_func_call26 31 .p2align 2 32local_func_call26: 33 bl local_func 34 .size local_func_call26, .-local_func_call26 35 36 .globl local_func_jump26 37 .p2align 2 38local_func_jump26: 39 b local_func 40 .size local_func_jump26, .-local_func_jump26 41 42# Check R_AARCH64_ADR_PREL_LO21 relocation of a local symbol 43# 44# jitlink-check: decode_operand(test_adr_prel_lo21, 1) = (adr_data - test_adr_prel_lo21)[20:0] 45 .globl test_adr_prel_lo21, adr_data 46 .p2align 2 47test_adr_prel_lo21: 48 adr x0, adr_data 49 .size test_adr_prel_lo21, .-test_adr_prel_lo21 50## ADR encoding is a bit tricky so use an offset with an irregular bit pattern 51## to test this bit better 52adr_data = test_adr_prel_lo21 + 0xe46f2 53 54# Check R_AARCH64_LD_PREL_LO19 relocation of a local symbol 55# 56# jitlink-check: decode_operand(test_ldr_prel_lo19 + 0, 1)[19:0] = \ 57# jitlink-check: (ldr_data - test_ldr_prel_lo19 + 0x4)[21:2] 58 .globl test_ldr_prel_lo19, ldr_data 59 .p2align 2 60test_ldr_prel_lo19: 61 ldr x0, ldr_data + 0x4 62 .size test_ldr_prel_lo19, .-test_ldr_prel_lo19 63ldr_data = test_ldr_prel_lo19 + 4 64 65# Check R_AARCH64_ADR_PREL_PG_HI21 / R_AARCH64_ADD_ABS_LO12_NC relocation of a local symbol 66# 67# For the ADR_PREL_PG_HI21/ADRP instruction we have the 21-bit delta to the 4k page 68# containing the global. 69# 70# jitlink-check: decode_operand(test_adr_prel, 1) = (named_data - test_adr_prel)[32:12] 71# jitlink-check: decode_operand(test_add_abs_lo12, 2) = (named_data + 0)[11:0] 72 .globl test_adr_prel 73 .p2align 2 74test_adr_prel: 75 adrp x0, named_data 76 .size test_adr_prel, .-test_adr_prel 77 78 .globl test_add_abs_lo12 79 .p2align 2 80test_add_abs_lo12: 81 add x0, x0, :lo12:named_data 82 .size test_add_abs_lo12, .-test_add_abs_lo12 83 84# Check that calls/jumps to external functions trigger the generation of stubs and GOT 85# entries. 86# 87# jitlink-check: decode_operand(test_external_call, 0) = (stub_addr(elf_reloc.o, external_func) - test_external_call)[27:2] 88# jitlink-check: decode_operand(test_external_jump, 0) = (stub_addr(elf_reloc.o, external_func) - test_external_jump)[27:2] 89# jitlink-check: *{8}(got_addr(elf_reloc.o, external_func)) = external_func 90 .globl test_external_call 91 .p2align 2 92test_external_call: 93 bl external_func 94 .size test_external_call, .-test_external_call 95 96 .globl test_external_jump 97 .p2align 2 98test_external_jump: 99 b external_func 100 .size test_external_jump, .-test_external_jump 101 102# Check R_AARCH64_LDST*_ABS_LO12_NC relocation of a local symbol 103# 104# The immediate value should be the symbol address right shifted according to its instruction bitwidth. 105# 106# jitlink-check: decode_operand(test_ldrb, 2) = named_data[11:0] 107# jitlink-check: decode_operand(test_ldrsb, 2) = (named_data + 0)[11:0] 108# jitlink-check: decode_operand(test_ldrh, 2) = (named_data + 0)[11:1] 109# jitlink-check: decode_operand(test_ldrsh, 2) = (named_data + 0)[11:1] 110# jitlink-check: decode_operand(test_ldr_32bit, 2) = (named_data + 0)[11:2] 111# jitlink-check: decode_operand(test_ldr_64bit, 2) = (named_data + 0)[11:3] 112# jitlink-check: decode_operand(test_strb, 2) = named_data[11:0] 113# jitlink-check: decode_operand(test_strh, 2) = (named_data + 0)[11:1] 114# jitlink-check: decode_operand(test_str_32bit, 2) = (named_data + 0)[11:2] 115# jitlink-check: decode_operand(test_str_64bit, 2) = (named_data + 0)[11:3] 116 117 .globl test_ldrb 118test_ldrb: 119 ldrb w0, [x1, :lo12:named_data] 120 .size test_ldrb, .-test_ldrb 121 122 .globl test_ldrsb 123test_ldrsb: 124 ldrsb w0, [x1, :lo12:named_data] 125 .size test_ldrsb, .-test_ldrsb 126 127 .globl test_ldrh 128test_ldrh: 129 ldrh w0, [x1, :lo12:named_data] 130 .size test_ldrh, .-test_ldrh 131 132 .globl test_ldrsh 133test_ldrsh: 134 ldrsh w0, [x1, :lo12:named_data] 135 .size test_ldrsh, .-test_ldrsh 136 137 .globl test_ldr_32bit 138test_ldr_32bit: 139 ldr w0, [x1, :lo12:named_data] 140 .size test_ldr_32bit, .-test_ldr_32bit 141 142 .globl test_ldr_64bit 143test_ldr_64bit: 144 ldr x0, [x1, :lo12:named_data] 145 .size test_ldr_64bit, .-test_ldr_64bit 146 147 .globl test_strb 148test_strb: 149 strb w0, [x1, :lo12:named_data] 150 .size test_strb, .-test_strb 151 152 .globl test_strh 153test_strh: 154 strh w0, [x1, :lo12:named_data] 155 .size test_strh, .-test_strh 156 157 .globl test_str_32bit 158test_str_32bit: 159 str w0, [x1, :lo12:named_data] 160 .size test_str_32bit, .-test_str_32bit 161 162 .globl test_str_64bit 163test_str_64bit: 164 str x0, [x1, :lo12:named_data] 165 .size test_str_64bit, .-test_str_64bit 166 167 168# Check R_AARCH64_MOVW_UABS_G*_NC relocation of a local symbol 169# 170# The immediate value should be the symbol address right shifted according to LSL value 171# 172# jitlink-check: decode_operand(test_movz_g0_nc, 1) = named_data[15:0] 173# jitlink-check: decode_operand(test_movk_g0_nc, 2) = named_data[15:0] 174# jitlink-check: decode_operand(test_movz_g1_nc, 1) = named_data[31:16] 175# jitlink-check: decode_operand(test_movk_g1_nc, 2) = named_data[31:16] 176# jitlink-check: decode_operand(test_movz_g2_nc, 1) = named_data[47:32] 177# jitlink-check: decode_operand(test_movk_g2_nc, 2) = named_data[47:32] 178# jitlink-check: decode_operand(test_movz_g3, 1) = named_data[63:48] 179# jitlink-check: decode_operand(test_movk_g3, 2) = named_data[63:48] 180 181 .globl test_movz_g0_nc 182test_movz_g0_nc: 183 movz x0, #:abs_g0_nc:named_data 184 .size test_movz_g0_nc, .-test_movz_g0_nc 185 186 .globl test_movk_g0_nc 187test_movk_g0_nc: 188 movk x0, #:abs_g0_nc:named_data 189 .size test_movk_g0_nc, .-test_movk_g0_nc 190 191 .globl test_movz_g1_nc 192test_movz_g1_nc: 193 movz x0, #:abs_g1_nc:named_data 194 .size test_movz_g1_nc, .-test_movz_g1_nc 195 196 .globl test_movk_g1_nc 197test_movk_g1_nc: 198 movk x0, #:abs_g1_nc:named_data 199 .size test_movk_g1_nc, .-test_movk_g1_nc 200 201 .globl test_movz_g2_nc 202test_movz_g2_nc: 203 movz x0, #:abs_g2_nc:named_data 204 .size test_movz_g2_nc, .-test_movz_g2_nc 205 206 .globl test_movk_g2_nc 207test_movk_g2_nc: 208 movk x0, #:abs_g2_nc:named_data 209 .size test_movk_g2_nc, .-test_movk_g2_nc 210 211 .globl test_movk_g3 212test_movk_g3: 213 movk x0, #:abs_g3:named_data 214 .size test_movk_g3, .-test_movk_g3 215 216 .globl test_movz_g3 217test_movz_g3: 218 movz x0, #:abs_g3:named_data 219 .size test_movz_g3, .-test_movz_g3 220 221# Check R_AARCH64_ABS64 relocation of a function pointer to local symbol 222# 223# jitlink-check: *{8}local_func_addr_quad = named_func 224 .globl local_func_addr_quad 225 .p2align 3 226local_func_addr_quad: 227 .xword named_func 228 .size local_func_addr_quad, 8 229 230# Check R_AARCH64_ABS64 relocation of a function pointer to external symbol 231# 232# jitlink-check: *{8}external_func_addr_quad = external_func 233 .globl external_func_addr_quad 234 .p2align 3 235external_func_addr_quad: 236 .xword external_func 237 .size external_func_addr_quad, 8 238 239# Check R_AARCH64_ADR_GOT_PAGE / R_AARCH64_LD64_GOT_LO12_NC handling with a 240# reference to an external symbol. Validate both the reference to the GOT entry, 241# and also the content of the GOT entry. 242# 243# For the ADRP :got: instruction we have the 21-bit delta to the 4k page 244# containing the GOT entry for external_data. 245# 246# For the LDR :got_lo12: instruction we have the 12-bit offset of the entry 247# within the page. 248# 249# jitlink-check: *{8}(got_addr(elf_reloc.o, external_data)) = external_data 250# jitlink-check: decode_operand(test_adr_gotpage_external, 1) = \ 251# jitlink-check: (got_addr(elf_reloc.o, external_data)[32:12] - \ 252# jitlink-check: test_adr_gotpage_external[32:12]) 253# jitlink-check: decode_operand(test_ld64_gotlo12_external, 2) = \ 254# jitlink-check: got_addr(elf_reloc.o, external_data)[11:3] 255 .globl test_adr_gotpage_external 256 .p2align 2 257test_adr_gotpage_external: 258 adrp x0, :got:external_data 259 .size test_adr_gotpage_external, .-test_adr_gotpage_external 260 261 .globl test_ld64_gotlo12_external 262 .p2align 2 263test_ld64_gotlo12_external: 264 ldr x0, [x0, :got_lo12:external_data] 265 .size test_ld64_gotlo12_external, .-test_ld64_gotlo12_external 266 267# Check R_AARCH64_LD64_GOTPAGE_LO15 handling with a reference to an external 268# symbol. Validate the reference to the GOT entry. 269# For the LDR :gotpage_lo15: instruction we have the 15-bit offset of the GOT 270# entry from the page containing the GOT. 271# jitlink-check: decode_operand(test_ld64_gotpagelo15_external, 2) = \ 272# jitlink-check: (got_addr(elf_reloc.o, external_data) - \ 273# jitlink-check: (section_addr(elf_reloc.o, $__GOT) & 0xfffffffffffff000)) \ 274# jitlink-check: [15:3] 275 .globl test_ld64_gotpagelo15_external 276 .p2align 2 277test_ld64_gotpagelo15_external: 278 ldr x0, [x0, :gotpage_lo15:external_data] 279 .size test_ld64_gotpagelo15_external, .-test_ld64_gotpagelo15_external 280 281# Check R_AARCH64_TSTBR14 for tbz 282# 283# jitlink-check: decode_operand(test_tstbr14_tbz, 2) = \ 284# jitlink-check: (test_tstbr14_tbz_target - test_tstbr14_tbz)[16:2] 285 .globl test_tstbr14_tbz, test_tstbr14_tbz_target 286 .p2align 2 287test_tstbr14_tbz: 288 tbz x0, 0, test_tstbr14_tbz_target 289 .skip (1 << 14) 290test_tstbr14_tbz_target: 291 .size test_tstbr14_tbz, .-test_tstbr14_tbz 292 293# Check R_AARCH64_TSTBR14 for tbnz 294# 295# jitlink-check: decode_operand(test_tstbr14_tbnz, 2) = \ 296# jitlink-check: (test_tstbr14_tbnz_target - test_tstbr14_tbnz)[16:2] 297 .globl test_tstbr14_tbnz, test_tstbr14_tbnz_target 298 .p2align 2 299test_tstbr14_tbnz: 300 tbnz x0, 0, test_tstbr14_tbnz_target 301 .skip (1 << 14) 302test_tstbr14_tbnz_target: 303 .size test_tstbr14_tbnz, .-test_tstbr14_tbnz 304 305# Check R_AARCH64_CONDBR19 for compare and branch instructions 306# 307# jitlink-check: decode_operand(test_condbr19_cbz, 1) = \ 308# jitlink-check: (test_condbr19_cbz_target - test_condbr19_cbz)[21:2] 309 .globl test_condbr19_cbz, test_condbr19_cbz_target 310 .p2align 2 311test_condbr19_cbz: 312 cbz x0, test_condbr19_cbz_target 313 .skip (1 << 19) 314test_condbr19_cbz_target: 315 .size test_condbr19_cbz, .-test_condbr19_cbz 316 317# Check R_AARCH64_CONDBR19 for conditional branch instructions 318# 319# jitlink-check: decode_operand(test_condbr19_bc, 1) = \ 320# jitlink-check: (test_condbr19_bc_target - test_condbr19_bc)[21:2] 321 .globl test_condbr19_bc, test_condbr19_bc_target 322 .p2align 2 323test_condbr19_bc: 324 b.eq test_condbr19_bc_target 325 .skip (1 << 19) 326test_condbr19_bc_target: 327 .size test_condbr19_bc, .-test_condbr19_bc 328 329 .globl named_data 330 .p2align 4 331 .type named_data,@object 332named_data: 333 .quad 0x2222222222222222 334 .quad 0x3333333333333333 335 .size named_data, .-named_data 336 337 .globl named_func 338 .p2align 2 339 .type named_func,@function 340named_func: 341 ret 342 .size named_func, .-named_func 343