summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2016-09-23 13:17:23 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2016-09-23 13:17:23 +0000
commitf34f45fd534140f082d41dbb6a7c60dc675870c4 (patch)
tree1172d9b359b658f984c144eb9493a78e17901cc9
parentd4dea164dd453f567d9d33f3c158c33d6904987f (diff)
downloadbcm5719-llvm-f34f45fd534140f082d41dbb6a7c60dc675870c4.tar.gz
bcm5719-llvm-f34f45fd534140f082d41dbb6a7c60dc675870c4.zip
[ELF] - Linkerscript: implement DEFINED() command.
DEFINED(symbol) Return 1 if symbol is in the linker global symbol table and is defined before the statement using DEFINED in the script, otherwise return 0. Can be used to define default values for symbols. Found it in the wild. Differential revision: https://reviews.llvm.org/D24858 llvm-svn: 282245
-rw-r--r--lld/ELF/LinkerScript.cpp12
-rw-r--r--lld/ELF/LinkerScript.h2
-rw-r--r--lld/test/ELF/linkerscript/define.s25
3 files changed, 39 insertions, 0 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 1b240f46ae9..0febb253149 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -756,6 +756,10 @@ template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) {
return 0;
}
+template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) {
+ return Symtab<ELFT>::X->find(S) != nullptr;
+}
+
// Returns indices of ELF headers containing specific section, identified
// by Name. Each index is a zero based number of ELF header listed within
// PHDRS {} script block.
@@ -1490,6 +1494,14 @@ Expr ScriptParser::readPrimary() {
expect(")");
return [=](uint64_t Dot) { return getConstant(Tok); };
}
+ if (Tok == "DEFINED") {
+ expect("(");
+ StringRef Tok = next();
+ expect(")");
+ return [=](uint64_t Dot) {
+ return ScriptBase->isDefined(Tok) ? 1 : 0;
+ };
+ }
if (Tok == "SEGMENT_START") {
expect("(");
next();
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 654aae21dc6..1d3a713d8ce 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -157,6 +157,7 @@ public:
virtual uint64_t getOutputSectionAlign(StringRef Name) = 0;
virtual uint64_t getHeaderSize() = 0;
virtual uint64_t getSymbolValue(StringRef S) = 0;
+ virtual bool isDefined(StringRef S) = 0;
};
// ScriptConfiguration holds linker script parse results.
@@ -203,6 +204,7 @@ public:
uint64_t getOutputSectionAlign(StringRef Name) override;
uint64_t getHeaderSize() override;
uint64_t getSymbolValue(StringRef S) override;
+ bool isDefined(StringRef S) override;
std::vector<OutputSectionBase<ELFT> *> *OutputSections;
diff --git a/lld/test/ELF/linkerscript/define.s b/lld/test/ELF/linkerscript/define.s
new file mode 100644
index 00000000000..b5f0b76e9e6
--- /dev/null
+++ b/lld/test/ELF/linkerscript/define.s
@@ -0,0 +1,25 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: echo "SECTIONS \
+# RUN: { \
+# RUN: . = DEFINED(defined) ? 0x11000 : .; \
+# RUN: .foo : { *(.foo*) } \
+# RUN: . = DEFINED(notdefined) ? 0x12000 : 0x13000; \
+# RUN: .bar : { *(.bar*) } \
+# RUN: }" > %t.script
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+
+# CHECK: 1 .foo 00000008 0000000000011000 DATA
+# CHECK: 2 .bar 00000008 0000000000013000 DATA
+# CHECK: 3 .text 00000000 0000000000013008 TEXT DATA
+
+.global defined
+defined = 0
+
+.section .foo,"a"
+.quad 1
+
+.section .bar,"a"
+.quad 1
OpenPOWER on IntegriCloud