[lld] r286053 - Rewrite CommonInputSection as a synthetic input section.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sat Nov 5 16:05:47 PDT 2016


Author: ruiu
Date: Sat Nov  5 18:05:47 2016
New Revision: 286053

URL: http://llvm.org/viewvc/llvm-project?rev=286053&view=rev
Log:
Rewrite CommonInputSection as a synthetic input section.

A CommonInputSection is a section containing all common symbols.
That was an input section but was abstracted in a different way
than the synthetic input sections because it was written before
the synthetic input section was invented.

This patch rewrites CommonInputSection as a synthetic input section
so that it behaves better with other sections.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/InputSection.h
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/linkerscript/double-bss.s

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Sat Nov  5 18:05:47 2016
@@ -825,31 +825,6 @@ bool MipsAbiFlagsInputSection<ELFT>::cla
   return S->kind() == InputSectionBase<ELFT>::MipsAbiFlags;
 }
 
-template <class ELFT>
-InputSection<ELFT> InputSection<ELFT>::createCommonInputSection(
-    std::vector<DefinedCommon *> Syms) {
-  // Sort the common symbols by alignment as an heuristic to pack them better.
-  std::stable_sort(Syms.begin(), Syms.end(),
-                   [](const DefinedCommon *A, const DefinedCommon *B) {
-                     return A->Alignment > B->Alignment;
-                   });
-
-  size_t Size = 0;
-  uintX_t Alignment = 1;
-  for (DefinedCommon *Sym : Syms) {
-    Alignment = std::max<uintX_t>(Alignment, Sym->Alignment);
-    Size = alignTo(Size, Sym->Alignment);
-
-    // Compute symbol offset relative to beginning of input section.
-    Sym->Offset = Size;
-    Size += Sym->Size;
-  }
-  ArrayRef<uint8_t> Data = makeArrayRef<uint8_t>(nullptr, Size);
-  InputSection Ret(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, Alignment, Data, "");
-  Ret.Live = true;
-  return Ret;
-}
-
 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=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Sat Nov  5 18:05:47 2016
@@ -273,14 +273,6 @@ public:
   template <class RelTy>
   void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
 
-  // Common symbols don't belong to any section. But it is easier for us
-  // to handle them as if they belong to some input section. So we defined
-  // this section that "contains" all common symbols.
-  static InputSection<ELFT> *CommonInputSection;
-
-  static InputSection<ELFT>
-  createCommonInputSection(std::vector<DefinedCommon *> Syms);
-
 private:
   template <class RelTy>
   void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
@@ -294,9 +286,6 @@ private:
   llvm::TinyPtrVector<const Thunk<ELFT> *> Thunks;
 };
 
-template <class ELFT>
-InputSection<ELFT> *InputSection<ELFT>::CommonInputSection;
-
 // MIPS .reginfo section provides information on the registers used by the code
 // in the object file. Linker should collect this information and write a single
 // .reginfo section in the output file. The output section contains a union of

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Sat Nov  5 18:05:47 2016
@@ -202,13 +202,9 @@ void LinkerScript<ELFT>::computeInputSec
       if (elf::ObjectFile<ELFT> *F = S->getFile())
         Filename = sys::path::filename(F->getName());
 
-      if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
-        continue;
-
-      if (Pat.SectionPat.match(S->Name))
+      if (I->FilePat.match(Filename) && !Pat.ExcludedFilePat.match(Filename) &&
+          Pat.SectionPat.match(S->Name))
         I->Sections.push_back(S);
-      if (Pat.SectionPat.match("COMMON"))
-        I->Sections.push_back(InputSection<ELFT>::CommonInputSection);
     }
 
     // Sort sections as instructed by SORT-family commands and --sort-section

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Sat Nov  5 18:05:47 2016
@@ -15,6 +15,7 @@
 #include "Memory.h"
 #include "Strings.h"
 #include "SymbolTable.h"
+#include "SyntheticSections.h"
 #include "Target.h"
 #include "lld/Core/Parallel.h"
 #include "llvm/Support/Dwarf.h"
@@ -1556,7 +1557,7 @@ SymbolTableSection<ELFT>::getOutputSecti
     break;
   }
   case SymbolBody::DefinedCommonKind:
-    return InputSection<ELFT>::CommonInputSection->OutSec;
+    return In<ELFT>::Common->OutSec;
   case SymbolBody::SharedKind:
     if (cast<SharedSymbol<ELFT>>(Sym)->needsCopy())
       return Out<ELFT>::Bss;

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Sat Nov  5 18:05:47 2016
@@ -12,6 +12,7 @@
 #include "InputFiles.h"
 #include "InputSection.h"
 #include "OutputSections.h"
+#include "SyntheticSections.h"
 #include "Target.h"
 
 #include "llvm/ADT/STLExtras.h"
@@ -69,8 +70,7 @@ static typename ELFT::uint getSymVA(cons
     return VA;
   }
   case SymbolBody::DefinedCommonKind:
