[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