diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -113,13 +113,13 @@ ", " + Twine(max).str() + "]" + hint); } -void elf::checkRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym, - const Twine &msg) { +void elf::reportRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym, + const Twine &msg) { ErrorPlace errPlace = getErrorPlace(loc); std::string hint; - if (!sym.isLocal()) + if (!sym.getName().empty()) hint = "; references " + lld::toString(sym) + getDefinedLocation(sym); - errorOrWarn(errPlace.loc + msg + " out of range: " + Twine(v) + + errorOrWarn(errPlace.loc + msg + " is out of range: " + Twine(v) + " is not in [" + Twine(llvm::minIntN(n)) + ", " + Twine(llvm::maxIntN(n)) + "]" + hint); } diff --git a/lld/ELF/Target.h b/lld/ELF/Target.h --- a/lld/ELF/Target.h +++ b/lld/ELF/Target.h @@ -229,6 +229,8 @@ void reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v, int64_t min, uint64_t max); +void reportRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym, + const Twine &msg); // Make sure that V can be represented as an N bit signed integer. inline void checkInt(uint8_t *loc, int64_t v, int n, const Relocation &rel) { @@ -260,8 +262,6 @@ " is not aligned to " + Twine(n) + " bytes"); } -void checkRangeError(uint8_t *loc, int64_t v, int n, const Symbol &sym, const Twine &msg); - // Endianness-aware read/write. inline uint16_t read16(const void *p) { return llvm::support::endian::read16(p, config->endianness); diff --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp --- a/lld/ELF/Thunks.cpp +++ b/lld/ELF/Thunks.cpp @@ -896,7 +896,8 @@ int64_t offset = destination.getVA() - (getThunkTargetSym()->getVA() + 4); // The branch offset needs to fit in 26 bits. if (!isInt<26>(offset)) - fatal("R2 save stub branch offset is too large: " + Twine(offset)); + reportRangeError(buf, offset, 26, destination, "R2 save stub offset"); + // fatal("R2 save stub branch offset is too large: " + Twine(offset)); write32(buf + 0, 0xf8410018); // std r2,24(r1) write32(buf + 4, 0x48000000 | (offset & 0x03fffffc)); // b } @@ -910,7 +911,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"); + reportRangeError(buf, offset, 34, destination, "R12 setup stub offset"); uint64_t paddi = PADDI_R12_NO_DISP | (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff); @@ -927,7 +928,8 @@ 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"); + reportRangeError(buf, offset, 34, destination, + "PC-relative PLT stub offset"); uint64_t pld = PLD_R12_NO_DISP | (((offset >> 16) & 0x3ffff) << 32) | (offset & 0xffff); diff --git a/lld/test/ELF/ppc64-toc-call-to-pcrel-long-jump.s b/lld/test/ELF/ppc64-toc-call-to-pcrel-long-jump.s --- a/lld/test/ELF/ppc64-toc-call-to-pcrel-long-jump.s +++ b/lld/test/ELF/ppc64-toc-call-to-pcrel-long-jump.s @@ -10,7 +10,7 @@ # RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o # RUN: not ld.lld -T %t.script %t.o -o /dev/null 2>&1 | FileCheck %s -# CHECK: error: R2 save stub branch offset is too large: -268501028 +# CHECK: error: R2 save stub offset is out of range: -268501028 is not in [-33554432, 33554431]; references callee .section .text_callee, "ax", %progbits callee: