[lld] r267460 - [ELF][MIPS] Move MIPS GOT header generation to the GotSection

Simon Atanasyan via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 25 13:25:06 PDT 2016


Author: atanasyan
Date: Mon Apr 25 15:25:05 2016
New Revision: 267460

URL: http://llvm.org/viewvc/llvm-project?rev=267460&view=rev
Log:
[ELF][MIPS] Move MIPS GOT header generation to the GotSection

MIPS is the only target requires GOT header. We already have MIPS
specific code in the `GotSection` class, so move MIPS GOT header
generation there and delete redundant stuff like `GotHeaderEntriesNum`
field and `writeGotHeader` method.

Differential Revision: http://reviews.llvm.org/D19465

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

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=267460&r1=267459&r2=267460&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Apr 25 15:25:05 2016
@@ -146,7 +146,7 @@ template <class ELFT> void GotSection<EL
 template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) {
   if (Sym.hasGlobalDynIndex())
     return false;
-  Sym.GlobalDynIndex = Target->GotHeaderEntriesNum + Entries.size();
+  Sym.GlobalDynIndex = Entries.size();
   // Global Dynamic TLS entries take two GOT slots.
   Entries.push_back(&Sym);
   Entries.push_back(nullptr);
@@ -175,7 +175,9 @@ GotSection<ELFT>::getMipsLocalPageOffset
 template <class ELFT>
 typename GotSection<ELFT>::uintX_t
 GotSection<ELFT>::getMipsLocalEntryOffset(uintX_t EntryValue) {
-  size_t NewIndex = Target->GotHeaderEntriesNum + MipsLocalGotPos.size();
+  // Take into account MIPS GOT header.
+  // See comment in the GotSection::writeTo.
+  size_t NewIndex = MipsLocalGotPos.size() + 2;
   auto P = MipsLocalGotPos.insert(std::make_pair(EntryValue, NewIndex));
   assert(!P.second || MipsLocalGotPos.size() <= MipsLocalEntries);
   return P.first->second * sizeof(uintX_t) - MipsGPOffset;
@@ -200,10 +202,14 @@ const SymbolBody *GotSection<ELFT>::getM
 
 template <class ELFT>
 unsigned GotSection<ELFT>::getMipsLocalEntriesNum() const {
-  return Target->GotHeaderEntriesNum + MipsLocalEntries;
+  return MipsLocalEntries;
 }
 
 template <class ELFT> void GotSection<ELFT>::finalize() {
+  if (Config->EMachine == EM_MIPS)
+    // Take into account MIPS GOT header.
+    // See comment in the GotSection::writeTo.
+    MipsLocalEntries += 2;
   for (const OutputSectionBase<ELFT> *OutSec : MipsOutSections) {
     // Calculate an upper bound of MIPS GOT entries required to store page
     // addresses of local symbols. We assume the worst case - each 64kb
@@ -212,18 +218,32 @@ template <class ELFT> void GotSection<EL
     // in the GOT entry is calculated as (value + 0x8000) & ~0xffff.
     MipsLocalEntries += (OutSec->getSize() + 0x8000 + 0xfffe) / 0xffff;
   }
-  this->Header.sh_size =
-      (Target->GotHeaderEntriesNum + MipsLocalEntries + Entries.size()) *
-      sizeof(uintX_t);
+  this->Header.sh_size = (MipsLocalEntries + Entries.size()) * sizeof(uintX_t);
 }
 
 template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
-  Target->writeGotHeader(Buf);
+  if (Config->EMachine == EM_MIPS) {
+    // Set the MSB of the second GOT slot. This is not required by any
+    // MIPS ABI documentation, though.
+    //
+    // There is a comment in glibc saying that "The MSB of got[1] of a
+    // gnu object is set to identify gnu objects," and in GNU gold it
+    // says "the second entry will be used by some runtime loaders".
+    // But how this field is being used is unclear.
+    //
+    // We are not really willing to mimic other linkers behaviors
+    // without understanding why they do that, but because all files
+    // generated by GNU tools have this special GOT value, and because
+    // we've been doing this for years, it is probably a safe bet to
+    // keep doing this for now. We really need to revisit this to see
+    // if we had to do this.
+    auto *P = reinterpret_cast<typename ELFT::Off *>(Buf);
+    P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31);
+  }
   for (std::pair<uintX_t, size_t> &L : MipsLocalGotPos) {
     uint8_t *Entry = Buf + L.second * sizeof(uintX_t);
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, L.first);
   }
