[lld] r286950 - [ELF] Convert DynamicSection to input section.

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 15 04:26:56 PST 2016


Author: evgeny777
Date: Tue Nov 15 06:26:55 2016
New Revision: 286950

URL: http://llvm.org/viewvc/llvm-project?rev=286950&view=rev
Log:
[ELF] Convert DynamicSection to input section.

This patch introduces the following changes:
- DynamicSection now inherits InputSection<ELFT> and was moved
  to SyntheticSections.h/.cpp.
- Link and Entsize fields of DynamicSection are propagated to 
  its output section
- In<ELFT>::SyntheticSections was removed.
- Finalization of synthetic sections was removed from 
  OutputSection<ELFT>::finalize. Now finalizeSyntheticSections is
  used instead.

Differential revision: https://reviews.llvm.org/D26603

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

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Tue Nov 15 06:26:55 2016
@@ -395,177 +395,6 @@ void GnuHashTableSection<ELFT>::addSymbo
 static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
 
 template <class ELFT>
-DynamicSection<ELFT>::DynamicSection()
-    : OutputSectionBase(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE) {
-  this->Addralign = sizeof(uintX_t);
-  this->Entsize = ELFT::Is64Bits ? 16 : 8;
-
-  // .dynamic section is not writable on MIPS.
-  // See "Special Section" in Chapter 4 in the following document:
-  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-  if (Config->EMachine == EM_MIPS)
-    this->Flags = SHF_ALLOC;
-
-  addEntries();
-}
-
-// There are some dynamic entries that don't depend on other sections.
-// Such entries can be set early.
-template <class ELFT> void DynamicSection<ELFT>::addEntries() {
-  // Add strings to .dynstr early so that .dynstr's size will be
-  // fixed early.
-  for (StringRef S : Config->AuxiliaryList)
-    Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)});
-  if (!Config->RPath.empty())
-    Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
-         In<ELFT>::DynStrTab->addString(Config->RPath)});
-  for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
-    if (F->isNeeded())
-      Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())});
-  if (!Config->SoName.empty())
-    Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)});
-
-  // Set DT_FLAGS and DT_FLAGS_1.
-  uint32_t DtFlags = 0;
-  uint32_t DtFlags1 = 0;
-  if (Config->Bsymbolic)
-    DtFlags |= DF_SYMBOLIC;
-  if (Config->ZNodelete)
-    DtFlags1 |= DF_1_NODELETE;
-  if (Config->ZNow) {
-    DtFlags |= DF_BIND_NOW;
-    DtFlags1 |= DF_1_NOW;
-  }
-  if (Config->ZOrigin) {
-    DtFlags |= DF_ORIGIN;
-    DtFlags1 |= DF_1_ORIGIN;
-  }
-
-  if (DtFlags)
-    Add({DT_FLAGS, DtFlags});
-  if (DtFlags1)
-    Add({DT_FLAGS_1, DtFlags1});
-
-  if (!Config->Entry.empty())
-    Add({DT_DEBUG, (uint64_t)0});
-}
-
-// Add remaining entries to complete .dynamic contents.
-template <class ELFT> void DynamicSection<ELFT>::finalize() {
-  if (this->Size)
-    return; // Already finalized.
-
-  this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
-
-  if (Out<ELFT>::RelaDyn->hasRelocs()) {
-    bool IsRela = Config->Rela;
-    Add({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
-    Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->Size});
-    Add({IsRela ? DT_RELAENT : DT_RELENT,
-         uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
-
-    // MIPS dynamic loader does not support RELCOUNT tag.
-    // The problem is in the tight relation between dynamic
-    // relocations and GOT. So do not emit this tag on MIPS.
-    if (Config->EMachine != EM_MIPS) {
-      size_t NumRelativeRels = Out<ELFT>::RelaDyn->getRelativeRelocCount();
-      if (Config->ZCombreloc && NumRelativeRels)
-        Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
-    }
-  }
-  if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
-    Add({DT_JMPREL, Out<ELFT>::RelaPlt});
-    Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});
-    Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
-         In<ELFT>::GotPlt});
-    Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
-  }
-
-  Add({DT_SYMTAB, Out<ELFT>::DynSymTab});
-  Add({DT_SYMENT, sizeof(Elf_Sym)});
-  Add({DT_STRTAB, In<ELFT>::DynStrTab});
-  Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
-  if (Out<ELFT>::GnuHashTab)
-    Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab});
-  if (Out<ELFT>::HashTab)
-    Add({DT_HASH, Out<ELFT>::HashTab});
-
-  if (Out<ELFT>::PreinitArray) {
-    Add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray});
-    Add({DT_PREINIT_ARRAYSZ, Out<ELFT>::PreinitArray, Entry::SecSize});
-  }
-  if (Out<ELFT>::InitArray) {
-    Add({DT_INIT_ARRAY, Out<ELFT>::InitArray});
-    Add({DT_INIT_ARRAYSZ, Out<ELFT>::InitArray, Entry::SecSize});
-  }
-  if (Out<ELFT>::FiniArray) {
-    Add({DT_FINI_ARRAY, Out<ELFT>::FiniArray});
-    Add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize});
-  }
-
-  if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init))
-    Add({DT_INIT, B});
-  if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
-    Add({DT_FINI, B});
-
-  bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0;
-  if (HasVerNeed || Out<ELFT>::VerDef)
-    Add({DT_VERSYM, Out<ELFT>::VerSym});
-  if (Out<ELFT>::VerDef) {
-    Add({DT_VERDEF, Out<ELFT>::VerDef});
-    Add({DT_VERDEFNUM, getVerDefNum()});
-  }
-  if (HasVerNeed) {
-    Add({DT_VERNEED, Out<ELFT>::VerNeed});
-    Add({DT_VERNEEDNUM, Out<ELFT>::VerNeed->getNeedNum()});
-  }
-
-  if (Config->EMachine == EM_MIPS) {
-    Add({DT_MIPS_RLD_VERSION, 1});
-    Add({DT_MIPS_FLAGS, RHF_NOTPOT});
-    Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
-    Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()});
-    Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::Got->getMipsLocalEntriesNum()});
-    if (const SymbolBody *B = In<ELFT>::Got->getMipsFirstGlobalEntry())
-      Add({DT_MIPS_GOTSYM, B->DynsymIndex});
-    else
-      Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()});
-    Add({DT_PLTGOT, In<ELFT>::Got});
-    if (Out<ELFT>::MipsRldMap)
-      Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap});
-  }
-
-  // +1 for DT_NULL
-  this->Size = (Entries.size() + 1) * this->Entsize;
-}
-
-template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
-  auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
-
-  for (const Entry &E : Entries) {
-    P->d_tag = E.Tag;
-    switch (E.Kind) {
-    case Entry::SecAddr:
-      P->d_un.d_ptr = E.OutSec->Addr;
-      break;
-    case Entry::InSecAddr:
-      P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
-      break;
-    case Entry::SecSize:
-      P->d_un.d_val = E.OutSec->Size;
-      break;
-    case Entry::SymAddr:
-      P->d_un.d_ptr = E.Sym->template getVA<ELFT>();
-      break;
-    case Entry::PlainInt:
-      P->d_un.d_val = E.Val;
-      break;
-    }
-    ++P;
-  }
-}
-
-template <class ELFT>
 EhFrameHeader<ELFT>::EhFrameHeader()
     : OutputSectionBase(".eh_frame_hdr", SHT_PROGBITS, SHF_ALLOC) {}
 
@@ -650,14 +479,6 @@ template <class ELFT> void OutputSection
     }
   }
 
-  // Recalculate input section offsets if we own any synthetic section
-  for (auto *SS : In<ELFT>::SyntheticSections)
-    if (SS && this == SS->OutSec) {
-      this->Size = 0;
-      assignOffsets();
-      break;
-    }
-
   if (Type != SHT_RELA && Type != SHT_REL)
     return;
   this->Link = Out<ELFT>::SymTab->SectionIndex;
@@ -1544,11 +1365,6 @@ template class HashTableSection<ELF32BE>
 template class HashTableSection<ELF64LE>;
 template class HashTableSection<ELF64BE>;
 
-template class DynamicSection<ELF32LE>;
-template class DynamicSection<ELF32BE>;
-template class DynamicSection<ELF64LE>;
-template class DynamicSection<ELF64BE>;
-
 template class OutputSection<ELF32LE>;
 template class OutputSection<ELF32BE>;
 template class OutputSection<ELF64LE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Tue Nov 15 06:26:55 2016
@@ -45,7 +45,6 @@ class OutputSectionBase {
 public:
   enum Kind {
     Base,
-    Dynamic,
     EHFrame,
     EHFrameHdr,
     GnuHashTable,
@@ -478,55 +477,6 @@ private:
   unsigned Shift2;
 };
 
-template <class ELFT> class DynamicSection final : public OutputSectionBase {
-  typedef typename ELFT::Dyn Elf_Dyn;
-  typedef typename ELFT::Rel Elf_Rel;
-  typedef typename ELFT::Rela Elf_Rela;
-  typedef typename ELFT::Shdr Elf_Shdr;
-  typedef typename ELFT::Sym Elf_Sym;
-  typedef typename ELFT::uint uintX_t;
-
-  // The .dynamic section contains information for the dynamic linker.
-  // The section consists of fixed size entries, which consist of
-  // type and value fields. Value are one of plain integers, symbol
-  // addresses, or section addresses. This struct represents the entry.
-  struct Entry {
-    int32_t Tag;
-    union {
-      OutputSectionBase *OutSec;
-      InputSection<ELFT> *InSec;
-      uint64_t Val;
-      const SymbolBody *Sym;
-    };
-    enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
-    Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
-        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
-    Entry(int32_t Tag, InputSection<ELFT> *Sec)
-        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
-    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
-    Entry(int32_t Tag, const SymbolBody *Sym)
-        : Tag(Tag), Sym(Sym), Kind(SymAddr) {}
-  };
-
-  // finalize() fills this vector with the section contents. finalize()
-  // cannot directly create final section contents because when the
-  // function is called, symbol or section addresses are not fixed yet.
-  std::vector<Entry> Entries;
-
-public:
-  DynamicSection();
-  void finalize() override;
-  void writeTo(uint8_t *Buf) override;
-  Kind getKind() const override { return Dynamic; }
-  static bool classof(const OutputSectionBase *B) {
-    return B->getKind() == Dynamic;
-  }
-
-private:
-  void addEntries();
-  void Add(Entry E) { Entries.push_back(E); }
-};
-
 // --eh-frame-hdr option tells linker to construct a header for all the
 // .eh_frame sections. This header is placed to a section named .eh_frame_hdr
 // and also to a PT_GNU_EH_FRAME segment.
@@ -566,7 +516,6 @@ template <class ELFT> struct Out {
   typedef typename ELFT::Phdr Elf_Phdr;
 
   static uint8_t First;
-  static DynamicSection<ELFT> *Dynamic;
   static EhFrameHeader<ELFT> *EhFrameHdr;
   static EhOutputSection<ELFT> *EhFrame;
   static GdbIndexSection<ELFT> *GdbIndex;
@@ -627,7 +576,6 @@ template <class ELFT> uint64_t getHeader
 }
 
 template <class ELFT> uint8_t Out<ELFT>::First;
-template <class ELFT> DynamicSection<ELFT> *Out<ELFT>::Dynamic;
 template <class ELFT> EhFrameHeader<ELFT> *Out<ELFT>::EhFrameHdr;
 template <class ELFT> EhOutputSection<ELFT> *Out<ELFT>::EhFrame;
 template <class ELFT> GdbIndexSection<ELFT> *Out<ELFT>::GdbIndex;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Tue Nov 15 06:26:55 2016
@@ -673,6 +673,181 @@ template <class ELFT> void StringTableSe
   }
 }
 
+static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
+
+template <class ELFT>
+DynamicSection<ELFT>::DynamicSection()
+    : SyntheticSection<ELFT>(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC,
+                             sizeof(uintX_t), ".dynamic") {
+  this->Entsize = ELFT::Is64Bits ? 16 : 8;
+  // .dynamic section is not writable on MIPS.
+  // See "Special Section" in Chapter 4 in the following document:
+  // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
+  if (Config->EMachine == EM_MIPS)
+    this->Flags = SHF_ALLOC;
+
+  addEntries();
+}
+
+// There are some dynamic entries that don't depend on other sections.
+// Such entries can be set early.
+template <class ELFT> void DynamicSection<ELFT>::addEntries() {
+  // Add strings to .dynstr early so that .dynstr's size will be
+  // fixed early.
+  for (StringRef S : Config->AuxiliaryList)
+    Add({DT_AUXILIARY, In<ELFT>::DynStrTab->addString(S)});
+  if (!Config->RPath.empty())
+    Add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
+         In<ELFT>::DynStrTab->addString(Config->RPath)});
+  for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
+    if (F->isNeeded())
+      Add({DT_NEEDED, In<ELFT>::DynStrTab->addString(F->getSoName())});
+  if (!Config->SoName.empty())
+    Add({DT_SONAME, In<ELFT>::DynStrTab->addString(Config->SoName)});
+
+  // Set DT_FLAGS and DT_FLAGS_1.
+  uint32_t DtFlags = 0;
+  uint32_t DtFlags1 = 0;
+  if (Config->Bsymbolic)
+    DtFlags |= DF_SYMBOLIC;
+  if (Config->ZNodelete)
+    DtFlags1 |= DF_1_NODELETE;
+  if (Config->ZNow) {
+    DtFlags |= DF_BIND_NOW;
+    DtFlags1 |= DF_1_NOW;
+  }
+  if (Config->ZOrigin) {
+    DtFlags |= DF_ORIGIN;
+    DtFlags1 |= DF_1_ORIGIN;
+  }
+
+  if (DtFlags)
+    Add({DT_FLAGS, DtFlags});
+  if (DtFlags1)
+    Add({DT_FLAGS_1, DtFlags1});
+
+  if (!Config->Entry.empty())
+    Add({DT_DEBUG, (uint64_t)0});
+}
+
+// Add remaining entries to complete .dynamic contents.
+template <class ELFT> void DynamicSection<ELFT>::finalize() {
+  if (this->Size)
+    return; // Already finalized.
+
+  this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
+
+  if (Out<ELFT>::RelaDyn->hasRelocs()) {
+    bool IsRela = Config->Rela;
+    Add({IsRela ? DT_RELA : DT_REL, Out<ELFT>::RelaDyn});
+    Add({IsRela ? DT_RELASZ : DT_RELSZ, Out<ELFT>::RelaDyn->Size});
+    Add({IsRela ? DT_RELAENT : DT_RELENT,
+         uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
+
+    // MIPS dynamic loader does not support RELCOUNT tag.
+    // The problem is in the tight relation between dynamic
+    // relocations and GOT. So do not emit this tag on MIPS.
+    if (Config->EMachine != EM_MIPS) {
+      size_t NumRelativeRels = Out<ELFT>::RelaDyn->getRelativeRelocCount();
+      if (Config->ZCombreloc && NumRelativeRels)
+        Add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
+    }
+  }
+  if (Out<ELFT>::RelaPlt && Out<ELFT>::RelaPlt->hasRelocs()) {
+    Add({DT_JMPREL, Out<ELFT>::RelaPlt});
+    Add({DT_PLTRELSZ, Out<ELFT>::RelaPlt->Size});
+    Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
+         In<ELFT>::GotPlt});
+    Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
+  }
+
+  Add({DT_SYMTAB, Out<ELFT>::DynSymTab});
+  Add({DT_SYMENT, sizeof(Elf_Sym)});
+  Add({DT_STRTAB, In<ELFT>::DynStrTab});
+  Add({DT_STRSZ, In<ELFT>::DynStrTab->getSize()});
+  if (Out<ELFT>::GnuHashTab)
+    Add({DT_GNU_HASH, Out<ELFT>::GnuHashTab});
+  if (Out<ELFT>::HashTab)
+    Add({DT_HASH, Out<ELFT>::HashTab});
+
+  if (Out<ELFT>::PreinitArray) {
+    Add({DT_PREINIT_ARRAY, Out<ELFT>::PreinitArray});
+    Add({DT_PREINIT_ARRAYSZ, Out<ELFT>::PreinitArray, Entry::SecSize});
+  }
+  if (Out<ELFT>::InitArray) {
+    Add({DT_INIT_ARRAY, Out<ELFT>::InitArray});
+    Add({DT_INIT_ARRAYSZ, Out<ELFT>::InitArray, Entry::SecSize});
+  }
+  if (Out<ELFT>::FiniArray) {
+    Add({DT_FINI_ARRAY, Out<ELFT>::FiniArray});
+    Add({DT_FINI_ARRAYSZ, Out<ELFT>::FiniArray, Entry::SecSize});
+  }
+
+  if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Init))
+    Add({DT_INIT, B});
+  if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Fini))
+    Add({DT_FINI, B});
+
+  bool HasVerNeed = Out<ELFT>::VerNeed->getNeedNum() != 0;
+  if (HasVerNeed || Out<ELFT>::VerDef)
+    Add({DT_VERSYM, Out<ELFT>::VerSym});
+  if (Out<ELFT>::VerDef) {
+    Add({DT_VERDEF, Out<ELFT>::VerDef});
+    Add({DT_VERDEFNUM, getVerDefNum()});
+  }
+  if (HasVerNeed) {
+    Add({DT_VERNEED, Out<ELFT>::VerNeed});
+    Add({DT_VERNEEDNUM, Out<ELFT>::VerNeed->getNeedNum()});
+  }
+
+  if (Config->EMachine == EM_MIPS) {
+    Add({DT_MIPS_RLD_VERSION, 1});
+    Add({DT_MIPS_FLAGS, RHF_NOTPOT});
+    Add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
+    Add({DT_MIPS_SYMTABNO, Out<ELFT>::DynSymTab->getNumSymbols()});
+    Add({DT_MIPS_LOCAL_GOTNO, In<ELFT>::Got->getMipsLocalEntriesNum()});
+    if (const SymbolBody *B = In<ELFT>::Got->getMipsFirstGlobalEntry())
+      Add({DT_MIPS_GOTSYM, B->DynsymIndex});
+    else
+      Add({DT_MIPS_GOTSYM, Out<ELFT>::DynSymTab->getNumSymbols()});
+    Add({DT_PLTGOT, In<ELFT>::Got});
+    if (Out<ELFT>::MipsRldMap)
+      Add({DT_MIPS_RLD_MAP, Out<ELFT>::MipsRldMap});
+  }
+
+  this->OutSec->Entsize = this->Entsize;
+  this->OutSec->Link = this->Link;
+
+  // +1 for DT_NULL
+  this->Size = (Entries.size() + 1) * this->Entsize;
+}
+
+template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
+  auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
+
+  for (const Entry &E : Entries) {
+    P->d_tag = E.Tag;
+    switch (E.Kind) {
+    case Entry::SecAddr:
+      P->d_un.d_ptr = E.OutSec->Addr;
+      break;
+    case Entry::InSecAddr:
+      P->d_un.d_ptr = E.InSec->OutSec->Addr + E.InSec->OutSecOff;
+      break;
+    case Entry::SecSize:
+      P->d_un.d_val = E.OutSec->Size;
+      break;
+    case Entry::SymAddr:
+      P->d_un.d_ptr = E.Sym->template getVA<ELFT>();
+      break;
+    case Entry::PlainInt:
+      P->d_un.d_val = E.Val;
+      break;
+    }
+    ++P;
+  }
+}
+
 template InputSection<ELF32LE> *elf::createCommonSection();
 template InputSection<ELF32BE> *elf::createCommonSection();
 template InputSection<ELF64LE> *elf::createCommonSection();
@@ -747,3 +922,8 @@ template class elf::StringTableSection<E
 template class elf::StringTableSection<ELF32BE>;
 template class elf::StringTableSection<ELF64LE>;
 template class elf::StringTableSection<ELF64BE>;
+
+template class elf::DynamicSection<ELF32LE>;
+template class elf::DynamicSection<ELF32BE>;
+template class elf::DynamicSection<ELF64LE>;
+template class elf::DynamicSection<ELF64BE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Tue Nov 15 06:26:55 2016
@@ -72,6 +72,7 @@ public:
 
   virtual void writeTo(uint8_t *Buf) = 0;
   virtual size_t getSize() const { return this->Data.size(); }
+  virtual void finalize() {}
   uintX_t getVA() const {
     return this->OutSec ? this->OutSec->Addr + this->OutSecOff : 0;
   }
@@ -144,7 +145,7 @@ public:
   GotSection();
   void writeTo(uint8_t *Buf) override;
   size_t getSize() const override { return Size; }
-  void finalize();
+  void finalize() override;
   void addEntry(SymbolBody &Sym);
   void addMipsEntry(SymbolBody &Sym, uintX_t Addend, RelExpr Expr);
   bool addDynTlsEntry(SymbolBody &Sym);
@@ -238,6 +239,54 @@ private:
   std::vector<StringRef> Strings;
 };
 
+template <class ELFT>
+class DynamicSection final : public SyntheticSection<ELFT> {
+  typedef typename ELFT::Dyn Elf_Dyn;
+  typedef typename ELFT::Rel Elf_Rel;
+  typedef typename ELFT::Rela Elf_Rela;
+  typedef typename ELFT::Shdr Elf_Shdr;
+  typedef typename ELFT::Sym Elf_Sym;
+  typedef typename ELFT::uint uintX_t;
+
+  // The .dynamic section contains information for the dynamic linker.
+  // The section consists of fixed size entries, which consist of
+  // type and value fields. Value are one of plain integers, symbol
+  // addresses, or section addresses. This struct represents the entry.
+  struct Entry {
+    int32_t Tag;
+    union {
+      OutputSectionBase *OutSec;
+      InputSection<ELFT> *InSec;
+      uint64_t Val;
+      const SymbolBody *Sym;
+    };
+    enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
+    Entry(int32_t Tag, OutputSectionBase *OutSec, KindT Kind = SecAddr)
+        : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
+    Entry(int32_t Tag, InputSection<ELFT> *Sec)
+        : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
+    Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
+    Entry(int32_t Tag, const SymbolBody *Sym)
+        : Tag(Tag), Sym(Sym), Kind(SymAddr) {}
+  };
+
+  // finalize() fills this vector with the section contents. finalize()
+  // cannot directly create final section contents because when the
+  // function is called, symbol or section addresses are not fixed yet.
+  std::vector<Entry> Entries;
+
+public:
+  DynamicSection();
+  void finalize() override;
+  void writeTo(uint8_t *Buf) override;
+  size_t getSize() const override { return Size; }
+
+private:
+  void addEntries();
+  void Add(Entry E) { Entries.push_back(E); }
+  uintX_t Size = 0;
+};
+
 template <class ELFT> InputSection<ELFT> *createCommonSection();
 template <class ELFT> InputSection<ELFT> *createInterpSection();
 template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
