From 69082f051d678e662b922b5424c0db88eb08e791 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 18 Mar 2016 18:11:26 +0000 Subject: [PATCH] Revert "bar" This reverts commit r263799. It was a mistake. Sorry about that. llvm-svn: 263801 --- lld/ELF/InputSection.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++--- lld/ELF/InputSection.h | 11 ++---- lld/ELF/OutputSections.cpp | 12 +++++- lld/ELF/Writer.cpp | 5 +-- 4 files changed, 105 insertions(+), 19 deletions(-) diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 169c9f4..79f5abb 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -215,10 +215,89 @@ static uintX_t getMipsGotVA(const SymbolBody &Body, uintX_t SymVA, return Body.getGotVA(); } -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); +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); } } @@ -242,7 +321,14 @@ template void InputSection::writeTo(uint8_t *Buf) { memcpy(Buf + OutSecOff, Data.data(), Data.size()); - this->relocate(Buf); + 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)); + } } template diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 1644f81..0b6117e 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -23,12 +23,6 @@ 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: @@ -81,8 +75,9 @@ public: InputSectionBase *getRelocTarget(const Elf_Rel &Rel) const; InputSectionBase *getRelocTarget(const Elf_Rela &Rel) const; - void relocate(uint8_t *Buf); - std::vector Relocations; + template + void relocate(uint8_t *Buf, uint8_t *BufEnd, + llvm::iterator_range Rels); private: template diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 042bc44..b456ac6 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1168,8 +1168,16 @@ template void EHOutputSection::writeTo(uint8_t *Buf) { } } - for (EHInputSection *S : Sections) - S->relocate(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)); + } } template diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index f732965..377eed4 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -466,11 +466,8 @@ 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)) { - C.Relocations.push_back({Relocation::R_64, RI.r_offset, &Body}); + if (!Config->Pic || Target->isRelRelative(Type) || Target->isSizeRel(Type)) continue; - } uintX_t Addend = getAddend(RI); if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) { -- 2.7.4