[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