Index: lld/trunk/ELF/LinkerScript.h =================================================================== --- lld/trunk/ELF/LinkerScript.h +++ lld/trunk/ELF/LinkerScript.h @@ -140,8 +140,6 @@ // 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; @@ -166,7 +164,7 @@ public: LinkerScript(); ~LinkerScript(); - void createAssignments(); + void processCommands(OutputSectionFactory &Factory); void createSections(OutputSectionFactory &Factory); std::vector> createPhdrs(); @@ -191,6 +189,8 @@ void computeInputSections(InputSectionDescription *, ConstraintKind Constraint); + void addSection(OutputSectionFactory &Factory, + InputSectionBase *Sec, StringRef Name); void discard(ArrayRef *> V); std::vector *> Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -48,6 +48,11 @@ Symbol *Sym = Symtab::X->addRegular(Cmd->Name, STB_GLOBAL, STV_DEFAULT); Sym->Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT; Cmd->Sym = Sym->body(); + + // If we have no SECTIONS then we don't have '.' and don't call + // assignAddresses(). We calculate symbol value immediately in this case. + if (!ScriptConfig->HasSections) + cast>(Cmd->Sym)->Value = Cmd->Expression(0); } template static void addSynthetic(SymbolAssignment *Cmd) { @@ -215,15 +220,6 @@ return Ret; } -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 static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) { @@ -256,15 +252,19 @@ } template -void LinkerScript::createSections(OutputSectionFactory &Factory) { - auto AddSec = [&](InputSectionBase *Sec, StringRef Name) { - OutputSectionBase *OutSec; - bool IsNew; - std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); - if (IsNew) - OutputSections->push_back(OutSec); - return OutSec; - }; +void LinkerScript::addSection(OutputSectionFactory &Factory, + InputSectionBase *Sec, + StringRef Name) { + OutputSectionBase *OutSec; + bool IsNew; + std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec); + if (IsNew) + OutputSections->push_back(OutSec); + OutSec->addSection(Sec); +} + +template +void LinkerScript::processCommands(OutputSectionFactory &Factory) { for (const std::unique_ptr &Base1 : Opt.Commands) { if (auto *Cmd = dyn_cast(Base1.get())) { @@ -272,6 +272,14 @@ addRegular(Cmd); continue; } + if (auto *Cmd = dyn_cast(Base1.get())) { + // If we don't have SECTIONS then output sections have already been + // created by Writer. The LinkerScript::assignAddresses + // will not be called, so ASSERT should be evaluated now. + if (!Opt.HasSections) + Cmd->Expression(0); + continue; + } if (auto *Cmd = dyn_cast(Base1.get())) { std::vector *> V = createInputSectionList(*Cmd); @@ -285,25 +293,22 @@ continue; for (InputSectionBase *Sec : V) { - OutputSectionBase *OutSec = AddSec(Sec, Cmd->Name); - uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0; - - if (Subalign) + addSection(Factory, Sec, Cmd->Name); + if (uint32_t Subalign = Cmd->SubalignExpr ? Cmd->SubalignExpr(0) : 0) Sec->Alignment = Subalign; - OutSec->addSection(Sec); } } } +} +template +void LinkerScript::createSections(OutputSectionFactory &Factory) { + processCommands(Factory); // Add orphan sections. - for (ObjectFile *F : Symtab::X->getObjectFiles()) { - for (InputSectionBase *S : F->getSections()) { - if (isDiscarded(S) || S->OutSec) - continue; - OutputSectionBase *OutSec = AddSec(S, getOutputSectionName(S)); - OutSec->addSection(S); - } - } + for (ObjectFile *F : Symtab::X->getObjectFiles()) + for (InputSectionBase *S : F->getSections()) + if (!isDiscarded(S) && !S->OutSec) + addSection(Factory, S, getOutputSectionName(S)); } // Sets value of a section-defined symbol. Two kinds of @@ -754,7 +759,9 @@ if (Tok == ";") continue; - if (Tok == "ENTRY") { + if (Tok == "ASSERT") { + Opt.Commands.emplace_back(new AssertCommand(readAssert())); + } else if (Tok == "ENTRY") { readEntry(); } else if (Tok == "EXTERN") { readExtern(); @@ -777,10 +784,7 @@ } else if (Tok == "VERSION") { readVersion(); } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok, true)) { - if (Opt.HasSections) - Opt.Commands.emplace_back(Cmd); - else - Opt.Assignments.emplace_back(Cmd); + Opt.Commands.emplace_back(Cmd); } else { setError("unknown directive: " + Tok); } Index: lld/trunk/ELF/Writer.cpp =================================================================== --- lld/trunk/ELF/Writer.cpp +++ lld/trunk/ELF/Writer.cpp @@ -249,13 +249,13 @@ CommonInputSection Common(getCommonSymbols()); CommonInputSection::X = &Common; - Script::X->createAssignments(); - Script::X->OutputSections = &OutputSections; - if (ScriptConfig->HasSections) + if (ScriptConfig->HasSections) { Script::X->createSections(Factory); - else + } else { createSections(); + Script::X->processCommands(Factory); + } finalizeSections(); if (HasError) Index: lld/trunk/test/ELF/linkerscript/assert.s =================================================================== --- lld/trunk/test/ELF/linkerscript/assert.s +++ lld/trunk/test/ELF/linkerscript/assert.s @@ -25,3 +25,18 @@ # RUN: }" > %t4.script # RUN: ld.lld -shared -o %t4 --script %t4.script %t1.o # RUN: llvm-readobj %t4 > /dev/null + +# RUN: echo "SECTIONS { \ +# RUN: .foo : { *(.foo) } \ +# RUN: } \ +# RUN: ASSERT(SIZEOF(.foo) == 8, \"true\");" > %t5.script +# RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o +# RUN: llvm-readobj %t5 > /dev/null + +## Even without SECTIONS block we still use section names +## in expressions +# RUN: echo "ASSERT(SIZEOF(.foo) == 8, \"true\");" > %t5.script +# RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o +# RUN: llvm-readobj %t5 > /dev/null +.section .foo, "a" + .quad 0