[lld] r333420 - [PPC64] Support General-Dynamic tls.

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Tue May 29 07:34:39 PDT 2018


Author: sfertile
Date: Tue May 29 07:34:38 2018
New Revision: 333420

URL: http://llvm.org/viewvc/llvm-project?rev=333420&view=rev
Log:
[PPC64] Support General-Dynamic tls.

Adds handling of all the relocation types for general-dynamic thread local
storage.

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

Added:
    lld/trunk/test/ELF/ppc64-general-dynamic-tls.s
Modified:
    lld/trunk/ELF/Arch/PPC64.cpp
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Relocations.h

Modified: lld/trunk/ELF/Arch/PPC64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/PPC64.cpp?rev=333420&r1=333419&r2=333420&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Tue May 29 07:34:38 2018
@@ -80,6 +80,9 @@ PPC64::PPC64() {
   PltHeaderSize = 60;
   NeedsThunks = true;
 
+  TlsModuleIndexRel = R_PPC64_DTPMOD64;
+  TlsOffsetRel = R_PPC64_DTPREL64;
+
   // We need 64K pages (at least under glibc/Linux, the loader won't
   // set different permissions on a finer granularity than that).
   DefaultMaxPageSize = 65536;
@@ -167,6 +170,13 @@ RelExpr PPC64::getRelExpr(RelType Type,
   case R_PPC64_REL32:
   case R_PPC64_REL64:
     return R_PC;
+  case R_PPC64_GOT_TLSGD16:
+  case R_PPC64_GOT_TLSGD16_HA:
+  case R_PPC64_GOT_TLSGD16_HI:
+  case R_PPC64_GOT_TLSGD16_LO:
+    return R_TLSGD_GOT;
+  case R_PPC64_TLSGD:
+    return R_HINT;
   default:
     return R_ABS;
   }
@@ -210,14 +220,18 @@ void PPC64::writePlt(uint8_t *Buf, uint6
 static std::pair<RelType, uint64_t> toAddr16Rel(RelType Type, uint64_t Val) {
   uint64_t V = Val - PPC64TocOffset;
   switch (Type) {
+  case R_PPC64_GOT_TLSGD16:
   case R_PPC64_TOC16:
     return {R_PPC64_ADDR16, V};
   case R_PPC64_TOC16_DS:
     return {R_PPC64_ADDR16_DS, V};
+  case R_PPC64_GOT_TLSGD16_HA:
   case R_PPC64_TOC16_HA:
     return {R_PPC64_ADDR16_HA, V};
+  case R_PPC64_GOT_TLSGD16_HI:
   case R_PPC64_TOC16_HI:
     return {R_PPC64_ADDR16_HI, V};
+  case R_PPC64_GOT_TLSGD16_LO:
   case R_PPC64_TOC16_LO:
     return {R_PPC64_ADDR16_LO, V};
   case R_PPC64_TOC16_LO_DS:

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=333420&r1=333419&r2=333420&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Tue May 29 07:34:38 2018
@@ -633,6 +633,8 @@ static uint64_t getRelocTargetVA(RelType
            getAArch64Page(P);
   case R_TLSGD:
     return InX::Got->getGlobalDynOffset(Sym) + A - InX::Got->getSize();
+  case R_TLSGD_GOT:
+    return InX::Got->getGlobalDynOffset(Sym) + A;
   case R_TLSGD_PC:
     return InX::Got->getGlobalDynAddr(Sym) + A - P;
   case R_TLSLD:

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=333420&r1=333419&r2=333420&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue May 29 07:34:38 2018
@@ -219,7 +219,7 @@ handleTlsRelocation(RelType Type, Symbol
   }
 
   if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD,
-                     R_TLSGD_PC>(Expr)) {
+                     R_TLSGD_GOT, R_TLSGD_PC>(Expr)) {
     if (Config->Shared) {
       if (InX::Got->addDynTlsEntry(Sym)) {
         uint64_t Off = InX::Got->getGlobalDynOffset(Sym);
@@ -347,9 +347,9 @@ static bool isStaticLinkTimeConstant(Rel
   if (isRelExprOneOf<R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
                      R_MIPS_GOTREL, R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32,
                      R_MIPS_GOT_GP_PC, R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC,
-                     R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC,
-                     R_TLSGD, R_PPC_CALL_PLT, R_TLSDESC_CALL, R_TLSDESC_PAGE,
-                     R_HINT>(E))
+                     R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_GOT,
+                     R_TLSGD_PC, R_TLSGD, R_PPC_CALL_PLT, R_TLSDESC_CALL,
+                     R_TLSDESC_PAGE, R_HINT>(E))
     return true;
 
   // These never do, except if the entire file is position dependent or if

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=333420&r1=333419&r2=333420&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Tue May 29 07:34:38 2018
@@ -78,6 +78,7 @@ enum RelExpr {
   R_TLSDESC_CALL,
   R_TLSDESC_PAGE,
   R_TLSGD,
+  R_TLSGD_GOT,
   R_TLSGD_PC,
   R_TLSLD,
   R_TLSLD_PC,

Added: lld/trunk/test/ELF/ppc64-general-dynamic-tls.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-general-dynamic-tls.s?rev=333420&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-general-dynamic-tls.s (added)
+++ lld/trunk/test/ELF/ppc64-general-dynamic-tls.s Tue May 29 07:34:38 2018
@@ -0,0 +1,112 @@
+// REQUIRES: ppc
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
+
+// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
+// RUN: ld.lld -shared %t.o -o %t.so
+// RUN: llvm-readelf -relocations --wide %t.o | FileCheck --check-prefix=InputRelocs %s
+// RUN: llvm-readelf -relocations --wide %t.so | FileCheck --check-prefix=OutputRelocs %s
+// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
+// RUN: llvm-objdump -D %t.so | FileCheck --check-prefix=Dis %s
+
+	.text
+	.abiversion 2
+	.globl	test
+	.p2align	4
+	.type	test, at function
+test:
+.Lfunc_gep0:
+	addis 2, 12, .TOC.-.Lfunc_gep0 at ha
+	addi 2, 2, .TOC.-.Lfunc_gep0 at l
+.Lfunc_lep0:
+	.localentry	test, .Lfunc_lep0-.Lfunc_gep0
+	mflr 0
+	std 31, -8(1)
+	std 0, 16(1)
+	stdu 1, -48(1)
+	mr 31, 1
+	std 30, 32(31)
+	addis 3, 2, i at got@tlsgd at ha
+	addi 3, 3, i at got@tlsgd at l
+	bl __tls_get_addr(i at tlsgd)
+	nop
+	lwz 30, 0(3)
+	extsw 3, 30
+	ld 30, 32(31)
+	addi 1, 1, 48
+	ld 0, 16(1)
+	ld 31, -8(1)
+	mtlr 0
+	blr
+
+
+test_hi:
+.Lfunc_gep1:
+  addis 2, 12, .TOC.-.Lfunc_gep1 at ha
+  addi  2, 2,  .TOC.-.Lfunc_gep1 at l
+.Lfunc_lep1:
+  .localentry test2, .Lfunc_lep1-.Lfunc_gep1
+  addis 3, 0, j at got@tlsgd at h
+  blr
+
+test_16:
+.Lfunc_gep2:
+  addis 2, 12, .TOC.-.Lfunc_gep2 at ha
+  addi 2, 2, .TOC.-.Lfunc_gep2 at l
+.Lfunc_lep2:
+  .localentry test16, .Lfunc_lep2-.Lfunc_gep2
+  addi 3, 0, k at got@tlsgd
+  blr
+
+// Verify that the input has every general-dynamic tls relocation type.
+// InputRelocs:  Relocation section '.rela.text'
+// InputRelocs: R_PPC64_GOT_TLSGD16_HA  {{0+}}  i + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16_LO  {{0+}}  i + 0
+// InputRelocs: R_PPC64_TLSGD           {{0+}}  i + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16_HI  {{0+}}  j + 0
+// InputRelocs: R_PPC64_GOT_TLSGD16     {{0+}}  k + 0
+
+// There is 2 got entries for each tls variable that is accessed with the
+// general-dynamic model.  The entries can be though of as a structure to be
+// filled in by the dynamic linker:
+// typedef struct {
+//  unsigned long int ti_module; --> R_PPC64_DTPMOD64
+//  unsigned long int ti_offset; --> R_PPC64_DTPREL64
+//} tls_index;
+// OutputRelocs: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 6 entries:
+// OutputRelocs: R_PPC64_DTPMOD64  {{0+}}  i + 0
+// OutputRelocs: R_PPC64_DTPREL64  {{0+}}  i + 0
+// OutputRelocs: R_PPC64_DTPMOD64  {{0+}}  j + 0
+// OutputRelocs: R_PPC64_DTPREL64  {{0+}}  j + 0
+// OutputRelocs: R_PPC64_DTPMOD64  {{0+}}  k + 0
+// OutputRelocs: R_PPC64_DTPREL64  {{0+}}  k + 0
+
+// Check that the got has 7 entires. (1 for the TOC and 3 structures of
+// 2 entries for the tls variables). Also verify the address so we can check
+// the offsets we calculated for each relocation type.
+// CheckGot: got          00000038 00000000000200f0
+
+// got starts at 0x200f0, so .TOC. will be 0x280f0.
+
+// We are building the address of the first tls_index in the got which starts at
+// 0x200f8 (got[1]).
+// #ha(i at got@tlsgd) --> (0x200f8 - 0x280f0 + 0x8000) >> 16 = 0
+// #lo(i at got@tlsgd) --> (0x200f8 - 0x280f0) & 0xFFFF =  -7ff8 = -32760
+// Dis:  test:
+// Dis:    addis 3, 2, 0
+// Dis:    addi 3, 3, -32760
+
+// Second tls_index starts at got[3].
+// #hi(j at got@tlsgd) --> (0x20108 - 0x280f0) >> 16 = -1
+// Dis: test_hi:
+// Dis:   lis 3, -1
+
+// Third tls index is at got[5].
+// k at got@tlsgd --> (0x20118 -  0x280f0) = -0x7fd8 = -32728
+// Dis: test_16:
+// Dis:   li 3, -32728




More information about the llvm-commits mailing list