From 4dc4bc4e3c8c6fcfadfe896419a443534a1a0cc8 Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Thu, 13 Apr 2017 10:56:40 +0000 Subject: [PATCH] [ELF] Tidy up handleARMTlsRelocation [NFC] Replace addModuleReloc with AddTlsReloc so that we can use it for both the module relocation and the offset relocation. Differential Revision: https://reviews.llvm.org/D31751 llvm-svn: 300192 --- lld/ELF/Relocations.cpp | 36 +++++++++++++++++------------------- lld/ELF/Target.cpp | 1 + 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 7cc048f74800..baef0a2f2257 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -147,17 +147,18 @@ template static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C, uint64_t Offset, int64_t Addend, RelExpr Expr) { - auto addModuleReloc = [&](uint64_t Off, bool LD) { - // The Dynamic TLS Module Index Relocation can be statically resolved to 1 - // if we know that the TLS Symbol is in an executable. - if (!Body.isPreemptible() && !Config->Pic) - In::Got->Relocations.push_back( - {R_ABS, Target->TlsModuleIndexRel, Off, 0, &Body}); - else { - SymbolBody *Dest = LD ? nullptr : &Body; - In::RelaDyn->addReloc( - {Target->TlsModuleIndexRel, In::Got, Off, false, Dest, 0}); - } + // The Dynamic TLS Module Index Relocation for a symbol defined in an + // executable is always 1. If the target Symbol is not preemtible then + // we know the offset into the TLS block at static link time. + bool NeedDynId = Body.isPreemptible() || Config->Shared; + bool NeedDynOff = Body.isPreemptible(); + + auto AddTlsReloc = [&](uint64_t Off, uint32_t Type, SymbolBody *Dest, + bool Dyn) { + if (Dyn) + In::RelaDyn->addReloc({Type, In::Got, Off, false, Dest, 0}); + else + In::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest}); }; // Local Dynamic is for access to module local TLS variables, while still @@ -165,7 +166,8 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, // GOT[e0] is the module index, with a special value of 0 for the current // module. GOT[e1] is unused. There only needs to be one module index entry. if (Expr == R_TLSLD_PC && In::Got->addTlsIndex()) { - addModuleReloc(In::Got->getTlsIndexOff(), true); + AddTlsReloc(In::Got->getTlsIndexOff(), Target->TlsModuleIndexRel, + NeedDynId ? nullptr : &Body, NeedDynId); C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; } @@ -176,13 +178,9 @@ static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body, if (Expr == R_TLSGD_PC) { if (In::Got->addDynTlsEntry(Body)) { uint64_t Off = In::Got->getGlobalDynOffset(Body); - addModuleReloc(Off, false); - if (Body.isPreemptible()) - In::RelaDyn->addReloc({Target->TlsOffsetRel, In::Got, - Off + Config->Wordsize, false, &Body, 0}); - else - In::Got->Relocations.push_back( - {R_ABS, R_ARM_ABS32, Off + Config->Wordsize, 0, &Body}); + AddTlsReloc(Off, Target->TlsModuleIndexRel, &Body, NeedDynId); + AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Body, + NeedDynOff); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp index 017775791a55..664dcd1ed44e 100644 --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -1874,6 +1874,7 @@ void ARMTargetInfo::relocateOne(uint8_t *Loc, uint32_t Type, case R_ARM_TLS_LDO32: case R_ARM_TLS_LE32: case R_ARM_TLS_TPOFF32: + case R_ARM_TLS_DTPOFF32: write32le(Loc, Val); break; case R_ARM_TLS_DTPMOD32: