summaryrefslogtreecommitdiffstats
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorZaara Syeda <syzaara@ca.ibm.com>2018-06-08 17:04:09 +0000
committerZaara Syeda <syzaara@ca.ibm.com>2018-06-08 17:04:09 +0000
commit4455b3766671a8b467eccf5cb388d45d3ff0b70a (patch)
tree66ac09297e57fe279aa23dd94d8db316ff8826b9 /lld/ELF/InputSection.cpp
parent89deac669441f847fb389dacab0bcdf7e7f85de2 (diff)
downloadbcm5719-llvm-4455b3766671a8b467eccf5cb388d45d3ff0b70a.tar.gz
bcm5719-llvm-4455b3766671a8b467eccf5cb388d45d3ff0b70a.zip
[PPC64] Add support for local-exec TLS model
This patch adds the relocations needed support the local-exec TLS model: R_PPC64_TPREL16 R_PPC64_TPREL16_HA R_PPC64_TPREL16_LO R_PPC64_TPREL16_HI R_PPC64_TPREL16_DS R_PPC64_TPREL16_LO_DS R_PPC64_TPREL16_HIGHER R_PPC64_TPREL16_HIGHERA R_PPC64_TPREL16_HIGHEST R_PPC64_TPREL16_HIGHESTA Differential Revision: https://reviews.llvm.org/D47598 llvm-svn: 334304
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp17
1 files changed, 16 insertions, 1 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 09bc39eaed1..32f1f4846f7 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -618,8 +618,23 @@ static uint64_t getRelocTargetVA(RelType Type, int64_t A, uint64_t P,
// statically to zero.
if (Sym.isTls() && Sym.isUndefWeak())
return 0;
- if (Target->TcbSize)
+
+ // For TLS variant 1 the TCB is a fixed size, whereas for TLS variant 2 the
+ // TCB is on unspecified size and content. Targets that implement variant 1
+ // should set TcbSize.
+ if (Target->TcbSize) {
+ // PPC64 V2 ABI has the thread pointer offset into the middle of the TLS
+ // storage area by TlsTpOffset for efficient addressing TCB and up to
+ // 4KB – 8 B of other thread library information (placed before the TCB).
+ // Subtracting this offset will get the address of the first TLS block.
+ if (Target->TlsTpOffset)
+ return Sym.getVA(A) - Target->TlsTpOffset;
+
+ // If thread pointer is not offset into the middle, the first thing in the
+ // TLS storage area is the TCB. Add the TcbSize to get the address of the
+ // first TLS block.
return Sym.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align);
+ }
return Sym.getVA(A) - Out::TlsPhdr->p_memsz;
case R_RELAX_TLS_GD_TO_LE_NEG:
case R_NEG_TLS:
OpenPOWER on IntegriCloud