diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -910,7 +910,7 @@ void PPC64R12SetupStub::writeTo(uint8_t *buf) { int64_t offset = destination.getVA() - getThunkTargetSym()->getVA(); if (!isInt<34>(offset)) - fatal("offset must fit in 34 bits to encode in the instruction"); + fatal("offset overflow 34 bits, please compile using the large code model"); uint64_t paddi = PADDI_R12_NO_DISP | (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff); @@ -927,7 +927,7 @@ void PPC64PCRelPLTStub::writeTo(uint8_t *buf) { int64_t offset = destination.getGotPltVA() - getThunkTargetSym()->getVA(); if (!isInt<34>(offset)) - fatal("offset must fit in 34 bits to encode in the instruction"); + fatal("offset overflow 34 bits, please compile using the large code model"); uint64_t pld = PLD_R12_NO_DISP | (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff); diff --git a/lld/test/ELF/ppc64-pcrel-call-to-extern-error.s b/lld/test/ELF/ppc64-pcrel-call-to-extern-error.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-pcrel-call-to-extern-error.s @@ -0,0 +1,30 @@ +# REQUIRES: ppc, linux +# RUN: echo 'SECTIONS { \ +# RUN: .text_low 0x2000: { *(.text_low) } \ +# RUN: .text_high 0x200002010 : { *(.text_high) } \ +# RUN: }' > %t.script + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le --defsym AUX=1 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t2.o +# RUN: lld.lld --shared %t2.o -o %t2.so +# RUN: not ld.lld -T %t.script %t1.o %t2.so -o %t 2>&1 | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 --defsym AUX=1 %s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t2.o +# RUN: lld.lld --shared %t2.o -o %t2.so +# RUN: not ld.lld -T %t.script %t1.o %t2.so -o %t 2>&1 | FileCheck %s + +# CHECK: error: offset overflow 34 bits, please compile using the large code model + +.ifdef AUX +.section .text_low, "ax", %progbits +caller: + .localentry caller, 1 + bl callee@notoc + blr +.else +.section .text_high, "ax", %progbits +.globl callee +callee: + blr +.endif diff --git a/lld/test/ELF/ppc64-pcrel-call-to-toc-error.s b/lld/test/ELF/ppc64-pcrel-call-to-toc-error.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-pcrel-call-to-toc-error.s @@ -0,0 +1,33 @@ +# REQUIRES: ppc, linux +# RUN: echo 'SECTIONS { \ +# RUN: .text_low 0x2000: { *(.text_low) } \ +# RUN: .text_high 0x200002010 : { *(.text_high) } \ +# RUN: }' > %t.script + +# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t.o +# RUN: not ld.lld -T %t.script %t.o -o %t 2>&1 | FileCheck %s + +# RUN: llvm-mc -filetype=obj -triple=ppc64 %s -o %t.o +# RUN: not ld.lld -T %t.script %t.o -o %t 2>&1 | FileCheck %s + +# CHECK: error: offset overflow 34 bits, please compile using the large code model + +.section .text_high, "ax", %progbits +callee: + .Lfunc_gep1: + addis 2, 12, .TOC.-.Lfunc_gep1@ha + addi 2, 2, .TOC.-.Lfunc_gep1@l + .Lfunc_lep1: + .localentry callee, .Lfunc_lep1-.Lfunc_gep1 + addis 4, 2, global@toc@ha + lwz 4, global@toc@l(4) + blr + +.section .text_low, "ax", %progbits +caller: + .localentry caller, 1 + bl callee@notoc + blr +global: + .long 0 + .size global, 4