forked from OSchip/llvm-project
[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:
parent
154a4fd5dc
commit
41c7ab4a3d
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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("(");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue