From ed30ce7ae43967dc26e4cecb4d377fa81f031d4d Mon Sep 17 00:00:00 2001 From: Eugene Leviant Date: Mon, 28 Nov 2016 09:58:04 +0000 Subject: [PATCH] [ELF] Print file:line for 'undefined section' errors Differential revision: https://reviews.llvm.org/D27108 llvm-svn: 288019 --- lld/ELF/LinkerScript.cpp | 20 ++++++++++++-------- lld/ELF/LinkerScript.h | 6 ++++-- lld/ELF/ScriptParser.cpp | 7 +++++++ lld/ELF/ScriptParser.h | 1 + lld/test/ELF/linkerscript/alignof.s | 2 +- lld/test/ELF/linkerscript/loadaddr.s | 2 +- 6 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index feafd370fd84..07497f4fcc48 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -884,13 +884,15 @@ template bool LinkerScript::hasPhdrsCommands() { } template -const OutputSectionBase *LinkerScript::getOutputSection(StringRef Name) { +const OutputSectionBase *LinkerScript::getOutputSection(const Twine &Loc, + StringRef Name) { static OutputSectionBase FakeSec("", 0, 0); for (OutputSectionBase *Sec : *OutputSections) if (Sec->getName() == Name) return Sec; - error("undefined section " + Name); + + error(Loc + ": undefined section " + Name); return &FakeSec; } @@ -1697,6 +1699,7 @@ Expr ScriptParser::readPrimary() { return readParenExpr(); StringRef Tok = next(); + std::string Location = currentLocation(); if (Tok == "~") { Expr E = readPrimary(); @@ -1711,15 +1714,16 @@ Expr ScriptParser::readPrimary() { // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. if (Tok == "ADDR") { StringRef Name = readParenLiteral(); - return { - [=](uint64_t Dot) { return ScriptBase->getOutputSection(Name)->Addr; }, - [=] { return false; }, - [=] { return ScriptBase->getOutputSection(Name); }}; + return {[=](uint64_t Dot) { + return ScriptBase->getOutputSection(Location, Name)->Addr; + }, + [=] { return false; }, + [=] { return ScriptBase->getOutputSection(Location, Name); }}; } if (Tok == "LOADADDR") { StringRef Name = readParenLiteral(); return [=](uint64_t Dot) { - return ScriptBase->getOutputSection(Name)->getLMA(); + return ScriptBase->getOutputSection(Location, Name)->getLMA(); }; } if (Tok == "ASSERT") @@ -1776,7 +1780,7 @@ Expr ScriptParser::readPrimary() { if (Tok == "ALIGNOF") { StringRef Name = readParenLiteral(); return [=](uint64_t Dot) { - return ScriptBase->getOutputSection(Name)->Addralign; + return ScriptBase->getOutputSection(Location, Name)->Addralign; }; } if (Tok == "SIZEOF_HEADERS") diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index d6dae4d457e1..f2d49a88466f 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -194,7 +194,8 @@ public: virtual bool isDefined(StringRef S) = 0; virtual bool isAbsolute(StringRef S) = 0; virtual const OutputSectionBase *getSymbolSection(StringRef S) = 0; - virtual const OutputSectionBase *getOutputSection(StringRef S) = 0; + virtual const OutputSectionBase *getOutputSection(const Twine &Loc, + StringRef S) = 0; virtual uint64_t getOutputSectionSize(StringRef S) = 0; }; @@ -245,7 +246,8 @@ public: bool isDefined(StringRef S) override; bool isAbsolute(StringRef S) override; const OutputSectionBase *getSymbolSection(StringRef S) override; - const OutputSectionBase *getOutputSection(StringRef S) override; + const OutputSectionBase *getOutputSection(const Twine &Loc, + StringRef S) override; uint64_t getOutputSectionSize(StringRef S) override; std::vector *OutputSections; diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 33c2f9095f10..fc0d233138e6 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -172,6 +172,13 @@ void ScriptParserBase::expect(StringRef Expect) { setError(Expect + " expected, but got " + Tok); } +std::string ScriptParserBase::currentLocation() { + MemoryBufferRef MB = currentBuffer(); + return (MB.getBufferIdentifier() + ":" + + Twine(getPos(MB.getBuffer(), Tokens[Pos - 1]).first)) + .str(); +} + // Returns true if string 'Bigger' contains string 'Shorter'. static bool containsString(StringRef Bigger, StringRef Shorter) { const char *BiggerEnd = Bigger.data() + Bigger.size(); diff --git a/lld/ELF/ScriptParser.h b/lld/ELF/ScriptParser.h index 6c314a4d12e5..a0da48dee802 100644 --- a/lld/ELF/ScriptParser.h +++ b/lld/ELF/ScriptParser.h @@ -32,6 +32,7 @@ public: void skip(); bool consume(StringRef Tok); void expect(StringRef Expect); + std::string currentLocation(); std::vector MBs; std::vector Tokens; diff --git a/lld/test/ELF/linkerscript/alignof.s b/lld/test/ELF/linkerscript/alignof.s index f530abd3393e..8880634df243 100644 --- a/lld/test/ELF/linkerscript/alignof.s +++ b/lld/test/ELF/linkerscript/alignof.s @@ -23,7 +23,7 @@ # RUN: }" > %t.script # RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ # RUN: | FileCheck -check-prefix=ERR %s -# ERR: undefined section .foo +# ERR: {{.*}}.script:1: undefined section .foo .global _start _start: nop diff --git a/lld/test/ELF/linkerscript/loadaddr.s b/lld/test/ELF/linkerscript/loadaddr.s index 870d694d05a9..33c5f21b52ba 100644 --- a/lld/test/ELF/linkerscript/loadaddr.s +++ b/lld/test/ELF/linkerscript/loadaddr.s @@ -23,7 +23,7 @@ # CHECK-NEXT: 0000000000003000 *ABS* 00000000 ccc_lma # CHECK-NEXT: 0000000000004000 *ABS* 00000000 ddd_lma # CHECK-NEXT: 0000000000004008 *ABS* 00000000 txt_lma -# ERROR: undefined section .zzz +# ERROR: {{.*}}.script:1: undefined section .zzz .global _start _start: