llvm.org GIT mirror llvm / 9066b8a
[PowerPC] fix broken JIT-compiled code with tail call optimization The relocation for branch instructions in the dynamic loader of ExecutionEngine assumes branch instructions with R_PPC64_REL24 relocation type are only bl. However, with the tail call optimization, b instructions can be also used to jump into another function. This patch makes the relocation to keep bits in the branch instruction other than the jump offset to avoid relocation rewrites a b instruction into bl. Differential Revision: https://reviews.llvm.org/D47456 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@333502 91177308-0d34-0410-b5e6-96231b3b80d8 Hiroshi Inoue 2 years ago
2 changed file(s) with 51 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
771771 int64_t delta = static_cast(Value - FinalAddress + Addend);
772772 if (SignExtend64<26>(delta) != delta)
773773 llvm_unreachable("Relocation R_PPC64_REL24 overflow");
774 // Generates a 'bl
' instruction
775 writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
774 // We preserve bits other than LI field, i.e. PO and AA/LK fields.
775 uint32_t Inst = readBytesUnaligned(LocalAddress, 4);
776 writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
776777 } break;
777778 case ELF::R_PPC64_REL32: {
778779 uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);
0 # test for little endian
1 # RUN: rm -rf %t && mkdir -p %t
2 # RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t/ppc64_reloc.o %s
3 # RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t/ppc64_elf_module_b.o %S/Inputs/ppc64_elf_module_b.s
4 # RUN: llvm-rtdyld -triple=powerpc64le-unknown-linux-gnu -verify -check=%s %t/ppc64_reloc.o %t/ppc64_elf_module_b.o
5 # test for big endian
6 # RUN: rm -rf %t && mkdir -p %t
7 # RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t/ppc64_reloc.o %s
8 # RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t/ppc64_elf_module_b.o %S/Inputs/ppc64_elf_module_b.s
9 # RUN: llvm-rtdyld -triple=powerpc64-unknown-linux-gnu -verify -check=%s %t/ppc64_reloc.o %t/ppc64_elf_module_b.o
10
11 .text
12 .abiversion 2
13 .file "test.c"
14 .globl func
15 .p2align 4
16 .type func,@function
17 func: # @func
18 .Lfunc_begin0:
19 .Lfunc_gep0:
20 addis 2, 12, .TOC.-.Lfunc_gep0@ha
21 addi 2, 2, .TOC.-.Lfunc_gep0@l
22 .Lfunc_lep0:
23 .localentry func, .Lfunc_lep0-.Lfunc_gep0
24 mflr 0
25 std 31, -8(1)
26 std 0, 16(1)
27 stdu 1, -112(1)
28 mr 31, 1
29 # confirm that LK flag is set for bl
30 # rtdyld-check: (*{4}call_bl) & 1 = 1
31 call_bl:
32 bl foo
33 nop
34
35 li 3, 0
36 addi 1, 1, 112
37 ld 0, 16(1)
38 ld 31, -8(1)
39 mtlr 0
40 # confirm that LK flag is not set for b
41 # rtdyld-check: (*{4}call_b) & 1 = 0
42 call_b:
43 b foo
44 .long 0
45 .quad 0
46 .Lfunc_end0:
47 .size func, .Lfunc_end0-.Lfunc_begin0