[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