[ELF] Print file:line for 'undefined section' errors

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

llvm-svn: 288019
This commit is contained in:
Eugene Leviant 2016-11-28 09:58:04 +00:00
parent 0f0d5d8f8d
commit ed30ce7ae4
6 changed files with 26 additions and 12 deletions

View File

@ -884,13 +884,15 @@ template <class ELFT> bool LinkerScript<ELFT>::hasPhdrsCommands() {
} }
template <class ELFT> template <class ELFT>
const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(StringRef Name) { const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(const Twine &Loc,
StringRef Name) {
static OutputSectionBase FakeSec("", 0, 0); static OutputSectionBase FakeSec("", 0, 0);
for (OutputSectionBase *Sec : *OutputSections) for (OutputSectionBase *Sec : *OutputSections)
if (Sec->getName() == Name) if (Sec->getName() == Name)
return Sec; return Sec;
error("undefined section " + Name);
error(Loc + ": undefined section " + Name);
return &FakeSec; return &FakeSec;
} }
@ -1697,6 +1699,7 @@ Expr ScriptParser::readPrimary() {
return readParenExpr(); return readParenExpr();
StringRef Tok = next(); StringRef Tok = next();
std::string Location = currentLocation();
if (Tok == "~") { if (Tok == "~") {
Expr E = readPrimary(); Expr E = readPrimary();
@ -1711,15 +1714,16 @@ Expr ScriptParser::readPrimary() {
// https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
if (Tok == "ADDR") { if (Tok == "ADDR") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return { return {[=](uint64_t Dot) {
[=](uint64_t Dot) { return ScriptBase->getOutputSection(Name)->Addr; }, return ScriptBase->getOutputSection(Location, Name)->Addr;
[=] { return false; }, },
[=] { return ScriptBase->getOutputSection(Name); }}; [=] { return false; },
[=] { return ScriptBase->getOutputSection(Location, Name); }};
} }
if (Tok == "LOADADDR") { if (Tok == "LOADADDR") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return [=](uint64_t Dot) { return [=](uint64_t Dot) {
return ScriptBase->getOutputSection(Name)->getLMA(); return ScriptBase->getOutputSection(Location, Name)->getLMA();
}; };
} }
if (Tok == "ASSERT") if (Tok == "ASSERT")
@ -1776,7 +1780,7 @@ Expr ScriptParser::readPrimary() {
if (Tok == "ALIGNOF") { if (Tok == "ALIGNOF") {
StringRef Name = readParenLiteral(); StringRef Name = readParenLiteral();
return [=](uint64_t Dot) { return [=](uint64_t Dot) {
return ScriptBase->getOutputSection(Name)->Addralign; return ScriptBase->getOutputSection(Location, Name)->Addralign;
}; };
} }
if (Tok == "SIZEOF_HEADERS") if (Tok == "SIZEOF_HEADERS")

View File

@ -194,7 +194,8 @@ public:
virtual bool isDefined(StringRef S) = 0; virtual bool isDefined(StringRef S) = 0;
virtual bool isAbsolute(StringRef S) = 0; virtual bool isAbsolute(StringRef S) = 0;
virtual const OutputSectionBase *getSymbolSection(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; virtual uint64_t getOutputSectionSize(StringRef S) = 0;
}; };
@ -245,7 +246,8 @@ public:
bool isDefined(StringRef S) override; bool isDefined(StringRef S) override;
bool isAbsolute(StringRef S) override; bool isAbsolute(StringRef S) override;
const OutputSectionBase *getSymbolSection(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; uint64_t getOutputSectionSize(StringRef S) override;
std::vector<OutputSectionBase *> *OutputSections; std::vector<OutputSectionBase *> *OutputSections;

View File

@ -172,6 +172,13 @@ void ScriptParserBase::expect(StringRef Expect) {
setError(Expect + " expected, but got " + Tok); 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'. // Returns true if string 'Bigger' contains string 'Shorter'.
static bool containsString(StringRef Bigger, StringRef Shorter) { static bool containsString(StringRef Bigger, StringRef Shorter) {
const char *BiggerEnd = Bigger.data() + Bigger.size(); const char *BiggerEnd = Bigger.data() + Bigger.size();

View File

@ -32,6 +32,7 @@ public:
void skip(); void skip();
bool consume(StringRef Tok); bool consume(StringRef Tok);
void expect(StringRef Expect); void expect(StringRef Expect);
std::string currentLocation();
std::vector<MemoryBufferRef> MBs; std::vector<MemoryBufferRef> MBs;
std::vector<StringRef> Tokens; std::vector<StringRef> Tokens;

View File

@ -23,7 +23,7 @@
# RUN: }" > %t.script # RUN: }" > %t.script
# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \ # RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \
# RUN: | FileCheck -check-prefix=ERR %s # RUN: | FileCheck -check-prefix=ERR %s
# ERR: undefined section .foo # ERR: {{.*}}.script:1: undefined section .foo
.global _start .global _start
_start: _start:
nop nop

View File

@ -23,7 +23,7 @@
# CHECK-NEXT: 0000000000003000 *ABS* 00000000 ccc_lma # CHECK-NEXT: 0000000000003000 *ABS* 00000000 ccc_lma
# CHECK-NEXT: 0000000000004000 *ABS* 00000000 ddd_lma # CHECK-NEXT: 0000000000004000 *ABS* 00000000 ddd_lma
# CHECK-NEXT: 0000000000004008 *ABS* 00000000 txt_lma # CHECK-NEXT: 0000000000004008 *ABS* 00000000 txt_lma
# ERROR: undefined section .zzz # ERROR: {{.*}}.script:1: undefined section .zzz
.global _start .global _start
_start: _start: