Index: lld/ELF/Relocations.cpp =================================================================== --- lld/ELF/Relocations.cpp +++ lld/ELF/Relocations.cpp @@ -188,10 +188,13 @@ // If the symbol is preemptible we need the dynamic linker to write // the offset too. + uintX_t OffsetOff = Off + (uintX_t)sizeof(uintX_t); if (isPreemptible(Body, Type)) In::RelaDyn->addReloc({Target->TlsOffsetRel, In::Got, - Off + (uintX_t)sizeof(uintX_t), false, - &Body, 0}); + OffsetOff, false, &Body, 0}); + else + In::Got->Relocations.push_back( + {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Body}); } C.Relocations.push_back({Expr, Type, Offset, Addend, &Body}); return 1; @@ -741,17 +744,19 @@ continue; In::Got->addEntry(Body); - if (Preemptible || (Config->Pic && !isAbsolute(Body))) { - uint32_t DynType; - if (Body.isTls()) - DynType = Target->TlsGotRel; - else if (Preemptible) - DynType = Target->GotRel; - else - DynType = Target->RelativeRel; - AddDyn({DynType, In::Got, Body.getGotOffset(), !Preemptible, - &Body, 0}); - } + uintX_t Off = Body.getGotOffset(); + uint32_t DynType; + if (Body.isTls()) + DynType = Target->TlsGotRel; + else if (!Preemptible && Config->Pic && !isAbsolute(Body)) + DynType = Target->RelativeRel; + else + DynType = Target->GotRel; + + if (Preemptible || (Config->Pic && !isAbsolute(Body))) + AddDyn({DynType, In::Got, Off, !Preemptible, &Body, 0}); + else + In::Got->Relocations.push_back({R_ABS, DynType, Off, 0, &Body}); continue; } } Index: lld/ELF/SyntheticSections.h =================================================================== --- lld/ELF/SyntheticSections.h +++ lld/ELF/SyntheticSections.h @@ -67,7 +67,7 @@ bool HasGotOffRel = false; private: - std::vector Entries; + size_t NumEntries = 0; uint32_t TlsIndexOff = -1; uintX_t Size = 0; }; Index: lld/ELF/SyntheticSections.cpp =================================================================== --- lld/ELF/SyntheticSections.cpp +++ lld/ELF/SyntheticSections.cpp @@ -383,17 +383,16 @@ Target->GotEntrySize, ".got") {} template void GotSection::addEntry(SymbolBody &Sym) { - Sym.GotIndex = Entries.size(); - Entries.push_back(&Sym); + Sym.GotIndex = NumEntries; + ++NumEntries; } template bool GotSection::addDynTlsEntry(SymbolBody &Sym) { if (Sym.GlobalDynIndex != -1U) return false; - Sym.GlobalDynIndex = Entries.size(); + Sym.GlobalDynIndex = NumEntries; // Global Dynamic TLS entries take two GOT slots. - Entries.push_back(nullptr); - Entries.push_back(&Sym); + NumEntries += 2; return true; } @@ -402,9 +401,8 @@ template bool GotSection::addTlsIndex() { if (TlsIndexOff != uint32_t(-1)) return false; - TlsIndexOff = Entries.size() * sizeof(uintX_t); - Entries.push_back(nullptr); - Entries.push_back(nullptr); + TlsIndexOff = NumEntries * sizeof(uintX_t); + NumEntries += 2; return true; } @@ -421,26 +419,18 @@ } template void GotSection::finalize() { - Size = Entries.size() * sizeof(uintX_t); + Size = NumEntries * sizeof(uintX_t); } template bool GotSection::empty() const { // If we have a relocation that is relative to GOT (such as GOTOFFREL), // we need to emit a GOT even if it's empty. - return Entries.empty() && !HasGotOffRel; + return NumEntries == 0 && !HasGotOffRel; } template void GotSection::writeTo(uint8_t *Buf) { - for (const SymbolBody *B : Entries) { - uint8_t *Entry = Buf; - Buf += sizeof(uintX_t); - if (!B) - continue; - if (B->isPreemptible()) - continue; // The dynamic linker will take care of it. - uintX_t VA = B->getVA(); - write(Entry, VA); - } + uint8_t *BufEnd = Buf + Size; + this->relocate(Buf, BufEnd); } template Index: lld/ELF/Target.cpp =================================================================== --- lld/ELF/Target.cpp +++ lld/ELF/Target.cpp @@ -802,6 +802,7 @@ case R_X86_64_DTPOFF64: case R_X86_64_SIZE64: case R_X86_64_PC64: + case R_X86_64_GLOB_DAT: write64le(Loc, Val); break; default: @@ -1696,6 +1697,8 @@ case R_ARM_TLS_LDM32: case R_ARM_TLS_LDO32: case R_ARM_TLS_LE32: + case R_ARM_GLOB_DAT: + case R_ARM_TLS_TPOFF32: write32le(Loc, Val); break; case R_ARM_PREL31: