[lld] r287092 - [ELF] Convert RelocationSection to input section

Eugene Leviant via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 16 02:02:27 PST 2016


Author: evgeny777
Date: Wed Nov 16 04:02:27 2016
New Revision: 287092

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

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

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.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=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Nov 16 04:02:27 2016
@@ -104,8 +104,12 @@ template <class ELFT>
 typename ELFT::uint InputSectionBase<ELFT>::getOffset(uintX_t Offset) const {
   switch (kind()) {
   case Regular:
-  case Synthetic:
     return cast<InputSection<ELFT>>(this)->OutSecOff + Offset;
+  case Synthetic:
+    // For synthetic sections we treat offset -1 as the end of the section.
+    // The same approach is used for synthetic symbols (DefinedSynthetic).
+    return cast<InputSection<ELFT>>(this)->OutSecOff +
+           (Offset == uintX_t(-1) ? getSize() : Offset);
   case EHFrame:
     // The file crtbeginT.o has relocations pointing to the start of an empty
     // .eh_frame that is known to be the first in the link. It does that to
@@ -525,6 +529,11 @@ template <class ELFT> void InputSection<
   if (this->Type == SHT_NOBITS)
     return;
 
+  if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) {
+    S->writeTo(Buf);
+    return;
+  }
+
   // If -r is given, then an InputSection may be a relocation section.
   if (this->Type == SHT_RELA) {
     copyRelocations(Buf + OutSecOff, this->template getDataAs<Elf_Rela>());
@@ -535,11 +544,6 @@ template <class ELFT> void InputSection<
     return;
   }
 
-  if (auto *S = dyn_cast<SyntheticSection<ELFT>>(this)) {
-    S->writeTo(Buf);
-    return;
-  }
-
   // Copy section contents from source object file to output file.
   ArrayRef<uint8_t> Data = this->Data;
   memcpy(Buf + OutSecOff, Data.data(), Data.size());

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Nov 16 04:02:27 2016
@@ -132,7 +132,7 @@ template <class ELFT> void PltSection<EL
 
 template <class ELFT> void PltSection<ELFT>::addEntry(SymbolBody &Sym) {
   Sym.PltIndex = Entries.size();
-  unsigned RelOff = Out<ELFT>::RelaPlt->getRelocOffset();
+  unsigned RelOff = In<ELFT>::RelaPlt->getRelocOffset();
   Entries.push_back(std::make_pair(&Sym, RelOff));
 }
 
@@ -141,69 +141,6 @@ template <class ELFT> void PltSection<EL
 }
 
 template <class ELFT>
-RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
-    : OutputSectionBase(Name, Config->Rela ? SHT_RELA : SHT_REL, SHF_ALLOC),
-      Sort(Sort) {
-  this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
-  this->Addralign = sizeof(uintX_t);
-}
-
-template <class ELFT>
-void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
-  if (Reloc.Type == Target->RelativeRel)
-    ++NumRelativeRelocs;
-  Relocs.push_back(Reloc);
-}
-
-template <class ELFT, class RelTy>
-static bool compRelocations(const RelTy &A, const RelTy &B) {
-  bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel;
-  bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel;
-  if (AIsRel != BIsRel)
-    return AIsRel;
-
-  return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL);
-}
-
-template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
-  uint8_t *BufBegin = Buf;
-  for (const DynamicReloc<ELFT> &Rel : Relocs) {
-    auto *P = reinterpret_cast<Elf_Rela *>(Buf);
-    Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
-
-    if (Config->Rela)
-      P->r_addend = Rel.getAddend();
-    P->r_offset = Rel.getOffset();
-    if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::Got)
-      // Dynamic relocation against MIPS GOT section make deal TLS entries
-      // allocated in the end of the GOT. We need to adjust the offset to take
-      // in account 'local' and 'global' GOT entries.
-      P->r_offset += In<ELFT>::Got->getMipsTlsOffset();
-    P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL);
-  }
-
-  if (Sort) {
-    if (Config->Rela)
-      std::stable_sort((Elf_Rela *)BufBegin,
-                       (Elf_Rela *)BufBegin + Relocs.size(),
-                       compRelocations<ELFT, Elf_Rela>);
-    else
-      std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(),
-                       compRelocations<ELFT, Elf_Rel>);
-  }
-}
-
-template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
-  return this->Entsize * Relocs.size();
-}
-
-template <class ELFT> void RelocationSection<ELFT>::finalize() {
-  this->Link = Out<ELFT>::DynSymTab ? Out<ELFT>::DynSymTab->SectionIndex
-                                    : Out<ELFT>::SymTab->SectionIndex;
-  this->Size = Relocs.size() * this->Entsize;
-}
-
-template <class ELFT>
 HashTableSection<ELFT>::HashTableSection()
     : OutputSectionBase(".hash", SHT_HASH, SHF_ALLOC) {
   this->Entsize = sizeof(Elf_Word);
@@ -463,20 +400,21 @@ OutputSection<ELFT>::OutputSection(Strin
 }
 
 template <class ELFT> void OutputSection<ELFT>::finalize() {
+  if (!Config->Relocatable) {
+    // SHF_LINK_ORDER only has meaning in relocatable objects
+    this->Flags &= ~SHF_LINK_ORDER;
+    return;
+  }
+
   uint32_t Type = this->Type;
-  if (this->Flags & SHF_LINK_ORDER) {
-    if (!Config->Relocatable) {
-      // SHF_LINK_ORDER only has meaning in relocatable objects
-      this->Flags &= ~SHF_LINK_ORDER;
-    } else if (!this->Sections.empty()) {
-      // When doing a relocatable link we must preserve the link order
-      // dependency of sections with the SHF_LINK_ORDER flag. The dependency
-      // is indicated by the sh_link field. We need to translate the
-      // InputSection sh_link to the OutputSection sh_link, all InputSections
-      // in the OutputSection have the same dependency.
-      if (auto *D = this->Sections.front()->getLinkOrderDep())
-        this->Link = D->OutSec->SectionIndex;
-    }
+  if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
+    // When doing a relocatable link we must preserve the link order
+    // dependency of sections with the SHF_LINK_ORDER flag. The dependency
+    // is indicated by the sh_link field. We need to translate the
+    // InputSection sh_link to the OutputSection sh_link, all InputSections
+    // in the OutputSection have the same dependency.
+    if (auto *D = this->Sections.front()->getLinkOrderDep())
+      this->Link = D->OutSec->SectionIndex;
   }
 
   if (Type != SHT_RELA && Type != SHT_REL)
@@ -881,26 +819,6 @@ template <class ELFT> void MergeOutputSe
 }
 
 template <class ELFT>
-typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
-  if (OutputSec)
-    return OutputSec->Addr + OffsetInSec;
-  return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec);
-}
-
-template <class ELFT>
-typename ELFT::uint DynamicReloc<ELFT>::getAddend() const {
-  if (UseSymVA)
-    return Sym->getVA<ELFT>(Addend);
-  return Addend;
-}
-
-template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const {
-  if (Sym && !UseSymVA)
-    return Sym->DynsymIndex;
-  return 0;
-}
-
-template <class ELFT>
 SymbolTableSection<ELFT>::SymbolTableSection(
     StringTableSection<ELFT> &StrTabSec)
     : OutputSectionBase(StrTabSec.isDynamic() ? ".dynsym" : ".symtab",
@@ -1350,11 +1268,6 @@ template class PltSection<ELF32BE>;
 template class PltSection<ELF64LE>;
 template class PltSection<ELF64BE>;
 
-template class RelocationSection<ELF32LE>;
-template class RelocationSection<ELF32BE>;
-template class RelocationSection<ELF64LE>;
-template class RelocationSection<ELF64BE>;
-
 template class GnuHashTableSection<ELF32LE>;
 template class GnuHashTableSection<ELF32BE>;
 template class GnuHashTableSection<ELF64LE>;

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Nov 16 04:02:27 2016
@@ -52,7 +52,6 @@ public:
     Merge,
     Plt,
     Regular,
-    Reloc,
     SymTable,
     VersDef,
     VersNeed,
@@ -156,39 +155,6 @@ private:
   std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
 };
 
-template <class ELFT> class DynamicReloc {
-  typedef typename ELFT::uint uintX_t;
-
-public:
-  DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec,
-               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
-               uintX_t Addend)
-      : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
-        UseSymVA(UseSymVA), Addend(Addend) {}
-
-  DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
-               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
-               uintX_t Addend)
-      : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
-        UseSymVA(UseSymVA), Addend(Addend) {}
-
-  uintX_t getOffset() const;
-  uintX_t getAddend() const;
-  uint32_t getSymIndex() const;
-  const OutputSectionBase *getOutputSec() const { return OutputSec; }
-  const InputSectionBase<ELFT> *getInputSec() const { return InputSec; }
-
-  uint32_t Type;
-
-private:
-  SymbolBody *Sym;
-  const InputSectionBase<ELFT> *InputSec = nullptr;
-  const OutputSectionBase *OutputSec = nullptr;
-  uintX_t OffsetInSec;
-  bool UseSymVA;
-  uintX_t Addend;
-};
-
 struct SymbolTableEntry {
   SymbolBody *Symbol;
   size_t StrTabOffset;
@@ -305,30 +271,6 @@ public:
   }
 };
 
-template <class ELFT> class RelocationSection final : public OutputSectionBase {
-  typedef typename ELFT::Rel Elf_Rel;
-  typedef typename ELFT::Rela Elf_Rela;
-  typedef typename ELFT::uint uintX_t;
-
-public:
-  RelocationSection(StringRef Name, bool Sort);
-  void addReloc(const DynamicReloc<ELFT> &Reloc);
-  unsigned getRelocOffset();
-  void finalize() override;
-  void writeTo(uint8_t *Buf) override;
-  bool hasRelocs() const { return !Relocs.empty(); }
-  Kind getKind() const override { return Reloc; }
-  size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
-  static bool classof(const OutputSectionBase *B) {
-    return B->getKind() == Reloc;
-  }
-
-private:
-  bool Sort;
-  size_t NumRelativeRelocs = 0;
-  std::vector<DynamicReloc<ELFT>> Relocs;
-};
-
 template <class ELFT> class OutputSection final : public OutputSectionBase {
 
 public:
@@ -526,8 +468,6 @@ template <class ELFT> struct Out {
   static OutputSectionBase *Opd;
   static uint8_t *OpdBuf;
   static PltSection<ELFT> *Plt;
-  static RelocationSection<ELFT> *RelaDyn;
-  static RelocationSection<ELFT> *RelaPlt;
   static SymbolTableSection<ELFT> *DynSymTab;
   static SymbolTableSection<ELFT> *SymTab;
   static VersionDefinitionSection<ELFT> *VerDef;
@@ -586,8 +526,6 @@ template <class ELFT> OutputSection<ELFT
 template <class ELFT> OutputSectionBase *Out<ELFT>::Opd;
 template <class ELFT> uint8_t *Out<ELFT>::OpdBuf;
 template <class ELFT> PltSection<ELFT> *Out<ELFT>::Plt;
-template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaDyn;
-template <class ELFT> RelocationSection<ELFT> *Out<ELFT>::RelaPlt;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::DynSymTab;
 template <class ELFT> SymbolTableSection<ELFT> *Out<ELFT>::SymTab;
 template <class ELFT> VersionDefinitionSection<ELFT> *Out<ELFT>::VerDef;

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Nov 16 04:02:27 2016
@@ -103,9 +103,9 @@ static unsigned handleNoRelaxTlsRelocati
   if (Expr == R_MIPS_TLSLD || Expr == R_TLSLD_PC) {
     if (In<ELFT>::Got->addTlsIndex() &&
         (Config->Pic || Config->EMachine == EM_ARM))
-      Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
-                                    In<ELFT>::Got->getTlsIndexOff(), false,
-                                    nullptr, 0});
+      In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
+                                   In<ELFT>::Got->getTlsIndexOff(), false,
+                                   nullptr, 0});
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
     return 1;
   }
@@ -114,12 +114,12 @@ static unsigned handleNoRelaxTlsRelocati
     if (In<ELFT>::Got->addDynTlsEntry(Body) &&
         (Body.isPreemptible() || Config->EMachine == EM_ARM)) {
       uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
-      Out<ELFT>::RelaDyn->addReloc(
+      In<ELFT>::RelaDyn->addReloc(
           {Target->TlsModuleIndexRel, In<ELFT>::Got, Off, false, &Body, 0});
       if (Body.isPreemptible())
-        Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
-                                      Off + (uintX_t)sizeof(uintX_t), false,
-                                      &Body, 0});
+        In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
+                                     Off + (uintX_t)sizeof(uintX_t), false,
+                                     &Body, 0});
     }
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
     return 1;
@@ -149,7 +149,7 @@ static unsigned handleTlsRelocation(uint
       Config->Shared) {
     if (In<ELFT>::Got->addDynTlsEntry(Body)) {
       uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
-      Out<ELFT>::RelaDyn->addReloc(
+      In<ELFT>::RelaDyn->addReloc(
           {Target->TlsDescRel, In<ELFT>::Got, Off, false, &Body, 0});
     }
     if (Expr != R_TLSDESC_CALL)
@@ -165,9 +165,9 @@ static unsigned handleTlsRelocation(uint
       return 2;
     }
     if (In<ELFT>::Got->addTlsIndex())
-      Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
-                                    In<ELFT>::Got->getTlsIndexOff(), false,
-                                    nullptr, 0});
+      In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, In<ELFT>::Got,
+                                   In<ELFT>::Got->getTlsIndexOff(), false,
+                                   nullptr, 0});
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
     return 1;
   }
@@ -184,15 +184,15 @@ static unsigned handleTlsRelocation(uint
     if (Config->Shared) {
       if (In<ELFT>::Got->addDynTlsEntry(Body)) {
         uintX_t Off = In<ELFT>::Got->getGlobalDynOffset(Body);
-        Out<ELFT>::RelaDyn->addReloc(
+        In<ELFT>::RelaDyn->addReloc(
             {Target->TlsModuleIndexRel, In<ELFT>::Got, Off, false, &Body, 0});
 
         // If the symbol is preemptible we need the dynamic linker to write
         // the offset too.
         if (isPreemptible(Body, Type))
-          Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
-                                        Off + (uintX_t)sizeof(uintX_t), false,
-                                        &Body, 0});
+          In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
+                                       Off + (uintX_t)sizeof(uintX_t), false,
+                                       &Body, 0});
       }
       C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
       return 1;
@@ -206,9 +206,9 @@ static unsigned handleTlsRelocation(uint
            Offset, Addend, &Body});
       if (!Body.isInGot()) {
         In<ELFT>::Got->addEntry(Body);
-        Out<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::Got,
-                                      Body.getGotOffset<ELFT>(), false, &Body,
-                                      0});
+        In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, In<ELFT>::Got,
+                                     Body.getGotOffset<ELFT>(), false, &Body,
+                                     0});
       }
       return Target->TlsGdRelaxSkip;
     }
@@ -417,7 +417,7 @@ template <class ELFT> static void addCop
     Alias->NeedsCopyOrPltAddr = true;
     Alias->symbol()->IsUsedInRegularObj = true;
   }
-  Out<ELFT>::RelaDyn->addReloc(
+  In<ELFT>::RelaDyn->addReloc(
       {Target->CopyRel, Out<ELFT>::Bss, SS->OffsetInBss, false, SS, 0});
 }
 
@@ -619,7 +619,7 @@ static void scanRelocs(InputSectionBase<
   bool IsWrite = C.Flags & SHF_WRITE;
 
   auto AddDyn = [=](const DynamicReloc<ELFT> &Reloc) {
-    Out<ELFT>::RelaDyn->addReloc(Reloc);
+    In<ELFT>::RelaDyn->addReloc(Reloc);
   };
 
   const elf::ObjectFile<ELFT> *File = C.getFile();
@@ -754,9 +754,9 @@ static void scanRelocs(InputSectionBase<
         Rel = Target->PltRel;
 
       In<ELFT>::GotPlt->addEntry(Body);
-      Out<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,
-                                    Body.getGotPltOffset<ELFT>(), !Preemptible,
-                                    &Body, 0});
+      In<ELFT>::RelaPlt->addReloc({Rel, In<ELFT>::GotPlt,
+                                   Body.getGotPltOffset<ELFT>(), !Preemptible,
+                                   &Body, 0});
       continue;
     }
 

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Nov 16 04:02:27 2016
@@ -737,10 +737,10 @@ template <class ELFT> void DynamicSectio
 
   this->Link = In<ELFT>::DynStrTab->OutSec->SectionIndex;
 
-  if (Out<ELFT>::RelaDyn->hasRelocs()) {
+  if (In<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_RELA : DT_REL, In<ELFT>::RelaDyn});
+    Add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getSize()});
     Add({IsRela ? DT_RELAENT : DT_RELENT,
          uintX_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
 
@@ -748,14 +748,14 @@ template <class ELFT> void DynamicSectio
     // 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();
+      size_t NumRelativeRels = In<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});
+  if (In<ELFT>::RelaPlt->hasRelocs()) {
+    Add({DT_JMPREL, In<ELFT>::RelaPlt});
+    Add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getSize()});
     Add({Config->EMachine == EM_MIPS ? DT_MIPS_PLTGOT : DT_PLTGOT,
          In<ELFT>::GotPlt});
     Add({DT_PLTREL, uint64_t(Config->Rela ? DT_RELA : DT_REL)});
@@ -848,6 +848,92 @@ template <class ELFT> void DynamicSectio
   }
 }
 
+template <class ELFT>
+typename ELFT::uint DynamicReloc<ELFT>::getOffset() const {
+  if (OutputSec)
+    return OutputSec->Addr + OffsetInSec;
+  return InputSec->OutSec->Addr + InputSec->getOffset(OffsetInSec);
+}
+
+template <class ELFT>
+typename ELFT::uint DynamicReloc<ELFT>::getAddend() const {
+  if (UseSymVA)
+    return Sym->getVA<ELFT>(Addend);
+  return Addend;
+}
+
+template <class ELFT> uint32_t DynamicReloc<ELFT>::getSymIndex() const {
+  if (Sym && !UseSymVA)
+    return Sym->DynsymIndex;
+  return 0;
+}
+
+template <class ELFT>
+RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
+    : SyntheticSection<ELFT>(SHF_ALLOC, Config->Rela ? SHT_RELA : SHT_REL,
+                             sizeof(uintX_t), Name),
+      Sort(Sort) {
+  this->Entsize = Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+}
+
+template <class ELFT>
+void RelocationSection<ELFT>::addReloc(const DynamicReloc<ELFT> &Reloc) {
+  if (Reloc.Type == Target->RelativeRel)
+    ++NumRelativeRelocs;
+  Relocs.push_back(Reloc);
+}
+
+template <class ELFT, class RelTy>
+static bool compRelocations(const RelTy &A, const RelTy &B) {
+  bool AIsRel = A.getType(Config->Mips64EL) == Target->RelativeRel;
+  bool BIsRel = B.getType(Config->Mips64EL) == Target->RelativeRel;
+  if (AIsRel != BIsRel)
+    return AIsRel;
+
+  return A.getSymbol(Config->Mips64EL) < B.getSymbol(Config->Mips64EL);
+}
+
+template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
+  uint8_t *BufBegin = Buf;
+  for (const DynamicReloc<ELFT> &Rel : Relocs) {
+    auto *P = reinterpret_cast<Elf_Rela *>(Buf);
+    Buf += Config->Rela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+
+    if (Config->Rela)
+      P->r_addend = Rel.getAddend();
+    P->r_offset = Rel.getOffset();
+    if (Config->EMachine == EM_MIPS && Rel.getInputSec() == In<ELFT>::Got)
+      // Dynamic relocation against MIPS GOT section make deal TLS entries
+      // allocated in the end of the GOT. We need to adjust the offset to take
+      // in account 'local' and 'global' GOT entries.
+      P->r_offset += In<ELFT>::Got->getMipsTlsOffset();
+    P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->Mips64EL);
+  }
+
+  if (Sort) {
+    if (Config->Rela)
+      std::stable_sort((Elf_Rela *)BufBegin,
+                       (Elf_Rela *)BufBegin + Relocs.size(),
+                       compRelocations<ELFT, Elf_Rela>);
+    else
+      std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(),
+                       compRelocations<ELFT, Elf_Rel>);
+  }
+}
+
+template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
+  return this->Entsize * Relocs.size();
+}
+
+template <class ELFT> void RelocationSection<ELFT>::finalize() {
+  this->Link = Out<ELFT>::DynSymTab ? Out<ELFT>::DynSymTab->SectionIndex
+                                    : Out<ELFT>::SymTab->SectionIndex;
+
+  // Set required output section properties.
+  this->OutSec->Link = this->Link;
+  this->OutSec->Entsize = this->Entsize;
+}
+
 template InputSection<ELF32LE> *elf::createCommonSection();
 template InputSection<ELF32BE> *elf::createCommonSection();
 template InputSection<ELF64LE> *elf::createCommonSection();
