Skip to content

Commit f34f45f

Browse files
author
George Rimar
committedSep 23, 2016
[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
1 parent d4dea16 commit f34f45f

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed
 

‎lld/ELF/LinkerScript.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,10 @@ template <class ELFT> uint64_t LinkerScript<ELFT>::getSymbolValue(StringRef S) {
756756
return 0;
757757
}
758758

759+
template <class ELFT> bool LinkerScript<ELFT>::isDefined(StringRef S) {
760+
return Symtab<ELFT>::X->find(S) != nullptr;
761+
}
762+
759763
// Returns indices of ELF headers containing specific section, identified
760764
// by Name. Each index is a zero based number of ELF header listed within
761765
// PHDRS {} script block.
@@ -1490,6 +1494,14 @@ Expr ScriptParser::readPrimary() {
14901494
expect(")");
14911495
return [=](uint64_t Dot) { return getConstant(Tok); };
14921496
}
1497+
if (Tok == "DEFINED") {
1498+
expect("(");
1499+
StringRef Tok = next();
1500+
expect(")");
1501+
return [=](uint64_t Dot) {
1502+
return ScriptBase->isDefined(Tok) ? 1 : 0;
1503+
};
1504+
}
14931505
if (Tok == "SEGMENT_START") {
14941506
expect("(");
14951507
next();

‎lld/ELF/LinkerScript.h

+2
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class LinkerScriptBase {
157157
virtual uint64_t getOutputSectionAlign(StringRef Name) = 0;
158158
virtual uint64_t getHeaderSize() = 0;
159159
virtual uint64_t getSymbolValue(StringRef S) = 0;
160+
virtual bool isDefined(StringRef S) = 0;
160161
};
161162

162163
// ScriptConfiguration holds linker script parse results.
@@ -203,6 +204,7 @@ template <class ELFT> class LinkerScript final : public LinkerScriptBase {
203204
uint64_t getOutputSectionAlign(StringRef Name) override;
204205
uint64_t getHeaderSize() override;
205206
uint64_t getSymbolValue(StringRef S) override;
207+
bool isDefined(StringRef S) override;
206208

207209
std::vector<OutputSectionBase<ELFT> *> *OutputSections;
208210

‎lld/test/ELF/linkerscript/define.s

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3+
4+
# RUN: echo "SECTIONS \
5+
# RUN: { \
6+
# RUN: . = DEFINED(defined) ? 0x11000 : .; \
7+
# RUN: .foo : { *(.foo*) } \
8+
# RUN: . = DEFINED(notdefined) ? 0x12000 : 0x13000; \
9+
# RUN: .bar : { *(.bar*) } \
10+
# RUN: }" > %t.script
11+
# RUN: ld.lld -o %t1 --script %t.script %t
12+
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
13+
14+
# CHECK: 1 .foo 00000008 0000000000011000 DATA
15+
# CHECK: 2 .bar 00000008 0000000000013000 DATA
16+
# CHECK: 3 .text 00000000 0000000000013008 TEXT DATA
17+
18+
.global defined
19+
defined = 0
20+
21+
.section .foo,"a"
22+
.quad 1
23+
24+
.section .bar,"a"
25+
.quad 1

0 commit comments

Comments
 (0)
Please sign in to comment.