summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2015-10-19 20:24:44 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2015-10-19 20:24:44 +0000
commit932efcfa77236a91afc6eb3d48edbaefa59264ac (patch)
tree4482a68e1bee4eec27daa71aed31a2171f037fda
parent4975752389cfab99166b6f06e2a5b32ba6453b71 (diff)
downloadbcm5719-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.cpp21
-rw-r--r--lld/ELF/InputSection.h6
-rw-r--r--lld/ELF/OutputSections.cpp31
-rw-r--r--lld/ELF/OutputSections.h16
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);
OpenPOWER on IntegriCloud