@@ -927,3 +1013,8 @@ template class elf::DynamicSection<ELF32
 template class elf::DynamicSection<ELF32BE>;
 template class elf::DynamicSection<ELF64LE>;
 template class elf::DynamicSection<ELF64BE>;
+
+template class elf::RelocationSection<ELF32LE>;
+template class elf::RelocationSection<ELF32BE>;
+template class elf::RelocationSection<ELF64LE>;
+template class elf::RelocationSection<ELF64BE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Wed Nov 16 04:02:27 2016
@@ -239,6 +239,39 @@ private:
   std::vector<StringRef> Strings;
 };
 
+template <class ELFT> class DynamicReloc {
+  typedef typename ELFT::uint uintX_t;
+
+public:
+  DynamicReloc(uint32_t Type, const InputSectionBase<ELFT> *InputSec,
+               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
+               uintX_t Addend)
+      : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
+        UseSymVA(UseSymVA), Addend(Addend) {}
+
+  DynamicReloc(uint32_t Type, const OutputSectionBase *OutputSec,
+               uintX_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
+               uintX_t Addend)
+      : Type(Type), Sym(Sym), OutputSec(OutputSec), OffsetInSec(OffsetInSec),
+        UseSymVA(UseSymVA), Addend(Addend) {}
+
+  uintX_t getOffset() const;
+  uintX_t getAddend() const;
+  uint32_t getSymIndex() const;
+  const OutputSectionBase *getOutputSec() const { return OutputSec; }
+  const InputSectionBase<ELFT> *getInputSec() const { return InputSec; }
+
+  uint32_t Type;
+
+private:
+  SymbolBody *Sym;
+  const InputSectionBase<ELFT> *InputSec = nullptr;
+  const OutputSectionBase *OutputSec = nullptr;
+  uintX_t OffsetInSec;
+  bool UseSymVA;
+  uintX_t Addend;
+};
+
 template <class ELFT>
 class DynamicSection final : public SyntheticSection<ELFT> {
   typedef typename ELFT::Dyn Elf_Dyn;
@@ -287,6 +320,28 @@ private:
   uintX_t Size = 0;
 };
 
+template <class ELFT>
+class RelocationSection final : public SyntheticSection<ELFT> {
+  typedef typename ELFT::Rel Elf_Rel;
+  typedef typename ELFT::Rela Elf_Rela;
+  typedef typename ELFT::uint uintX_t;
+
+public:
+  RelocationSection(StringRef Name, bool Sort);
+  void addReloc(const DynamicReloc<ELFT> &Reloc);
+  unsigned getRelocOffset();
+  void finalize() override;
+  void writeTo(uint8_t *Buf) override;
+  size_t getSize() const override { return Relocs.size() * this->Entsize; }
+  bool hasRelocs() const { return !Relocs.empty(); }
+  size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
+
+private:
+  bool Sort;
+  size_t NumRelativeRelocs = 0;
+  std::vector<DynamicReloc<ELFT>> Relocs;
+};
+
 template <class ELFT> InputSection<ELFT> *createCommonSection();
 template <class ELFT> InputSection<ELFT> *createInterpSection();
 template <class ELFT> MergeInputSection<ELFT> *createCommentSection();
@@ -303,6 +358,8 @@ template <class ELFT> struct In {
   static MipsAbiFlagsSection<ELFT> *MipsAbiFlags;
   static MipsOptionsSection<ELFT> *MipsOptions;
   static MipsReginfoSection<ELFT> *MipsReginfo;
+  static RelocationSection<ELFT> *RelaDyn;
+  static RelocationSection<ELFT> *RelaPlt;
   static StringTableSection<ELFT> *ShStrTab;
   static StringTableSection<ELFT> *StrTab;
 };
