summaryrefslogtreecommitdiffstats
path: root/lld/ELF/LinkerScript.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-10-31 21:36:23 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-10-31 21:36:23 +0000
commitb0de56b59d1fc77c05c52ab752dc784edf8256d7 (patch)
tree5434242c4431b35b090dbbbd7956e604ac90b9f2 /lld/ELF/LinkerScript.cpp
parent75f9d3ac7e442342685432f650a226414b44248b (diff)
downloadbcm5719-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.cpp22
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))
OpenPOWER on IntegriCloud