Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -73,6 +73,9 @@ struct BaseCommand { BaseCommand(int K) : Kind(K) {} int Kind; + + // Whether the command is within SECTIONS command. + bool Sections = true; }; // This represents ". = " or " = ". @@ -257,6 +260,7 @@ void allocateHeaders(std::vector &Phdrs); void addSymbol(SymbolAssignment *Cmd); void processCommands(OutputSectionFactory &Factory); + void processOutsideSectionsCommands(); // Parsed linker script configurations are set to this struct. ScriptConfiguration Opt; Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -773,6 +773,23 @@ } } +void LinkerScript::processOutsideSectionsCommands() { + for (BaseCommand *Base : Opt.Commands) { + if (Base->Sections) + continue; + + if (auto *Cmd = dyn_cast(Base)) { + assignSymbol(Cmd, false); + continue; + } + + if (auto *Cmd = dyn_cast(Base)) { + Cmd->Expression(); + continue; + } + } +} + void LinkerScript::assignAddresses() { // Assign addresses as instructed by linker script SECTIONS sub-commands. Dot = 0; @@ -786,6 +803,9 @@ switchTo(Aether); for (BaseCommand *Base : Opt.Commands) { + if (!Base->Sections) + continue; + if (auto *Cmd = dyn_cast(Base)) { assignSymbol(Cmd, false); continue; Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -87,6 +87,7 @@ SortSectionPolicy readSortKind(); SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); SymbolAssignment *readProvideOrAssignment(StringRef Tok); + void readSort(); AssertCommand *readAssert(); Expr readAssertExpr(); @@ -217,7 +218,9 @@ continue; if (Tok == "ASSERT") { - Script->Opt.Commands.push_back(readAssert()); + BaseCommand *Cmd = readAssert(); + Cmd->Sections = false; + Script->Opt.Commands.push_back(Cmd); } else if (Tok == "ENTRY") { readEntry(); } else if (Tok == "EXTERN") { @@ -243,6 +246,7 @@ } else if (Tok == "VERSION") { readVersion(); } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) { + Cmd->Sections = false; Script->Opt.Commands.push_back(Cmd); } else { setError("unknown directive: " + Tok); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -224,6 +224,8 @@ fixPredefinedSymbols(); } + Script->processOutsideSectionsCommands(); + // It does not make sense try to open the file if we have error already. if (ErrorCount) return; Index: test/ELF/linkerscript/symbol-reserved.s =================================================================== --- test/ELF/linkerscript/symbol-reserved.s +++ test/ELF/linkerscript/symbol-reserved.s @@ -27,6 +27,12 @@ # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGN-SUB %s # ALIGN-SUB: 0000000000000006 *ABS* 00000000 .hidden newsym +# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script +# RUN: ld.lld -o %t1 %t %t.script +# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE %s +# RELATIVE: 0000000000202005 .text 00000000 .hidden newsym +# RELATIVE: 0000000000201007 .text 00000000 _end + # RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(_end, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script # RUN: ld.lld -o %t1 --script %p/Inputs/symbol-reserved.script %t %t.script # RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=RELATIVE-ADD %s