-  Buf += Target->GotHeaderEntriesNum * sizeof(uintX_t);
   Buf += MipsLocalEntries * sizeof(uintX_t);
   for (const SymbolBody *B : Entries) {
     uint8_t *Entry = Buf;

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=267460&r1=267459&r2=267460&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Apr 25 15:25:05 2016
@@ -179,7 +179,6 @@ public:
   void writePltZero(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
                 int32_t Index, unsigned RelOff) const override;
-  void writeGotHeader(uint8_t *Buf) const override;
   void writeThunk(uint8_t *Buf, uint64_t S) const override;
   bool needsThunk(uint32_t Type, const InputFile &File,
                   const SymbolBody &S) const override;
@@ -1294,7 +1293,6 @@ RelExpr AMDGPUTargetInfo::getRelExpr(uin
 }
 
 template <class ELFT> MipsTargetInfo<ELFT>::MipsTargetInfo() {
-  GotHeaderEntriesNum = 2;
   GotPltHeaderEntriesNum = 2;
   PageSize = 65536;
   PltEntrySize = 16;
@@ -1353,29 +1351,6 @@ uint32_t MipsTargetInfo<ELFT>::getDynRel
 }
 
 template <class ELFT>
-void MipsTargetInfo<ELFT>::writeGotHeader(uint8_t *Buf) const {
-  typedef typename ELFT::Off Elf_Off;
-  typedef typename ELFT::uint uintX_t;
-
-  // Set the MSB of the second GOT slot. This is not required by any
-  // MIPS ABI documentation, though.
-  //
-  // There is a comment in glibc saying that "The MSB of got[1] of a
-  // gnu object is set to identify gnu objects," and in GNU gold it
-  // says "the second entry will be used by some runtime loaders".
-  // But how this field is being used is unclear.
-  //
-  // We are not really willing to mimic other linkers behaviors
-  // without understanding why they do that, but because all files
-  // generated by GNU tools have this special GOT value, and because
-  // we've been doing this for years, it is probably a safe bet to
-  // keep doing this for now. We really need to revisit this to see
-  // if we had to do this.
-  auto *P = reinterpret_cast<Elf_Off *>(Buf);
-  P[1] = uintX_t(1) << (ELFT::Is64Bits ? 63 : 31);
-}
-
-template <class ELFT>
 void MipsTargetInfo<ELFT>::writeGotPlt(uint8_t *Buf, uint64_t Plt) const {
   write32<ELFT::TargetEndianness>(Buf, Out<ELFT>::Plt->getVA());
 }

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=267460&r1=267459&r2=267460&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Mon Apr 25 15:25:05 2016
@@ -29,7 +29,6 @@ public:
   virtual bool isTlsGlobalDynamicRel(uint32_t Type) const;
   virtual uint32_t getDynRel(uint32_t Type) const { return Type; }
   virtual uint32_t getTlsGotRel(uint32_t Type) const { return TlsGotRel; }
-  virtual void writeGotHeader(uint8_t *Buf) const {}
   virtual void writeGotPltHeader(uint8_t *Buf) const {}
   virtual void writeGotPlt(uint8_t *Buf, uint64_t Plt) const {};
   virtual uint64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const;
@@ -85,7 +84,6 @@ public:
   uint32_t TlsOffsetRel;
   unsigned PltEntrySize = 8;
   unsigned PltZeroSize = 0;
-  unsigned GotHeaderEntriesNum = 0;
   unsigned GotPltHeaderEntriesNum = 3;
   uint32_t ThunkSize = 0;
   bool UseLazyBinding = false;




More information about the llvm-commits mailing list