diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp index 684ff5154a332..eada4254a3c22 100644 --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -966,7 +966,8 @@ bool PPC64LongBranchThunk::isCompatibleWith(const InputSection &isec, void PPC64PCRelLongBranchThunk::writeTo(uint8_t *buf) { int64_t offset = destination.getVA() - getThunkTargetSym()->getVA(); if (!isInt<34>(offset)) - fatal("offset overflow 34 bits, please compile using the large code model"); + reportRangeError(buf, offset, 34, destination, + "PC-relative long branch stub offset"); uint64_t paddi = PADDI_R12_NO_DISP | (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff); 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 index 0000000000000..7fe4b2ed127fa --- /dev/null +++ b/lld/test/ELF/ppc64-pcrel-call-to-toc-error.s @@ -0,0 +1,44 @@ +# REQUIRES: ppc +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=ppc64le %t/asm -o %t.o +# RUN: not ld.lld --script %t/lds %t.o -o %t1 2>&1 | FileCheck %s +# RUN: ld.lld --script %t/lds %t.o -o %t1 --noinhibit-exec +# RUN: rm %t.o %t1 + +# RUN: llvm-mc -filetype=obj -triple=ppc64 %t/asm -o %t.o +# RUN: not ld.lld --script %t/lds %t.o -o %t1 2>&1 | FileCheck %s +# RUN: ld.lld --script %t/lds %t.o -o %t1 --noinhibit-exec +# RUN: rm %t.o %t1 + +# CHECK: error: R12 setup stub offset is out of range: 8589934592 is not in [-8589934592, 8589934591]; references callee +# CHECK-NEXT: >>> defined in {{.*}}.o + +//--- asm +.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 + +//--- lds +PHDRS { + low PT_LOAD FLAGS(0x1 | 0x4); + high PT_LOAD FLAGS(0x1 | 0x4); +} +SECTIONS { + .text_low 0x2000 : { *(.text_low) } :low + .text_high 0x200002010 : { *(.text_high) } :high +} diff --git a/lld/test/ELF/ppc64-pcrel-long-branch-error.s b/lld/test/ELF/ppc64-pcrel-long-branch-error.s index 2db9d15b70d07..00a1e7dd4d9ad 100644 --- a/lld/test/ELF/ppc64-pcrel-long-branch-error.s +++ b/lld/test/ELF/ppc64-pcrel-long-branch-error.s @@ -1,26 +1,27 @@ -# REQUIRES: ppc, system-linux -# RUN: echo 'SECTIONS { \ -# RUN: .text_low 0x2000: { *(.text_low) } \ -# RUN: .text_high 0x200002010 : { *(.text_high) } \ -# RUN: }' > %t.script +# REQUIRES: ppc +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=ppc64le %t/asm -o %t.o +# RUN: not ld.lld --script %t/lds %t.o -o %t1 2>&1 | FileCheck %s +# RUN: ld.lld --script %t/lds %t.o -o %t1 --noinhibit-exec +# RUN: rm %t.o %t1 +# RUN: llvm-mc -filetype=obj -triple=ppc64le -defsym HIDDEN=1 %t/asm -o %t.o +# RUN: not ld.lld -shared --script %t/lds %t.o -o %t1 2>&1 | FileCheck %s +# RUN: ld.lld -shared --script %t/lds %t.o -o %t1 --noinhibit-exec +# RUN: rm %t.o %t1 -## In this test, we do not use -o /dev/null like other similar cases do since -## it will fail in some enviroments with out-of-memory errors associated with -## buffering the output in memeory. The test is enabled for ppc linux only since -## writing to an allocated file will cause time out error for this case on freebsd. +# RUN: llvm-mc -filetype=obj -triple=ppc64 %t/asm -o %t.o +# RUN: not ld.lld --script %t/lds %t.o -o %t1 2>&1 | FileCheck %s +# RUN: ld.lld --script %t/lds %t.o -o %t1 --noinhibit-exec +# RUN: rm %t.o %t1 +# RUN: llvm-mc -filetype=obj -triple=ppc64 -defsym HIDDEN=1 %t/asm -o %t.o +# RUN: not ld.lld -shared --script %t/lds %t.o -o %t1 2>&1 | FileCheck %s +# RUN: ld.lld -shared --script %t/lds %t.o -o %t1 --noinhibit-exec +# RUN: rm %t.o %t1 -# 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=ppc64le -defsym HIDDEN=1 %s -o %t.o -# RUN: not ld.lld -shared -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 -# RUN: llvm-mc -filetype=obj -triple=ppc64 -defsym HIDDEN=1 %s -o %t.o -# RUN: not ld.lld -shared -T %t.script %t.o -o %t 2>&1 | FileCheck %s - -# CHECK: error: offset overflow 34 bits, please compile using the large code model +# CHECK: error: PC-relative long branch stub offset is out of range: 8589934592 is not in [-8589934592, 8589934591]; references high +# CHECK-NEXT: >>> defined in {{.*}}.o +//--- asm .section .text_low, "ax", %progbits .globl _start _start: @@ -34,3 +35,13 @@ _start: .globl high high: blr + +//--- lds +PHDRS { + low PT_LOAD FLAGS(0x1 | 0x4); + high PT_LOAD FLAGS(0x1 | 0x4); +} +SECTIONS { + .text_low 0x2000 : { *(.text_low) } :low + .text_high 0x200002010 : { *(.text_high) } :high +}