diff options
| author | George Rimar <grimar@accesssoftek.com> | 2015-11-30 17:49:19 +0000 |
|---|---|---|
| committer | George Rimar <grimar@accesssoftek.com> | 2015-11-30 17:49:19 +0000 |
| commit | 5828c2319ed3750f4d0fb6b23fc84a0193ebe6a2 (patch) | |
| tree | 95ca5db965616f22f7785f986e788f40281de7e9 | |
| parent | 9b6d4ffdf9c1d31eb61be5738dc869917009d1a8 (diff) | |
| download | bcm5719-llvm-5828c2319ed3750f4d0fb6b23fc84a0193ebe6a2.tar.gz bcm5719-llvm-5828c2319ed3750f4d0fb6b23fc84a0193ebe6a2.zip | |
[ELF] - Split RelocationSection<ELFT>::writeTo function.
Splitted writeTo to separate tls relocs handling stuff which is too long for one method now. NFC.
Differential revision: http://reviews.llvm.org/D15012
llvm-svn: 254309
| -rw-r--r-- | lld/ELF/OutputSections.cpp | 45 | ||||
| -rw-r--r-- | lld/ELF/OutputSections.h | 3 |
2 files changed, 29 insertions, 19 deletions
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index eb8f5d782ac..e3c910f5230 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -193,6 +193,31 @@ RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela) this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4; } +// Applies corresponding symbol and type for dynamic tls relocation. +// Returns true if relocation was handled. +template <class ELFT> +bool RelocationSection<ELFT>::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<ELFT>::Got->getVA() + Out<ELFT>::LocalModuleTlsIndexOffset; + return true; + } + + if (Body && Target->isTlsGlobalDynamicReloc(Type)) { + P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), + Target->getTlsModuleIndexReloc(), Config->Mips64EL); + P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); + N->setSymbolAndType(Body->getDynamicSymbolTableIndex(), + Target->getTlsOffsetReloc(), Config->Mips64EL); + N->r_offset = Out<ELFT>::Got->getEntryAddr(*Body) + sizeof(uintX_t); + return true; + } + return false; +} + template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { const unsigned EntrySize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel); for (const DynamicReloc<ELFT> &Rel : Relocs) { @@ -213,26 +238,8 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { 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<ELFT>::Got->getVA() + Out<ELFT>::LocalModuleTlsIndexOffset; + if (applyTlsDynamicReloc(Body, Type, P, reinterpret_cast<Elf_Rel *>(Buf))) continue; - } - - if (Body && Target->isTlsGlobalDynamicReloc(Type)) { - P->setSymbolAndType(Body->getDynamicSymbolTableIndex(), - Target->getTlsModuleIndexReloc(), Config->Mips64EL); - P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body); - auto *PNext = reinterpret_cast<Elf_Rel *>(Buf); - PNext->setSymbolAndType(Body->getDynamicSymbolTableIndex(), - Target->getTlsOffsetReloc(), Config->Mips64EL); - PNext->r_offset = Out<ELFT>::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); diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index 27e6b68ab72..dea9bb3c120 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -223,6 +223,9 @@ public: bool isRela() const { return IsRela; } private: + bool applyTlsDynamicReloc(SymbolBody *Body, uint32_t Type, Elf_Rel *P, + Elf_Rel *N); + std::vector<DynamicReloc<ELFT>> Relocs; const bool IsRela; }; |

