[ELF] Linkerscript: print location of undefined symbol usage
authorEugene Leviant <eleviant@accesssoftek.com>
Thu, 22 Dec 2016 13:13:12 +0000 (13:13 +0000)
committerEugene Leviant <eleviant@accesssoftek.com>
Thu, 22 Dec 2016 13:13:12 +0000 (13:13 +0000)
Differential revision: https://reviews.llvm.org/D27194

llvm-svn: 290339

lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/test/ELF/linkerscript/segment-start.s
lld/test/ELF/linkerscript/symbol-assignexpr.s

index e4b1e55..925c9fa 100644 (file)
@@ -901,10 +901,11 @@ template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() {
   return elf::getHeaderSize<ELFT>();
 }
 
-template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) {
+template <class ELFT>
+uint64_t LinkerScript<ELFT>::getSymbolValue(const Twine &Loc, StringRef S) {
   if (SymbolBody *B = Symtab<ELFT>::X->find(S))
     return B->getVA<ELFT>();
-  error("symbol not found: " + S);
+  error(Loc + ": symbol not found: " + S);
   return 0;
 }
 
@@ -1523,10 +1524,10 @@ SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
   return Cmd;
 }
 
-static uint64_t getSymbolValue(StringRef S, uint64_t Dot) {
+static uint64_t getSymbolValue(const Twine &Loc, StringRef S, uint64_t Dot) {
   if (S == ".")
     return Dot;
-  return ScriptBase->getSymbolValue(S);
+  return ScriptBase->getSymbolValue(Loc, S);
 }
 
 static bool isAbsolute(StringRef S) {
@@ -1547,8 +1548,12 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
   } else {
     E = readExpr();
   }
-  if (Op == "+=")
-    E = [=](uint64_t Dot) { return getSymbolValue(Name, Dot) + E(Dot); };
+  if (Op == "+=") {
+    std::string Loc = getCurrentLocation();
+    E = [=](uint64_t Dot) {
+      return getSymbolValue(Loc, Name, Dot) + E(Dot);
+    };
+  }
   return new SymbolAssignment(Name, E);
 }
 
@@ -1800,7 +1805,7 @@ Expr ScriptParser::readPrimary() {
   // Tok is a symbol name.
   if (Tok != "." && !isValidCIdentifier(Tok))
     setError("malformed number: " + Tok);
-  return {[=](uint64_t Dot) { return getSymbolValue(Tok, Dot); },
+  return {[=](uint64_t Dot) { return getSymbolValue(Location, Tok, Dot); },
           [=] { return isAbsolute(Tok); },
           [=] { return ScriptBase->getSymbolSection(Tok); }};
 }
index a377af3..505162f 100644 (file)
@@ -193,7 +193,7 @@ protected:
 
 public:
   virtual uint64_t getHeaderSize() = 0;
-  virtual uint64_t getSymbolValue(StringRef S) = 0;
+  virtual uint64_t getSymbolValue(const Twine &Loc, StringRef S) = 0;
   virtual bool isDefined(StringRef S) = 0;
   virtual bool isAbsolute(StringRef S) = 0;
   virtual const OutputSectionBase *getSymbolSection(StringRef S) = 0;
@@ -245,7 +245,7 @@ public:
   void assignAddresses(std::vector<PhdrEntry> &Phdrs);
   bool hasPhdrsCommands();
   uint64_t getHeaderSize() override;
-  uint64_t getSymbolValue(StringRef S) override;
+  uint64_t getSymbolValue(const Twine &Loc, StringRef S) override;
   bool isDefined(StringRef S) override;
   bool isAbsolute(StringRef S) override;
   const OutputSectionBase *getSymbolSection(StringRef S) override;
index 00245e4..e46c398 100644 (file)
@@ -24,4 +24,4 @@
 // RUN: echo "SECTIONS { . = SEGMENT_START(\"foobar\", foo); }" > %t.script
 // RUN: not ld.lld %t.o %t.script -shared -o %t2.so 2>&1 \
 // RUN: | FileCheck --check-prefix=ERR %s
-// ERR: symbol not found: foo
+// ERR: {{.*}}.script:1: symbol not found: foo
index 9af817d..b988abc 100644 (file)
@@ -38,7 +38,7 @@
 # RUN:       }" > %t2.script
 # RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \
 # RUN:  | FileCheck -check-prefix=ERR %s
-# ERR: symbol not found: symbol
+# ERR: {{.*}}.script:1: symbol not found: symbol
 
 .global _start
 _start: