[lld] r262748 - Refactor target independent code.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 4 13:37:10 PST 2016


Author: rafael
Date: Fri Mar  4 15:37:09 2016
New Revision: 262748

URL: http://llvm.org/viewvc/llvm-project?rev=262748&view=rev
Log:
Refactor target independent code.

The rules for when we can relax tls relocations are target independent.
The only things that are target dependent are the relocation values.

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/ELF/Target.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=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Mar  4 15:37:09 2016
@@ -201,7 +201,7 @@ void InputSectionBase<ELFT>::relocate(ui
     uintX_t AddrLoc = OutSec->getVA() + Offset;
     auto NextRelocs = llvm::make_range(&RI, Rels.end());
 
-    if (Target->isTlsLocalDynamicRel(Type) &&
+    if (Target->pointsToLocalDynamicGotEntry(Type) &&
         !Target->canRelaxTls(Type, nullptr)) {
       Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc,
                           Out<ELFT>::Got->getTlsIndexVA() +

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Fri Mar  4 15:37:09 2016
@@ -83,8 +83,10 @@ public:
   void writeGotPltHeader(uint8_t *Buf) const override;
   unsigned getDynRel(unsigned Type) const override;
   unsigned getTlsGotRel(unsigned Type) const override;
+  bool pointsToLocalDynamicGotEntry(unsigned Type) const override;
   bool isTlsLocalDynamicRel(unsigned Type) const override;
   bool isTlsGlobalDynamicRel(unsigned Type) const override;
+  bool isTlsInitialExecRel(unsigned Type) const override;
   bool isTlsDynRel(unsigned Type, const SymbolBody &S) const override;
   void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZero(uint8_t *Buf) const override;
@@ -97,7 +99,6 @@ public:
   void relocateOne(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
                    uint64_t SA, uint64_t ZA = 0,
                    uint8_t *PairedLoc = nullptr) const override;
-  bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const override;
   unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
                     uint64_t SA, const SymbolBody *S) const override;
   bool isGotRelative(uint32_t Type) const override;
@@ -118,8 +119,10 @@ class X86_64TargetInfo final : public Ta
 public:
   X86_64TargetInfo();
   unsigned getTlsGotRel(unsigned Type) const override;
+  bool pointsToLocalDynamicGotEntry(unsigned Type) const override;
   bool isTlsLocalDynamicRel(unsigned Type) const override;
   bool isTlsGlobalDynamicRel(unsigned Type) const override;
+  bool isTlsInitialExecRel(unsigned Type) const override;
   bool isTlsDynRel(unsigned Type, const SymbolBody &S) const override;
   void writeGotPltHeader(uint8_t *Buf) const override;
   void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override;
@@ -134,7 +137,6 @@ public:
                    uint64_t SA, uint64_t ZA = 0,
                    uint8_t *PairedLoc = nullptr) const override;
   bool isRelRelative(uint32_t Type) const override;
-  bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const override;
   bool isSizeRel(uint32_t Type) const override;
   unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
                     uint64_t SA, const SymbolBody *S) const override;
@@ -177,6 +179,7 @@ public:
   AArch64TargetInfo();
   unsigned getDynRel(unsigned Type) const override;
   bool isTlsGlobalDynamicRel(unsigned Type) const override;
+  bool isTlsInitialExecRel(unsigned Type) const override;
   void writeGotPlt(uint8_t *Buf, uint64_t Plt) const override;
   void writePltZero(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
@@ -192,7 +195,6 @@ public:
                    uint8_t *PairedLoc = nullptr) const override;
   unsigned relaxTls(uint8_t *Loc, uint8_t *BufEnd, uint32_t Type, uint64_t P,
                     uint64_t SA, const SymbolBody *S) const override;
