diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 79f5abb068e1..169c9f488e72 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -215,89 +215,10 @@ static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA, return Body.getGotVA(); } -template -template -void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd, - iterator_range Rels) { - size_t Num = Rels.end() - Rels.begin(); - for (size_t I = 0; I < Num; ++I) { - const RelTy &RI = *(Rels.begin() + I); - uintX_t Offset = getOffset(RI.r_offset); - if (Offset == (uintX_t)-1) - continue; - - uintX_t A = getAddend(RI); - uint32_t SymIndex = RI.getSymbol(Config->Mips64EL); - uint32_t Type = RI.getType(Config->Mips64EL); - uint8_t *BufLoc = Buf + Offset; - uintX_t AddrLoc = OutSec->getVA() + Offset; - - if (Target->pointsToLocalDynamicGotEntry(Type) && - !Target->canRelaxTls(Type, nullptr)) { - Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, - Out::Got->getTlsIndexVA() + A); - continue; - } - - SymbolBody &Body = File->getSymbolBody(SymIndex).repl(); - - if (Target->canRelaxTls(Type, &Body)) { - uintX_t SymVA; - if (Target->needsGot(Type, Body)) - SymVA = Body.getGotVA(); - else - SymVA = Body.getVA(); - // By optimizing TLS relocations, it is sometimes needed to skip - // relocations that immediately follow TLS relocations. This function - // knows how many slots we need to skip. - I += Target->relaxTls(BufLoc, BufEnd, Type, AddrLoc, SymVA, Body); - continue; - } - - // PPC64 has a special relocation representing the TOC base pointer - // that does not have a corresponding symbol. - if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) { - uintX_t SymVA = getPPC64TocBase() + A; - Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0); - continue; - } - - if (Target->isTlsGlobalDynamicRel(Type) && - !Target->canRelaxTls(Type, &Body)) { - Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, - Out::Got->getGlobalDynAddr(Body) + A); - continue; - } - - uintX_t SymVA = Body.getVA(A); - uint8_t *PairedLoc = nullptr; - if (Config->EMachine == EM_MIPS) - PairedLoc = findMipsPairedReloc(Buf, &RI, Rels.end()); - - if (Target->needsPlt(Type, Body)) { - SymVA = Body.getPltVA() + A; - } else if (Target->needsGot(Type, Body)) { - if (Config->EMachine == EM_MIPS) - SymVA = getMipsGotVA(Body, SymVA, BufLoc, PairedLoc) + A; - else - SymVA = Body.getGotVA() + A; - if (Body.IsTls) - Type = Target->getTlsGotRel(Type); - } else if (Target->isSizeRel(Type) && Body.isPreemptible()) { - // A SIZE relocation is supposed to set a symbol size, but if a symbol - // can be preempted, the size at runtime may be different than link time. - // If that's the case, we leave the field alone rather than filling it - // with a possibly incorrect value. - continue; - } else if (Config->EMachine == EM_MIPS) { - SymVA = adjustMipsSymVA(Type, *File, Body, AddrLoc, SymVA) + A; - } else if (!Target->needsCopyRel(Type, Body) && - Body.isPreemptible()) { - continue; - } - uintX_t Size = Body.getSize(); - Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, Size + A, - PairedLoc); +template void InputSectionBase::relocate(uint8_t *Buf) { + for (const Relocation &Rel : Relocations) { + uint8_t *Pos = Buf + Rel.Offset; + *(uint64_t *)Pos = Rel.Sym->getVA(0); } } @@ -321,14 +242,7 @@ template void InputSection::writeTo(uint8_t *Buf) { memcpy(Buf + OutSecOff, Data.data(), Data.size()); - uint8_t *BufEnd = Buf + OutSecOff + Data.size(); - // Iterate over all relocation sections that apply to this section. - for (const Elf_Shdr *RelSec : this->RelocSections) { - if (RelSec->sh_type == SHT_RELA) - this->relocate(Buf, BufEnd, EObj.relas(RelSec)); - else - this->relocate(Buf, BufEnd, EObj.rels(RelSec)); - } + this->relocate(Buf); } template diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 0b6117ee242e..1644f818847a 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -23,6 +23,12 @@ template class ObjectFile; template class OutputSection; template class OutputSectionBase; +struct Relocation { + enum RelType { R_64 } Type; + uint64_t Offset; + SymbolBody *Sym; +}; + // This corresponds to a section of an input file. template class InputSectionBase { protected: @@ -75,9 +81,8 @@ public: InputSectionBase *getRelocTarget(const Elf_Rel &Rel) const; InputSectionBase *getRelocTarget(const Elf_Rela &Rel) const; - template - void relocate(uint8_t *Buf, uint8_t *BufEnd, - llvm::iterator_range Rels); + void relocate(uint8_t *Buf); + std::vector Relocations; private: template diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index b456ac6fe791..042bc44f11c5 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1168,16 +1168,8 @@ template void EHOutputSection::writeTo(uint8_t *Buf) { } } - for (EHInputSection *S : Sections) { - const Elf_Shdr *RelSec = S->RelocSection; - if (!RelSec) - continue; - ELFFile &EObj = S->getFile()->getObj(); - if (RelSec->sh_type == SHT_RELA) - S->relocate(Buf, nullptr, EObj.relas(RelSec)); - else - S->relocate(Buf, nullptr, EObj.rels(RelSec)); - } + for (EHInputSection *S : Sections) + S->relocate(Buf); } template diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 377eed4c8380..f7329652b379 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -466,8 +466,11 @@ void Writer::scanRelocs(InputSectionBase &C, // We can however do better than just copying the incoming relocation. We // can process some of it and and just ask the dynamic linker to add the // load address. - if (!Config->Pic || Target->isRelRelative(Type) || Target->isSizeRel(Type)) + if (!Config->Pic || Target->isRelRelative(Type) || + Target->isSizeRel(Type)) { + C.Relocations.push_back({Relocation::R_64, RI.r_offset, &Body}); continue; + } uintX_t Addend = getAddend(RI); if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) {