[lld] r288153 - [ELF] Add support for static TLS to ARM

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 29 08:23:51 PST 2016


Author: psmith
Date: Tue Nov 29 10:23:50 2016
New Revision: 288153

URL: http://llvm.org/viewvc/llvm-project?rev=288153&view=rev
Log:
[ELF] Add support for static TLS to ARM

The module index dynamic relocation R_ARM_DTPMOD32 is always 1 for an
executable. When static linking and when we know that we are not a shared
object we can resolve the module index relocation statically.
    
The logic in handleNoRelaxTlsRelocation remains the same for Mips as it
has its own custom GOT writing code. For ARM we add the module index
relocation to the GOT when it can be resolved statically.
    
In addition the type of the RelExpr for the static resolution of TlsGotRel
should be R_TLS and not R_ABS as we need to include the size of
the thread control block in the calculation.
    
Addresses the TLS part of PR30218.

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


Modified:
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Target.cpp
    lld/trunk/test/ELF/arm-tls-norelax-gd-le.s
    lld/trunk/test/ELF/arm-tls-norelax-ie-le.s
    lld/trunk/test/ELF/arm-tls-norelax-ld-le.s

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=288153&r1=288152&r2=288153&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Nov 29 10:23:50 2016
@@ -90,28 +90,36 @@ static bool isPreemptible(const SymbolBo
 // support any relaxations for TLS relocations so by factoring out ARM and MIPS
 // handling in to the separate function we can simplify the code and do not
 // pollute `handleTlsRelocation` by ARM and MIPS `ifs` statements.
-// FIXME: The ARM implementation always adds the module index dynamic
-// relocation even for non-preemptible symbols in applications. For static
-// linking support we must either resolve the module index relocation at static
-// link time, or hard code the module index (1) for the application in the GOT.
 template <class ELFT, class GOT>
 static unsigned handleNoRelaxTlsRelocation(
     GOT *Got, uint32_t Type, SymbolBody &Body, InputSectionBase<ELFT> &C,
     typename ELFT::uint Offset, typename ELFT::uint Addend, RelExpr Expr) {
+  typedef typename ELFT::uint uintX_t;
+  auto addModuleReloc = [](SymbolBody &Body, GOT *Got, uintX_t Off, bool LD) {
+    // The Dynamic TLS Module Index Relocation can be statically resolved to 1
+    // if we know that we are linking an executable. For ARM we resolve the
+    // relocation when writing the Got. MIPS has a custom Got implementation
+    // that writes the Module index in directly.
+    if (!Body.isPreemptible() && !Config->Pic && Config->EMachine == EM_ARM)
+      Got->Relocations.push_back(
+          {R_ABS, Target->TlsModuleIndexRel, Off, 0, &Body});
+    else {
+      SymbolBody *Dest = LD ? nullptr : &Body;
+      In<ELFT>::RelaDyn->addReloc(
+          {Target->TlsModuleIndexRel, Got, Off, false, Dest, 0});
+    }
+  };
   if (Expr == R_MIPS_TLSLD || Expr == R_TLSLD_PC) {
     if (Got->addTlsIndex() && (Config->Pic || Config->EMachine == EM_ARM))
-      In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, Got,
-                                   Got->getTlsIndexOff(), false, nullptr, 0});
+      addModuleReloc(Body, Got, Got->getTlsIndexOff(), true);
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
     return 1;
   }
-  typedef typename ELFT::uint uintX_t;
   if (Target->isTlsGlobalDynamicRel(Type)) {
     if (Got->addDynTlsEntry(Body) &&
         (Body.isPreemptible() || Config->EMachine == EM_ARM)) {
       uintX_t Off = Got->getGlobalDynOffset(Body);
-      In<ELFT>::RelaDyn->addReloc(
-          {Target->TlsModuleIndexRel, Got, Off, false, &Body, 0});
+      addModuleReloc(Body, Got, Off, false);
       if (Body.isPreemptible())
         In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Got,
                                      Off + (uintX_t)sizeof(uintX_t), false,
@@ -746,9 +754,11 @@ static void scanRelocs(InputSectionBase<
       In<ELFT>::Got->addEntry(Body);
       uintX_t Off = Body.getGotOffset<ELFT>();
       uint32_t DynType;
-      if (Body.isTls())
+      RelExpr GotRE = R_ABS;
+      if (Body.isTls()) {
         DynType = Target->TlsGotRel;
-      else if (!Preemptible && Config->Pic && !isAbsolute<ELFT>(Body))
+        GotRE = R_TLS;
+      } else if (!Preemptible && Config->Pic && !isAbsolute<ELFT>(Body))
         DynType = Target->RelativeRel;
       else
         DynType = Target->GotRel;
@@ -756,7 +766,7 @@ static void scanRelocs(InputSectionBase<
       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});
+        In<ELFT>::Got->Relocations.push_back({GotRE, DynType, Off, 0, &Body});
       continue;
     }
   }

