Commit 4a4ce14e authored by Fangrui Song's avatar Fangrui Song
Browse files

[ELF] Mention symbol name in reportRangeError()

For an out-of-range relocation referencing a non-local symbol, report the symbol name and the object file that defines the symbol. As an example:
```
t.o:(function func: .text.func+0x3): relocation R_X86_64_32S out of range: -281474974609120 is not in [-2147483648, 2147483647]
```
=>
```
t.o:(function func: .text.func+0x3): relocation R_X86_64_32S out of range: -281474974609120 is not in [-2147483648, 2147483647]; references func
>>> defined in t1.o
```

Reviewed By: grimar

Differential Revision: https://reviews.llvm.org/D73518
parent 25b8e963
Loading
Loading
Loading
Loading
+27 −7
Original line number Diff line number Diff line
@@ -73,6 +73,15 @@ static Optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
  return None;
}

static std::string getDefinedLocation(const Symbol &sym) {
  std::string msg = "\n>>> defined in ";
  if (sym.file)
    msg += toString(sym.file);
  else if (Optional<std::string> loc = getLinkerScriptLocation(sym))
    msg += *loc;
  return msg;
}

// Construct a message in the following format.
//
// >>> defined in /home/alice/src/foo.o
@@ -80,19 +89,30 @@ static Optional<std::string> getLinkerScriptLocation(const Symbol &sym) {
// >>>               /home/alice/src/bar.o:(.text+0x1)
static std::string getLocation(InputSectionBase &s, const Symbol &sym,
                               uint64_t off) {
  std::string msg = "\n>>> defined in ";
  if (sym.file)
    msg += toString(sym.file);
  else if (Optional<std::string> loc = getLinkerScriptLocation(sym))
    msg += *loc;

  msg += "\n>>> referenced by ";
  std::string msg = getDefinedLocation(sym) + "\n>>> referenced by ";
  std::string src = s.getSrcMsg(sym, off);
  if (!src.empty())
    msg += src + "\n>>>               ";
  return msg + s.getObjMsg(off);
}

void reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
                      int64_t min, uint64_t max) {
  ErrorPlace errPlace = getErrorPlace(loc);
  std::string hint;
  if (rel.sym && !rel.sym->isLocal())
    hint = "; references " + lld::toString(*rel.sym) +
           getDefinedLocation(*rel.sym);

  if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
    hint += "; consider recompiling with -fdebug-types-section to reduce size "
            "of debug sections";

  errorOrWarn(errPlace.loc + "relocation " + lld::toString(rel.type) +
              " out of range: " + v.str() + " is not in [" + Twine(min).str() +
              ", " + Twine(max).str() + "]" + hint);
}

namespace {
// Build a bitmask with one bit set for each RelExpr.
//
+2 −12
Original line number Diff line number Diff line
@@ -204,18 +204,8 @@ TargetInfo *getTarget();

template <class ELFT> bool isMipsPIC(const Defined *sym);

static inline void reportRangeError(uint8_t *loc, const Relocation &rel,
                                    const Twine &v, int64_t min, uint64_t max) {
  ErrorPlace errPlace = getErrorPlace(loc);
  StringRef hint;
  if (errPlace.isec && errPlace.isec->name.startswith(".debug"))
    hint = "; consider recompiling with -fdebug-types-section to reduce size "
           "of debug sections";

  errorOrWarn(errPlace.loc + "relocation " + lld::toString(rel.type) +
              " out of range: " + v.str() + " is not in [" + Twine(min).str() +
              ", " + Twine(max).str() + "]" + hint);
}
void reportRangeError(uint8_t *loc, const Relocation &rel, const Twine &v,
                      int64_t min, uint64_t max);

// 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) {
+2 −2
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ _start:
// CHECK-NEXT: 220158 ffff0080

// RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 65535]
// OVERFLOW1: relocation R_AARCH64_ABS16 out of range: -32769 is not in [-32768, 65535]; references foo

// RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]
// OVERFLOW2: relocation R_AARCH64_ABS16 out of range: 65536 is not in [-32768, 65535]; references foo
+2 −2
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ _start:
// CHECK-NEXT: 220158 ffffffff 00000080

// RUN: not ld.lld %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 4294967295]
// OVERFLOW1: relocation R_AARCH64_ABS32 out of range: -2147483649 is not in [-2147483648, 4294967295]; references foo

// RUN: not ld.lld %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]
// OVERFLOW2: relocation R_AARCH64_ABS32 out of range: 4294967296 is not in [-2147483648, 4294967295]; references foo
+2 −2
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ _start:
// CHECK-NEXT: 202158 ffff0080

// RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW1
// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 65535]
// OVERFLOW1: relocation R_AARCH64_PREL16 out of range: -32769 is not in [-32768, 65535]; references foo

// RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o %t2 2>&1 | FileCheck %s --check-prefix=OVERFLOW2
// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 65535]
// OVERFLOW2: relocation R_AARCH64_PREL16 out of range: 65536 is not in [-32768, 65535]; references foo
Loading