[lld] r301484 - Create an OutputSection for each non-empty OutputSectionCommand.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 26 15:30:15 PDT 2017


Author: rafael
Date: Wed Apr 26 17:30:15 2017
New Revision: 301484

URL: http://llvm.org/viewvc/llvm-project?rev=301484&view=rev
Log:
Create an OutputSection for each non-empty OutputSectionCommand.

We were already pretty close, the one exception was when a name was
reused in another SECTIONS directive:

SECTIONS {
  .text : { *(.text) }
  .data : { *(.data) }
}
SECTIONS {
  .data : { *(other) }
}

In this case we would create a single .data and magically output
"other" while looking at the first OutputSectionCommand.

We now create two .data sections. This matches what gold does. If we
really want to create a single one, we should change the parser so that
the above is parsed as if the user had written

SECTIONS {
  .text : { *(.text) }
  .data : { *(.data) *(other)}
}

That is, there should be only one OutputSectionCommand for .data and
it would have two InputSectionDescriptions.

By itself this patch makes the code a bit more complicated, but is an
important step in allowing assignAddresses to operate just on the
linker script.

Modified:
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/test/ELF/linkerscript/sections.s

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=301484&r1=301483&r2=301484&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Apr 26 17:30:15 2017
@@ -407,7 +407,7 @@ void LinkerScript::processCommands(Outpu
 
       // Add input sections to an output section.
       for (InputSectionBase *S : V)
-        Factory.addInputSec(S, Cmd->Name);
+        Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
     }
   }
   CurOutSec = nullptr;
@@ -465,9 +465,21 @@ void LinkerScript::fabricateDefaultComma
 
 // Add sections that didn't match any sections command.
 void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
-  for (InputSectionBase *S : InputSections)
-    if (S->Live && !S->OutSec)
-      Factory.addInputSec(S, getOutputSectionName(S->Name));
+  for (InputSectionBase *S : InputSections) {
+    if (!S->Live || S->OutSec)
+      continue;
+    StringRef Name = getOutputSectionName(S->Name);
+    auto I = std::find_if(
+        Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
+          if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
+            return Cmd->Name == Name;
+          return false;
+        });
+    if (I == Opt.Commands.end())
+      Factory.addInputSec(S, Name);
+    else
+      Factory.addInputSec(S, Name, cast<OutputSectionCommand>(*I)->Sec);
+  }
 }
 
 static bool isTbss(OutputSection *Sec) {
@@ -576,14 +588,6 @@ void LinkerScript::process(BaseCommand &
   }
 }
 
-static OutputSection *
-findSection(StringRef Name, const std::vector<OutputSection *> &Sections) {
-  for (OutputSection *Sec : Sections)
-    if (Sec->Name == Name)
-      return Sec;
-  return nullptr;
-}
-
 // This function searches for a memory region to place the given output
 // section in. If found, a pointer to the appropriate memory region is
 // returned. Otherwise, a nullptr is returned.
@@ -663,7 +667,8 @@ void LinkerScript::removeEmptyCommands()
   auto Pos = std::remove_if(
       Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
         if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
-          return !Cmd->Sec;
+          return std::find(OutputSections->begin(), OutputSections->end(),
+                           Cmd->Sec) == OutputSections->end();
         return false;
       });
   Opt.Commands.erase(Pos, Opt.Commands.end());
@@ -687,8 +692,7 @@ void LinkerScript::adjustSectionsBeforeS
     auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
     if (!Cmd)
       continue;
-    if (OutputSection *Sec = findSection(Cmd->Name, *OutputSections)) {
-      Cmd->Sec = Sec;
+    if (OutputSection *Sec = Cmd->Sec) {
       Flags = Sec->Flags;
       Type = Sec->Type;
       continue;

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=301484&r1=301483&r2=301484&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Apr 26 17:30:15 2017
@@ -395,14 +395,20 @@ static void reportDiscarded(InputSection
 
 void OutputSectionFactory::addInputSec(InputSectionBase *IS,
                                        StringRef OutsecName) {
+  SectionKey Key = createKey(IS, OutsecName);
+  OutputSection *&Sec = Map[Key];
+  return addInputSec(IS, OutsecName, Sec);
+}
+
+void OutputSectionFactory::addInputSec(InputSectionBase *IS,
+                                       StringRef OutsecName,
+                                       OutputSection *&Sec) {
   if (!IS->Live) {
     reportDiscarded(IS);
     return;
   }
 
-  SectionKey Key = createKey(IS, OutsecName);
   uint64_t Flags = getOutFlags(IS);
-  OutputSection *&Sec = Map[Key];
   if (Sec) {
     if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
       error("incompatible section flags for " + Sec->Name +
@@ -418,7 +424,7 @@ void OutputSectionFactory::addInputSec(I
     }
     Sec->Flags |= Flags;
   } else {
-    Sec = make<OutputSection>(Key.Name, IS->Type, Flags);
+    Sec = make<OutputSection>(OutsecName, IS->Type, Flags);
     OutputSections.push_back(Sec);
   }
 

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=301484&r1=301483&r2=301484&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Apr 26 17:30:15 2017
@@ -141,6 +141,8 @@ public:
   ~OutputSectionFactory();
 
   void addInputSec(InputSectionBase *IS, StringRef OutsecName);
+  void addInputSec(InputSectionBase *IS, StringRef OutsecName,
+                   OutputSection *&Sec);
 
 private:
   llvm::SmallDenseMap<SectionKey, OutputSection *> Map;

Modified: lld/trunk/test/ELF/linkerscript/sections.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/sections.s?rev=301484&r1=301483&r2=301484&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/sections.s (original)
+++ lld/trunk/test/ELF/linkerscript/sections.s Wed Apr 26 17:30:15 2017
@@ -86,7 +86,8 @@
 
 #           Idx Name          Size
 # SEC-MULTI:      1 .text         0000000e {{[0-9a-f]*}} TEXT DATA
-# SEC-MULTI-NEXT:   .data         00000023 {{[0-9a-f]*}} DATA
+# SEC-MULTI-NEXT:   .data         00000020 {{[0-9a-f]*}} DATA
+# SEC-MULTI-NEXT:   .data         00000003 {{[0-9a-f]*}} DATA
 # SEC-MULTI-NEXT:   .bss          00000002 {{[0-9a-f]*}} BSS
 # SEC-MULTI-NEXT:   .comment      00000008 {{[0-9a-f]*}}
 # SEC-MULTI-NEXT:   .symtab       00000030 {{[0-9a-f]*}}




More information about the llvm-commits mailing list