diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-03-18 18:09:32 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-03-18 18:09:32 +0000 |
commit | c2cfd9fa342662ce70382465f9ba90f3b9e70c96 (patch) | |
tree | 7ae1b75af8d159e6b6857e3c13caefb0e143c7c9 | |
parent | 5b5061f0cad610ff12b422ba29a4114a3221654e (diff) | |
download | bcm5719-llvm-c2cfd9fa342662ce70382465f9ba90f3b9e70c96.tar.gz bcm5719-llvm-c2cfd9fa342662ce70382465f9ba90f3b9e70c96.zip |
bar
llvm-svn: 263799
-rw-r--r-- | lld/ELF/InputSection.cpp | 96 | ||||
-rw-r--r-- | lld/ELF/InputSection.h | 11 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 5 |
4 files changed, 19 insertions, 105 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 79f5abb068e..169c9f488e7 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<ELFT>(); } -template <class ELFT> -template <class RelTy> -void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd, - iterator_range<const RelTy *> 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<ELFT>(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<ELFT>::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<ELFT>(); - else - SymVA = Body.getVA<ELFT>(); - // 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<ELFT>::Got->getGlobalDynAddr(Body) + A); - continue; - } - - uintX_t SymVA = Body.getVA<ELFT>(A); - uint8_t *PairedLoc = nullptr; - if (Config->EMachine == EM_MIPS) - PairedLoc = findMipsPairedReloc(Buf, &RI, Rels.end()); - - if (Target->needsPlt<ELFT>(Type, Body)) { - SymVA = Body.getPltVA<ELFT>() + A; - } else if (Target->needsGot(Type, Body)) { - if (Config->EMachine == EM_MIPS) - SymVA = getMipsGotVA<ELFT>(Body, SymVA, BufLoc, PairedLoc) + A; - else - SymVA = Body.getGotVA<ELFT>() + 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<ELFT>(Type, *File, Body, AddrLoc, SymVA) + A; - } else if (!Target->needsCopyRel<ELFT>(Type, Body) && - Body.isPreemptible()) { - continue; - } - uintX_t Size = Body.getSize<ELFT>(); - Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, Size + A, - PairedLoc); +template <class ELFT> void InputSectionBase<ELFT>::relocate(uint8_t *Buf) { + for (const Relocation &Rel : Relocations) { + uint8_t *Pos = Buf + Rel.Offset; + *(uint64_t *)Pos = Rel.Sym->getVA<ELFT>(0); } } @@ -321,14 +242,7 @@ template <class ELFT> void InputSection<ELFT>::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 <class ELFT> diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 0b6117ee242..1644f818847 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -23,6 +23,12 @@ template <class ELFT> class ObjectFile; template <class ELFT> class OutputSection; template <class ELFT> 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 ELFT> class InputSectionBase { protected: @@ -75,9 +81,8 @@ public: InputSectionBase<ELFT> *getRelocTarget(const Elf_Rel &Rel) const; InputSectionBase<ELFT> *getRelocTarget(const Elf_Rela &Rel) const; - template <class RelTy> - void relocate(uint8_t *Buf, uint8_t *BufEnd, - llvm::iterator_range<const RelTy *> Rels); + void relocate(uint8_t *Buf); + std::vector<Relocation> Relocations; private: template <class RelTy> diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index b456ac6fe79..042bc44f11c 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1168,16 +1168,8 @@ template <class ELFT> void EHOutputSection<ELFT>::writeTo(uint8_t *Buf) { } } - for (EHInputSection<ELFT> *S : Sections) { - const Elf_Shdr *RelSec = S->RelocSection; - if (!RelSec) - continue; - ELFFile<ELFT> &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<ELFT> *S : Sections) + S->relocate(Buf); } template <class ELFT> diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 377eed4c838..f7329652b37 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -466,8 +466,11 @@ void Writer<ELFT>::scanRelocs(InputSectionBase<ELFT> &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<ELFT>(RI); if (Config->EMachine == EM_PPC64 && RI.getType(false) == R_PPC64_TOC) { |