-    return InputSection<ELFT>::CommonInputSection->OutSec->getVA() +
-           InputSection<ELFT>::CommonInputSection->OutSecOff +
+    return In<ELFT>::Common->OutSec->getVA() + In<ELFT>::Common->OutSecOff +
            cast<DefinedCommon>(Body).Offset;
   case SymbolBody::SharedKind: {
     auto &SS = cast<SharedSymbol<ELFT>>(Body);

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sat Nov  5 18:05:47 2016
@@ -21,6 +21,7 @@
 #include "Memory.h"
 #include "OutputSections.h"
 #include "Strings.h"
+#include "SymbolTable.h"
 
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/MD5.h"
@@ -37,6 +38,43 @@ using namespace llvm::support::endian;
 using namespace lld;
 using namespace lld::elf;
 
+template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
+  std::vector<DefinedCommon *> V;
+  for (Symbol *S : Symtab<ELFT>::X->getSymbols())
+    if (auto *B = dyn_cast<DefinedCommon>(S->body()))
+      V.push_back(B);
+  return V;
+}
+
+// Find all common symbols and allocate space for them.
+template <class ELFT>
+CommonSection<ELFT>::CommonSection()
+    : InputSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 1,
+                         ArrayRef<uint8_t>(), "COMMON") {
+  this->Live = true;
+
+  // Sort the common symbols by alignment as an heuristic to pack them better.
+  std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
+  std::stable_sort(Syms.begin(), Syms.end(),
+                   [](const DefinedCommon *A, const DefinedCommon *B) {
+                     return A->Alignment > B->Alignment;
+                   });
+
+  // Assign offsets to symbols.
+  size_t Size = 0;
+  size_t Alignment = 1;
+  for (DefinedCommon *Sym : Syms) {
+    Alignment = std::max(Alignment, Sym->Alignment);
+    Size = alignTo(Size, Sym->Alignment);
+
+    // Compute symbol offset relative to beginning of input section.
+    Sym->Offset = Size;
+    Size += Sym->Size;
+  }
+  this->Alignment = Alignment;
+  this->Data = makeArrayRef<uint8_t>(nullptr, Size);
+}
+
 static ArrayRef<uint8_t> createInterp() {
   // StringSaver guarantees that the returned string ends with '\0'.
   StringRef S = Saver.save(Config->DynamicLinker);
@@ -111,6 +149,11 @@ void BuildIdHexstring<ELFT>::writeBuildI
          Config->BuildIdVector.size());
 }
 
+template class elf::CommonSection<ELF32LE>;
+template class elf::CommonSection<ELF32BE>;
+template class elf::CommonSection<ELF64LE>;
+template class elf::CommonSection<ELF64BE>;
+
 template class elf::InterpSection<ELF32LE>;
 template class elf::InterpSection<ELF32BE>;
 template class elf::InterpSection<ELF64LE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Sat Nov  5 18:05:47 2016
@@ -15,11 +15,19 @@
 namespace lld {
 namespace elf {
 
+// This class represents a BSS section containing all common symbols.
+template <class ELFT> class CommonSection final : public InputSection<ELFT> {
+public:
+  CommonSection();
+};
+
+// .interp section.
 template <class ELFT> class InterpSection final : public InputSection<ELFT> {
 public:
   InterpSection();
 };
 
+// .note.gnu.build-id section.
 template <class ELFT> class BuildIdSection : public InputSection<ELFT> {
 public:
   virtual void writeBuildId(llvm::MutableArrayRef<uint8_t> Buf) = 0;
@@ -67,13 +75,13 @@ public:
 // Linker generated sections which can be used as inputs.
 template <class ELFT> struct In {
   static BuildIdSection<ELFT> *BuildId;
+  static CommonSection<ELFT> *Common;
   static InterpSection<ELFT> *Interp;
-  static std::vector<InputSection<ELFT> *> Sections;
 };
 
 template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
+template <class ELFT> CommonSection<ELFT> *In<ELFT>::Common;
 template <class ELFT> InterpSection<ELFT> *In<ELFT>::Interp;
-template <class ELFT> std::vector<InputSection<ELFT> *> In<ELFT>::Sections;
 
 } // namespace elf
 } // namespace lld

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sat Nov  5 18:05:47 2016
@@ -105,6 +105,11 @@ StringRef elf::getOutputSectionName(Stri
       return Prefix;
   }
 
+  // CommonSection is identified as "COMMON" in linker scripts.
+  // By default, it should go to .bss section.
+  if (Name == "COMMON")
+    return ".bss";
+
   // ".zdebug_" is a prefix for ZLIB-compressed sections.
   // Because we decompressed input sections, we want to remove 'z'.
   if (Name.startswith(".zdebug_"))
@@ -130,14 +135,6 @@ template <class ELFT> void elf::writeRes
   Writer<ELFT>().run();
 }
 
