Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -157,6 +157,7 @@ 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 @@ uint64_t getOutputSectionAlign(StringRef Name) override; uint64_t getHeaderSize() override; uint64_t getSymbolValue(StringRef S) override; + bool isDefined(StringRef S) override; std::vector *> *OutputSections; Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -756,6 +756,10 @@ return 0; } +template bool LinkerScript::isDefined(StringRef S) { + return Symtab::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 @@ 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(); Index: lld/trunk/test/ELF/linkerscript/define.s =================================================================== --- lld/trunk/test/ELF/linkerscript/define.s +++ lld/trunk/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