[lld] r282250 - [ARM] ARM TLS shouldn't use relaxations

Peter Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 23 06:54:49 PDT 2016


Author: psmith
Date: Fri Sep 23 08:54:48 2016
New Revision: 282250

URL: http://llvm.org/viewvc/llvm-project?rev=282250&view=rev
Log:
[ARM] ARM TLS shouldn't use relaxations

The ARM TLS relocations are placed on literal data and not the 
code-sequence, it is therefore not possible to implement the relaxTls* 
functions. This change updates handleMipsTlsRelocation() to
handleNoRelaxTlsRelocation() and incorporates ARM as well as Mips.

The ARM support in handleNoRelaxTlsRelocation() currently needs to ouput
the module index dynamic relocation in all cases as it is relying on the 
dynamic linker to set the module index in the got.

Should address PR30218

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


Added:
    lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s   (with props)
    lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s   (with props)
    lld/trunk/test/ELF/arm-tls-norelax-gd-le.s   (with props)
    lld/trunk/test/ELF/arm-tls-norelax-ie-le.s   (with props)
    lld/trunk/test/ELF/arm-tls-norelax-ld-le.s   (with props)
Modified:
    lld/trunk/ELF/Relocations.cpp

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=282250&r1=282249&r2=282250&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Fri Sep 23 08:54:48 2016
@@ -83,32 +83,40 @@ static bool isPreemptible(const SymbolBo
   return Body.isPreemptible();
 }
 
-// This function is similar to the `handleTlsRelocation`. MIPS does not support
-// any relaxations for TLS relocations so by factoring out MIPS handling into
-// the separate function we can simplify the code and does not pollute
-// `handleTlsRelocation` by MIPS `ifs` statements.
+// This function is similar to the `handleTlsRelocation`. ARM and MIPS do not
+// 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>
-static unsigned
-handleMipsTlsRelocation(uint32_t Type, SymbolBody &Body,
-                        InputSectionBase<ELFT> &C, typename ELFT::uint Offset,
-                        typename ELFT::uint Addend, RelExpr Expr) {
-  if (Expr == R_MIPS_TLSLD) {
-    if (Out<ELFT>::Got->addTlsIndex() && Config->Pic)
+static unsigned handleNoRelaxTlsRelocation(uint32_t Type, SymbolBody &Body,
+                                           InputSectionBase<ELFT> &C,
+                                           typename ELFT::uint Offset,
+                                           typename ELFT::uint Addend,
+                                           RelExpr Expr) {
+  if (Expr == R_MIPS_TLSLD || Expr == R_TLSLD_PC) {
+    if (Out<ELFT>::Got->addTlsIndex() &&
+        (Config->Pic || Config->EMachine == EM_ARM))
       Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, Out<ELFT>::Got,
                                     Out<ELFT>::Got->getTlsIndexOff(), false,
                                     nullptr, 0});
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
     return 1;
   }
+  typedef typename ELFT::uint uintX_t;
   if (Target->isTlsGlobalDynamicRel(Type)) {
-    if (Out<ELFT>::Got->addDynTlsEntry(Body) && Body.isPreemptible()) {
-      typedef typename ELFT::uint uintX_t;
+    if (Out<ELFT>::Got->addDynTlsEntry(Body) &&
+        (Body.isPreemptible() || Config->EMachine == EM_ARM)) {
       uintX_t Off = Out<ELFT>::Got->getGlobalDynOffset(Body);
       Out<ELFT>::RelaDyn->addReloc(
           {Target->TlsModuleIndexRel, Out<ELFT>::Got, Off, false, &Body, 0});
-      Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Out<ELFT>::Got,
-                                    Off + (uintX_t)sizeof(uintX_t), false,
-                                    &Body, 0});
+      if (Body.isPreemptible())
+        Out<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, Out<ELFT>::Got,
+                                      Off + (uintX_t)sizeof(uintX_t), false,
+                                      &Body, 0});
     }
     C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
     return 1;
@@ -130,8 +138,9 @@ static unsigned handleTlsRelocation(uint
 
   typedef typename ELFT::uint uintX_t;
 
-  if (Config->EMachine == EM_MIPS)
-    return handleMipsTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr);
+  if (Config->EMachine == EM_MIPS || Config->EMachine == EM_ARM)
+    return handleNoRelaxTlsRelocation<ELFT>(Type, Body, C, Offset, Addend,
+                                            Expr);
 
   if ((Expr == R_TLSDESC || Expr == R_TLSDESC_PAGE || Expr == R_HINT) &&
       Config->Shared) {

Added: lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s?rev=282250&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s (added)
+++ lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s Fri Sep 23 08:54:48 2016
@@ -0,0 +1,13 @@
+ .syntax unified
+ .text
+ .globl __tls_get_addr
+ .type __tls_get_addr,%function
+__tls_get_addr:
+ bx lr
+
+.section       .tbss,"awT",%nobits
+ .p2align  2
+y:
+ .space 4
+ .globl y
+ .type  y, %object

Propchange: lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/Inputs/arm-tls-get-addr.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s?rev=282250&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s (added)
+++ lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s Fri Sep 23 08:54:48 2016
@@ -0,0 +1,30 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
+// 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
+// REQUIRES: arm
+
+// This tls global-dynamic sequence is with respect to a preemptible symbol but
+// is in an application so a relaxation to Initial Exec would normally be
+// possible. This would result in an assertion failure on ARM as the
+// relaxation functions can't be implemented on ARM. Check that the sequence
+// is handled as global dynamic
+
+ .text
+ .syntax unified
+ .globl  func
+ .p2align        2
+ .type   func,%function
+func:
+.L0:
+ .globl __tls_get_addr
+ bl __tls_get_addr
+ bx lr
+ .p2align 2
+ .Lt0: .word   y(TLSGD) + (. - .L0 - 8)
+
+// CHECK: Dynamic Relocations {
+// CHECK-NEXT:   0x12078 R_ARM_TLS_DTPMOD32 y
+// CHECK-NEXT:   0x1207C R_ARM_TLS_DTPOFF32 y
+// CHECK-NEXT:   0x1300C R_ARM_JUMP_SLOT __tls_get_addr

Propchange: lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-tls-norelax-gd-ie.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: 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=282250&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-gd-le.s (added)
+++ lld/trunk/test/ELF/arm-tls-norelax-gd-le.s Fri Sep 23 08:54:48 2016
@@ -0,0 +1,37 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
+// 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
+// REQUIRES: arm
+
+// This tls global-dynamic sequence is with respect to a non-preemptible
+// symbol in an application so a relaxation to Local Exec would normally be
+// possible. This would result in an assertion failure on ARM as the
+// relaxation functions can't be implemented on ARM. Check that the sequence
+// is handled as global dynamic
+
+ .text
+ .syntax unified
+ .globl  func
+ .p2align        2
+ .type   func,%function
+func:
+.L0:
+ .globl __tls_get_addr
+ bl __tls_get_addr
+ bx lr
+ .p2align 2
+ .Lt0: .word   x(TLSGD) + (. - .L0 - 8)
+
+ .globl  x
+.section       .tbss,"awT",%nobits
+ .p2align  2
+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
+

Propchange: lld/trunk/test/ELF/arm-tls-norelax-gd-le.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-tls-norelax-gd-le.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: 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=282250&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-ie-le.s (added)
+++ lld/trunk/test/ELF/arm-tls-norelax-ie-le.s Fri Sep 23 08:54:48 2016
@@ -0,0 +1,41 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
+// 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
+// REQUIRES: arm
+
+// This tls Initial Exec sequence is with respect to a non-preemptible symbol
+// so a relaxation would normally be possible. This would result in an assertion
+// failure on ARM as the relaxation functions can't be implemented on ARM.
+// Check that the sequence is handled as initial exec
+ .text
+ .syntax unified
+ .globl  func
+ .p2align        2
+ .type   func,%function
+func:
+.L0:
+ .globl __tls_get_addr
+ bl __tls_get_addr
+.L1:
+ bx lr
+ .p2align 2
+ .Lt0: .word  x1(gottpoff) + (. - .L0 - 8)
+ .Lt1: .word  x2(gottpoff) + (. - .L1 - 8)
+
+ .globl  x1
+ .section       .trw,"awT",%progbits
+ .p2align  2
+x1:
+ .word 0x1
+ .globl x2
+ .section       .tbss,"awT",%nobits
+ .type  x1, %object
+x2:
+ .space 4
+ .type x2, %object
+
+// CHECK: Contents of section .got
+// x1 at offset 0 from TP, x2 at offset 4 from TP
+// 12064 00000000 04000000

Propchange: lld/trunk/test/ELF/arm-tls-norelax-ie-le.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-tls-norelax-ie-le.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id

Added: 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=282250&view=auto
==============================================================================
--- lld/trunk/test/ELF/arm-tls-norelax-ld-le.s (added)
+++ lld/trunk/test/ELF/arm-tls-norelax-ld-le.s Fri Sep 23 08:54:48 2016
@@ -0,0 +1,36 @@
+// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
+// 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
+// REQUIRES: arm
+
+ .global __tls_get_addr
+ .text
+ .p2align  2
+ .global _start
+ .syntax unified
+ .arm
+ .type   _start, %function
+_start:
+.L0:
+ bl __tls_get_addr
+
+ .word   x(tlsldm) + (. - .L0 - 8)
+ .word   x(tlsldo)
+ .word   y(tlsldo)
+
+ .section        .tbss,"awT",%nobits
+ .p2align  2
+ .type   y, %object
+y:
+ .space  4
+ .section        .tdata,"awT",%progbits
+ .p2align  2
+ .type   x, %object
+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

Propchange: lld/trunk/test/ELF/arm-tls-norelax-ld-le.s
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lld/trunk/test/ELF/arm-tls-norelax-ld-le.s
------------------------------------------------------------------------------
    svn:keywords = Rev Date Author URL Id




More information about the llvm-commits mailing list