[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