1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
# RUN: rm -rf %t && mkdir -p %t
# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent \
# RUN: -filetype=obj -o %t/elf_sm_pic_reloc.o %s
# RUN: llvm-jitlink -noexec \
# RUN: -slab-allocate 100Kb -slab-address 0xfff00000 -slab-page-size 4096 \
# RUN: -abs external_data=0x1 \
# RUN: -abs extern_out_of_range32=0x7fff00000000 \
# RUN: -check %s %t/elf_sm_pic_reloc.o
#
# Test ELF small/PIC relocations.
.text
.file "testcase.c"
# Empty main entry point.
.globl main
.p2align 4, 0x90
.type main,@function
main:
retq
.size main, .-main
# Test PCRel32 / R_X86_64_PC32 handling.
# jitlink-check: decode_operand(test_pcrel32, 4) = named_data - next_pc(test_pcrel32)
.globl test_pcrel32
.p2align 4, 0x90
.type test_pcrel32,@function
test_pcrel32:
movl named_data(%rip), %eax
.size test_pcrel32, .-test_pcrel32
.globl named_func
.p2align 4, 0x90
.type named_func,@function
named_func:
xorq %rax, %rax
.size named_func, .-named_func
# Check R_X86_64_PLT32 handling with a call to a local function in the text
# section. This produces a Branch32 edge that is resolved like a regular
# PCRel32 (no PLT entry created).
#
# jitlink-check: decode_operand(test_call_local, 0) = \
# jitlink-check: named_func - next_pc(test_call_local)
.globl test_call_local
.p2align 4, 0x90
.type test_call_local,@function
test_call_local:
callq named_func
.size test_call_local, .-test_call_local
# Check R_X86_64_PLT32 handling with a call to a local linkage function in a
# different text section and at a non-zero offset. This produces a Branch32 edge
# that is resolved like a regular PCRel32 (no PLT entry created). The non-zero
# offset requires us to handle addends for branch relocations correctly.
#
# jitlink-check: decode_operand(test_call_alt_sec_at_offset, 0) = \
# jitlink-check: (section_addr(elf_sm_pic_reloc.o, .text.alt) + 16) - \
# jitlink-check: next_pc(test_call_alt_sec_at_offset)
.globl test_call_alt_sec_at_offset
.p2align 4, 0x90
.type test_call_alt_sec_at_offset,@function
test_call_alt_sec_at_offset:
callq named_func_alt_sec_at_offset
.size test_call_alt_sec_at_offset, .-test_call_alt_sec_at_offset
# Check R_X86_64_PLT32 handling with a call to an external via PLT. This
# produces a Branch32ToStub edge, because externals are not defined locally.
# As the target is out-of-range from the callsite, the edge keeps using its PLT
# entry.
#
# jitlink-check: decode_operand(test_call_extern_plt, 0) = \
# jitlink-check: stub_addr(elf_sm_pic_reloc.o, extern_out_of_range32) - \
# jitlink-check: next_pc(test_call_extern_plt)
# jitlink-check: *{8}(got_addr(elf_sm_pic_reloc.o, extern_out_of_range32)) = \
# jitlink-check: extern_out_of_range32
.globl test_call_extern_plt
.p2align 4, 0x90
.type test_call_extern_plt,@function
test_call_extern_plt:
callq extern_out_of_range32@plt
.size test_call_extern_plt, .-test_call_extern_plt
# Test GOTPCREL handling. We want to check both the offset to the GOT entry and its
# contents. "movl" will be optimized to "leal" and a non-got access if the pc relative
# offset to named_data is in range of 32 bits signed immediate. So use "leal" here to
# suppress optimization
# jitlink-check: decode_operand(test_gotpcrel, 4) = \
# jitlink-check: got_addr(elf_sm_pic_reloc.o, named_data) - next_pc(test_gotpcrel)
# jitlink-check: *{8}(got_addr(elf_sm_pic_reloc.o, named_data)) = named_data
.globl test_gotpcrel
.p2align 4, 0x90
.type test_gotpcrel,@function
test_gotpcrel:
leal named_data@GOTPCREL(%rip), %eax
.size test_gotpcrel, .-test_gotpcrel
# Test REX_GOTPCRELX handling. We want to check both the offset to the GOT entry and its
# contents.
# jitlink-check: decode_operand(test_rex_gotpcrelx, 4) = \
# jitlink-check: got_addr(elf_sm_pic_reloc.o, external_data) - next_pc(test_rex_gotpcrelx)
.globl test_rex_gotpcrelx
.p2align 4, 0x90
.type test_rex_gotpcrelx,@function
test_rex_gotpcrelx:
movq external_data@GOTPCREL(%rip), %rax
.size test_rex_gotpcrelx, .-test_rex_gotpcrelx
# Test GOTOFF64 handling.
# jitlink-check: decode_operand(test_gotoff64, 1) = named_func - _GLOBAL_OFFSET_TABLE_
.globl test_gotoff64
.p2align 4, 0x90
.type test_gotoff64,@function
test_gotoff64:
movabsq $named_func@GOTOFF, %rax
.size test_gotoff64, .-test_gotoff64
# Test that relocations to anonymous constant pool entries work.
.globl test_anchor_LCPI
.p2align 4, 0x90
.type test_anchor_LCPI,@function
test_anchor_LCPI:
movq .LCPI0_0(%rip), %rax
.size test_anchor_LCPI, .-test_anchor_LCPI
.data
.type named_data,@object
.p2align 3
named_data:
.quad 42
.size named_data, 8
# Test BSS / zero-fill section handling.
# llvm-jitlink: *{4}bss_variable = 0
.type bss_variable,@object
.bss
.globl bss_variable
.p2align 2
bss_variable:
.long 0
.size bss_variable, 4
# Named functions in a separate section.
.section .text.alt,"ax",@progbits
# .byte plus alignment of 16 should put named_func_alt_sec_at_offset at offset
# 16 within .text.alt.
.byte 7
.p2align 4, 0x90
.type named_func_alt_sec_at_offset,@function
named_func_alt_sec_at_offset:
retq
.size named_func_alt_sec_at_offset, .-named_func_alt_sec_at_offset
# Constant pool entry with type STT_NOTYPE.
.section .rodata.cst8,"aM",@progbits,8
.p2align 3
.LCPI0_0:
.quad 0x400921fb54442d18
.ident "clang version 10.0.0-4ubuntu1 "
.section ".note.GNU-stack","",@progbits
.addrsig
|