@@ -317,6 +374,8 @@ template <class ELFT> InputSection<ELFT>
 template <class ELFT> MipsAbiFlagsSection<ELFT> *In<ELFT>::MipsAbiFlags;
 template <class ELFT> MipsOptionsSection<ELFT> *In<ELFT>::MipsOptions;
 template <class ELFT> MipsReginfoSection<ELFT> *In<ELFT>::MipsReginfo;
+template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
+template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
 template <class ELFT> StringTableSection<ELFT> *In<ELFT>::ShStrTab;
 template <class ELFT> StringTableSection<ELFT> *In<ELFT>::StrTab;
 } // namespace elf

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=287092&r1=287091&r2=287092&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Nov 16 04:02:27 2016
@@ -213,7 +213,7 @@ template <class ELFT> void Writer<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>>(
+  In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
       Config->Rela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
   In<ELFT>::ShStrTab = make<StringTableSection<ELFT>>(".shstrtab", false);
   Out<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
@@ -245,7 +245,7 @@ template <class ELFT> void Writer<ELFT>:
   if (Config->GdbIndex)
     Out<ELFT>::GdbIndex = make<GdbIndexSection<ELFT>>();
 
-  Out<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
+  In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
       Config->Rela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
   if (Config->Strip != StripPolicy::All) {
     In<ELFT>::StrTab = make<StringTableSection<ELFT>>(".strtab", false);
@@ -589,11 +589,10 @@ template <class ELFT> void Writer<ELFT>:
   if (Out<ELFT>::DynSymTab)
     return;
   StringRef S = Config->Rela ? "__rela_iplt_start" : "__rel_iplt_start";
-  addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt, 0);
+  addOptionalRegular<ELFT>(S, In<ELFT>::RelaPlt, 0);
 
   S = Config->Rela ? "__rela_iplt_end" : "__rel_iplt_end";
-  addOptionalSynthetic<ELFT>(S, Out<ELFT>::RelaPlt,
-                             DefinedSynthetic<ELFT>::SectionEnd);
+  addOptionalRegular<ELFT>(S, In<ELFT>::RelaPlt, -1);
 }
 
 // The linker is expected to define some symbols depending on
@@ -945,8 +944,10 @@ template <class ELFT> void Writer<ELFT>:
   for (OutputSectionBase *Sec : OutputSections)
     Sec->finalize();
 
+  // Dynamic section must be the last one in this list.
   finalizeSynthetic<ELFT>({In<ELFT>::ShStrTab, In<ELFT>::StrTab,
                            In<ELFT>::DynStrTab, In<ELFT>::Got, In<ELFT>::GotPlt,
+                           In<ELFT>::RelaDyn, In<ELFT>::RelaPlt,
                            In<ELFT>::Dynamic});
 
   // Now that all output offsets are fixed. Finalize mergeable sections
@@ -997,15 +998,15 @@ template <class ELFT> void Writer<ELFT>:
     Add(Out<ELFT>::HashTab);
     addInputSec(In<ELFT>::Dynamic);
     addInputSec(In<ELFT>::DynStrTab);
-    if (Out<ELFT>::RelaDyn->hasRelocs())
-      Add(Out<ELFT>::RelaDyn);
+    if (In<ELFT>::RelaDyn->hasRelocs())
+      addInputSec(In<ELFT>::RelaDyn);
     Add(Out<ELFT>::MipsRldMap);
   }
 
   // We always need to add rel[a].plt to output if it has entries.
   // Even during static linking it can contain R_[*]_IRELATIVE relocations.
-  if (Out<ELFT>::RelaPlt->hasRelocs())
-    Add(Out<ELFT>::RelaPlt);
+  if (In<ELFT>::RelaPlt->hasRelocs())
+    addInputSec(In<ELFT>::RelaPlt);
 
   // We fill .got and .got.plt sections in scanRelocs(). This is the
   // reason we don't add it earlier in createSections().




More information about the llvm-commits mailing list