[llvm] r333502 - [PowerPC] fix broken JIT-compiled code with tail call optimization

Hiroshi Inoue via llvm-commits llvm-commits at lists.llvm.org
Tue May 29 21:48:29 PDT 2018


Author: inouehrs
Date: Tue May 29 21:48:29 2018
New Revision: 333502

URL: http://llvm.org/viewvc/llvm-project?rev=333502&view=rev
Log:
[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


Added:
    llvm/trunk/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s
Modified:
    llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp

Modified: llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp?rev=333502&r1=333501&r2=333502&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp Tue May 29 21:48:29 2018
@@ -772,8 +772,9 @@ void RuntimeDyldELF::resolvePPC64Relocat
     int64_t delta = static_cast<int64_t>(Value - FinalAddress + Addend);
     if (SignExtend64<26>(delta) != delta)
       llvm_unreachable("Relocation R_PPC64_REL24 overflow");
-    // Generates a 'bl <address>' instruction
-    writeInt32BE(LocalAddress, 0x48000001 | (delta & 0x03FFFFFC));
+    // We preserve bits other than LI field, i.e. PO and AA/LK fields.
+    uint32_t Inst = readBytesUnaligned(LocalAddress, 4);
+    writeInt32BE(LocalAddress, (Inst & 0xFC000003) | (delta & 0x03FFFFFC));
   } break;
   case ELF::R_PPC64_REL32: {
     uint64_t FinalAddress = Section.getLoadAddressWithOffset(Offset);

Added: llvm/trunk/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s?rev=333502&view=auto
==============================================================================
--- llvm/trunk/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s (added)
+++ llvm/trunk/test/ExecutionEngine/RuntimeDyld/PowerPC/ppc64_reloc.s Tue May 29 21:48:29 2018
@@ -0,0 +1,48 @@
+# test for little endian
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t/ppc64_reloc.o %s
+# RUN: llvm-mc -triple=powerpc64le-unknown-linux-gnu -filetype=obj -o %t/ppc64_elf_module_b.o %S/Inputs/ppc64_elf_module_b.s
+# RUN: llvm-rtdyld -triple=powerpc64le-unknown-linux-gnu -verify -check=%s %t/ppc64_reloc.o %t/ppc64_elf_module_b.o
+# test for big endian
+# RUN: rm -rf %t && mkdir -p %t
+# RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t/ppc64_reloc.o %s
+# RUN: llvm-mc -triple=powerpc64-unknown-linux-gnu -filetype=obj -o %t/ppc64_elf_module_b.o %S/Inputs/ppc64_elf_module_b.s
+# RUN: llvm-rtdyld -triple=powerpc64-unknown-linux-gnu -verify -check=%s %t/ppc64_reloc.o %t/ppc64_elf_module_b.o
+
+	.text
+	.abiversion 2
+	.file	"test.c"
+	.globl	func
+	.p2align	4
+	.type	func, at function
+func:                                   # @func
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0 at ha
+	addi 2, 2, .TOC.-.Lfunc_gep0 at l
+.Lfunc_lep0:
+	.localentry	func, .Lfunc_lep0-.Lfunc_gep0
+	mflr 0
+	std 31, -8(1)
+	std 0, 16(1)
+	stdu 1, -112(1)
+	mr 31, 1
+# confirm that LK flag is set for bl
+# rtdyld-check: (*{4}call_bl) & 1 = 1
+call_bl:
+	bl foo
+	nop
+
+	li 3, 0
+	addi 1, 1, 112
+	ld 0, 16(1)
+	ld 31, -8(1)
+	mtlr 0
+# confirm that LK flag is not set for b
+# rtdyld-check: (*{4}call_b) & 1 = 0
+call_b:
+	b foo
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	func, .Lfunc_end0-.Lfunc_begin0




More information about the llvm-commits mailing list