[lld] [lld][ELF] Use the containing symbol, not the referenced symbol, for undefined symbol errors. (PR #70800)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 31 06:19:56 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld-elf

Author: Bevin Hansson (bevin-hansson)

<details>
<summary>Changes</summary>

When reporting undefined symbols, the symbol being used to find
the source location for where the symbol was referenced from was
the symbol being referenced, not the symbol where the reference
was made from.

Use the relocation offset to locate the correct symbol.

With this, the following program:

```
extern int ex;

int * p[] = { &ex };

int main() {
  return 0;
}
```

When built with `clang -fuse-ld=lld a.c -g`, it goes from
```
ld.lld: error: undefined symbol: ex
>>> referenced by a.c
>>>               /tmp/a-0e7dc8.o:(p)
```
to
```
ld.lld: error: undefined symbol: ex
>>> referenced by a.c:3 ([...]/a.c:3)
>>>               /tmp/a-0e7dc8.o:(p)
```

I'm unsure how to construct a reasonable lit test for this.


---
Full diff: https://github.com/llvm/llvm-project/pull/70800.diff


1 Files Affected:

- (modified) lld/ELF/Relocations.cpp (+29-1) 


``````````diff
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index f3fb0c71a8b3064..bf4d452f3ed9f79 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -693,6 +693,34 @@ static const Symbol *getAlternativeSpelling(const Undefined &sym,
   return nullptr;
 }
 
+static Symbol &
+getSymAtOffset(InputSectionBase &sec, uint64_t off, Symbol &sym) {
+  ArrayRef<Symbol *> syms;
+  switch (config->ekind) {
+  case ELF32LEKind:
+    syms = sec.getFile<ELF32LE>()->getSymbols();
+    break;
+  case ELF32BEKind:
+    syms = sec.getFile<ELF32BE>()->getSymbols();
+    break;
+  case ELF64LEKind:
+    syms = sec.getFile<ELF64LE>()->getSymbols();
+    break;
+  case ELF64BEKind:
+    syms = sec.getFile<ELF64BE>()->getSymbols();
+    break;
+  default:
+    llvm_unreachable("");
+  }
+  // Get the symbol that contains this offset.
+  for (Symbol *b : syms)
+    if (auto *d = dyn_cast_or_null<Defined>(b))
+      if (d->section == &sec && d->value <= off && off < d->value + d->size)
+        return *d;
+  // Fall back to the supplied symbol otherwise.
+  return sym;
+}
+
 static void reportUndefinedSymbol(const UndefinedDiag &undef,
                                   bool correctSpelling) {
   Undefined &sym = *undef.sym;
@@ -739,7 +767,7 @@ static void reportUndefinedSymbol(const UndefinedDiag &undef,
     uint64_t offset = l.offset;
 
     msg += "\n>>> referenced by ";
-    std::string src = sec.getSrcMsg(sym, offset);
+    std::string src = sec.getSrcMsg(getSymAtOffset(sec, offset, sym), offset);
     if (!src.empty())
       msg += src + "\n>>>               ";
     msg += sec.getObjMsg(offset);

``````````

</details>


https://github.com/llvm/llvm-project/pull/70800


More information about the llvm-commits mailing list