diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-10-31 21:36:23 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-10-31 21:36:23 +0000 |
commit | b0de56b59d1fc77c05c52ab752dc784edf8256d7 (patch) | |
tree | 5434242c4431b35b090dbbbd7956e604ac90b9f2 /lld/ELF/LinkerScript.cpp | |
parent | 75f9d3ac7e442342685432f650a226414b44248b (diff) | |
download | bcm5719-llvm-b0de56b59d1fc77c05c52ab752dc784edf8256d7.tar.gz bcm5719-llvm-b0de56b59d1fc77c05c52ab752dc784edf8256d7.zip |
The expr '.' is not absolute.
With this patch we keep track of the fact that . is a position in the
file and therefore not absolute. This allow us to compute relative
relocations that involve symbol that are defined in linker scripts
with '.'.
This fixes https://llvm.org/bugs/show_bug.cgi?id=30406
There is still more work to track absoluteness over the various
expressions, but this should unblock linking the EFI bootloader.
llvm-svn: 285641
Diffstat (limited to 'lld/ELF/LinkerScript.cpp')
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 9061dacf259..6c5fc9e07e0 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -299,7 +299,7 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) { const std::unique_ptr<BaseCommand> &Base1 = *Iter; if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) { if (shouldDefine<ELFT>(Cmd)) - addRegular<ELFT>(Cmd); + addSymbol<ELFT>(Cmd); continue; } if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) { @@ -621,7 +621,8 @@ void LinkerScript<ELFT>::assignAddresses(std::vector<PhdrEntry<ELFT>> &Phdrs) { if (Cmd->Name == ".") { Dot = Cmd->Expression(Dot); } else if (Cmd->Sym) { - cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(Dot); + assignSectionSymbol(Cmd, CurOutSec ? CurOutSec : (*OutputSections)[0], + Dot); } continue; } @@ -1186,7 +1187,7 @@ void ScriptParser::readSections() { expect("{"); while (!Error && !consume("}")) { StringRef Tok = next(); - BaseCommand *Cmd = readProvideOrAssignment(Tok, true); + BaseCommand *Cmd = readProvideOrAssignment(Tok, false); if (!Cmd) { if (Tok == "ASSERT") Cmd = new AssertCommand(readAssert()); @@ -1636,7 +1637,7 @@ Expr ScriptParser::readPrimary() { } if (Tok == "CONSTANT") { StringRef Name = readParenLiteral(); - return {[=](uint64_t Dot) { return getConstant(Name); }, true}; + return [=](uint64_t Dot) { return getConstant(Name); }; } if (Tok == "DEFINED") { expect("("); @@ -1679,23 +1680,20 @@ Expr ScriptParser::readPrimary() { } if (Tok == "SIZEOF") { StringRef Name = readParenLiteral(); - return { - [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }, - true}; + return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); }; } if (Tok == "ALIGNOF") { StringRef Name = readParenLiteral(); - return { - [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }, - true}; + return + [=](uint64_t Dot) { return ScriptBase->getOutputSectionAlign(Name); }; } if (Tok == "SIZEOF_HEADERS") - return {[=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }, true}; + return [=](uint64_t Dot) { return ScriptBase->getHeaderSize(); }; // Tok is a literal number. uint64_t V; if (readInteger(Tok, V)) - return {[=](uint64_t Dot) { return V; }, true}; + return [=](uint64_t Dot) { return V; }; // Tok is a symbol name. if (Tok != "." && !isValidCIdentifier(Tok)) |