[lld] 9195b01 - [ELF][PPC64] Enable R_PPC64_REL14 trunks

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Apr 4 11:00:33 PDT 2020


Author: Fangrui Song
Date: 2020-04-04T10:59:17-07:00
New Revision: 9195b0191130a8d5f1751f60b3489782ca5dc315

URL: https://github.com/llvm/llvm-project/commit/9195b0191130a8d5f1751f60b3489782ca5dc315
DIFF: https://github.com/llvm/llvm-project/commit/9195b0191130a8d5f1751f60b3489782ca5dc315.diff

LOG: [ELF][PPC64] Enable R_PPC64_REL14 trunks

The thunk implementation is available but an assertion disallows it.
Linux kernel has such a use case: in arch/powerpc/kernel/exceptions-64s.S:handle_page_fault,
beq+ ret_from_except_lite may get out of range.

Link: https://github.com/ClangBuiltLinux/linux/issues/951

Differential Revision: https://reviews.llvm.org/D76904

Added: 
    lld/test/ELF/ppc64-long-branch-rel14.s

Modified: 
    lld/ELF/Thunks.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 8603b330f854..3b8086931ddb 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -945,7 +945,8 @@ static Thunk *addThunkPPC32(const InputSection &isec, const Relocation &rel,
 }
 
 static Thunk *addThunkPPC64(RelType type, Symbol &s, int64_t a) {
-  assert(type == R_PPC64_REL24 && "unexpected relocation type for thunk");
+  assert((type == R_PPC64_REL14 || type == R_PPC64_REL24) &&
+         "unexpected relocation type for thunk");
   if (s.isInPlt())
     return make<PPC64PltCallStub>(s);
 

diff  --git a/lld/test/ELF/ppc64-long-branch-rel14.s b/lld/test/ELF/ppc64-long-branch-rel14.s
new file mode 100644
index 000000000000..dc67e932fd3c
--- /dev/null
+++ b/lld/test/ELF/ppc64-long-branch-rel14.s
@@ -0,0 +1,60 @@
+# REQUIRES: ppc
+# RUN: echo 'SECTIONS { \
+# RUN:       .text_low 0x2000: { *(.text_low) } \
+# RUN:       .text_high 0xa000 : { *(.text_high) } \
+# RUN:       }' > %t.lds
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o
+# RUN: ld.lld -T %t.lds %t.o -o %t
+# RUN: llvm-readelf -r %t | FileCheck --check-prefix=SEC %s
+# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
+
+# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
+# RUN: ld.lld -pie -T %t.lds %t.o -o %t
+# RUN: llvm-readelf -r %t | FileCheck --check-prefix=SEC %s
+# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
+
+# SEC: There are no relocations in this file.
+
+# CHECK-LABEL: <_start>:
+# CHECK-NEXT:  2000: bt 2, 0x2014
+# CHECK-NEXT:        bt+ 2, 0x2014
+# CHECK-NEXT:        bf 2, 0xa004
+# CHECK-NEXT:        bt 2, 0x2024
+# CHECK-NEXT:        blr
+# CHECK-EMPTY:
+# CHECK-NEXT: <__long_branch_high>:
+# CHECK-NEXT:  2014: addis 12, 2, 0
+# CHECK-NEXT:        ld 12, {{.*}}(12)
+# CHECK-NEXT:        mtctr 12
+# CHECK-NEXT:        bctr
+# CHECK-EMPTY:
+
+# CHECK-NEXT: <__long_branch_>:
+# CHECK-NEXT:  2024: addis 12, 2, 0
+# CHECK-NEXT:        ld 12, {{.*}}(12)
+# CHECK-NEXT:        mtctr 12
+# CHECK-NEXT:        bctr
+
+.section .text_low, "ax", @progbits
+.globl _start
+_start:
+beq high           # Need a thunk
+beq+ high          # Need a thunk
+bne high
+beq .text_high+16  # Need a thunk
+blr
+
+# CHECK-LABEL: <.text_high>:
+# CHECK-NEXT:      a000: nop
+# CHECK-EMPTY:
+# CHECK-LABEL: <high>:
+# CHECK-NEXT:      a004: bf 0, 0x2008
+# CHECK-NEXT:            bt 1, 0x2008
+
+.section .text_high, "ax", @progbits
+nop
+.globl high
+high:
+bge .text_low+8    # Need a thunk
+bgt .text_low+8    # Need a thunk


        


More information about the llvm-commits mailing list