[lld] r333681 - [PPC64] Support R_PPC64_GOT_TLSLD16 relocations.

Sean Fertile via llvm-commits llvm-commits at lists.llvm.org
Thu May 31 11:44:12 PDT 2018


Author: sfertile
Date: Thu May 31 11:44:12 2018
New Revision: 333681

URL: http://llvm.org/viewvc/llvm-project?rev=333681&view=rev
Log:
[PPC64] Support R_PPC64_GOT_TLSLD16 relocations.

Add support for the R_PPC64_GOT_TLSLD16 relocations used to build the address of
the tls_index struct used in local-dynamic tls.

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

Added:
    lld/trunk/test/ELF/ppc64-local-dynamic.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=333681&r1=333680&r2=333681&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/PPC64.cpp (original)
+++ lld/trunk/ELF/Arch/PPC64.cpp Thu May 31 11:44:12 2018
@@ -175,7 +175,13 @@ RelExpr PPC64::getRelExpr(RelType Type,
   case R_PPC64_GOT_TLSGD16_HI:
   case R_PPC64_GOT_TLSGD16_LO:
     return R_TLSGD_GOT;
+  case R_PPC64_GOT_TLSLD16:
+  case R_PPC64_GOT_TLSLD16_HA:
+  case R_PPC64_GOT_TLSLD16_HI:
+  case R_PPC64_GOT_TLSLD16_LO:
+    return R_TLSLD_GOT;
   case R_PPC64_TLSGD:
+  case R_PPC64_TLSLD:
     return R_HINT;
   default:
     return R_ABS;
@@ -221,17 +227,21 @@ static std::pair<RelType, uint64_t> toAd
   uint64_t V = Val - PPC64TocOffset;
   switch (Type) {
   case R_PPC64_GOT_TLSGD16:
+  case R_PPC64_GOT_TLSLD16:
   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_GOT_TLSLD16_HA:
   case R_PPC64_TOC16_HA:
     return {R_PPC64_ADDR16_HA, V};
   case R_PPC64_GOT_TLSGD16_HI:
+  case R_PPC64_GOT_TLSLD16_HI:
   case R_PPC64_TOC16_HI:
     return {R_PPC64_ADDR16_HI, V};
   case R_PPC64_GOT_TLSGD16_LO:
+  case R_PPC64_GOT_TLSLD16_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=333681&r1=333680&r2=333681&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Thu May 31 11:44:12 2018
@@ -639,6 +639,8 @@ static uint64_t getRelocTargetVA(RelType
     return InX::Got->getGlobalDynAddr(Sym) + A - P;
   case R_TLSLD_GOT_FROM_END:
     return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();
+  case R_TLSLD_GOT:
+      return InX::Got->getTlsIndexOff() + A;
   case R_TLSLD_PC:
     return InX::Got->getTlsIndexVA() + A - P;
   }

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=333681&r1=333680&r2=333681&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Thu May 31 11:44:12 2018
@@ -198,7 +198,7 @@ handleTlsRelocation(RelType Type, Symbol
     return 1;
   }
 
-  if (isRelExprOneOf<R_TLSLD_PC, R_TLSLD_GOT_FROM_END>(Expr)) {
+  if (isRelExprOneOf<R_TLSLD_GOT, R_TLSLD_GOT_FROM_END, R_TLSLD_PC>(Expr)) {
     // Local-Dynamic relocs can be relaxed to Local-Exec.
     if (!Config->Shared) {
       C.Relocations.push_back(

Modified: lld/trunk/ELF/Relocations.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.h?rev=333681&r1=333680&r2=333681&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.h (original)
+++ lld/trunk/ELF/Relocations.h Thu May 31 11:44:12 2018
@@ -81,6 +81,7 @@ enum RelExpr {
   R_TLSGD_GOT_FROM_END,
   R_TLSGD_PC,
   R_TLSLD_GOT_FROM_END,
+  R_TLSLD_GOT,
   R_TLSLD_PC,
 };
 

Added: lld/trunk/test/ELF/ppc64-local-dynamic.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/ppc64-local-dynamic.s?rev=333681&view=auto
==============================================================================
--- lld/trunk/test/ELF/ppc64-local-dynamic.s (added)
+++ lld/trunk/test/ELF/ppc64-local-dynamic.s Thu May 31 11:44:12 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 0, 16(1)
+        stdu 1, -32(1)
+        addis 3, 2, i at got@tlsld at ha
+        addi 3, 3, i at got@tlsld at l
+        bl __tls_get_addr(i at tlsld)
+        nop
+        ld 0, 16(1)
+        mtlr 0
+        blr
+
+        .globl test_hi
+        .p2align 4
+        .type test_hi, at function
+test_hi:
+         lis 3, j at got@tlsld at h
+         blr
+
+        .globl test_16
+        .p2align 4
+        .type test_16, at function
+test_16:
+         li 3, k at got@tlsld
+         blr
+
+        .type   i, at object
+        .section        .tdata,"awT", at progbits
+        .p2align        2
+i:
+        .long   55
+        .size   i, 4
+
+        .type   j, at object
+        .section        .tbss,"awT", at nobits
+        .p2align        2
+j:
+        .long   0
+        .size   j, 4
+
+        .type   k, at object
+        .section        .tdata,"awT", at progbits
+        .p2align        3
+k:
+        .quad   66
+        .size   k, 8
+
+// Verify that the input contains all the R_PPC64_GOT_TLSLD16* relocations.
+// InputRelocs: Relocation section '.rela.text'
+// InputRelocs:     R_PPC64_GOT_TLSLD16_HA 0000000000000000 i + 0
+// InputRelocs:     R_PPC64_GOT_TLSLD16_LO 0000000000000000 i + 0
+// InputRelocs:     R_PPC64_TLSLD          0000000000000000 i + 0
+// InputRelocs:     R_PPC64_GOT_TLSLD16_HI 0000000000000000 j + 0
+// InputRelocs:     R_PPC64_GOT_TLSLD16    0000000000000008 k + 0
+
+// The local dynamic version of tls needs to use the same mechanism to look up
+// a variables address as general-dynamic. ie a call to __tls_get_addr with the
+// address of a tls_index struct as the argument. However for local-dynamic
+// variables  all will have the same ti_module, and the offset field is left as
+// as 0, so the same struct can be used for every local-dynamic variable
+// used in the shared-object.
+// OutputRelocs:      Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 1 entries:
+// OutputRelocs-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
+// OutputRelocs-NEXT: R_PPC64_DTPMOD64
+
+// Check that the got has 3 entries, 1 for the TOC and 1 stucture of 2 entries
+// for the tls variables. Also verify the address so we can check the offsets
+// we calculate for each relocation type.
+// CheckGot: got          00000018 0000000000020100
+
+// got starts at 0x20100 so .TOC. will be 0x28100, and the tls_index struct is
+// at 0x20108.
+
+// #ha(i at got@tlsld) --> (0x20108 - 0x28100 + 0x8000) >> 16 = 0
+// #lo(i at got@tlsld) --> (0x20108 - 0x28100) = -7ff8 = -32760
+// Dis:     test:
+// Dis:        addis 3, 2, 0
+// Dis-NEXT:   addi 3, 3, -32760
+
+// #hi(j at got@tlsld) --> (0x20108 - 0x28100 ) > 16 = -1
+// Dis: test_hi:
+// Dis:   lis 3, -1
+
+// k at got@tlsld --> (0x20108 - 0x28100) = -7ff8 = -32760
+// Dis: test_16:
+// Dis:   li 3, -32760




More information about the llvm-commits mailing list