summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp36
-rw-r--r--lld/ELF/LinkerScript.h1
-rw-r--r--lld/ELF/Writer.cpp1
-rw-r--r--lld/test/ELF/linkerscript/absolute.s17
4 files changed, 34 insertions, 21 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 647725ebf67..5f2c9a16906 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -153,11 +153,6 @@ void LinkerScript<ELFT>::addSymbol(SymbolAssignment *Cmd) {
return;
Cmd->Sym = addRegular<ELFT>(Cmd);
-
- // If there are sections, then let the value be assigned later in
- // `assignAddresses`.
- if (!ScriptConfig->HasSections)
- assignSymbol(Cmd);
}
bool SymbolAssignment::classof(const BaseCommand *C) {
@@ -344,15 +339,6 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory &Factory) {
continue;
}
- if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) {
- // If we don't have SECTIONS then output sections have already been
- // created by Writer<ELFT>. The LinkerScript<ELFT>::assignAddresses
- // will not be called, so ASSERT should be evaluated now.
- if (!Opt.HasSections)
- Cmd->Expression();
- continue;
- }
-
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
@@ -779,6 +765,15 @@ void LinkerScriptBase::placeOrphanSections() {
}
}
+void LinkerScriptBase::processNonSectionCommands() {
+ for (const std::unique_ptr<BaseCommand> &Base : Opt.Commands) {
+ if (auto *Cmd = dyn_cast<SymbolAssignment>(Base.get()))
+ assignSymbol(Cmd);
+ else if (auto *Cmd = dyn_cast<AssertCommand>(Base.get()))
+ Cmd->Expression();
+ }
+}
+
void LinkerScriptBase::assignAddresses(std::vector<PhdrEntry> &Phdrs) {
// Assign addresses as instructed by linker script SECTIONS sub-commands.
Dot = 0;
@@ -1556,14 +1551,8 @@ SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
StringRef Op = next();
- Expr E;
assert(Op == "=" || Op == "+=");
- if (consume("ABSOLUTE")) {
- E = readExpr();
- E.IsAbsolute = [] { return true; };
- } else {
- E = readExpr();
- }
+ Expr E = readExpr();
if (Op == "+=") {
std::string Loc = getCurrentLocation();
E = [=] { return ScriptBase->getSymbolValue(Loc, Name) + E(); };
@@ -1739,6 +1728,11 @@ Expr ScriptParser::readPrimary() {
// Built-in functions are parsed here.
// https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
+ if (Tok == "ABSOLUTE") {
+ Expr E = readParenExpr();
+ E.IsAbsolute = [] { return true; };
+ return E;
+ }
if (Tok == "ADDR") {
StringRef Name = readParenLiteral();
return {[=] { return ScriptBase->getOutputSection(Location, Name)->Addr; },
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 3180f9913f1..27a157033ea 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -287,6 +287,7 @@ public:
bool shouldKeep(InputSectionBase *S);
void assignOffsets(OutputSectionCommand *Cmd);
void placeOrphanSections();
+ void processNonSectionCommands();
void assignAddresses(std::vector<PhdrEntry> &Phdrs);
int getSectionIndex(StringRef Name);
};
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c4795f02820..e66ba91dd2f 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -270,6 +270,7 @@ template <class ELFT> void Writer<ELFT>::run() {
} else {
fixSectionAlignments();
assignAddresses();
+ Script<ELFT>::X->processNonSectionCommands();
}
// Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
diff --git a/lld/test/ELF/linkerscript/absolute.s b/lld/test/ELF/linkerscript/absolute.s
index e4b156e2f01..54f1c7037d2 100644
--- a/lld/test/ELF/linkerscript/absolute.s
+++ b/lld/test/ELF/linkerscript/absolute.s
@@ -4,6 +4,11 @@
# RUN: ld.lld -o %t --script %t.script %t.o
# RUN: llvm-readobj --symbols %t | FileCheck %s
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "PROVIDE(foo = 1 + ABSOLUTE(ADDR(.text)));" > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-readobj --symbols %t | FileCheck --check-prefix=CHECK-RHS %s
+
# CHECK: Name: foo
# CHECK-NEXT: Value:
# CHECK-NEXT: Size:
@@ -13,6 +18,18 @@
# CHECK-NEXT: Section: Absolute
# CHECK-NEXT: }
+# CHECK-RHS: Name: foo
+# CHECK-RHS-NEXT: Value: 0x201001
+# CHECK-RHS-NEXT: Size:
+# CHECK-RHS-NEXT: Binding:
+# CHECK-RHS-NEXT: Type:
+# CHECK-RHS-NEXT: Other:
+# CHECK-RHS-NEXT: Section: Absolute
+# CHECK-RHS-NEXT: }
+
.text
.globl _start
_start:
+ nop
+
+.global foo
OpenPOWER on IntegriCloud