[lld] 94921e9 - [ELF] Define a reportRangeError() overload for thunks and tidy up recent PPC64 thunk range errors

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 14 09:57:37 PDT 2020


Author: Fangrui Song
Date: 2020-09-14T09:55:59-07:00
New Revision: 94921e9f8ad04793638e02a6104f63e06ae62b9e

URL: https://github.com/llvm/llvm-project/commit/94921e9f8ad04793638e02a6104f63e06ae62b9e
DIFF: https://github.com/llvm/llvm-project/commit/94921e9f8ad04793638e02a6104f63e06ae62b9e.diff

LOG: [ELF] Define a reportRangeError() overload for thunks and tidy up recent PPC64 thunk range errors

Prefer `errorOrWarn` to `fatal` for recoverable errors and graceful degradation
when --noinhibit-exec is specified.

Mention the destination symbol, otherwise the diagnostic is not really actionable.
Two errors are not tested but the patch does not intend to add the coverage.

Reviewed By: grimar

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

Added: 
    

Modified: 
    lld/ELF/Relocations.cpp
    lld/ELF/Target.h
    lld/ELF/Thunks.cpp
    lld/test/ELF/ppc64-toc-call-to-pcrel-long-jump.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 3080d53c3329..1ff47244c990 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -113,6 +113,17 @@ void elf::reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
               ", " + Twine(max).str() + "]" + hint);
 }
 
+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.getName().empty())
+    hint = "; references " + lld::toString(sym) + getDefinedLocation(sym);
+  errorOrWarn(errPlace.loc + msg + " is out of range: " + Twine(v) +
+              " is not in [" + Twine(llvm::minIntN(n)) + ", " +
+              Twine(llvm::maxIntN(n)) + "]" + hint);
+}
+
 namespace {
 // Build a bitmask with one bit set for each RelExpr.
 //

diff  --git a/lld/ELF/Target.h b/lld/ELF/Target.h
index e53ac4d06627..9399ecf526f4 100644
--- a/lld/ELF/Target.h
+++ b/lld/ELF/Target.h
@@ -229,6 +229,8 @@ template <class ELFT> bool isMipsPIC(const Defined *sym);
 
 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) {

diff  --git a/lld/ELF/Thunks.cpp b/lld/ELF/Thunks.cpp
index 6a8ea4dc0e48..684ff5154a33 100644
--- a/lld/ELF/Thunks.cpp
+++ b/lld/ELF/Thunks.cpp
@@ -896,7 +896,7 @@ void PPC64R2SaveStub::writeTo(uint8_t *buf) {
   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");
   write32(buf + 0, 0xf8410018);                         // std  r2,24(r1)
   write32(buf + 4, 0x48000000 | (offset & 0x03fffffc)); // b    <offset>
 }
@@ -910,7 +910,7 @@ void PPC64R2SaveStub::addSymbols(ThunkSection &isec) {
 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 +927,8 @@ void PPC64R12SetupStub::addSymbols(ThunkSection &isec) {
 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
index a6e99db8c5c0..4175ba313108 100644
--- 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,10 @@
 # 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
+# CHECK-NEXT: >>> defined in {{.*}}.o
+
+# RUN: ld.lld -T %t.script %t.o -o /dev/null --noinhibit-exec
 
 .section .text_callee, "ax", %progbits
 callee:


        


More information about the llvm-commits mailing list