Index: lld/trunk/ELF/OutputSections.h =================================================================== --- lld/trunk/ELF/OutputSections.h +++ lld/trunk/ELF/OutputSections.h @@ -223,6 +223,9 @@ bool isRela() const { return IsRela; } private: + bool applyTlsDynamicReloc(SymbolBody *Body, uint32_t Type, Elf_Rel *P, + Elf_Rel *N); + std::vector> Relocs; const bool IsRela; }; Index: lld/trunk/ELF/OutputSections.cpp =================================================================== --- lld/trunk/ELF/OutputSections.cpp +++ lld/trunk/ELF/OutputSections.cpp @@ -193,6 +193,31 @@ this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; } +// Applies corresponding symbol and type for dynamic tls relocation. +// Returns true if relocation was handled. +template +bool RelocationSection::applyTlsDynamicReloc(SymbolBody *Body, + uint32_t Type, Elf_Rel *P, + Elf_Rel *N) { + if (Target->isTlsLocalDynamicReloc(Type)) { + P->setSymbolAndType(0, Target->getTlsModuleIndexReloc(), Config->Mips64EL); + P->r_offset = + Out::Got->getVA() + Out::LocalModuleTlsIndexOffset; + return true; + } + + if (Body && Target->isTlsGlobalDynamicReloc(Type)) { + P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), + Target->getTlsModuleIndexReloc(), Config->Mips64EL); + P->r_offset = Out::Got->getEntryAddr(*Body); + N->setSymbolAndType(Body->getDynamicSymbolTableIndex(), + Target->getTlsOffsetReloc(), Config->Mips64EL); + N->r_offset = Out::Got->getEntryAddr(*Body) + sizeof(uintX_t); + return true; + } + return false; +} + template void RelocationSection::writeTo(uint8_t *Buf) { const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); for (const DynamicReloc &Rel : Relocs) { @@ -213,26 +238,8 @@ Body = Body->repl(); uint32_t Type = RI.getType(Config->Mips64EL); - - if (Target->isTlsLocalDynamicReloc(Type)) { - P->setSymbolAndType(0, Target->getTlsModuleIndexReloc(), - Config->Mips64EL); - P->r_offset = - Out::Got->getVA() + Out::LocalModuleTlsIndexOffset; + if (applyTlsDynamicReloc(Body, Type, P, reinterpret_cast(Buf))) continue; - } - - if (Body && Target->isTlsGlobalDynamicReloc(Type)) { - P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), - Target->getTlsModuleIndexReloc(), Config->Mips64EL); - P->r_offset = Out::Got->getEntryAddr(*Body); - auto *PNext = reinterpret_cast(Buf); - PNext->setSymbolAndType(Body->getDynamicSymbolTableIndex(), - Target->getTlsOffsetReloc(), Config->Mips64EL); - PNext->r_offset = Out::Got->getEntryAddr(*Body) + sizeof(uintX_t); - continue; - } - bool NeedsCopy = Body && Target->relocNeedsCopy(Type, *Body); bool NeedsGot = Body && Target->relocNeedsGot(Type, *Body); bool CanBePreempted = canBePreempted(Body, NeedsGot);