Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -147,17 +147,18 @@ 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 @@ // 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 @@ 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; Index: lld/trunk/ELF/Target.cpp =================================================================== --- lld/trunk/ELF/Target.cpp +++ lld/trunk/ELF/Target.cpp @@ -1874,6 +1874,7 @@ 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: