xref: /llvm-project/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_relocations.s (revision 199c400387a5492e021925ef42ea744ccf7812de)
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