[lld] r297297 - Revert r297008: [ELF] - Make Bss and BssRelRo sections to be synthetic (#2).

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 8 09:24:25 PST 2017


Author: ruiu
Date: Wed Mar  8 11:24:24 2017
New Revision: 297297

URL: http://llvm.org/viewvc/llvm-project?rev=297297&view=rev
Log:
Revert r297008: [ELF] - Make Bss and BssRelRo sections to be synthetic (#2).

This reverts commit r297008 because it's reported that that
change broke AArch64 bots.

Modified:
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Mar  8 11:24:24 2017
@@ -31,6 +31,8 @@ using namespace lld;
 using namespace lld::elf;
 
 uint8_t Out::First;
+OutputSection *Out::Bss;
+OutputSection *Out::BssRelRo;
 OutputSection *Out::Opd;
 uint8_t *Out::OpdBuf;
 PhdrEntry *Out::TlsPhdr;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Mar  8 11:24:24 2017
@@ -98,6 +98,8 @@ public:
 // until Writer is initialized.
 struct Out {
   static uint8_t First;
+  static OutputSection *Bss;
+  static OutputSection *BssRelRo;
   static OutputSection *Opd;
   static uint8_t *OpdBuf;
   static PhdrEntry *TlsPhdr;

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Mar  8 11:24:24 2017
@@ -479,20 +479,23 @@ template <class ELFT> static void addCop
   // See if this symbol is in a read-only segment. If so, preserve the symbol's
   // memory protection by reserving space in the .bss.rel.ro section.
   bool IsReadOnly = isReadOnly<ELFT>(SS);
-  BssRelSection<ELFT> *RelSec = IsReadOnly ? In<ELFT>::BssRelRo : In<ELFT>::Bss;
-  uintX_t Off = RelSec->addCopyRelocation(SS->getAlignment<ELFT>(), SymSize);
+  OutputSection *OSec = IsReadOnly ? Out::BssRelRo : Out::Bss;
+
+  // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc.
+  auto *ISec =
+      make<CopyRelSection<ELFT>>(IsReadOnly, SS->getAlignment<ELFT>(), SymSize);
+  OSec->addSection(ISec);
 
   // Look through the DSO's dynamic symbol table for aliases and create a
   // dynamic symbol for each one. This causes the copy relocation to correctly
   // interpose any aliases.
   for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
+    Sym->NeedsCopy = true;
+    Sym->Section = ISec;
     Sym->symbol()->IsUsedInRegularObj = true;
-    replaceBody<DefinedRegular>(Sym->symbol(), Sym->getName(),
-                                /*IsLocal=*/false, Sym->StOther, Sym->Type, Off,
-                                Sym->getSize<ELFT>(), RelSec, nullptr);
   }
 
-  In<ELFT>::RelaDyn->addReloc({Target->CopyRel, RelSec, Off, false, SS, 0});
+  In<ELFT>::RelaDyn->addReloc({Target->CopyRel, ISec, 0, false, SS, 0});
 }
 
 template <class ELFT>
@@ -532,12 +535,14 @@ static RelExpr adjustExpr(const elf::Obj
   if (Body.isObject()) {
     // Produce a copy relocation.
     auto *B = cast<SharedSymbol>(&Body);
-    if (Config->ZNocopyreloc)
-      error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " +
-            toString(Type) + " against symbol '" + toString(*B) +
-            "'; recompile with -fPIC or remove '-z nocopyreloc'");
+    if (!B->NeedsCopy) {
+      if (Config->ZNocopyreloc)
+        error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " +
+              toString(Type) + " against symbol '" + toString(*B) +
+              "'; recompile with -fPIC or remove '-z nocopyreloc'");
 
-    addCopyRelSymbol<ELFT>(B);
+      addCopyRelSymbol<ELFT>(B);
+    }
     return Expr;
   }
   if (Body.isFunc()) {

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Wed Mar  8 11:24:24 2017
@@ -112,10 +112,14 @@ static typename ELFT::uint getSymVA(cons
       return 0;
     return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
            cast<DefinedCommon>(Body).Offset;
-  case SymbolBody::SharedKind:
-    if (cast<SharedSymbol>(Body).NeedsPltAddr)
+  case SymbolBody::SharedKind: {
+    auto &SS = cast<SharedSymbol>(Body);
+    if (SS.NeedsCopy)
+      return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
+    if (SS.NeedsPltAddr)
       return Body.getPltVA<ELFT>();
     return 0;
+  }
   case SymbolBody::UndefinedKind:
     return 0;
   case SymbolBody::LazyArchiveKind:
@@ -128,7 +132,7 @@ static typename ELFT::uint getSymVA(cons
 
 SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
                        uint8_t Type)
-    : SymbolKind(K), NeedsPltAddr(false), IsLocal(IsLocal),
+    : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal),
       IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
       IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
 
@@ -139,9 +143,10 @@ bool SymbolBody::isPreemptible() const {
     return false;
 
   // Shared symbols resolve to the definition in the DSO. The exceptions are
-  // symbols that needs plt entries (which resolve to that plt entry).
+  // symbols with copy relocations (which resolve to .bss) or preempt plt
+  // entries (which resolve to that plt entry).
   if (isShared())
-    return !NeedsPltAddr;
+    return !NeedsCopy && !NeedsPltAddr;
 
   // That's all that can be preempted in a non-DSO.
   if (!Config->Shared)
@@ -210,8 +215,11 @@ const OutputSection *SymbolBody::getOutp
     return nullptr;
   }
 
-  if (isa<SharedSymbol>(this))
+  if (auto *S = dyn_cast<SharedSymbol>(this)) {
+    if (S->NeedsCopy)
+      return S->Section->OutSec;
     return nullptr;
+  }
 
   if (isa<DefinedCommon>(this)) {
     if (Config->DefineCommon)

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Wed Mar  8 11:24:24 2017
@@ -102,6 +102,10 @@ protected:
   const unsigned SymbolKind : 8;
 
 public:
+  // True if the linker has to generate a copy relocation.
+  // For SharedSymbol only.
+  unsigned NeedsCopy : 1;
+
   // True the symbol should point to its PLT entry.
   // For SharedSymbol only.
   unsigned NeedsPltAddr : 1;
@@ -266,6 +270,9 @@ public:
   // This field is a pointer to the symbol's version definition.
   const void *Verdef;
 
+  // Section is significant only when NeedsCopy is true.
+  InputSection *Section = nullptr;
+
 private:
   template <class ELFT> const typename ELFT::Sym &getSym() const {
     return *(const typename ELFT::Sym *)ElfSym;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Mar  8 11:24:24 2017
@@ -377,17 +377,10 @@ void BuildIdSection<ELFT>::computeHash(
 }
 
 template <class ELFT>
-BssRelSection<ELFT>::BssRelSection(bool RelRo)
-    : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0,
-                       RelRo ? ".bss.rel.ro" : ".bss"),
-      Size(0) {}
-
-template <class ELFT>
-size_t BssRelSection<ELFT>::addCopyRelocation(uintX_t AddrAlign, size_t Size) {
-  OutSec->updateAlignment(AddrAlign);
-  this->Size = alignTo(this->Size, AddrAlign) + Size;
-  return this->Size - Size;
-}
+CopyRelSection<ELFT>::CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t S)
+    : SyntheticSection(SHF_ALLOC, SHT_NOBITS, AddrAlign,
+                       ReadOnly ? ".bss.rel.ro" : ".bss"),
+      Size(S) {}
 
 template <class ELFT>
 void BuildIdSection<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
@@ -2311,10 +2304,10 @@ template class elf::BuildIdSection<ELF32
 template class elf::BuildIdSection<ELF64LE>;
 template class elf::BuildIdSection<ELF64BE>;
 
-template class elf::BssRelSection<ELF32LE>;
-template class elf::BssRelSection<ELF32BE>;
-template class elf::BssRelSection<ELF64LE>;
-template class elf::BssRelSection<ELF64BE>;
+template class elf::CopyRelSection<ELF32LE>;
+template class elf::CopyRelSection<ELF32BE>;
+template class elf::CopyRelSection<ELF64LE>;
+template class elf::CopyRelSection<ELF64BE>;
 
 template class elf::GotSection<ELF32LE>;
 template class elf::GotSection<ELF32BE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Wed Mar  8 11:24:24 2017
@@ -152,16 +152,14 @@ private:
   uint8_t *HashBuf;
 };
 
-// Section used for storing copy relocations. We create two sections now,
-// .bss.rel.ro for RelRo case and .bss for regular case.
-template <class ELFT> class BssRelSection final : public SyntheticSection {
+// For each copy relocation, we create an instance of this class to
+// reserve space in .bss or .bss.rel.ro.
+template <class ELFT> class CopyRelSection final : public SyntheticSection {
   typedef typename ELFT::uint uintX_t;
 
 public:
-  BssRelSection(bool RelRo);
+  CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t Size);
   void writeTo(uint8_t *) override {}
-  bool empty() const override { return getSize() == 0; }
-  size_t addCopyRelocation(uintX_t AddrAlign, size_t Size);
   size_t getSize() const override { return Size; }
   size_t Size;
 };
@@ -764,8 +762,6 @@ SymbolBody *addSyntheticLocal(StringRef
 template <class ELFT> struct In {
   static InputSection *ARMAttributes;
   static BuildIdSection<ELFT> *BuildId;
-  static BssRelSection<ELFT> *Bss;
-  static BssRelSection<ELFT> *BssRelRo;
   static InputSection *Common;
   static DynamicSection<ELFT> *Dynamic;
   static StringTableSection<ELFT> *DynStrTab;
@@ -795,8 +791,6 @@ template <class ELFT> struct In {
 };
 
 template <class ELFT> InputSection *In<ELFT>::ARMAttributes;
-template <class ELFT> BssRelSection<ELFT> *In<ELFT>::Bss;
-template <class ELFT> BssRelSection<ELFT> *In<ELFT>::BssRelRo;
 template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
 template <class ELFT> InputSection *In<ELFT>::Common;
 template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=297297&r1=297296&r2=297297&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Mar  8 11:24:24 2017
@@ -111,8 +111,8 @@ StringRef elf::getOutputSectionName(Stri
   }
 
   for (StringRef V :
-       {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
-        ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
+       {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.",
+        ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
         ".gcc_except_table.", ".tdata.", ".ARM.exidx."}) {
     StringRef Prefix = V.drop_back();
     if (Name.startswith(V) || Name == Prefix)
@@ -309,6 +309,10 @@ template <class ELFT> void Writer<ELFT>:
 
   auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
 
+  // Create singleton output sections.
+  Out::Bss = make<OutputSection>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
+  Out::BssRelRo =
+      make<OutputSection>(".bss.rel.ro", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
   In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
   In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
   In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
@@ -346,11 +350,6 @@ template <class ELFT> void Writer<ELFT>:
     Add(Common);
   }
 
-  In<ELFT>::Bss = make<BssRelSection<ELFT>>(false /*RelRo*/);
-  Add(In<ELFT>::Bss);
-  In<ELFT>::BssRelRo = make<BssRelSection<ELFT>>(true /*RelRo*/);
-  Add(In<ELFT>::BssRelRo);
-
   // Add MIPS-specific sections.
   bool HasDynSymTab =
       !Symtab<ELFT>::X->getSharedFiles().empty() || Config->pic() ||
@@ -596,7 +595,7 @@ template <class ELFT> bool elf::isRelroS
     return true;
   if (In<ELFT>::Got && Sec == In<ELFT>::Got->OutSec)
     return true;
-  if (Sec == In<ELFT>::BssRelRo->OutSec)
+  if (Sec == Out::BssRelRo)
     return true;
 
   StringRef S = Sec->Name;
@@ -1150,15 +1149,14 @@ template <class ELFT> void Writer<ELFT>:
   // Dynamic section must be the last one in this list and dynamic
   // symbol table section (DynSymTab) must be the first one.
   applySynthetic<ELFT>(
-      {In<ELFT>::DynSymTab,  In<ELFT>::Bss,      In<ELFT>::BssRelRo,
-       In<ELFT>::GnuHashTab, In<ELFT>::HashTab,  In<ELFT>::SymTab,
-       In<ELFT>::ShStrTab,   In<ELFT>::StrTab,   In<ELFT>::VerDef,
-       In<ELFT>::DynStrTab,  In<ELFT>::GdbIndex, In<ELFT>::Got,
-       In<ELFT>::MipsGot,    In<ELFT>::IgotPlt,  In<ELFT>::GotPlt,
-       In<ELFT>::RelaDyn,    In<ELFT>::RelaIplt, In<ELFT>::RelaPlt,
-       In<ELFT>::Plt,        In<ELFT>::Iplt,     In<ELFT>::Plt,
-       In<ELFT>::EhFrameHdr, In<ELFT>::VerSym,   In<ELFT>::VerNeed,
-       In<ELFT>::Dynamic},
+      {In<ELFT>::DynSymTab, In<ELFT>::GnuHashTab, In<ELFT>::HashTab,
+       In<ELFT>::SymTab,    In<ELFT>::ShStrTab,   In<ELFT>::StrTab,
+       In<ELFT>::VerDef,    In<ELFT>::DynStrTab,  In<ELFT>::GdbIndex,
+       In<ELFT>::Got,       In<ELFT>::MipsGot,    In<ELFT>::IgotPlt,
+       In<ELFT>::GotPlt,    In<ELFT>::RelaDyn,    In<ELFT>::RelaIplt,
+       In<ELFT>::RelaPlt,   In<ELFT>::Plt,        In<ELFT>::Iplt,
+       In<ELFT>::Plt,       In<ELFT>::EhFrameHdr, In<ELFT>::VerSym,
+       In<ELFT>::VerNeed,   In<ELFT>::Dynamic},
       [](SyntheticSection *SS) { SS->finalizeContents(); });
 
   // Some architectures use small displacements for jump instructions.
@@ -1187,6 +1185,16 @@ template <class ELFT> void Writer<ELFT>:
 }
 
 template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
+  // Add BSS sections.
+  auto Add = [=](OutputSection *Sec) {
+    if (!Sec->Sections.empty()) {
+      Sec->assignOffsets<ELFT>();
+      OutputSections.push_back(Sec);
+    }
+  };
+  Add(Out::Bss);
+  Add(Out::BssRelRo);
+
   // ARM ABI requires .ARM.exidx to be terminated by some piece of data.
   // We have the terminater synthetic section class. Add that at the end.
   auto *OS = dyn_cast_or_null<OutputSection>(findSection(".ARM.exidx"));




More information about the llvm-commits mailing list