[ELF] Create output sections in LinkerScript class

llvm-svn: 276121
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index e56e1a2..aaf2b9d 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -196,7 +196,7 @@
 
 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 @@
 }
 
 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