[lld] r263225 - Compute value of local symbol with getVA.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 11 04:19:05 PST 2016
Author: rafael
Date: Fri Mar 11 06:19:05 2016
New Revision: 263225
URL: http://llvm.org/viewvc/llvm-project?rev=263225&view=rev
Log:
Compute value of local symbol with getVA.
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=263225&r1=263224&r2=263225&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Fri Mar 11 06:19:05 2016
@@ -171,48 +171,6 @@ InputSectionBase<ELFT>::findMipsPairedRe
return nullptr;
}
-// Returns a VA which a relocatin RI refers to. Used only for local symbols.
-// For non-local symbols, use SymbolBody::getVA instead.
-template <class ELFT, bool IsRela>
-static typename ELFFile<ELFT>::uintX_t
-getLocalRelTarget(const ObjectFile<ELFT> &File,
- const Elf_Rel_Impl<ELFT, IsRela> &RI,
- typename ELFFile<ELFT>::uintX_t Addend) {
- typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
- typedef typename ELFFile<ELFT>::uintX_t uintX_t;
-
- // 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() + Addend;
-
- const Elf_Sym *Sym =
- File.getObj().getRelocationSymbol(&RI, File.getSymbolTable());
-
- if (!Sym)
- fatal("Unsupported relocation without symbol");
-
- InputSectionBase<ELFT> *Section = File.getSection(*Sym);
-
- if (Sym->getType() == STT_TLS)
- return (Section->OutSec->getVA() + Section->getOffset(*Sym) + Addend) -
- Out<ELFT>::TlsPhdr->p_vaddr;
-
- // According to the ELF spec reference to a local symbol from outside
- // the group are not allowed. Unfortunately .eh_frame breaks that rule
- // and must be treated specially. For now we just replace the symbol with
- // 0.
- if (Section == InputSection<ELFT>::Discarded || !Section->Live)
- return Addend;
-
- uintX_t Offset = Sym->st_value;
- if (Sym->getType() == STT_SECTION) {
- Offset += Addend;
- Addend = 0;
- }
- return Section->OutSec->getVA() + Section->getOffset(Offset) + Addend;
-}
-
template <class ELFT>
template <bool isRela>
void InputSectionBase<ELFT>::relocate(uint8_t *Buf, uint8_t *BufEnd,
@@ -244,7 +202,7 @@ void InputSectionBase<ELFT>::relocate(ui
if (Target->canRelaxTls(Type, &Body)) {
uintX_t SymVA;
if (Body.isLocal())
- SymVA = getLocalRelTarget(*File, RI, 0);
+ SymVA = Body.getVA<ELFT>();
else if (Target->needsGot(Type, Body))
SymVA = Body.getGotVA<ELFT>();
else
@@ -256,11 +214,19 @@ void InputSectionBase<ELFT>::relocate(ui
continue;
}
- // Handle relocations for local symbols -- they never get
- // resolved so we don't allocate a SymbolBody.
uintX_t A = 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) {
+ uintX_t SymVA = getPPC64TocBase() + A;
+ Target->relocateOne(BufLoc, BufEnd, Type, AddrLoc, SymVA, 0);
+ continue;
+ }
+
+ // Handle relocations for local symbols.
if (Body.isLocal()) {
- uintX_t SymVA = getLocalRelTarget(*File, RI, A);
+ uintX_t SymVA = Body.getVA<ELFT>(A);
uint8_t *PairedLoc = nullptr;
if (Config->EMachine == EM_MIPS) {
if (Type == R_MIPS_GPREL16 || Type == R_MIPS_GPREL32)
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=263225&r1=263224&r2=263225&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Fri Mar 11 06:19:05 2016
@@ -266,21 +266,12 @@ template <class ELFT> void RelocationSec
SymbolBody *Sym = Rel.Sym;
if (IsRela) {
- uintX_t VA = 0;
- uintX_t Addend = Rel.Addend;
- if (Rel.UseSymVA) {
- if (auto *L = dyn_cast<LocalSymbol<ELFT>>(Sym)) {
- uintX_t Pos = L->Sym.st_value;
- if (L->Sym.getType() == STT_SECTION) {
- Pos += Addend;
- Addend = 0;
- }
- VA = L->Section->OutSec->getVA() + L->Section->getOffset(Pos);
- } else {
- VA = Sym->getVA<ELFT>();
- }
- }
- reinterpret_cast<Elf_Rela *>(P)->r_addend = Addend + VA;
+ uintX_t VA;
+ if (Rel.UseSymVA)
+ VA = Sym->getVA<ELFT>(Rel.Addend);
+ else
+ VA = Rel.Addend;
+ reinterpret_cast<Elf_Rela *>(P)->r_addend = VA;
}
P->r_offset = Rel.getOffset();
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=263225&r1=263224&r2=263225&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Fri Mar 11 06:19:05 2016
@@ -29,52 +29,81 @@ using namespace lld;
using namespace lld::elf;
template <class ELFT>
-typename ELFFile<ELFT>::uintX_t SymbolBody::getVA() const {
- switch (kind()) {
- case DefinedSyntheticKind: {
- auto *D = cast<DefinedSynthetic<ELFT>>(this);
- return D->Section.getVA() + D->Value;
+static typename ELFFile<ELFT>::uintX_t
+getSymVA(const SymbolBody &Body, typename ELFFile<ELFT>::uintX_t &Addend) {
+ typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
+ typedef typename ELFFile<ELFT>::uintX_t uintX_t;
+
+ switch (Body.kind()) {
+ case SymbolBody::DefinedSyntheticKind: {
+ auto &D = cast<DefinedSynthetic<ELFT>>(Body);
+ return D.Section.getVA() + D.Value;
}
- case DefinedRegularKind: {
- auto *D = cast<DefinedRegular<ELFT>>(this);
- InputSectionBase<ELFT> *SC = D->Section;
+ case SymbolBody::DefinedRegularKind: {
+ auto &D = cast<DefinedRegular<ELFT>>(Body);
+ InputSectionBase<ELFT> *SC = D.Section;
// This is an absolute symbol.
if (!SC)
- return D->Sym.st_value;
+ return D.Sym.st_value;
assert(SC->Live);
- if (D->Sym.getType() == STT_TLS)
- return SC->OutSec->getVA() + SC->getOffset(D->Sym) -
+ if (D.Sym.getType() == STT_TLS)
+ return SC->OutSec->getVA() + SC->getOffset(D.Sym) -
Out<ELFT>::TlsPhdr->p_vaddr;
- return SC->OutSec->getVA() + SC->getOffset(D->Sym);
+ return SC->OutSec->getVA() + SC->getOffset(D.Sym);
}
- case DefinedCommonKind:
- return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(this)->OffsetInBss;
- case SharedKind: {
- auto *SS = cast<SharedSymbol<ELFT>>(this);
- if (!SS->NeedsCopyOrPltAddr)
+ case SymbolBody::DefinedCommonKind:
+ return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(Body).OffsetInBss;
+ case SymbolBody::SharedKind: {
+ auto &SS = cast<SharedSymbol<ELFT>>(Body);
+ if (!SS.NeedsCopyOrPltAddr)
return 0;
- if (SS->IsFunc)
- return getPltVA<ELFT>();
+ if (SS.IsFunc)
+ return Body.getPltVA<ELFT>();
else
- return Out<ELFT>::Bss->getVA() + SS->OffsetInBss;
+ return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
}
- case UndefinedElfKind:
- case UndefinedKind:
+ case SymbolBody::UndefinedElfKind:
+ case SymbolBody::UndefinedKind:
return 0;
- case LazyKind:
- assert(isUsedInRegularObj() && "Lazy symbol reached writer");
+ case SymbolBody::LazyKind:
+ assert(Body.isUsedInRegularObj() && "Lazy symbol reached writer");
return 0;
- case DefinedBitcodeKind:
+ case SymbolBody::DefinedBitcodeKind:
llvm_unreachable("Should have been replaced");
- case DefinedLocalKind:
- llvm_unreachable("Should not be used");
+ case SymbolBody::DefinedLocalKind: {
+ auto &L = cast<LocalSymbol<ELFT>>(Body);
+ InputSectionBase<ELFT> *SC = L.Section;
+
+ // According to the ELF spec reference to a local symbol from outside the
+ // group are not allowed. Unfortunately .eh_frame breaks that rule and must
+ // be treated specially. For now we just replace the symbol with 0.
+ if (SC == InputSection<ELFT>::Discarded || !SC->Live)
+ return 0;
+
+ const Elf_Sym &Sym = L.Sym;
+ uintX_t Offset = Sym.st_value;
+ if (Sym.getType() == STT_TLS)
+ return (SC->OutSec->getVA() + SC->getOffset(Sym) + Addend) -
+ Out<ELFT>::TlsPhdr->p_vaddr;
+ if (Sym.getType() == STT_SECTION) {
+ Offset += Addend;
+ Addend = 0;
+ }
+ return SC->OutSec->getVA() + SC->getOffset(Offset);
+ }
}
llvm_unreachable("Invalid symbol kind");
}
template <class ELFT>
+typename ELFFile<ELFT>::uintX_t
+SymbolBody::getVA(typename ELFFile<ELFT>::uintX_t Addend) const {
+ return getSymVA<ELFT>(*this, Addend) + Addend;
+}
+
+template <class ELFT>
typename ELFFile<ELFT>::uintX_t SymbolBody::getGotVA() const {
return Out<ELFT>::Got->getVA() +
(Out<ELFT>::Got->getMipsLocalEntriesNum() + GotIndex) *
@@ -231,10 +260,10 @@ std::string elf::demangle(StringRef Name
#endif
}
-template uint32_t SymbolBody::template getVA<ELF32LE>() const;
-template uint32_t SymbolBody::template getVA<ELF32BE>() const;
-template uint64_t SymbolBody::template getVA<ELF64LE>() const;
-template uint64_t SymbolBody::template getVA<ELF64BE>() const;
+template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
+template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
+template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;
+template uint64_t SymbolBody::template getVA<ELF64BE>(uint64_t) const;
template uint32_t SymbolBody::template getGotVA<ELF32LE>() const;
template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=263225&r1=263224&r2=263225&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Fri Mar 11 06:19:05 2016
@@ -98,7 +98,8 @@ public:
bool isInPlt() const { return PltIndex != -1U; }
template <class ELFT>
- typename llvm::object::ELFFile<ELFT>::uintX_t getVA() const;
+ typename llvm::object::ELFFile<ELFT>::uintX_t
+ getVA(typename llvm::object::ELFFile<ELFT>::uintX_t Addend = 0) const;
template <class ELFT>
typename llvm::object::ELFFile<ELFT>::uintX_t getGotVA() const;
template <class ELFT>
More information about the llvm-commits
mailing list