-  bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const override;
 
 private:
   void relocateTlsGdToLe(unsigned Type, uint8_t *Loc, uint8_t *BufEnd,
@@ -264,10 +266,23 @@ TargetInfo::~TargetInfo() {}
 bool TargetInfo::canRelaxTls(unsigned Type, const SymbolBody *S) const {
   if (Config->Shared || (S && !S->isTls()))
     return false;
-  return canRelaxTlsImpl(Type, S);
-}
 
-bool TargetInfo::canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const {
+  // We know we are producing an executable.
+
+  // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
+  // depending on the symbol being locally defined or not.
+  if (isTlsGlobalDynamicRel(Type))
+    return true;
+
+  // Local-Dynamic relocs can be relaxed to Local-Exec.
+  if (isTlsLocalDynamicRel(Type))
+    return true;
+
+  // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
+  // defined.
+  if (isTlsInitialExecRel(Type))
+    return !canBePreempted(S);
+
   return false;
 }
 
@@ -341,10 +356,14 @@ TargetInfo::PltNeed TargetInfo::needsPlt
   return Plt_No;
 }
 
-bool TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+bool TargetInfo::isTlsInitialExecRel(unsigned Type) const { return false; }
+
+bool TargetInfo::pointsToLocalDynamicGotEntry(unsigned Type) const {
   return false;
 }
 
+bool TargetInfo::isTlsLocalDynamicRel(unsigned Type) const { return false; }
+
 bool TargetInfo::isTlsGlobalDynamicRel(unsigned Type) const {
   return false;
 }
@@ -398,9 +417,17 @@ bool X86TargetInfo::isTlsGlobalDynamicRe
 }
 
 bool X86TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+  return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM;
+}
+
+bool X86TargetInfo::pointsToLocalDynamicGotEntry(unsigned Type) const {
   return Type == R_386_TLS_LDM;
 }
 
+bool X86TargetInfo::isTlsInitialExecRel(unsigned Type) const {
+  return Type == R_386_TLS_IE || Type == R_386_TLS_GOTIE;
+}
+
 bool X86TargetInfo::isTlsDynRel(unsigned Type, const SymbolBody &S) const {
   if (Type == R_386_TLS_LE || Type == R_386_TLS_LE_32 ||
       Type == R_386_TLS_GOTIE)
@@ -528,12 +555,6 @@ void X86TargetInfo::relocateOne(uint8_t
   }
 }
 
-bool X86TargetInfo::canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const {
-  return Type == R_386_TLS_LDO_32 || Type == R_386_TLS_LDM ||
-         Type == R_386_TLS_GD || (Type == R_386_TLS_IE && !canBePreempted(S)) ||
-         (Type == R_386_TLS_GOTIE && !canBePreempted(S));
-}
-
 bool X86TargetInfo::needsDynRelative(unsigned Type) const {
   return Config->Shared && Type == R_386_TLS_IE;
 }
@@ -740,14 +761,22 @@ unsigned X86_64TargetInfo::getTlsGotRel(
   return R_X86_64_PC32;
 }
 
+bool X86_64TargetInfo::isTlsInitialExecRel(unsigned Type) const {
+  return Type == R_X86_64_GOTTPOFF;
+}
+
 bool X86_64TargetInfo::isTlsGlobalDynamicRel(unsigned Type) const {
   return Type == R_X86_64_TLSGD;
 }
 
-bool X86_64TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+bool X86_64TargetInfo::pointsToLocalDynamicGotEntry(unsigned Type) const {
   return Type == R_X86_64_TLSLD;
 }
 
+bool X86_64TargetInfo::isTlsLocalDynamicRel(unsigned Type) const {
+  return Type == R_X86_64_DTPOFF32 || Type == R_X86_64_TLSLD;
+}
+
 bool X86_64TargetInfo::isTlsDynRel(unsigned Type, const SymbolBody &S) const {
   return Type == R_X86_64_GOTTPOFF || Type == R_X86_64_TLSGD;
 }
@@ -775,13 +804,6 @@ bool X86_64TargetInfo::isSizeRel(uint32_
   return Type == R_X86_64_SIZE32 || Type == R_X86_64_SIZE64;
 }
 
-bool X86_64TargetInfo::canRelaxTlsImpl(unsigned Type,
-                                       const SymbolBody *S) const {
-  return Type == R_X86_64_TLSGD || Type == R_X86_64_TLSLD ||
-         Type == R_X86_64_DTPOFF32 ||
-         (Type == R_X86_64_GOTTPOFF && !canBePreempted(S));
-}
-
 // "Ulrich Drepper, ELF Handling For Thread-Local Storage" (5.5
 // x86-x64 linker optimizations, http://www.akkadia.org/drepper/tls.pdf) shows
 // how LD can be optimized to LE:
@@ -1221,6 +1243,11 @@ bool AArch64TargetInfo::isTlsGlobalDynam
          Type == R_AARCH64_TLSDESC_CALL;
 }
 
+bool AArch64TargetInfo::isTlsInitialExecRel(unsigned Type) const {
+  return Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 ||
+         Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
+}
+
 unsigned AArch64TargetInfo::getDynRel(unsigned Type) const {
   if (Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64)
     return Type;
@@ -1459,23 +1486,6 @@ void AArch64TargetInfo::relocateOne(uint
   }
 }
 
-bool AArch64TargetInfo::canRelaxTlsImpl(unsigned Type,
-                                        const SymbolBody *S) const {
-  // Global-Dynamic relocs can be relaxed to Initial-Exec if the target is
-  // an executable.  And if the target is local it can also be fully relaxed to
-  // Local-Exec.
-  if (isTlsGlobalDynamicRel(Type))
-    return !canBePreempted(S);
-
-  // Initial-Exec relocs can be relaxed to Local-Exec if the target is a local
-  // symbol.
-  if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 ||
-      Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC)
-    return !canBePreempted(S);
-
-  return false;
-}
-
 unsigned AArch64TargetInfo::relaxTls(uint8_t *Loc, uint8_t *BufEnd,
                                      uint32_t Type, uint64_t P, uint64_t SA,
                                      const SymbolBody *S) const {

Modified: lld/trunk/ELF/Target.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.h?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/Target.h (original)
+++ lld/trunk/ELF/Target.h Fri Mar  4 15:37:09 2016
@@ -22,6 +22,8 @@ class SymbolBody;
 class TargetInfo {
 public:
   uint64_t getVAStart() const;
+  virtual bool isTlsInitialExecRel(unsigned Type) const;
+  virtual bool pointsToLocalDynamicGotEntry(unsigned Type) const;
   virtual bool isTlsLocalDynamicRel(unsigned Type) const;
   virtual bool isTlsGlobalDynamicRel(unsigned Type) const;
   virtual unsigned getDynRel(unsigned Type) const { return Type; }
@@ -99,7 +101,6 @@ public:
 private:
   virtual bool needsCopyRelImpl(uint32_t Type) const;
   virtual bool needsPltImpl(uint32_t Type) const;
-  virtual bool canRelaxTlsImpl(unsigned Type, const SymbolBody *S) const;
 };
 
 uint64_t getPPC64TocBase();

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=262748&r1=262747&r2=262748&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Fri Mar  4 15:37:09 2016
@@ -258,7 +258,7 @@ template <bool Is64Bits> struct DenseMap
 template <class ELFT, class RelT>
 static bool handleTlsRelocation(unsigned Type, SymbolBody *Body,
                                 InputSectionBase<ELFT> &C, RelT &RI) {
-  if (Target->isTlsLocalDynamicRel(Type)) {
+  if (Target->pointsToLocalDynamicGotEntry(Type)) {
     if (Target->canRelaxTls(Type, nullptr))
       return true;
     if (Out<ELFT>::Got->addTlsIndex())




More information about the llvm-commits mailing list