[lld] r294577 - [ELF] Use synthetic section to hold copy relocation

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 9 02:27:57 PST 2017


Author: psmith
Date: Thu Feb  9 04:27:57 2017
New Revision: 294577

URL: http://llvm.org/viewvc/llvm-project?rev=294577&view=rev
Log:
[ELF] Use synthetic section to hold copy relocation
    
When we need a copy relocation we create a synthetic SHT_NOBITS
section that contains the right amount of ZI and assign it to either
.bss or .rel.ro.bss as appropriate. This allows the dynamic relocation
to be placed on the InputSection, removing the last case where a
dynamic relocation is stored as an offset from the OutputSection. This
has the side effect that we can run assignOffsets() after scanRelocs()
without losing the additional ZI needed for the copy relocations.

Differential Revision: https://reviews.llvm.org/D29637


Modified:
    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

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=294577&r1=294576&r2=294577&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu Feb  9 04:27:57 2017
@@ -434,6 +434,13 @@ template <class ELFT> static void addCop
   CopySec->updateAlignment(Alignment);
   uintX_t Shndx = SS->Sym.st_shndx;
   uintX_t Value = SS->Sym.st_value;
+
+  // Create a SyntheticSection in CopySec to hold the .bss and the Copy Reloc
+  auto *CopyISec = make<CopyRelSection<ELFT>>(IsReadOnly, Alignment, SymSize);
+  CopyISec->OutSecOff = Off;
+  CopyISec->OutSec = CopySec;
+  CopySec->Sections.push_back(CopyISec);
+
   // 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.
@@ -444,12 +451,11 @@ template <class ELFT> static void addCop
         Symtab<ELFT>::X->find(check(S.getName(SS->file()->getStringTable()))));
     if (!Alias)
       continue;
-    Alias->CopyIsInBssRelRo = IsReadOnly;
-    Alias->CopyOffset = Off;
+    Alias->CopySection = CopyISec;
     Alias->NeedsCopyOrPltAddr = true;
     Alias->symbol()->IsUsedInRegularObj = true;
   }
-  In<ELFT>::RelaDyn->addReloc({Target->CopyRel, CopySec, Off, false, SS, 0});
+  In<ELFT>::RelaDyn->addReloc({Target->CopyRel, CopyISec, 0, false, SS, 0});
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=294577&r1=294576&r2=294577&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Feb  9 04:27:57 2017
@@ -84,7 +84,8 @@ static typename ELFT::uint getSymVA(cons
       return 0;
     if (SS.isFunc())
       return Body.getPltVA<ELFT>();
-    return SS.getBssSectionForCopy()->Addr + SS.CopyOffset;
+    InputSection<ELFT> *CopyISec = SS.getBssSectionForCopy();
+    return CopyISec->OutSec->Addr + CopyISec->OutSecOff;
   }
   case SymbolBody::UndefinedKind:
     return 0;
@@ -100,7 +101,7 @@ SymbolBody::SymbolBody(Kind K, StringRef
                        uint8_t Type)
     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(IsLocal),
       IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
-      IsInIgot(false), CopyIsInBssRelRo(false), Type(Type), StOther(StOther),
+      IsInIgot(false), Type(Type), StOther(StOther),
       Name(Name) {}
 
 // Returns true if a symbol can be replaced at load-time by a symbol
@@ -231,9 +232,10 @@ Undefined::Undefined(StringRefZ Name, bo
 }
 
 template <typename ELFT>