Modified: lld/trunk/ELF/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Target.cpp?rev=288153&r1=288152&r2=288153&view=diff
==============================================================================
--- lld/trunk/ELF/Target.cpp (original)
+++ lld/trunk/ELF/Target.cpp Tue Nov 29 10:23:50 2016
@@ -1711,6 +1711,9 @@ void ARMTargetInfo::relocateOne(uint8_t
   case R_ARM_TLS_TPOFF32:
     write32le(Loc, Val);
     break;
+  case R_ARM_TLS_DTPMOD32:
+    write32le(Loc, 1);
+    break;
   case R_ARM_PREL31:
     checkInt<31>(Loc, Val, Type);
     write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));

Modified: lld/trunk/test/ELF/arm-tls-norelax-gd-le.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tls-norelax-gd-le.s?rev=288153&r1=288152&r2=288153&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-gd-le.s (original)
+++ lld/trunk/test/ELF/arm-tls-norelax-gd-le.s Tue Nov 29 10:23:50 2016
@@ -2,7 +2,7 @@
 // RUN: ld.lld %t1 --shared -o %t1.so
 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
 // RUN: ld.lld %t1.so %t.o -o %t
-// RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s
+// RUN: llvm-objdump -s %t | FileCheck %s
 // REQUIRES: arm
 
 // This tls global-dynamic sequence is with respect to a non-preemptible
@@ -31,7 +31,7 @@ x:
  .space 4
  .type  x, %object
 
-// CHECK: Dynamic Relocations {
-// CHECK-NEXT:   0x12078 R_ARM_TLS_DTPMOD32
-// CHECK-NEXT:   0x1300C R_ARM_JUMP_SLOT __tls_get_addr
+// CHECK:       Contents of section .got:
+// Module index is always 1 for executable
+// CHECK-NEXT:  12060 01000000 00000000
 

Modified: lld/trunk/test/ELF/arm-tls-norelax-ie-le.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tls-norelax-ie-le.s?rev=288153&r1=288152&r2=288153&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-ie-le.s (original)
+++ lld/trunk/test/ELF/arm-tls-norelax-ie-le.s Tue Nov 29 10:23:50 2016
@@ -2,7 +2,7 @@
 // RUN: ld.lld %t1 --shared -o %t1.so
 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
 // RUN: ld.lld %t1.so %t.o -o %t
-// RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t
+// RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t | FileCheck %s
 // REQUIRES: arm
 
 // This tls Initial Exec sequence is with respect to a non-preemptible symbol
@@ -37,5 +37,5 @@ x2:
  .type x2, %object
 
 // CHECK: Contents of section .got
-// x1 at offset 0 from TP, x2 at offset 4 from TP
-// 12064 00000000 04000000
+// x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 8
+// CHECK-NEXT: 12064 08000000 0c000000

Modified: lld/trunk/test/ELF/arm-tls-norelax-ld-le.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tls-norelax-ld-le.s?rev=288153&r1=288152&r2=288153&view=diff
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-ld-le.s (original)
+++ lld/trunk/test/ELF/arm-tls-norelax-ld-le.s Tue Nov 29 10:23:50 2016
@@ -2,7 +2,7 @@
 // RUN: ld.lld %t1 --shared -o %t1.so
 // RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
 // RUN: ld.lld %t1.so %t.o -o %t
-// RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s
+// RUN: llvm-objdump -s %t | FileCheck %s
 // REQUIRES: arm
 
  .global __tls_get_addr
@@ -31,6 +31,5 @@ y:
 x:
  .word   10
 
-// CHECK: Dynamic Relocations {
-// CHECK-NEXT:   0x1207C R_ARM_TLS_DTPMOD32 - 0x0
-// CHECK-NEXT:   0x1300C R_ARM_JUMP_SLOT __tls_get_addr 0x0
+// CHECK: Contents of section .got:
+// CHECK-NEXT:  12064 01000000 00000000




More information about the llvm-commits mailing list