[lld] r304881 - [ELF] - Linkerscript: improved error reporting.

George Rimar via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 7 01:54:45 PDT 2017


Author: grimar
Date: Wed Jun  7 03:54:43 2017
New Revision: 304881

URL: http://llvm.org/viewvc/llvm-project?rev=304881&view=rev
Log:
[ELF] - Linkerscript: improved error reporting.

When linking linux kernel LLD currently reports next errors:

ld: error: unable to evaluate expression: input section .head.text has no output section assigned
ld: error: At least one side of the expression must be absolute
ld: error: At least one side of the expression must be absolute

That does not provide file/line information and overall looks unclear. 
Patch adds location information to ExprValue and that allows
to provide more clear error messages.

Differential revision: https://reviews.llvm.org/D33943


Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/ScriptParser.cpp
    lld/trunk/test/ELF/linkerscript/early-assign-symbol.s
    lld/trunk/test/ELF/linkerscript/expr-invalid-sec.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=304881&r1=304880&r2=304881&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Jun  7 03:54:43 2017
@@ -54,7 +54,7 @@ uint64_t ExprValue::getValue() const {
   if (Sec) {
     if (OutputSection *OS = Sec->getOutputSection())
       return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
-    error("unable to evaluate expression: input section " + Sec->Name +
+    error(Loc + ": unable to evaluate expression: input section " + Sec->Name +
           " has no output section assigned");
   }
   return alignTo(Val, Alignment);
@@ -1231,12 +1231,12 @@ bool LinkerScript::hasLMA(OutputSection
 
 ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
   if (S == ".")
-    return {CurOutSec, Dot - CurOutSec->Addr};
+    return {CurOutSec, Dot - CurOutSec->Addr, Loc};
   if (SymbolBody *B = findSymbol(S)) {
     if (auto *D = dyn_cast<DefinedRegular>(B))
-      return {D->Section, D->Value};
+      return {D->Section, D->Value, Loc};
     if (auto *C = dyn_cast<DefinedCommon>(B))
-      return {InX::Common, C->Offset};
+      return {InX::Common, C->Offset, Loc};
   }
   error(Loc + ": symbol not found: " + S);
   return 0;

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=304881&r1=304880&r2=304881&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Jun  7 03:54:43 2017
@@ -42,15 +42,14 @@ struct ExprValue {
   uint64_t Val;
   bool ForceAbsolute;
   uint64_t Alignment = 1;
+  std::string Loc;
 
   ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
-            uint64_t Alignment)
-      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Alignment(Alignment) {
-  }
-  ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val)
-      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute) {}
-  ExprValue(SectionBase *Sec, uint64_t Val) : ExprValue(Sec, false, Val) {}
-  ExprValue(uint64_t Val) : ExprValue(nullptr, Val) {}
+            const Twine &Loc)
+      : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Loc(Loc.str()) {}
+  ExprValue(SectionBase *Sec, uint64_t Val, const Twine &Loc)
+      : ExprValue(Sec, false, Val, Loc) {}
+  ExprValue(uint64_t Val) : ExprValue(nullptr, Val, "") {}
   bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
   uint64_t getValue() const;
   uint64_t getSecAddr() const;

Modified: lld/trunk/ELF/ScriptParser.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/ScriptParser.cpp?rev=304881&r1=304880&r2=304881&view=diff
==============================================================================
--- lld/trunk/ELF/ScriptParser.cpp (original)
+++ lld/trunk/ELF/ScriptParser.cpp Wed Jun  7 03:54:43 2017
@@ -127,16 +127,16 @@ static void moveAbsRight(ExprValue &A, E
   if (A.isAbsolute())
     std::swap(A, B);
   if (!B.isAbsolute())
-    error("At least one side of the expression must be absolute");
+    error(A.Loc + ": at least one side of the expression must be absolute");
 }
 
 static ExprValue add(ExprValue A, ExprValue B) {
   moveAbsRight(A, B);
-  return {A.Sec, A.ForceAbsolute, A.Val + B.getValue()};
+  return {A.Sec, A.ForceAbsolute, A.Val + B.getValue(), A.Loc};
 }
 
 static ExprValue sub(ExprValue A, ExprValue B) {
-  return {A.Sec, A.Val - B.getValue()};
+  return {A.Sec, A.Val - B.getValue(), A.Loc};
 }
 
 static ExprValue mul(ExprValue A, ExprValue B) {
@@ -153,13 +153,13 @@ static ExprValue div(ExprValue A, ExprVa
 static ExprValue bitAnd(ExprValue A, ExprValue B) {
   moveAbsRight(A, B);
   return {A.Sec, A.ForceAbsolute,
-          (A.getValue() & B.getValue()) - A.getSecAddr()};
+          (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
 }
 
 static ExprValue bitOr(ExprValue A, ExprValue B) {
   moveAbsRight(A, B);
   return {A.Sec, A.ForceAbsolute,
-          (A.getValue() | B.getValue()) - A.getSecAddr()};
+          (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
 }
 
 void ScriptParser::readDynamicList() {
@@ -859,7 +859,9 @@ Expr ScriptParser::readPrimary() {
   if (Tok == "ADDR") {
     StringRef Name = readParenLiteral();
     OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
-    return [=]() -> ExprValue { return {checkSection(Cmd, Location), 0}; };
+    return [=]() -> ExprValue {
+      return {checkSection(Cmd, Location), 0, Location};
+    };
   }
   if (Tok == "ALIGN") {
     expect("(");

Modified: lld/trunk/test/ELF/linkerscript/early-assign-symbol.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/early-assign-symbol.s?rev=304881&r1=304880&r2=304881&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/early-assign-symbol.s (original)
+++ lld/trunk/test/ELF/linkerscript/early-assign-symbol.s Wed Jun  7 03:54:43 2017
@@ -7,7 +7,7 @@
 # RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text  : { *(.text*) } }" > %t2.script
 # RUN: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s
 
-# CHECK: error: unable to evaluate expression: input section .text has no output section assigned
+# CHECK: error: {{.*}}.script:1: unable to evaluate expression: input section .text has no output section assigned
 
 .section .text
 .globl foo

Modified: lld/trunk/test/ELF/linkerscript/expr-invalid-sec.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/expr-invalid-sec.s?rev=304881&r1=304880&r2=304881&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/expr-invalid-sec.s (original)
+++ lld/trunk/test/ELF/linkerscript/expr-invalid-sec.s Wed Jun  7 03:54:43 2017
@@ -3,4 +3,4 @@
 # RUN: echo "SECTIONS { foo = ADDR(.text) + ADDR(.text); };" > %t.script
 # RUN: not ld.lld -o %t.so --script %t.script %t.o -shared 2>&1 | FileCheck %s
 
-# CHECK: At least one side of the expression must be absolute
+# CHECK: error: {{.*}}.script:1: at least one side of the expression must be absolute




More information about the llvm-commits mailing list