[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

llvm-svn: 304881
This commit is contained in:
George Rimar 2017-06-07 08:54:43 +00:00
parent 154a4fd5dc
commit 41c7ab4a3d
5 changed files with 20 additions and 19 deletions

View File

@ -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 *Sec) {
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;

View File

@ -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;

View File

@ -127,16 +127,16 @@ static void moveAbsRight(ExprValue &A, ExprValue &B) {
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, ExprValue B) {
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("(");

View File

@ -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

View File

@ -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