Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -116,6 +116,8 @@ // ScriptConfiguration holds linker script parse results. struct ScriptConfiguration { + // Used to create symbol assignments outside SECTIONS command. + std::vector> Assignments; // Used to assign addresses to sections. std::vector> Commands; @@ -140,6 +142,7 @@ public: LinkerScript(); ~LinkerScript(); + void createAssignments(); void createSections(OutputSectionFactory &Factory); std::vector> createPhdrs(); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -259,6 +259,16 @@ } template +void LinkerScript::createAssignments() { + for (const std::unique_ptr &Cmd : Opt.Assignments) { + if (shouldDefine(Cmd.get())) + addRegular(Cmd.get()); + if (Cmd->Sym) + cast>(Cmd->Sym)->Value = Cmd->Expression(0); + } +} + +template void LinkerScript::createSections(OutputSectionFactory &Factory) { for (const std::unique_ptr &Base1 : Opt.Commands) { if (auto *Cmd = dyn_cast(Base1.get())) { @@ -643,12 +653,16 @@ void ScriptParser::run() { while (!atEOF()) { StringRef Tok = next(); - if (Handler Fn = Cmd.lookup(Tok)) + if (Handler Fn = Cmd.lookup(Tok)) { (this->*Fn)(); - else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) - Opt.Commands.emplace_back(Cmd); - else + } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { + if (Opt.HasContents) + Opt.Commands.emplace_back(Cmd); + else + Opt.Assignments.emplace_back(Cmd); + } else { setError("unknown directive: " + Tok); + } } } Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -250,6 +250,8 @@ CommonInputSection Common(getCommonSymbols()); CommonInputSection::X = &Common; + Script::X->createAssignments(); + Script::X->OutputSections = &OutputSections; if (ScriptConfig->HasContents) Script::X->createSections(Factory); Index: test/ELF/linkerscript/linkerscript-symbols.s =================================================================== --- test/ELF/linkerscript/linkerscript-symbols.s +++ test/ELF/linkerscript/linkerscript-symbols.s @@ -67,6 +67,15 @@ # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN5 %s # HIDDEN5: 0000000000000000 *ABS* 00000000 somesym +# Simple symbol assignment. All three symbols should have the +# same value. +# RUN: echo "foo = 0x100; SECTIONS { bar = foo; } baz = bar;" > %t.script +# RUN: ld.lld -o %t1 --script %t.script %t +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE2 %s +# SIMPLE2: 0000000000000100 *ABS* 00000000 foo +# SIMPLE2: 0000000000000100 *ABS* 00000000 bar +# SIMPLE2: 0000000000000100 *ABS* 00000000 baz + .global _start _start: nop