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.
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();
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.
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;
--- /dev/null
+# 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