[lld] r288107 - Use relocations to fill statically known got entries.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 28 19:45:36 PST 2016


Author: rafael
Date: Mon Nov 28 21:45:36 2016
New Revision: 288107

URL: http://llvm.org/viewvc/llvm-project?rev=288107&view=rev
Log:
Use relocations to fill statically known got entries.

Right now we just remember a SymbolBody for each got entry and
duplicate a bit of logic to decide what value, if any, should be
written for that SymbolBody.

With ARM there will be more complicated values, and it seems better to
just use the relocation code to fill the got entries. This makes it
clear that each entry is filled by the dynamic linker or by the static
linker.

Modified:
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Target.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=288107&r1=288106&r2=288107&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Nov 28 21:45:36 2016
@@ -188,10 +188,13 @@ static unsigned handleTlsRelocation(uint
 
         // If the symbol is preemptible we need the dynamic linker to write
         // the offset too.
+        uintX_t OffsetOff = Off + (uintX_t)sizeof(uintX_t);
         if (isPreemptible(Body, Type))
           In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, In<ELFT>::Got,
-                                       Off + (uintX_t)sizeof(uintX_t), false,
-                                       &Body, 0});
+                                       OffsetOff, false, &Body, 0});
+        else
+          In<ELFT>::Got->Relocations.push_back(
+              {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Body});
       }
       C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
       return 1;
@@ -741,17 +744,19 @@ static void scanRelocs(InputSectionBase<
         continue;
 
       In<ELFT>::Got->addEntry(Body);
-      if (Preemptible || (Config->Pic && !isAbsolute<ELFT>(Body))) {
-        uint32_t DynType;
-        if (Body.isTls())
-          DynType = Target->TlsGotRel;
-        else if (Preemptible)
-          DynType = Target->GotRel;
-        else
-          DynType = Target->RelativeRel;
-        AddDyn({DynType, In<ELFT>::Got, Body.getGotOffset<ELFT>(), !Preemptible,
-                &Body, 0});
-      }
+      uintX_t Off = Body.getGotOffset<ELFT>();
+      uint32_t DynType;
+      if (Body.isTls())
+        DynType = Target->TlsGotRel;
+      else if (!Preemptible && Config->Pic && !isAbsolute<ELFT>(Body))
+        DynType = Target->RelativeRel;
+      else
+        DynType = Target->GotRel;
+
+      if (Preemptible || (Config->Pic && !isAbsolute<ELFT>(Body)))
+        AddDyn({DynType, In<ELFT>::Got, Off, !Preemptible, &Body, 0});
+      else
+        In<ELFT>::Got->Relocations.push_back({R_ABS, DynType, Off, 0, &Body});
       continue;
     }
   }

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=288107&r1=288106&r2=288107&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Nov 28 21:45:36 2016
@@ -383,17 +383,16 @@ GotSection<ELFT>::GotSection()
                              Target->GotEntrySize, ".got") {}
 
 template <class ELFT> void GotSection<ELFT>::addEntry(SymbolBody &Sym) {
-  Sym.GotIndex = Entries.size();
-  Entries.push_back(&Sym);
+  Sym.GotIndex = NumEntries;
+  ++NumEntries;
 }
 
 template <class ELFT> bool GotSection<ELFT>::addDynTlsEntry(SymbolBody &Sym) {
   if (Sym.GlobalDynIndex != -1U)
     return false;
-  Sym.GlobalDynIndex = Entries.size();
+  Sym.GlobalDynIndex = NumEntries;
   // Global Dynamic TLS entries take two GOT slots.
-  Entries.push_back(nullptr);
-  Entries.push_back(&Sym);
+  NumEntries += 2;
   return true;
 }
 
@@ -402,9 +401,8 @@ template <class ELFT> bool GotSection<EL
 template <class ELFT> bool GotSection<ELFT>::addTlsIndex() {
   if (TlsIndexOff != uint32_t(-1))
     return false;
-  TlsIndexOff = Entries.size() * sizeof(uintX_t);
-  Entries.push_back(nullptr);
-  Entries.push_back(nullptr);
+  TlsIndexOff = NumEntries * sizeof(uintX_t);
+  NumEntries += 2;
   return true;
 }
 
@@ -421,26 +419,17 @@ GotSection<ELFT>::getGlobalDynOffset(con
 }
 
 template <class ELFT> void GotSection<ELFT>::finalize() {
-  Size = Entries.size() * sizeof(uintX_t);
+  Size = NumEntries * sizeof(uintX_t);
 }
 
 template <class ELFT> bool GotSection<ELFT>::empty() const {
   // If we have a relocation that is relative to GOT (such as GOTOFFREL),
   // we need to emit a GOT even if it's empty.
-  return Entries.empty() && !HasGotOffRel;
+  return NumEntries == 0 && !HasGotOffRel;
 }
 
 template <class ELFT> void GotSection<ELFT>::writeTo(uint8_t *Buf) {
-  for (const SymbolBody *B : Entries) {
-    uint8_t *Entry = Buf;
-    Buf += sizeof(uintX_t);
-    if (!B)
-      continue;
-    if (B->isPreemptible())
-      continue; // The dynamic linker will take care of it.
-    uintX_t VA = B->getVA<ELFT>();
-    write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
-  }
+  this->relocate(Buf, Buf + Size);
 }
 
 template <class ELFT>

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=288107&r1=288106&r2=288107&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Nov 28 21:45:36 2016
@@ -67,7 +67,7 @@ public:
   bool HasGotOffRel = false;
 
 private:
-  std::vector<const SymbolBody *> Entries;
+  size_t NumEntries = 0;
   uint32_t TlsIndexOff = -1;
   uintX_t Size = 0;
 };

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=288107&r1=288106&r2=288107&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Mon Nov 28 21:45:36 2016
@@ -800,6 +800,7 @@ void X86_64TargetInfo<ELFT>::relocateOne
     break;
   case R_X86_64_64:
   case R_X86_64_DTPOFF64:
+  case R_X86_64_GLOB_DAT:
   case R_X86_64_PC64:
   case R_X86_64_SIZE64:
     write64le(Loc, Val);
@@ -1319,6 +1320,7 @@ void AArch64TargetInfo::relocateOne(uint
     write32le(Loc, Val);
     break;
   case R_AARCH64_ABS64:
+  case R_AARCH64_GLOB_DAT:
   case R_AARCH64_PREL64:
     write64le(Loc, Val);
     break;
@@ -1685,6 +1687,7 @@ void ARMTargetInfo::relocateOne(uint8_t
   switch (Type) {
   case R_ARM_ABS32:
   case R_ARM_BASE_PREL:
+  case R_ARM_GLOB_DAT:
   case R_ARM_GOTOFF32:
   case R_ARM_GOT_BREL:
   case R_ARM_GOT_PREL:
@@ -1696,6 +1699,7 @@ void ARMTargetInfo::relocateOne(uint8_t
   case R_ARM_TLS_LDM32:
   case R_ARM_TLS_LDO32:
   case R_ARM_TLS_LE32:
+  case R_ARM_TLS_TPOFF32:
     write32le(Loc, Val);
     break;
   case R_ARM_PREL31:




More information about the llvm-commits mailing list