diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -681,6 +681,8 @@ case R_PPC64_REL14: case R_PPC64_REL24: return R_PPC64_CALL_PLT; + case R_PPC64_REL24_NOTOC: + return R_PLT_PC; case R_PPC64_REL16_LO: case R_PPC64_REL16_HA: case R_PPC64_REL16_HI: @@ -993,7 +995,8 @@ write32(loc, (read32(loc) & ~mask) | (val & mask)); break; } - case R_PPC64_REL24: { + case R_PPC64_REL24: + case R_PPC64_REL24_NOTOC: { uint32_t mask = 0x03FFFFFC; checkInt(loc, val, 26, rel); checkAlignment(loc, val, 4, rel); @@ -1032,7 +1035,8 @@ bool PPC64::needsThunk(RelExpr expr, RelType type, const InputFile *file, uint64_t branchAddr, const Symbol &s, int64_t a) const { - if (type != R_PPC64_REL14 && type != R_PPC64_REL24) + if (type != R_PPC64_REL14 && type != R_PPC64_REL24 + && type != R_PPC64_REL24_NOTOC) return false; // If a function is in the Plt it needs to be called with a call-stub. @@ -1064,7 +1068,7 @@ int64_t offset = dst - src; if (type == R_PPC64_REL14) return isInt<16>(offset); - if (type == R_PPC64_REL24) + if (type == R_PPC64_REL24 || type == R_PPC64_REL24_NOTOC) return isInt<26>(offset); llvm_unreachable("unsupported relocation type used in branch"); } diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -945,7 +945,8 @@ } static Thunk *addThunkPPC64(RelType type, Symbol &s, int64_t a) { - assert((type == R_PPC64_REL14 || type == R_PPC64_REL24) && + assert((type == R_PPC64_REL14 || type == R_PPC64_REL24 || + type == R_PPC64_REL24_NOTOC) && "unexpected relocation type for thunk"); if (s.isInPlt()) return make(s); diff --git a/lld/test/ELF/ppc64-reloc-rel24notoc-externcall-samedso-callee-st-other0.s b/lld/test/ELF/ppc64-reloc-rel24notoc-externcall-samedso-callee-st-other0.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-reloc-rel24notoc-externcall-samedso-callee-st-other0.s @@ -0,0 +1,68 @@ +# REQUIRES: ppc +# RUN: echo 'SECTIONS { \ +# RUN: .text_low 0x10010158: { *(.text_low) } \ +# RUN: }' > %t.script + + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: echo '.globl callee; \ +# RUN: callee:; \ +# RUN: mullw 3, 3, 3; \ +# RUN: extsw 3, 3; \ +# RUN: blr' | llvm-mc -filetype=obj -triple=powerpc64le - -o %t1.o +# RUN: ld.lld %t.o %t1.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o +# RUN: echo '.globl callee; \ +# RUN: callee:; \ +# RUN: mullw 3, 3, 3; \ +# RUN: extsw 3, 3; \ +# RUN: blr' | llvm-mc -filetype=obj -triple=powerpc64 - -o %t1.o +# RUN: ld.lld %t.o %t1.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + + +# SYMBOL: 1: 0000000010010164 0 NOTYPE LOCAL DEFAULT [] 2 caller1 +# SYMBOL: 2: 00000000100101a0 0 NOTYPE LOCAL DEFAULT [] 2 caller2 +# SYMBOL: 3: 0000000010010158 0 NOTYPE LOCAL HIDDEN 1 callee + + +# CHECK: 0000000010010158 + +# CHECK: 0000000010010164 +# CHECK: 10010180: bl 0x10010158 +# CHECK-NEXT: 10010184: add 3, 3, 30 +# CHECK: 1001019c: blr + +# CHECK: 00000000100101a0 +# CHECK: 100101a8: b 0x10010158 + + +.section .text_low, "ax", %progbits +caller1: + .localentry caller1, 1 + mflr 0 + std 30, -16(1) + std 0, 16(1) + stdu 1, -48(1) + add 3, 4, 3 + extsw 3, 3 + mr 30, 5 + bl callee@notoc + add 3, 3, 30 + extsw 3, 3 + addi 1, 1, 48 + ld 0, 16(1) + ld 30, -16(1) + mtlr 0 + blr +caller2: + .localentry caller2, 1 + add 3, 4, 3 + extsw 3, 3 + b callee@notoc + #TC_RETURNd8 callee@notoc 0 + .hidden callee diff --git a/lld/test/ELF/ppc64-reloc-rel24notoc-externcall-samedso-callee-st-other1.s b/lld/test/ELF/ppc64-reloc-rel24notoc-externcall-samedso-callee-st-other1.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-reloc-rel24notoc-externcall-samedso-callee-st-other1.s @@ -0,0 +1,103 @@ +# REQUIRES: ppc +# RUN: echo 'SECTIONS { \ +# RUN: .text_low 0x10010158: { *(.text_low) } \ +# RUN: }' > %t.script + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: echo 'func: \ +# RUN: slwi 3, 3, 1; \ +# RUN: extsw 3, 3; \ +# RUN: blr; \ +# RUN: .globl callee; \ +# RUN: callee: \ +# RUN: .localentry callee, 1; \ +# RUN: mflr 0; \ +# RUN: std 30, -16(1); \ +# RUN: std 0, 16(1); \ +# RUN: stdu 1, -48(1); \ +# RUN: mr 30, 3; \ +# RUN: bl func@notoc; \ +# RUN: mullw 3, 3, 30; \ +# RUN: extsw 3, 3; \ +# RUN: addi 1, 1, 48; \ +# RUN: ld 0, 16(1); \ +# RUN: ld 30, -16(1); \ +# RUN: mtlr 0; \ +# RUN: blr' | llvm-mc -filetype=obj -triple=powerpc64le - -o %t1.o +# RUN: ld.lld %t.o %t1.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o +# RUN: echo 'func: \ +# RUN: slwi 3, 3, 1; \ +# RUN: extsw 3, 3; \ +# RUN: blr; \ +# RUN: .globl callee; \ +# RUN: callee: \ +# RUN: .localentry callee, 1; \ +# RUN: mflr 0; \ +# RUN: std 30, -16(1); \ +# RUN: std 0, 16(1); \ +# RUN: stdu 1, -48(1); \ +# RUN: mr 30, 3; \ +# RUN: bl func@notoc; \ +# RUN: mullw 3, 3, 30; \ +# RUN: extsw 3, 3; \ +# RUN: addi 1, 1, 48; \ +# RUN: ld 0, 16(1); \ +# RUN: ld 30, -16(1); \ +# RUN: mtlr 0; \ +# RUN: blr' | llvm-mc -filetype=obj -triple=powerpc64 - -o %t1.o +# RUN: ld.lld %t.o %t1.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + + +# SYMBOL: 1: 0000000010010198 0 NOTYPE LOCAL DEFAULT [] 2 caller1 +# SYMBOL: 2: 00000000100101d4 0 NOTYPE LOCAL DEFAULT [] 2 caller2 +# SYMBOL: 3: 0000000010010158 0 NOTYPE LOCAL DEFAULT 1 func +# SYMBOL: 4: 0000000010010164 0 NOTYPE LOCAL HIDDEN [] 1 callee + + +# CHECK: 0000000010010158 + +# CHECK: 0000000010010164 +# CHECK: 10010178: bl 0x10010158 +# CHECK-NEXT: 1001017c: mullw 3, 3, 30 +# CHECK 10010194: blr + +# CHECK: 0000000010010198 +# CHECK: 100101b4: bl 0x10010164 +# CHECK-NEXT: 100101b8: add 3, 3, 30 +# CHECK: 100101d0: blr + +# CHECK: 00000000100101d4 +# CHECK: 100101dc: b 0x10010164 + + +.section .text_low, "ax", %progbits +caller1: + .localentry caller1, 1 + mflr 0 + std 30, -16(1) + std 0, 16(1) + stdu 1, -48(1) + add 3, 4, 3 + extsw 3, 3 + mr 30, 5 + bl callee@notoc + add 3, 3, 30 + extsw 3, 3 + addi 1, 1, 48 + ld 0, 16(1) + ld 30, -16(1) + mtlr 0 + blr +caller2: + .localentry caller2, 1 + add 3, 4, 3 + extsw 3, 3 + b callee@notoc + #TC_RETURNd8 callee@notoc 0 + .hidden callee diff --git a/lld/test/ELF/ppc64-reloc-rel24notoc-localcall-callee-st-other0.s b/lld/test/ELF/ppc64-reloc-rel24notoc-localcall-callee-st-other0.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-reloc-rel24notoc-localcall-callee-st-other0.s @@ -0,0 +1,60 @@ +# REQUIRES: ppc +# RUN: echo 'SECTIONS { \ +# RUN: .text_low 0x10010158: { *(.text_low) } \ +# RUN: }' > %t.script + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: ld.lld -T %t.script %t.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o +# RUN: ld.lld -T %t.script %t.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + + +# SYMBOL: 1: 0000000010010158 0 NOTYPE LOCAL DEFAULT 1 callee +# SYMBOL: 2: 0000000010010164 0 NOTYPE LOCAL DEFAULT [] 1 caller1 +# SYMBOL: 3: 00000000100101a0 0 NOTYPE LOCAL DEFAULT [] 1 caller2 + + +# CHECK: 0000000010010158 + +# CHECK: 0000000010010164 +# CHECK: 10010180: bl 0x10010158 +# CHECK-NEXT: 10010184: add 3, 3, 30 +# CHECK: 1001019c: blr + +# CHECK: 00000000100101a0 +# CHECK: 100101a8: b 0x10010158 + + +.section .text_low, "ax", %progbits +callee: + mullw 3, 3, 3 + extsw 3, 3 + blr +caller1: + .localentry caller1, 1 + mflr 0 + std 30, -16(1) + std 0, 16(1) + stdu 1, -48(1) + add 3, 4, 3 + extsw 3, 3 + mr 30, 5 + bl callee@notoc + add 3, 3, 30 + extsw 3, 3 + addi 1, 1, 48 + ld 0, 16(1) + ld 30, -16(1) + mtlr 0 + blr +caller2: + .localentry caller2, 1 + add 3, 4, 3 + extsw 3, 3 + b callee@notoc + #TC_RETURNd8 callee@notoc 0 diff --git a/lld/test/ELF/ppc64-reloc-rel24notoc-localcall-callee-st-other1.s b/lld/test/ELF/ppc64-reloc-rel24notoc-localcall-callee-st-other1.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-reloc-rel24notoc-localcall-callee-st-other1.s @@ -0,0 +1,81 @@ +# REQUIRES: ppc +# RUN: echo 'SECTIONS { \ +# RUN: .text_low 0x10010158: { *(.text_low) } \ +# RUN: }' > %t.script + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: ld.lld -T %t.script %t.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o +# RUN: ld.lld -T %t.script %t.o -o %t +# RUN: llvm-readelf -s %t | FileCheck %s --check-prefix=SYMBOL +# RUN: llvm-objdump -d --no-show-raw-insn --mcpu=future %t | FileCheck %s + + +# SYMBOL: 1: 0000000010010164 0 NOTYPE LOCAL DEFAULT [] 1 callee +# SYMBOL: 2: 0000000010010198 0 NOTYPE LOCAL DEFAULT [] 1 caller1 +# SYMBOL: 3: 00000000100101d4 0 NOTYPE LOCAL DEFAULT [] 1 caller2 +# SYMBOL: 4: 0000000010010158 0 NOTYPE LOCAL DEFAULT 1 func + + +# CHECK: 0000000010010158 + +# CHECK: 0000000010010164 +# CHECK: 10010178: bl 0x10010158 +# CHECK-NEXT: 1001017c: mullw 3, 3, 30 +# CHECK: 10010194: blr + +# CHECK: 0000000010010198 +# CHECK: 100101b4: bl 0x10010164 +# CHECK-NEXT: 100101b8: add 3, 3, 3 +# CHECK: 100101d0: blr + +# CHECK: 00000000100101d4 +# CHECK: 100101dc: b 0x10010164 + + +.section .text_low, "ax", %progbits +func: + slwi 3, 3, 1 + extsw 3, 3 + blr +callee: + .localentry callee, 1 + mflr 0 + std 30, -16(1) + std 0, 16(1) + stdu 1, -48(1) + mr 30, 3 + bl func@notoc + mullw 3, 3, 30 + extsw 3, 3 + addi 1, 1, 48 + ld 0, 16(1) + ld 30, -16(1) + mtlr 0 + blr +caller1: + .localentry caller1, 1 + mflr 0 + std 30, -16(1) + std 0, 16(1) + stdu 1, -48(1) + add 3, 4, 3 + extsw 3, 3 + mr 30, 5 + bl callee@notoc + add 3, 3, 30 + extsw 3, 3 + addi 1, 1, 48 + ld 0, 16(1) + ld 30, -16(1) + mtlr 0 + blr +caller2: + .localentry caller2, 1 + add 3, 4, 3 + extsw 3, 3 + b callee@notoc + #TC_RETURNd8 callee@notoc 0