@@ -246,6 +295,7 @@ template <class ELFT> MergeInputSection<
 template <class ELFT> struct In {
   static BuildIdSection<ELFT> *BuildId;
   static InputSection<ELFT> *Common;
+  static DynamicSection<ELFT> *Dynamic;
   static StringTableSection<ELFT> *DynStrTab;
   static GotSection<ELFT> *Got;
   static GotPltSection<ELFT> *GotPlt;
@@ -255,15 +305,11 @@ template <class ELFT> struct In {
   static MipsReginfoSection<ELFT> *MipsReginfo;
   static StringTableSection<ELFT> *ShStrTab;
   static StringTableSection<ELFT> *StrTab;
-
-  // Contains list of sections, which size is not known when
-  // createSections() is called. This list is used when output
-  // sections are being finalized to calculate their size correctly.
-  static std::vector<SyntheticSection<ELFT> *> SyntheticSections;
 };
 
 template <class ELFT> BuildIdSection<ELFT> *In<ELFT>::BuildId;
 template <class ELFT> InputSection<ELFT> *In<ELFT>::Common;
+template <class ELFT> DynamicSection<ELFT> *In<ELFT>::Dynamic;
 template <class ELFT> StringTableSection<ELFT> *In<ELFT>::DynStrTab;
 template <class ELFT> GotSection<ELFT> *In<ELFT>::Got;
 template <class ELFT> GotPltSection<ELFT> *In<ELFT>::GotPlt;
@@ -273,9 +319,6 @@ template <class ELFT> MipsOptionsSection
 template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
 template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;
 template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab;
-template <class ELFT>
-std::vector<SyntheticSection<ELFT> *> In<ELFT>::SyntheticSections;
-
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Nov 15 06:26:55 2016
@@ -356,7 +356,7 @@ RelExpr X86TargetInfo::adjustRelaxExpr(u
 }
 
 void X86TargetInfo::writeGotPltHeader(uint8_t *Buf) const {
-  write32le(Buf, Out<ELF32LE>::Dynamic->Addr);
+  write32le(Buf, In<ELF32LE>::Dynamic->getVA());
 }
 
 void X86TargetInfo::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {
@@ -596,7 +596,7 @@ void X86_64TargetInfo<ELFT>::writeGotPlt
   // required, but it is documented in the psabi and the glibc dynamic linker
   // seems to use it (note that this is relevant for linking ld.so, not any
   // other program).
-  write64le(Buf, Out<ELFT>::Dynamic->Addr);
+  write64le(Buf, In<ELFT>::Dynamic->getVA());
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=286950&r1=286949&r2=286950&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Nov 15 06:26:55 2016
@@ -210,7 +210,7 @@ template <class ELFT> void Writer<ELFT>:
   Out<ELFT>::Bss =
       make<OutputSection<ELFT>>(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
   In<ELFT>::DynStrTab = make<StringTableSection<ELFT>>(".dynstr", true);
-  Out<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
+  In<ELFT>::Dynamic = make<DynamicSection<ELFT>>();
   Out<ELFT>::EhFrame = make<EhOutputSection<ELFT>>();
   Out<ELFT>::Plt = make<PltSection<ELFT>>();
   Out<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
@@ -314,13 +314,6 @@ template <class ELFT> void Writer<ELFT>:
 
   In<ELFT>::Got = make<GotSection<ELFT>>();
   In<ELFT>::GotPlt = make<GotPltSection<ELFT>>();
-
-  // These sections are filled after createSections() is called.
-  // We use this list to fixup size of output sections, when they
-  // are finalized.
-  In<ELFT>::SyntheticSections = {In<ELFT>::ShStrTab, In<ELFT>::StrTab,
-                                 In<ELFT>::DynStrTab, In<ELFT>::Got,
-                                 In<ELFT>::GotPlt};
 }
 
 template <class ELFT>
@@ -434,7 +427,7 @@ template <class ELFT> bool elf::isRelroS
     return true;
   if (Sec == In<ELFT>::GotPlt->OutSec)
     return Config->ZNow;
-  if (Sec == Out<ELFT>::Dynamic || Sec == In<ELFT>::Got->OutSec)
+  if (Sec == In<ELFT>::Dynamic->OutSec || Sec == In<ELFT>::Got->OutSec)
     return true;
   StringRef S = Sec->getName();
   return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
@@ -861,6 +854,17 @@ template <class ELFT> void Writer<ELFT>:
   Script<ELFT>::X->adjustSectionsAfterSorting();
 }
 
+template <class ELFT>
+static void
+finalizeSynthetic(const std::vector<SyntheticSection<ELFT> *> &Sections) {
+  for (SyntheticSection<ELFT> *SS : Sections)
+    if (SS && SS->OutSec) {
+      SS->finalize();
+      SS->OutSec->Size = 0;
+      SS->OutSec->assignOffsets();
+    }
+}
+
 // Create output section objects and add them to OutputSections.
 template <class ELFT> void Writer<ELFT>::finalizeSections() {
   Out<ELFT>::DebugInfo = findSection(".debug_info");
@@ -882,8 +886,7 @@ template <class ELFT> void Writer<ELFT>:
   // Even the author of gold doesn't remember why gold behaves that way.
   // https://sourceware.org/ml/binutils/2002-03/msg00360.html
   if (Out<ELFT>::DynSymTab)
-    Symtab<ELFT>::X->addSynthetic("_DYNAMIC", Out<ELFT>::Dynamic, 0,
-                                  STV_HIDDEN);
+    addRegular("_DYNAMIC", In<ELFT>::Dynamic, 0);
 
   // Define __rel[a]_iplt_{start,end} symbols if needed.
   addRelIpltSymbols();
@@ -940,11 +943,11 @@ template <class ELFT> void Writer<ELFT>:
   // at the end because some tags like RELSZ depend on result
   // of finalizing other sections.
   for (OutputSectionBase *Sec : OutputSections)
-    if (Sec != Out<ELFT>::Dynamic)
-      Sec->finalize();
+    Sec->finalize();
 
-  if (Out<ELFT>::DynSymTab)
-    Out<ELFT>::Dynamic->finalize();
+  finalizeSynthetic<ELFT>({In<ELFT>::ShStrTab, In<ELFT>::StrTab,
+                           In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::GotPlt,
+                           In<ELFT>::Dynamic});
 
   // Now that all output offsets are fixed. Finalize mergeable sections
   // to fix their maps from input offsets to output offsets.
@@ -992,7 +995,7 @@ template <class ELFT> void Writer<ELFT>:
 
     Add(Out<ELFT>::GnuHashTab);
     Add(Out<ELFT>::HashTab);
-    Add(Out<ELFT>::Dynamic);
+    addInputSec(In<ELFT>::Dynamic);
     addInputSec(In<ELFT>::DynStrTab);
     if (Out<ELFT>::RelaDyn->hasRelocs())
       Add(Out<ELFT>::RelaDyn);
@@ -1006,10 +1009,8 @@ template <class ELFT> void Writer<ELFT>:
 
   // We fill .got and .got.plt sections in scanRelocs(). This is the
   // reason we don't add it earlier in createSections().
-  if (needsGot()) {
-    In<ELFT>::Got->finalize();
+  if (needsGot())
     addInputSec(In<ELFT>::Got);
-  }
 
   if (!In<ELFT>::GotPlt->empty())
     addInputSec(In<ELFT>::GotPlt);
@@ -1158,8 +1159,8 @@ template <class ELFT> std::vector<PhdrEn
 
   // Add an entry for .dynamic.
   if (Out<ELFT>::DynSymTab) {
-    Phdr &H = *AddHdr(PT_DYNAMIC, Out<ELFT>::Dynamic->getPhdrFlags());
-    H.add(Out<ELFT>::Dynamic);
+    Phdr &H = *AddHdr(PT_DYNAMIC, In<ELFT>::Dynamic->OutSec->getPhdrFlags());
+    H.add(In<ELFT>::Dynamic->OutSec);
   }
 
   // PT_GNU_RELRO includes all sections that should be marked as




More information about the llvm-commits mailing list