Move OutputSectionFactory to LinkerScript.cpp. NFC.
authorRui Ueyama <ruiu@google.com>
Sat, 4 Nov 2017 23:54:25 +0000 (23:54 +0000)
committerRui Ueyama <ruiu@google.com>
Sat, 4 Nov 2017 23:54:25 +0000 (23:54 +0000)
That class is used only by LinkerScript.cpp, so we should move it to
that file. Also, it no longer has to be a "factory" class. It can just
be a non-member function.

llvm-svn: 317427

lld/ELF/LinkerScript.cpp
lld/ELF/LinkerScript.h
lld/ELF/OutputSections.cpp
lld/ELF/Writer.cpp

index 6c32442..a59b1ef 100644 (file)
@@ -434,9 +434,107 @@ static void reportOrphan(InputSectionBase *IS, StringRef Name) {
     warn(toString(IS) + " is being placed in '" + Name + "'");
 }
 
+static OutputSection *createSection(InputSectionBase *IS,
+                                    StringRef OutsecName) {
+  OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>");
+  Sec->addSection(cast<InputSection>(IS));
+  return Sec;
+}
+
+static OutputSection *addInputSec(StringMap<OutputSection *> &Map,
+                                  InputSectionBase *IS, StringRef OutsecName) {
+  // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
+  // option is given. A section with SHT_GROUP defines a "section group", and
+  // its members have SHF_GROUP attribute. Usually these flags have already been
+  // stripped by InputFiles.cpp as section groups are processed and uniquified.
+  // However, for the -r option, we want to pass through all section groups
+  // as-is because adding/removing members or merging them with other groups
+  // change their semantics.
+  if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP))
+    return createSection(IS, OutsecName);
+
+  // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
+  // relocation sections .rela.foo and .rela.bar for example. Most tools do
+  // not allow multiple REL[A] sections for output section. Hence we
+  // should combine these relocation sections into single output.
+  // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
+  // other REL[A] sections created by linker itself.
+  if (!isa<SyntheticSection>(IS) &&
+      (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
+    auto *Sec = cast<InputSection>(IS);
+    OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
+
+    if (Out->RelocationSection) {
+      Out->RelocationSection->addSection(Sec);
+      return nullptr;
+    }
+
+    Out->RelocationSection = createSection(IS, OutsecName);
+    return Out->RelocationSection;
+  }
+
+  // When control reaches here, mergeable sections have already been
+  // merged except the -r case. If that's the case, we do not combine them
+  // and let final link to handle this optimization.
+  if (Config->Relocatable && (IS->Flags & SHF_MERGE))
+    return createSection(IS, OutsecName);
+
+  //  The ELF spec just says
+  // ----------------------------------------------------------------
+  // In the first phase, input sections that match in name, type and
+  // attribute flags should be concatenated into single sections.
+  // ----------------------------------------------------------------
+  //
+  // However, it is clear that at least some flags have to be ignored for
+  // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be
+  // ignored. We should not have two output .text sections just because one was
+  // in a group and another was not for example.
+  //
+  // It also seems that that wording was a late addition and didn't get the
+  // necessary scrutiny.
+  //
+  // Merging sections with different flags is expected by some users. One
+  // reason is that if one file has
+  //
+  // int *const bar __attribute__((section(".foo"))) = (int *)0;
+  //
+  // gcc with -fPIC will produce a read only .foo section. But if another
+  // file has
+  //
+  // int zed;
+  // int *const bar __attribute__((section(".foo"))) = (int *)&zed;
+  //
+  // gcc with -fPIC will produce a read write section.
+  //
+  // Last but not least, when using linker script the merge rules are forced by
+  // the script. Unfortunately, linker scripts are name based. This means that
+  // expressions like *(.foo*) can refer to multiple input sections with
+  // different flags. We cannot put them in different output sections or we
+  // would produce wrong results for
+  //
+  // start = .; *(.foo.*) end = .; *(.bar)
+  //
+  // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to
+  // another. The problem is that there is no way to layout those output
+  // sections such that the .foo sections are the only thing between the start
+  // and end symbols.
+  //
+  // Given the above issues, we instead merge sections by name and error on
+  // incompatible types and flags.
+  OutputSection *&Sec = Map[OutsecName];
+  if (Sec) {
+    Sec->addSection(cast<InputSection>(IS));
+    return nullptr;
+  }
+
+  Sec = createSection(IS, OutsecName);
+  return Sec;
+}
+
 // Add sections that didn't match any sections command.
-void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
+void LinkerScript::addOrphanSections() {
   unsigned End = SectionCommands.size();
+  StringMap<OutputSection *> Map;
 
   std::vector<OutputSection *> V;
   for (InputSectionBase *S : InputSections) {
@@ -452,7 +550,7 @@ void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
       continue;
     }
 
-    if (OutputSection *OS = Factory.addInputSec(S, Name))
+    if (OutputSection *OS = addInputSec(Map, S, Name))
       V.push_back(OS);
     assert(S->getOutputSection()->SectionIndex == INT_MAX);
   }
index 6474da5..b937e7f 100644 (file)
@@ -251,7 +251,7 @@ public:
 
   ExprValue getSymbolValue(StringRef Name, const Twine &Loc);
 
-  void addOrphanSections(OutputSectionFactory &Factory);
+  void addOrphanSections();
   void removeEmptyCommands();
   void adjustSectionsBeforeSorting();
   void adjustSectionsAfterSorting();
index b4c1c80..357affe 100644 (file)
@@ -142,8 +142,6 @@ void OutputSection::addSection(InputSection *IS) {
   }
 }
 
-OutputSectionFactory::OutputSectionFactory() {}
-
 void elf::sortByOrder(MutableArrayRef<InputSection *> In,
                       std::function<int(InputSectionBase *S)> Order) {
   typedef std::pair<int, InputSection *> Pair;
@@ -158,105 +156,6 @@ void elf::sortByOrder(MutableArrayRef<InputSection *> In,
     In[I] = V[I].second;
 }
 
-static OutputSection *createSection(InputSectionBase *IS, StringRef OutsecName) {
-  OutputSection *Sec = Script->createOutputSection(OutsecName, "<internal>");
-  Sec->addSection(cast<InputSection>(IS));
-  return Sec;
-}
-
-OutputSection *OutputSectionFactory::addInputSec(InputSectionBase *IS,
-                                                 StringRef OutsecName) {
-
-  // Sections with SHT_GROUP or SHF_GROUP attributes reach here only when the -r
-  // option is given. A section with SHT_GROUP defines a "section group", and
-  // its members have SHF_GROUP attribute. Usually these flags have already been
-  // stripped by InputFiles.cpp as section groups are processed and uniquified.
-  // However, for the -r option, we want to pass through all section groups
-  // as-is because adding/removing members or merging them with other groups
-  // change their semantics.
-  if (IS->Type == SHT_GROUP || (IS->Flags & SHF_GROUP))
-    return createSection(IS, OutsecName);
-
-  // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
-  // relocation sections .rela.foo and .rela.bar for example. Most tools do
-  // not allow multiple REL[A] sections for output section. Hence we
-  // should combine these relocation sections into single output.
-  // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
-  // other REL[A] sections created by linker itself.
-  if (!isa<SyntheticSection>(IS) &&
-      (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
-    auto *Sec = cast<InputSection>(IS);
-    OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
-
-    if (Out->RelocationSection) {
-      Out->RelocationSection->addSection(Sec);
-      return nullptr;
-    }
-
-    Out->RelocationSection = createSection(IS, OutsecName);
-    return Out->RelocationSection;
-  }
-
-  // When control reaches here, mergeable sections have already been
-  // merged except the -r case. If that's the case, we do not combine them
-  // and let final link to handle this optimization.
-  if (Config->Relocatable && (IS->Flags & SHF_MERGE))
-    return createSection(IS, OutsecName);
-
-  //  The ELF spec just says
-  // ----------------------------------------------------------------
-  // In the first phase, input sections that match in name, type and
-  // attribute flags should be concatenated into single sections.
-  // ----------------------------------------------------------------
-  //
-  // However, it is clear that at least some flags have to be ignored for
-  // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be
-  // ignored. We should not have two output .text sections just because one was
-  // in a group and another was not for example.
-  //
-  // It also seems that that wording was a late addition and didn't get the
-  // necessary scrutiny.
-  //
-  // Merging sections with different flags is expected by some users. One
-  // reason is that if one file has
-  //
-  // int *const bar __attribute__((section(".foo"))) = (int *)0;
-  //
-  // gcc with -fPIC will produce a read only .foo section. But if another
-  // file has
-  //
-  // int zed;
-  // int *const bar __attribute__((section(".foo"))) = (int *)&zed;
-  //
-  // gcc with -fPIC will produce a read write section.
-  //
-  // Last but not least, when using linker script the merge rules are forced by
-  // the script. Unfortunately, linker scripts are name based. This means that
-  // expressions like *(.foo*) can refer to multiple input sections with
-  // different flags. We cannot put them in different output sections or we
-  // would produce wrong results for
-  //
-  // start = .; *(.foo.*) end = .; *(.bar)
-  //
-  // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to
-  // another. The problem is that there is no way to layout those output
-  // sections such that the .foo sections are the only thing between the start
-  // and end symbols.
-  //
-  // Given the above issues, we instead merge sections by name and error on
-  // incompatible types and flags.
-  OutputSection *&Sec = Map[OutsecName];
-  if (Sec) {
-    Sec->addSection(cast<InputSection>(IS));
-    return nullptr;
-  }
-
-  Sec = createSection(IS, OutsecName);
-  return Sec;
-}
-
-OutputSectionFactory::~OutputSectionFactory() {}
-
 uint64_t elf::getHeaderSize() {
   if (Config->OFormatBinary)
     return 0;
index 56b8345..7bd7c2b 100644 (file)
@@ -72,8 +72,6 @@ private:
 
   std::unique_ptr<FileOutputBuffer> Buffer;
 
-  OutputSectionFactory Factory;
-
   void addRelIpltSymbols();
   void addStartEndSymbols();
   void addStartStopSymbols(OutputSection *Sec);
@@ -175,7 +173,7 @@ template <class ELFT> void Writer<ELFT>::run() {
   // Linker scripts controls how input sections are assigned to output sections.
   // Input sections that were not handled by scripts are called "orphans", and
   // they are assigned to output sections by the default rule. Process that.
-  Script->addOrphanSections(Factory);
+  Script->addOrphanSections();
 
   if (Config->Discard != DiscardPolicy::All)
     copyLocalSymbols();