[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