-template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
-  std::vector<DefinedCommon *> V;
-  for (Symbol *S : Symtab<ELFT>::X->getSymbols())
-    if (auto *B = dyn_cast<DefinedCommon>(S->body()))
-      V.push_back(B);
-  return V;
-}
-
 // The main function of the writer.
 template <class ELFT> void Writer<ELFT>::run() {
   createSyntheticSections();
@@ -146,10 +143,6 @@ template <class ELFT> void Writer<ELFT>:
   if (Target->NeedsThunks)
     forEachRelSec(createThunks<ELFT>);
 
-  InputSection<ELFT> Common =
-      InputSection<ELFT>::createCommonInputSection(getCommonSymbols<ELFT>());
-  InputSection<ELFT>::CommonInputSection = &Common;
-
   Script<ELFT>::X->OutputSections = &OutputSections;
   if (ScriptConfig->HasSections) {
     Script<ELFT>::X->createSections(Factory);
@@ -234,8 +227,12 @@ template <class ELFT> void Writer<ELFT>:
   Out<ELFT>::ProgramHeaders = make<OutputSectionBase<ELFT>>("", 0, SHF_ALLOC);
   Out<ELFT>::ProgramHeaders->updateAlignment(sizeof(uintX_t));
 
-  if (needsInterpSection<ELFT>())
+  if (needsInterpSection<ELFT>()) {
     In<ELFT>::Interp = make<InterpSection<ELFT>>();
+    Symtab<ELFT>::X->Sections.push_back(In<ELFT>::Interp);
+  } else {
+    In<ELFT>::Interp = nullptr;
+  }
 
   if (!Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic) {
     Out<ELFT>::DynSymTab =
@@ -284,8 +281,17 @@ template <class ELFT> void Writer<ELFT>:
     In<ELFT>::BuildId = make<BuildIdUuid<ELFT>>();
   else if (Config->BuildId == BuildIdKind::Hexstring)
     In<ELFT>::BuildId = make<BuildIdHexstring<ELFT>>();
+  else
+    In<ELFT>::BuildId = nullptr;
 
-  In<ELFT>::Sections = {In<ELFT>::BuildId, In<ELFT>::Interp};
+  if (In<ELFT>::BuildId)
+    Symtab<ELFT>::X->Sections.push_back(In<ELFT>::BuildId);
+
+  CommonSection<ELFT> *Common = make<CommonSection<ELFT>>();
+  if (!Common->Data.empty()) {
+    In<ELFT>::Common = Common;
+    Symtab<ELFT>::X->Sections.push_back(Common);
+  }
 }
 
 template <class ELFT>
@@ -803,22 +809,10 @@ template <class ELFT> void Writer<ELFT>:
   if (HasError)
     return;
 
-  // If linker script processor hasn't added common symbol section yet,
-  // then add it to .bss now.
-  if (!InputSection<ELFT>::CommonInputSection->OutSec) {
-    Out<ELFT>::Bss->addSection(InputSection<ELFT>::CommonInputSection);
-    Out<ELFT>::Bss->assignOffsets();
-  }
-
   // So far we have added sections from input object files.
   // This function adds linker-created Out<ELFT>::* sections.
   addPredefinedSections();
 
-  // Adds linker generated input sections to
-  // corresponding output sections.
-  for (InputSection<ELFT> *S : In<ELFT>::Sections)
-    addInputSec(S);
-
   sortSections();
 
   unsigned I = 1;
@@ -827,11 +821,6 @@ template <class ELFT> void Writer<ELFT>:
     Sec->setSHName(Out<ELFT>::ShStrTab->addString(Sec->getName()));
   }
 
-  // Finalize linker generated sections.
-  for (InputSection<ELFT> *S : In<ELFT>::Sections)
-    if (S && S->OutSec)
-      S->OutSec->assignOffsets();
-
   // Finalizers fix each section's size.
   // .dynsym is finalized early since that may fill up .gnu.hash.
   if (Out<ELFT>::DynSymTab)

Modified: lld/trunk/test/ELF/linkerscript/double-bss.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/double-bss.s?rev=286053&r1=286052&r2=286053&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/double-bss.s (original)
+++ lld/trunk/test/ELF/linkerscript/double-bss.s Sat Nov  5 18:05:47 2016
@@ -1,10 +1,15 @@
 # REQUIRES: x86
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text*) } }" > %t.script
+# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; " > %t.script
+# RUN: echo ".text : { *(.text*) }" >> %t.script
+# RUN: echo ".bss1 : { *(.bss) }" >> %t.script
+# RUN: echo ".bss2 : { *(COMMON) }" >> %t.script
+# RUN: echo "}" >> %t.script
+
 # RUN: ld.lld -o %t1 --script %t.script %t
 # RUN: llvm-objdump -section-headers %t1 | FileCheck %s
-# CHECK:      .bss          00000004 0000000000000122 BSS
-# CHECK-NEXT: .bss          00000080 0000000000000128 BSS
+# CHECK:      .bss1          00000004 0000000000000122 BSS
+# CHECK-NEXT: .bss2          00000080 0000000000000128 BSS
 
 .globl _start
 _start:




More information about the llvm-commits mailing list