[lld] r276121 - [ELF] Create output sections in LinkerScript class

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 20 07:43:20 PDT 2016


Author: evgeny777
Date: Wed Jul 20 09:43:20 2016
New Revision: 276121

URL: http://llvm.org/viewvc/llvm-project?rev=276121&view=rev
Log:
[ELF] Create output sections in LinkerScript class

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/LinkerScript.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Jul 20 09:43:20 2016
@@ -28,11 +28,6 @@ using namespace llvm::support::endian;
 using namespace lld;
 using namespace lld::elf;
 
-template <class ELFT> bool elf::isDiscarded(InputSectionBase<ELFT> *S) {
-  return !S || S == &InputSection<ELFT>::Discarded || !S->Live ||
-         Script<ELFT>::X->isDiscarded(S);
-}
-
 template <class ELFT>
 InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
                                          const Elf_Shdr *Header,
@@ -650,11 +645,6 @@ bool MipsOptionsInputSection<ELFT>::clas
   return S->SectionKind == InputSectionBase<ELFT>::MipsOptions;
 }
 
-template bool elf::isDiscarded<ELF32LE>(InputSectionBase<ELF32LE> *);
-template bool elf::isDiscarded<ELF32BE>(InputSectionBase<ELF32BE> *);
-template bool elf::isDiscarded<ELF64LE>(InputSectionBase<ELF64LE> *);
-template bool elf::isDiscarded<ELF64BE>(InputSectionBase<ELF64BE> *);
-
 template class elf::InputSectionBase<ELF32LE>;
 template class elf::InputSectionBase<ELF32BE>;
 template class elf::InputSectionBase<ELF64LE>;

Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Wed Jul 20 09:43:20 2016
@@ -21,8 +21,6 @@
 namespace lld {
 namespace elf {
 
-template <class ELFT> bool isDiscarded(InputSectionBase<ELFT> *S);
-
 class SymbolBody;
 
 template <class ELFT> class ICF;

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Jul 20 09:43:20 2016
@@ -196,7 +196,7 @@ StringRef LinkerScript<ELFT>::getOutputS
 
 template <class ELFT>
 bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) {
-  return getOutputSection(S) == "/DISCARD/";
+  return !S || !S->Live || getOutputSection(S) == "/DISCARD/";
 }
 
 template <class ELFT>
@@ -208,6 +208,46 @@ bool LinkerScript<ELFT>::shouldKeep(Inpu
 }
 
 template <class ELFT>
+std::vector<std::unique_ptr<OutputSectionBase<ELFT>>>
+LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
+  std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> Result;
+  // Add input section to output section. If there is no output section yet,
+  // then create it and add to output section list.
+  auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name) {
+    OutputSectionBase<ELFT> *Sec;
+    bool IsNew;
+    std::tie(Sec, IsNew) = Factory.create(C, Name);
+    if (IsNew)
+      Result.emplace_back(Sec);
+    Sec->addSection(C);
+  };
+
+  // Select input sections matching rule and add them to corresponding
+  // output section. Section rules are processed in order they're listed
+  // in script, so correct input section order is maintained by design.
+  for (SectionRule &R : Opt.Sections)
+    for (const std::unique_ptr<ObjectFile<ELFT>> &F :
+         Symtab<ELFT>::X->getObjectFiles())
+      for (InputSectionBase<ELFT> *S : F->getSections())
+        if (!isDiscarded(S) && !S->OutSec &&
+            globMatch(R.SectionPattern, S->getSectionName()))
+          // Add single input section to output section.
+          AddInputSec(S, R.Dest);
+
+  // Add all other input sections, which are not listed in script.
+  for (const std::unique_ptr<ObjectFile<ELFT>> &F :
+       Symtab<ELFT>::X->getObjectFiles())
+    for (InputSectionBase<ELFT> *S : F->getSections())
+      if (!isDiscarded(S)) {
+        if (!S->OutSec)
+          AddInputSec(S, getOutputSectionName(S));
+      } else
+        reportDiscarded(S, F);
+
+  return Result;
+}
+
+template <class ELFT>
 void LinkerScript<ELFT>::assignAddresses(
     ArrayRef<OutputSectionBase<ELFT> *> Sections) {
   // Orphan sections are sections present in the input files which

Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Jul 20 09:43:20 2016
@@ -19,6 +19,9 @@
 
 namespace lld {
 namespace elf {
+template <class ELFT> class InputSectionBase;
+template <class ELFT> class OutputSectionBase;
+template <class ELFT> class OutputSectionFactory;
 
 // Parses a linker script. Calling this function updates
 // Config and ScriptConfig.
@@ -93,6 +96,8 @@ public:
   ArrayRef<uint8_t> getFiller(StringRef Name);
   bool isDiscarded(InputSectionBase<ELFT> *S);
   bool shouldKeep(InputSectionBase<ELFT> *S);
+  std::vector<std::unique_ptr<OutputSectionBase<ELFT>>>
+  createSections(OutputSectionFactory<ELFT> &Factory);
   void assignAddresses(ArrayRef<OutputSectionBase<ELFT> *> S);
   int compareSections(StringRef A, StringRef B);
   void addScriptedSymbols();

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jul 20 09:43:20 2016
@@ -48,7 +48,8 @@ private:
 
   void copyLocalSymbols();
   void addReservedSymbols();
-  void createSections();
+  std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> createSections();
+  void finalizeSections();
   void addPredefinedSections();
   bool needsGot();
 
@@ -70,7 +71,7 @@ private:
 
   BumpPtrAllocator Alloc;
   std::vector<OutputSectionBase<ELFT> *> OutputSections;
-  std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
+  OutputSectionFactory<ELFT> Factory;
 
   void addRelIpltSymbols();
   void addStartEndSymbols();
@@ -216,7 +217,15 @@ template <class ELFT> void Writer<ELFT>:
   if (!Config->DiscardAll)
     copyLocalSymbols();
   addReservedSymbols();
-  createSections();
+
+  std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> Sections =
+      ScriptConfig->DoLayout ? Script<ELFT>::X->createSections(Factory)
+                             : createSections();
+
+  for (std::unique_ptr<OutputSectionBase<ELFT>> &S : Sections)
+    OutputSections.push_back(S.get());
+
+  finalizeSections();
   if (HasError)
     return;
 
@@ -477,6 +486,10 @@ template <class ELFT> bool elf::isOutput
   return !Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic;
 }
 
+template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
+  return !S || S == &InputSection<ELFT>::Discarded || !S->Live;
+}
+
 // Program header entry
 template<class ELFT>
 PhdrEntry<ELFT>::PhdrEntry(unsigned Type, unsigned Flags) {
@@ -623,11 +636,11 @@ template <class ELFT> static void sortCt
     reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
 }
 
-// Create output section objects and add them to OutputSections.
-template <class ELFT> void Writer<ELFT>::createSections() {
-  // Create output sections for input object file sections.
-  std::vector<OutputSectionBase<ELFT> *> RegularSections;
-  OutputSectionFactory<ELFT> Factory;
+template <class ELFT>
+std::vector<std::unique_ptr<OutputSectionBase<ELFT>>>
+Writer<ELFT>::createSections() {
+  std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> Result;
+
   for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
        Symtab.getObjectFiles()) {
     for (InputSectionBase<ELFT> *C : F->getSections()) {
@@ -638,14 +651,19 @@ template <class ELFT> void Writer<ELFT>:
       OutputSectionBase<ELFT> *Sec;
       bool IsNew;
       std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C));
-      if (IsNew) {
-        OwningSections.emplace_back(Sec);
-        OutputSections.push_back(Sec);
-        RegularSections.push_back(Sec);
-      }
+      if (IsNew)
+        Result.emplace_back(Sec);
+
       Sec->addSection(C);
     }
   }
+  return Result;
+}
+
+// Create output section objects and add them to OutputSections.
+template <class ELFT> void Writer<ELFT>::finalizeSections() {
+  // Create output sections for input object file sections.
+  std::vector<OutputSectionBase<ELFT> *> RegularSections = OutputSections;
 
   // If we have a .opd section (used under PPC64 for function descriptors),
   // store a pointer to it here so that we can use it later when processing




More information about the llvm-commits mailing list