diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2015-10-19 20:24:44 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2015-10-19 20:24:44 +0000 |
commit | 932efcfa77236a91afc6eb3d48edbaefa59264ac (patch) | |
tree | 4482a68e1bee4eec27daa71aed31a2171f037fda | |
parent | 4975752389cfab99166b6f06e2a5b32ba6453b71 (diff) | |
download | bcm5719-llvm-932efcfa77236a91afc6eb3d48edbaefa59264ac.tar.gz bcm5719-llvm-932efcfa77236a91afc6eb3d48edbaefa59264ac.zip |
Change getLocalRelTarget to include the addend.
Given the name, it is natural for this function to compute the full target.
This will simplify SHF_MERGE handling by allowing getLocalRelTarget to
centralize the addend logic.
llvm-svn: 250731
-rw-r--r-- | lld/ELF/InputSection.cpp | 21 | ||||
-rw-r--r-- | lld/ELF/InputSection.h | 6 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 31 | ||||
-rw-r--r-- | lld/ELF/OutputSections.h | 16 |
4 files changed, 37 insertions, 37 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 7aa9e7ea560..0ab85e44c39 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -26,22 +26,6 @@ InputSection<ELFT>::InputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header) : File(F), Header(Header) {} template <class ELFT> -void InputSection<ELFT>::relocateOne(uint8_t *Buf, uint8_t *BufEnd, - const Elf_Rel &Rel, uint32_t Type, - uintX_t BaseAddr, uintX_t SymVA) { - Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&Rel), Type, - BaseAddr, SymVA); -} - -template <class ELFT> -void InputSection<ELFT>::relocateOne(uint8_t *Buf, uint8_t *BufEnd, - const Elf_Rela &Rel, uint32_t Type, - uintX_t BaseAddr, uintX_t SymVA) { - Target->relocateOne(Buf, BufEnd, reinterpret_cast<const void *>(&Rel), Type, - BaseAddr, SymVA + Rel.r_addend); -} - -template <class ELFT> template <bool isRela> void InputSection<ELFT>::relocate( uint8_t *Buf, uint8_t *BufEnd, @@ -57,7 +41,7 @@ void InputSection<ELFT>::relocate( const Elf_Shdr *SymTab = File.getSymbolTable(); if (SymIndex < SymTab->sh_info) { uintX_t SymVA = getLocalRelTarget(File, RI); - relocateOne(Buf, BufEnd, RI, Type, BaseAddr, SymVA); + Target->relocateOne(Buf, BufEnd, &RI, Type, BaseAddr, SymVA); continue; } @@ -75,7 +59,8 @@ void InputSection<ELFT>::relocate( } else if (isa<SharedSymbol<ELFT>>(Body)) { continue; } - relocateOne(Buf, BufEnd, RI, Type, BaseAddr, SymVA); + Target->relocateOne(Buf, BufEnd, &RI, Type, BaseAddr, + SymVA + getAddend<ELFT>(RI)); } } diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h index 3cd889d24f4..95063ae101b 100644 --- a/lld/ELF/InputSection.h +++ b/lld/ELF/InputSection.h @@ -60,12 +60,6 @@ public: static InputSection<ELFT> Discarded; private: - static void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const Elf_Rel &Rel, - uint32_t Type, uintX_t BaseAddr, uintX_t SymVA); - - static void relocateOne(uint8_t *Buf, uint8_t *BufEnd, const Elf_Rela &Rel, - uint32_t Type, uintX_t BaseAddr, uintX_t SymVA); - template <bool isRela> void relocate(uint8_t *Buf, uint8_t *BufEnd, llvm::iterator_range< diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 61639d2f104..83a45bac26e 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -135,15 +135,20 @@ template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) { else P->r_offset = RI.r_offset + C.OutSec->getVA() + C.OutSecOff; - uintX_t Addend = 0; + uintX_t OrigAddend = 0; if (IsRela && !NeedsGot) - Addend = static_cast<const Elf_Rela &>(RI).r_addend; + OrigAddend = static_cast<const Elf_Rela &>(RI).r_addend; - if (!CanBePreempted) { + uintX_t Addend; + if (CanBePreempted) { + Addend = OrigAddend; + } else { if (Body) - Addend += getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Body)); + Addend = getSymVA<ELFT>(cast<ELFSymbolBody<ELFT>>(*Body)) + OrigAddend; + else if (IsRela) + Addend = getLocalRelTarget(File, static_cast<const Elf_Rela &>(RI)); else - Addend += getLocalRelTarget(File, RI); + Addend = getLocalRelTarget(File, RI); } if (IsRela) @@ -422,16 +427,20 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) { // Returns a VA which a relocatin RI refers to. Used only for local symbols. // For non-local symbols, use getSymVA instead. -template <class ELFT> +template <class ELFT, bool IsRela> typename ELFFile<ELFT>::uintX_t lld::elf2::getLocalRelTarget(const ObjectFile<ELFT> &File, - const typename ELFFile<ELFT>::Elf_Rel &RI) { + const Elf_Rel_Impl<ELFT, IsRela> &RI) { + typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; + typedef typename ELFFile<ELFT>::uintX_t uintX_t; + + uintX_t Addend = getAddend<ELFT>(RI); + // 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) - return getPPC64TocBase(); + return getPPC64TocBase() + Addend; - typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym; const Elf_Sym *Sym = File.getObj().getRelocationSymbol(&RI, File.getSymbolTable()); @@ -444,9 +453,9 @@ lld::elf2::getLocalRelTarget(const ObjectFile<ELFT> &File, // 0. InputSection<ELFT> *Section = File.getSection(*Sym); if (Section == &InputSection<ELFT>::Discarded) - return 0; + return Addend; - return Section->OutSec->getVA() + Section->OutSecOff + Sym->st_value; + return Section->OutSec->getVA() + Section->OutSecOff + Sym->st_value + Addend; } // Returns true if a symbol can be replaced at load-time by a symbol diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h index d8fc041ffe6..ecf49eea3bf 100644 --- a/lld/ELF/OutputSections.h +++ b/lld/ELF/OutputSections.h @@ -33,12 +33,24 @@ template <class ELFT> class DefinedRegular; template <class ELFT> class ELFSymbolBody; template <class ELFT> -typename llvm::object::ELFFile<ELFT>::uintX_t getSymVA(const SymbolBody &S); +static inline typename llvm::object::ELFFile<ELFT>::uintX_t +getAddend(const typename llvm::object::ELFFile<ELFT>::Elf_Rel &Rel) { + return 0; +} template <class ELFT> +static inline typename llvm::object::ELFFile<ELFT>::uintX_t +getAddend(const typename llvm::object::ELFFile<ELFT>::Elf_Rela &Rel) { + return Rel.r_addend; +} + +template <class ELFT> +typename llvm::object::ELFFile<ELFT>::uintX_t getSymVA(const SymbolBody &S); + +template <class ELFT, bool IsRela> typename llvm::object::ELFFile<ELFT>::uintX_t getLocalRelTarget(const ObjectFile<ELFT> &File, - const typename llvm::object::ELFFile<ELFT>::Elf_Rel &Sym); + const llvm::object::Elf_Rel_Impl<ELFT, IsRela> &Rel); bool canBePreempted(const SymbolBody *Body, bool NeedsGot); template <class ELFT> bool includeInSymtab(const SymbolBody &B); |