-OutputSection<ELFT> *SharedSymbol<ELFT>::getBssSectionForCopy() const {
+InputSection<ELFT> *SharedSymbol<ELFT>::getBssSectionForCopy() const {
   assert(needsCopy());
-  return CopyIsInBssRelRo ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
+  assert(CopySection);
+  return CopySection;
 }
 
 DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint64_t Alignment,

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=294577&r1=294576&r2=294577&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Feb  9 04:27:57 2017
@@ -122,11 +122,6 @@ public:
   // True if this symbol is in the Igot sub-section of the .got.plt or .got.
   unsigned IsInIgot : 1;
 
-  // True if this is a shared symbol in a read-only segment which requires a
-  // copy relocation. This causes space for the symbol to be allocated in the
-  // .bss.rel.ro section.
-  unsigned CopyIsInBssRelRo : 1;
-
   // The following fields have the same meaning as the ELF symbol attributes.
   uint8_t Type;    // symbol type
   uint8_t StOther; // st_other field value
@@ -276,12 +271,11 @@ public:
   // This field is a pointer to the symbol's version definition.
   const Elf_Verdef *Verdef;
 
-  // CopyOffset is significant only when needsCopy() is true.
-  uintX_t CopyOffset = 0;
-
+  // CopySection is significant only when needsCopy() is true.
+  InputSection<ELFT> *CopySection = nullptr;
   bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->isFunc(); }
 
-  OutputSection<ELFT> *getBssSectionForCopy() const;
+  InputSection<ELFT> *getBssSectionForCopy() const;
 };
 
 // This class represents a symbol defined in an archive file. It is

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=294577&r1=294576&r2=294577&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Thu Feb  9 04:27:57 2017
@@ -362,6 +362,15 @@ void BuildIdSection<ELFT>::computeHash(
 }
 
 template <class ELFT>
+CopyRelSection<ELFT>::CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t S)
+    : SyntheticSection<ELFT>(SHF_ALLOC, SHT_NOBITS, AddrAlign,
+                             ReadOnly ? ".bss.rel.ro" : ".bss"),
+      Size(S) {
+  if (!ReadOnly)
+    this->Flags |= SHF_WRITE;
+}
+
+template <class ELFT>
 void BuildIdSection<ELFT>::writeBuildId(ArrayRef<uint8_t> Buf) {
   switch (Config->BuildId) {
   case BuildIdKind::Fast:
@@ -965,8 +974,6 @@ 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);
 }
 
@@ -1228,7 +1235,7 @@ SymbolTableSection<ELFT>::getOutputSecti
   case SymbolBody::SharedKind: {
     auto &SS = cast<SharedSymbol<ELFT>>(*Sym);
     if (SS.needsCopy())
-      return SS.getBssSectionForCopy();
+      return SS.getBssSectionForCopy()->OutSec;
     break;
   }
   case SymbolBody::UndefinedKind:
@@ -2051,6 +2058,11 @@ template class elf::BuildIdSection<ELF32
 template class elf::BuildIdSection<ELF64LE>;
 template class elf::BuildIdSection<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>;
 template class elf::GotSection<ELF64LE>;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=294577&r1=294576&r2=294577&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Thu Feb  9 04:27:57 2017
@@ -107,6 +107,18 @@ private:
   uint8_t *HashBuf;
 };
 
+// SHT_NOBITS section created for a copyReloc
+template <class ELFT>
+class CopyRelSection final : public SyntheticSection<ELFT> {
+  typedef typename ELFT::uint uintX_t;
+
+public:
+  CopyRelSection(bool ReadOnly, uintX_t AddrAlign, size_t Size);
+  void writeTo(uint8_t *) override {}
+  size_t getSize() const override { return Size; }
+  size_t Size;
+};
+
 template <class ELFT>
 class MipsGotSection final : public SyntheticSection<ELFT> {
   typedef typename ELFT::uint uintX_t;
@@ -271,16 +283,9 @@ public:
       : 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;
@@ -288,7 +293,6 @@ public:
 private:
   SymbolBody *Sym;
   const InputSectionBase<ELFT> *InputSec = nullptr;
-  const OutputSectionBase *OutputSec = nullptr;
   uintX_t OffsetInSec;
   bool UseSymVA;
   uintX_t Addend;




More information about the llvm-commits mailing list