1# RUN: rm -rf %t && mkdir -p %t
2# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent -filetype=obj -o %t/elf_reloc.o %s
3# RUN: llvm-jitlink -noexec -slab-allocate 100Kb -slab-address 0xfff00000 \
4# RUN:              -define-abs external_data=0x1 \
5# RUN:              -define-abs extern_in_range32=0xffe00000 \
6# RUN:              -define-abs extern_out_of_range32=0x7fff00000000 \
7# RUN:              -check %s %t/elf_reloc.o
8#
9# Test standard ELF relocations.
10
11        .text
12        .file   "testcase.c"
13
14# Empty main entry point.
15        .globl  main
16        .p2align        4, 0x90
17        .type   main,@function
18main:
19        retq
20
21        .size   main, .-main
22
23# Test PCRel32 / R_X86_64_PC32 handling.
24# jitlink-check: decode_operand(test_pcrel32, 4) = named_data - next_pc(test_pcrel32)
25        .globl  test_pcrel32
26        .p2align       4, 0x90
27        .type   test_pcrel32,@function
28test_pcrel32:
29        movl    named_data(%rip), %eax
30
31         .size   test_pcrel32, .-test_pcrel32
32
33        .globl  named_func
34        .p2align       4, 0x90
35        .type   named_func,@function
36named_func:
37        xorq    %rax, %rax
38
39        .size   named_func, .-named_func
40
41# Check R_X86_64_PLT32 handling with a call to a local function. This produces a
42# Branch32 edge that is resolved like a regular PCRel32 (no PLT entry created).
43#
44# jitlink-check: decode_operand(test_call_local, 0) = named_func - next_pc(test_call_local)
45        .globl  test_call_local
46        .p2align       4, 0x90
47        .type   test_call_local,@function
48test_call_local:
49        callq   named_func
50
51        .size   test_call_local, .-test_call_local
52
53# Check R_X86_64_PLT32 handling with a call to an external. This produces a
54# Branch32ToStub edge, because externals are not defined locally. During
55# resolution, the target turns out to be in-range from the callsite and so the
56# edge is relaxed in post-allocation optimization.
57#
58# jitlink-check: decode_operand(test_call_extern, 0) = extern_in_range32 - next_pc(test_call_extern)
59        .globl  test_call_extern
60        .p2align       4, 0x90
61        .type   test_call_extern,@function
62test_call_extern:
63        callq   extern_in_range32@plt
64
65        .size   test_call_extern, .-test_call_extern
66
67# Check R_X86_64_PLT32 handling with a call to an external via PLT. This
68# produces a Branch32ToStub edge, because externals are not defined locally.
69# As the target is out-of-range from the callsite, the edge keeps using its PLT
70# entry.
71#
72# jitlink-check: decode_operand(test_call_extern_plt, 0) = \
73# jitlink-check:     stub_addr(elf_reloc.o, extern_out_of_range32) - next_pc(test_call_extern_plt)
74# jitlink-check: *{8}(got_addr(elf_reloc.o, extern_out_of_range32)) = extern_out_of_range32
75        .globl  test_call_extern_plt
76        .p2align       4, 0x90
77        .type   test_call_extern_plt,@function
78test_call_extern_plt:
79        callq   extern_out_of_range32@plt
80
81        .size   test_call_extern_plt, .-test_call_extern_plt
82
83# Test GOTPCREL handling. We want to check both the offset to the GOT entry and its
84# contents.
85# jitlink-check: decode_operand(test_gotpcrel, 4) = got_addr(elf_reloc.o, named_data) - next_pc(test_gotpcrel)
86# jitlink-check: *{8}(got_addr(elf_reloc.o, named_data)) = named_data
87
88        .globl test_gotpcrel
89        .p2align      4, 0x90
90        .type   test_gotpcrel,@function
91test_gotpcrel:
92	movl    named_data@GOTPCREL(%rip), %eax
93
94        .size   test_gotpcrel, .-test_gotpcrel
95
96# Test REX_GOTPCRELX handling. We want to check both the offset to the GOT entry and its
97# contents.
98# jitlink-check: decode_operand(test_rex_gotpcrelx, 4) = \
99# jitlink-check:   got_addr(elf_reloc.o, external_data) - next_pc(test_rex_gotpcrelx)
100
101        .globl test_rex_gotpcrelx
102        .p2align      4, 0x90
103        .type   test_rex_gotpcrelx,@function
104test_rex_gotpcrelx:
105	movq    external_data@GOTPCREL(%rip), %rax
106
107        .size   test_rex_gotpcrelx, .-test_rex_gotpcrelx
108
109        .type   named_data,@object
110        .data
111        .p2align        3
112named_data:
113        .quad   42
114        .size   named_data, 8
115
116# Test BSS / zero-fill section handling.
117# llvm-jitlink: *{4}bss_variable = 0
118
119	.type	bss_variable,@object
120	.bss
121	.globl	bss_variable
122	.p2align	2
123bss_variable:
124	.long	0
125	.size	bss_variable, 4
126
127        .ident  "clang version 10.0.0-4ubuntu1 "
128        .section        ".note.GNU-stack","",@progbits
129        .addrsig
130