[lld] r281740 - Improve handling ASSERT outside SECTIONS block
Eugene Leviant via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 16 08:30:47 PDT 2016
Author: evgeny777
Date: Fri Sep 16 10:30:47 2016
New Revision: 281740
URL: http://llvm.org/viewvc/llvm-project?rev=281740&view=rev
Log:
Improve handling ASSERT outside SECTIONS block
Differential revision: https://reviews.llvm.org/D24450
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/linkerscript/assert.s
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=281740&r1=281739&r2=281740&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Sep 16 10:30:47 2016
@@ -48,6 +48,11 @@ template <class ELFT> static void addReg
Symbol *Sym = Symtab<ELFT>::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<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
}
template <class ELFT> static void addSynthetic(SymbolAssignment *Cmd) {
@@ -215,15 +220,6 @@ LinkerScript<ELFT>::createInputSectionLi
return Ret;
}
-template <class ELFT> void LinkerScript<ELFT>::createAssignments() {
- for (const std::unique_ptr<SymbolAssignment> &Cmd : Opt.Assignments) {
- if (shouldDefine<ELFT>(Cmd.get()))
- addRegular<ELFT>(Cmd.get());
- if (Cmd->Sym)
- cast<DefinedRegular<ELFT>>(Cmd->Sym)->Value = Cmd->Expression(0);
- }
-}
-
template <class ELFT>
static SectionKey<ELFT::Is64Bits> createKey(InputSectionBase<ELFT> *C,
StringRef OutsecName) {
@@ -256,15 +252,19 @@ static SectionKey<ELFT::Is64Bits> create
}
template <class ELFT>
-void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
- auto AddSec = [&](InputSectionBase<ELFT> *Sec, StringRef Name) {
- OutputSectionBase<ELFT> *OutSec;
- bool IsNew;
- std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
- if (IsNew)
- OutputSections->push_back(OutSec);
- return OutSec;
- };
+void LinkerScript<ELFT>::addSection(OutputSectionFactory<ELFT> &Factory,
+ InputSectionBase<ELFT> *Sec,
+ StringRef Name) {
+ OutputSectionBase<ELFT> *OutSec;
+ bool IsNew;
+ std::tie(OutSec, IsNew) = Factory.create(createKey(Sec, Name), Sec);
+ if (IsNew)
+ OutputSections->push_back(OutSec);
+ OutSec->addSection(Sec);
+}
+
+template <class ELFT>
+void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
for (const std::unique_ptr<BaseCommand> &Base1 : Opt.Commands) {
if (auto *Cmd = dyn_cast<SymbolAssignment>(Base1.get())) {
@@ -272,6 +272,14 @@ void LinkerScript<ELFT>::createSections(
addRegular<ELFT>(Cmd);
continue;
}
+ if (auto *Cmd = dyn_cast<AssertCommand>(Base1.get())) {
+ // If we don't have SECTIONS then output sections have already been
+ // created by Writer<EFLT>. The LinkerScript<ELFT>::assignAddresses
+ // will not be called, so ASSERT should be evaluated now.
+ if (!Opt.HasSections)
+ Cmd->Expression(0);
+ continue;
+ }
if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base1.get())) {
std::vector<InputSectionBase<ELFT> *> V = createInputSectionList(*Cmd);
@@ -285,25 +293,22 @@ void LinkerScript<ELFT>::createSections(
continue;
for (InputSectionBase<ELFT> *Sec : V) {
- OutputSectionBase<ELFT> *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 <class ELFT>
+void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
+ processCommands(Factory);
// Add orphan sections.
- for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
- for (InputSectionBase<ELFT> *S : F->getSections()) {
- if (isDiscarded(S) || S->OutSec)
- continue;
- OutputSectionBase<ELFT> *OutSec = AddSec(S, getOutputSectionName(S));
- OutSec->addSection(S);
- }
- }
+ for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
+ for (InputSectionBase<ELFT> *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 @@ void ScriptParser::readLinkerScript() {
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 @@ void ScriptParser::readLinkerScript() {
} 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);
}
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=281740&r1=281739&r2=281740&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Sep 16 10:30:47 2016
@@ -140,8 +140,6 @@ public:
// ScriptConfiguration holds linker script parse results.
struct ScriptConfiguration {
- // Used to create symbol assignments outside SECTIONS command.
- std::vector<std::unique_ptr<SymbolAssignment>> Assignments;
// Used to assign addresses to sections.
std::vector<std::unique_ptr<BaseCommand>> Commands;
@@ -166,7 +164,7 @@ template <class ELFT> class LinkerScript
public:
LinkerScript();
~LinkerScript();
- void createAssignments();
+ void processCommands(OutputSectionFactory<ELFT> &Factory);
void createSections(OutputSectionFactory<ELFT> &Factory);
std::vector<PhdrEntry<ELFT>> createPhdrs();
@@ -191,6 +189,8 @@ private:
void computeInputSections(InputSectionDescription *,
ConstraintKind Constraint);
+ void addSection(OutputSectionFactory<ELFT> &Factory,
+ InputSectionBase<ELFT> *Sec, StringRef Name);
void discard(ArrayRef<InputSectionBase<ELFT> *> V);
std::vector<InputSectionBase<ELFT> *>
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=281740&r1=281739&r2=281740&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Sep 16 10:30:47 2016
@@ -249,13 +249,13 @@ template <class ELFT> void Writer<ELFT>:
CommonInputSection<ELFT> Common(getCommonSymbols<ELFT>());
CommonInputSection<ELFT>::X = &Common;
- Script<ELFT>::X->createAssignments();
-
Script<ELFT>::X->OutputSections = &OutputSections;
- if (ScriptConfig->HasSections)
+ if (ScriptConfig->HasSections) {
Script<ELFT>::X->createSections(Factory);
- else
+ } else {
createSections();
+ Script<ELFT>::X->processCommands(Factory);
+ }
finalizeSections();
if (HasError)
Modified: lld/trunk/test/ELF/linkerscript/assert.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/assert.s?rev=281740&r1=281739&r2=281740&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/assert.s (original)
+++ lld/trunk/test/ELF/linkerscript/assert.s Fri Sep 16 10:30:47 2016
@@ -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
More information about the llvm-commits
mailing list