[lld] r335730 - [PPC64] Add TLS global dynamic to local exec relaxation

Zaara Syeda via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 27 06:27:30 PDT 2018


Author: syzaara
Date: Wed Jun 27 06:27:29 2018
New Revision: 335730

URL: http://llvm.org/viewvc/llvm-project?rev=335730&view=rev
Log:
[PPC64] Add TLS global dynamic to local exec relaxation

This patch adds the target call back relaxTlsGdToLe to support TLS relaxation
from global dynamic to local exec model.

The relaxation performs the following transformation:
addis r3, r2, x at got@tlsgd at ha --> nop
addi r3, r3, x at got@tlsgd at l   --> addis r3, r13, x at tprel@ha
bl __tls_get_addr(x at tlsgd)   --> nop
nop                          --> addi r3, r3, x at tprel@l

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

Added:
    lld/trunk/test/ELF/ppc64-tls-gd-le.s
Modified:
    lld/trunk/ELF/Arch/PPC64.cpp

Modified: lld/trunk/ELF/Arch/PPC64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=335730&r1=335729&r2=335730&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Wed Jun 27 06:27:29 2018
@@ -54,6 +54,7 @@ public:
   RelExpr adjustRelaxExpr(RelType Type, const uint8_t *Data,
                           RelExpr Expr) const override;
   void relaxTlsGdToIe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
+  void relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const override;
 };
 } // namespace
 
@@ -159,6 +160,42 @@ uint32_t PPC64::calcEFlags() const {
   return 2;
 }
 
+void PPC64::relaxTlsGdToLe(uint8_t *Loc, RelType Type, uint64_t Val) const {
+  // Reference: 3.7.4.2 of the 64-bit ELF V2 abi supplement.
+  // The general dynamic code sequence for a global `x` will look like:
+  // Instruction                    Relocation                Symbol
+  // addis r3, r2, x at got@tlsgd at ha   R_PPC64_GOT_TLSGD16_HA      x
+  // addi  r3, r3, x at got@tlsgd at l    R_PPC64_GOT_TLSGD16_LO      x
+  // bl __tls_get_addr(x at tlsgd)     R_PPC64_TLSGD               x
+  //                                R_PPC64_REL24               __tls_get_addr
+  // nop                            None                       None
+
+  // Relaxing to local exec entails converting:
+  // addis r3, r2, x at got@tlsgd at ha    into      nop
+  // addi  r3, r3, x at got@tlsgd at l     into      addis r3, r13, x at tprel@ha
+  // bl __tls_get_addr(x at tlsgd)      into      nop
+  // nop                             into      addi r3, r3, x at tprel@l
+
+  uint32_t EndianOffset = Config->EKind == ELF64BEKind ? 2U : 0U;
+
+  switch (Type) {
+  case R_PPC64_GOT_TLSGD16_HA:
+    write32(Loc - EndianOffset, 0x60000000); // nop
+    break;
+  case R_PPC64_GOT_TLSGD16_LO:
+    write32(Loc - EndianOffset, 0x3c6d0000); // addis r3, r13
+    relocateOne(Loc, R_PPC64_TPREL16_HA, Val);
+    break;
+  case R_PPC64_TLSGD:
+    write32(Loc, 0x60000000);     // nop
+    write32(Loc + 4, 0x38630000); // addi r3, r3
+    relocateOne(Loc + 4 + EndianOffset, R_PPC64_TPREL16_LO, Val);
+    break;
+  default:
+    llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
+  }
+}
+
 RelExpr PPC64::getRelExpr(RelType Type, const Symbol &S,
                           const uint8_t *Loc) const {
   switch (Type) {

Added: lld/trunk/test/ELF/ppc64-tls-gd-le.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-tls-gd-le.s?rev=335730&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-tls-gd-le.s (added)
+++ lld/trunk/test/ELF/ppc64-tls-gd-le.s Wed Jun 27 06:27:29 2018
@@ -0,0 +1,83 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: ld.lld  %t.o -o %t
+// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: ld.lld  %t.o -o %t
+// RUN: llvm-objdump -D %t | FileCheck --check-prefix=Dis %s
+// RUN: llvm-readelf -relocations --wide %t | FileCheck --check-prefix=OutputRelocs %s
+
+	.text
+	.abiversion 2
+	.globl	_start                    # -- Begin function _start
+	.p2align	4
+	.type	_start, at function
+_start:                                   # @_start
+.Lfunc_begin0:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0 at ha
+	addi 2, 2, .TOC.-.Lfunc_gep0 at l
+.Lfunc_lep0:
+	.localentry	_start, .Lfunc_lep0-.Lfunc_gep0
+# %bb.0:                                # %entry
+	mflr 0
+	std 31, -8(1)
+	std 0, 16(1)
+	stdu 1, -64(1)
+	mr 31, 1
+	std 30, 48(31)                  # 8-byte Folded Spill
+	li 3, 0
+	stw 3, 44(31)
+	addis 3, 2, a at got@tlsgd at ha
+	addi 3, 3, a at got@tlsgd at l
+	bl __tls_get_addr(a at tlsgd)
+	nop
+	lwz 30, 0(3)
+	extsw 3, 30
+	ld 30, 48(31)                   # 8-byte Folded Reload
+	addi 1, 1, 64
+	ld 0, 16(1)
+	ld 31, -8(1)
+	mtlr 0
+	blr
+	.long	0
+	.quad	0
+.Lfunc_end0:
+	.size	_start, .Lfunc_end0-.Lfunc_begin0
+
+.globl __tls_get_addr
+.type __tls_get_addr, at function
+__tls_get_addr:
+
+                                        # -- End function
+	.type	a, at object               # @a
+	.section	.tdata,"awT", at progbits
+	.globl	a
+	.p2align	2
+a:
+	.long	55                      # 0x37
+	.size	a, 4
+
+// Verify that the input has general-dynamic tls relocation types
+// InputRelocs:  Relocation section '.rela.text'
+// InputRelocs: R_PPC64_GOT_TLSGD16_HA  {{0+}}  a + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16_LO  {{0+}}  a + 0
+// InputRelocs: R_PPC64_TLSGD           {{0+}}  a + 0
+
+// Verify that the general-dynamic sequence is  relaxed to local exec.
+// #ha(a at tprel) --> (0 - 0x7000 + 0x8000) >> 16 = 0
+// #lo(a at tprel)) --> (0 - 0x7000) &  0xFFFF =  -0x7000 = -28672
+// Dis: _start:
+// Dis: nop
+// Dis: addis 3, 13, 0
+// Dis: nop
+// Dis: addi 3, 3, -28672
+
+// Verify that no general-dynamic relocations exist for the dynamic linker.
+// OutputRelocs-NOT: R_PPC64_DTPMOD64
+// OutputRelocs-NOT: R_PPC64_DTPREL64




More information about the llvm-commits mailing list