summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp22
-rw-r--r--lld/ELF/LinkerScript.h8
-rw-r--r--lld/test/ELF/linkerscript/dot-is-not-abs.s53
-rw-r--r--lld/test/ELF/linkerscript/symbol-conflict.s2
-rw-r--r--lld/test/ELF/linkerscript/symbols.s2
5 files changed, 67 insertions, 20 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))
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 57536203a71..8ab04ab91c4 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -43,13 +43,9 @@ struct Expr {
uint64_t operator()(uint64_t Dot) const { return Val(Dot); }
operator bool() const { return (bool)Val; }
- template <typename T>
- Expr(T Val, std::function<bool()> IsAbsolute)
+ Expr(std::function<uint64_t(uint64_t)> Val, std::function<bool()> IsAbsolute)
: Val(Val), IsAbsolute(IsAbsolute) {}
- template <typename T> Expr(T Val, bool IsAbsolute) : Val(Val) {
- this->IsAbsolute = [=]() { return IsAbsolute; };
- }
- template <typename T> Expr(T V) : Expr(V, false) {}
+ template <typename T> Expr(T V) : Expr(V, []() { return true; }) {}
Expr() : Expr(nullptr) {}
};
diff --git a/lld/test/ELF/linkerscript/dot-is-not-abs.s b/lld/test/ELF/linkerscript/dot-is-not-abs.s
new file mode 100644
index 00000000000..4532cd59f2a
--- /dev/null
+++ b/lld/test/ELF/linkerscript/dot-is-not-abs.s
@@ -0,0 +1,53 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+# RUN: echo "SECTIONS { .text : { *(.text) } \
+# RUN: foo = .; \
+# RUN: .bar : { *(.bar) } }" > %t1.script
+# RUN: ld.lld -o %t1 --script %t1.script %t.o -shared
+# RUN: llvm-readobj -t -s -section-data %t1 | FileCheck %s
+
+.hidden foo
+.long foo - .
+
+.section .bar, "a"
+.long 0
+
+# The symbol foo is defined as a position in the file. This means that it is
+# not absolute and it is possible to compute the distance from foo to some other
+# position in the file. The symbol is not really in any output section, but
+# ELF has no magic constant for not absolute, but not in any section.
+# Fortunately the value of a symbol in a non relocatable file is a virtual
+# address, so the section can be arbitrary.
+
+# CHECK: Section {
+# CHECK: Index:
+# CHECK: Name: .text
+# CHECK-NEXT: Type: SHT_PROGBITS
+# CHECK-NEXT: Flags [
+# CHECK-NEXT: SHF_ALLOC
+# CHECK-NEXT: SHF_EXECINSTR
+# CHECK-NEXT: ]
+# CHECK-NEXT: Address: 0x0
+# CHECK-NEXT: Offset:
+# CHECK-NEXT: Size: 4
+# CHECK-NEXT: Link:
+# CHECK-NEXT: Info:
+# CHECK-NEXT: AddressAlignment:
+# CHECK-NEXT: EntrySize:
+# CHECK-NEXT: SectionData (
+# CHECK-NEXT: 0000: 04000000 |
+# CHECK-NEXT: )
+# CHECK-NEXT: }
+
+# CHECK: Symbol {
+# CHECK: Name: foo
+# CHECK-NEXT: Value: 0x4
+# CHECK-NEXT: Size: 0
+# CHECK-NEXT: Binding: Local
+# CHECK-NEXT: Type: None
+# CHECK-NEXT: Other [
+# CHECK-NEXT: STV_HIDDEN
+# CHECK-NEXT: ]
+# CHECK-NEXT: Section: .text
+# CHECK-NEXT: }
diff --git a/lld/test/ELF/linkerscript/symbol-conflict.s b/lld/test/ELF/linkerscript/symbol-conflict.s
index 35596739ce9..dcca7c13de6 100644
--- a/lld/test/ELF/linkerscript/symbol-conflict.s
+++ b/lld/test/ELF/linkerscript/symbol-conflict.s
@@ -4,7 +4,7 @@
# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : {*(.text.*)} end = .;}" > %t.script
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -t %t1 | FileCheck %s
-# CHECK: 00000000000000e9 *ABS* 00000000 end
+# CHECK: 00000000000000e9 .text 00000000 end
.global _start
_start:
diff --git a/lld/test/ELF/linkerscript/symbols.s b/lld/test/ELF/linkerscript/symbols.s
index ef6004cc84b..4656635171c 100644
--- a/lld/test/ELF/linkerscript/symbols.s
+++ b/lld/test/ELF/linkerscript/symbols.s
@@ -7,7 +7,7 @@
# RUN: echo "SECTIONS {.text : {*(.text.*)} text_end = .;}" > %t.script
# RUN: ld.lld -o %t1 --script %t.script %t
# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE %s
-# SIMPLE: *ABS* 00000000 text_end
+# SIMPLE: .text 00000000 text_end
# The symbol is not referenced. Don't provide it.
# RUN: echo "SECTIONS { PROVIDE(newsym = 1);}" > %t.script
OpenPOWER on IntegriCloud