[lld] r259404 - ELF: Teach SymbolBody about how to get its addresses.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon Feb 1 13:00:36 PST 2016


Author: ruiu
Date: Mon Feb  1 15:00:35 2016
New Revision: 259404

URL: http://llvm.org/viewvc/llvm-project?rev=259404&view=rev
Log:
ELF: Teach SymbolBody about how to get its addresses.

Previously, the methods to get symbol addresses were somewhat scattered
in many places. You can use getEntryAddr returns the address of the symbol,
but if you want to get the GOT address for the symbol, you needed to call
Out<ELFT>::Got->getEntryAddr(Sym). This change adds new functions, getVA,
getGotVA, getGotPltVA, and getPltVA to SymbolBody, so that you can use
SymbolBody as the central place to ask about symbols.

http://reviews.llvm.org/D16710

Modified:
    lld/trunk/ELF/InputSection.cpp
    lld/trunk/ELF/OutputSections.cpp
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=259404&r1=259403&r2=259404&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Mon Feb  1 15:00:35 2016
@@ -173,9 +173,9 @@ void InputSectionBase<ELFT>::relocate(ui
       if (!Body)
         SymVA = getLocalRelTarget(*File, RI, 0);
       else if (Target->needsGot(Type, *Body))
-        SymVA = Out<ELFT>::Got->getEntryAddr(*Body);
+        SymVA = Body->getGotVA<ELFT>();
       else
-        SymVA = getSymVA<ELFT>(*Body);
+        SymVA = Body->getVA<ELFT>();
       // By optimizing TLS relocations, it is sometimes needed to skip
       // relocations that immediately follow TLS relocations. This function
       // knows how many slots we need to skip.
@@ -213,9 +213,9 @@ void InputSectionBase<ELFT>::relocate(ui
       continue;
     }
 
-    uintX_t SymVA = getSymVA<ELFT>(*Body);
+    uintX_t SymVA = Body->getVA<ELFT>();
     if (Target->needsPlt(Type, *Body)) {
-      SymVA = Out<ELFT>::Plt->getEntryAddr(*Body);
+      SymVA = Body->getPltVA<ELFT>();
     } else if (Target->needsGot(Type, *Body)) {
       if (Config->EMachine == EM_MIPS && needsMipsLocalGot(Type, Body))
         // Under some conditions relocations against non-local symbols require
@@ -223,7 +223,7 @@ void InputSectionBase<ELFT>::relocate(ui
         // initialized by full address of the symbol.
         SymVA = Out<ELFT>::Got->getMipsLocalFullAddr(*Body);
       else
-        SymVA = Out<ELFT>::Got->getEntryAddr(*Body);
+        SymVA = Body->getGotVA<ELFT>();
       if (Body->isTls())
         Type = Target->getTlsGotRel(Type);
     } else if (!Target->needsCopyRel(Type, *Body) &&

Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=259404&r1=259403&r2=259404&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Mon Feb  1 15:00:35 2016
@@ -47,12 +47,6 @@ template <class ELFT> bool GotPltSection
   return Entries.empty();
 }
 
-template <class ELFT>
-typename GotPltSection<ELFT>::uintX_t
-GotPltSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
-  return this->getVA() + B.GotPltIndex * sizeof(uintX_t);
-}
-
 template <class ELFT> void GotPltSection<ELFT>::finalize() {
   this->Header.sh_size =
       (Target->GotPltHeaderEntriesNum + Entries.size()) * sizeof(uintX_t);
@@ -62,7 +56,7 @@ template <class ELFT> void GotPltSection
   Target->writeGotPltHeader(Buf);
   Buf += Target->GotPltHeaderEntriesNum * sizeof(uintX_t);
   for (const SymbolBody *B : Entries) {
-    Target->writeGotPlt(Buf, Out<ELFT>::Plt->getEntryAddr(*B));
+    Target->writeGotPlt(Buf, B->getPltVA<ELFT>());
     Buf += sizeof(uintX_t);
   }
 }
@@ -105,16 +99,8 @@ template <class ELFT> bool GotSection<EL
 
 template <class ELFT>
 typename GotSection<ELFT>::uintX_t
-GotSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
-  return this->getVA() +
-         (Target->GotHeaderEntriesNum + MipsLocalEntries + B.GotIndex) *
-             sizeof(uintX_t);
-}
-
-template <class ELFT>
-typename GotSection<ELFT>::uintX_t
 GotSection<ELFT>::getMipsLocalFullAddr(const SymbolBody &B) {
-  return getMipsLocalEntryAddr(getSymVA<ELFT>(B));
+  return getMipsLocalEntryAddr(B.getVA<ELFT>());
 }
 
 template <class ELFT>
@@ -176,7 +162,7 @@ template <class ELFT> void GotSection<EL
     // As the first approach, we can just store addresses for all symbols.
     if (Config->EMachine != EM_MIPS && canBePreempted(B, false))
       continue; // The dynamic linker will take care of it.
-    uintX_t VA = getSymVA<ELFT>(*B);
+    uintX_t VA = B->getVA<ELFT>();
     write<uintX_t, ELFT::TargetEndianness, sizeof(uintX_t)>(Entry, VA);
   }
 }
@@ -197,8 +183,8 @@ template <class ELFT> void PltSection<EL
   for (auto &I : Entries) {
     const SymbolBody *B = I.first;
     unsigned RelOff = I.second;
-    uint64_t Got = Target->UseLazyBinding ? Out<ELFT>::GotPlt->getEntryAddr(*B)
-                                          : Out<ELFT>::Got->getEntryAddr(*B);
+    uint64_t Got =
+        Target->UseLazyBinding ? B->getGotPltVA<ELFT>() : B->getGotVA<ELFT>();
     uint64_t Plt = this->getVA() + Off;
     Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
     Off += Target->PltEntrySize;
@@ -213,13 +199,6 @@ template <class ELFT> void PltSection<EL
   Entries.push_back(std::make_pair(Sym, RelOff));
 }
 
-template <class ELFT>
-typename PltSection<ELFT>::uintX_t
-PltSection<ELFT>::getEntryAddr(const SymbolBody &B) const {
-  return this->getVA() + Target->PltZeroSize +
-         B.PltIndex * Target->PltEntrySize;
-}
-
 template <class ELFT> void PltSection<ELFT>::finalize() {
   this->Header.sh_size =
       Target->PltZeroSize + Entries.size() * Target->PltEntrySize;
@@ -251,7 +230,7 @@ bool RelocationSection<ELFT>::applyTlsDy
   if (Target->canRelaxTls(Type, Body)) {
     P->setSymbolAndType(Body->DynsymIndex, Target->getTlsGotRel(),
                         Config->Mips64EL);
-    P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
+    P->r_offset = Body->getGotVA<ELFT>();
     return true;
   }
 
@@ -312,9 +291,9 @@ template <class ELFT> void RelocationSec
     if (!CBP && Body && isGnuIFunc<ELFT>(*Body)) {
       P->setSymbolAndType(0, Target->IRelativeRel, Config->Mips64EL);
       if (Out<ELFT>::GotPlt)
-        P->r_offset = Out<ELFT>::GotPlt->getEntryAddr(*Body);
+        P->r_offset = Body->getGotPltVA<ELFT>();
       else
-        P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
+        P->r_offset = Body->getGotVA<ELFT>();
       continue;
     }
 
@@ -333,9 +312,9 @@ template <class ELFT> void RelocationSec
     P->setSymbolAndType(CBP ? Body->DynsymIndex : 0, Reloc, Config->Mips64EL);
 
     if (LazyReloc)
-      P->r_offset = Out<ELFT>::GotPlt->getEntryAddr(*Body);
+      P->r_offset = Body->getGotPltVA<ELFT>();
     else if (NeedsGot)
-      P->r_offset = Out<ELFT>::Got->getEntryAddr(*Body);
+      P->r_offset = Body->getGotVA<ELFT>();
     else
       P->r_offset = C.getOffset(RI.r_offset) + C.OutSec->getVA();
 
@@ -348,7 +327,7 @@ template <class ELFT> void RelocationSec
     if (CBP)
       S->r_addend = A;
     else if (Body)
-      S->r_addend = getSymVA<ELFT>(*Body) + A;
+      S->r_addend = Body->getVA<ELFT>() + A;
     else
       S->r_addend = getLocalRelTarget(File, R, A);
   }
@@ -715,7 +694,7 @@ template <class ELFT> void DynamicSectio
       P->d_un.d_ptr = E.OutSec->getVA();
       break;
     case Entry::SymAddr:
-      P->d_un.d_ptr = getSymVA<ELFT>(*E.Sym);
+      P->d_un.d_ptr = E.Sym->template getVA<ELFT>();
       break;
     case Entry::PlainInt:
       P->d_un.d_val = E.Val;
@@ -835,48 +814,8 @@ void OutputSection<ELFT>::addSection(Inp
   this->Header.sh_size = Off;
 }
 
-template <class ELFT>
-typename ELFFile<ELFT>::uintX_t elf2::getSymVA(const SymbolBody &S) {
-  switch (S.kind()) {
-  case SymbolBody::DefinedSyntheticKind: {
-    auto &D = cast<DefinedSynthetic<ELFT>>(S);
-    return D.Section.getVA() + D.Value;
-  }
-  case SymbolBody::DefinedRegularKind: {
-    const auto &DR = cast<DefinedRegular<ELFT>>(S);
-    InputSectionBase<ELFT> *SC = DR.Section;
-    if (!SC)
-      return DR.Sym.st_value;
-
-    // Symbol offsets for AMDGPU need to be the offset in bytes of the symbol
-    // from the beginning of the section.
-    if (Config->EMachine == EM_AMDGPU)
-      return SC->getOffset(DR.Sym);
-    if (DR.Sym.getType() == STT_TLS)
-      return SC->OutSec->getVA() + SC->getOffset(DR.Sym) -
-             Out<ELFT>::TlsPhdr->p_vaddr;
-    return SC->OutSec->getVA() + SC->getOffset(DR.Sym);
-  }
-  case SymbolBody::DefinedCommonKind:
-    return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(S).OffsetInBss;
-  case SymbolBody::SharedKind: {
-    auto &SS = cast<SharedSymbol<ELFT>>(S);
-    if (SS.NeedsCopy)
-      return Out<ELFT>::Bss->getVA() + SS.OffsetInBss;
-    return 0;
-  }
-  case SymbolBody::UndefinedElfKind:
-  case SymbolBody::UndefinedKind:
-    return 0;
-  case SymbolBody::LazyKind:
-    assert(S.isUsedInRegularObj() && "Lazy symbol reached writer");
-    return 0;
-  }
-  llvm_unreachable("Invalid symbol kind");
-}
-
 // Returns a VA which a relocatin RI refers to. Used only for local symbols.
-// For non-local symbols, use getSymVA instead.
+// For non-local symbols, use SymbolBody::getVA instead.
 template <class ELFT, bool IsRela>
 typename ELFFile<ELFT>::uintX_t
 elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
@@ -1523,7 +1462,7 @@ void SymbolTableSection<ELFT>::writeGlob
     ESym->setBindingAndType(getSymbolBinding(Body), Type);
     ESym->st_size = Size;
     ESym->setVisibility(Body->getVisibility());
-    ESym->st_value = getSymVA<ELFT>(*Body);
+    ESym->st_value = Body->getVA<ELFT>();
 
     if (OutSec)
       ESym->st_shndx = OutSec->SectionIndex;
@@ -1650,11 +1589,6 @@ template class SymbolTableSection<ELF32B
 template class SymbolTableSection<ELF64LE>;
 template class SymbolTableSection<ELF64BE>;
 
-template ELFFile<ELF32LE>::uintX_t getSymVA<ELF32LE>(const SymbolBody &);
-template ELFFile<ELF32BE>::uintX_t getSymVA<ELF32BE>(const SymbolBody &);
-template ELFFile<ELF64LE>::uintX_t getSymVA<ELF64LE>(const SymbolBody &);
-template ELFFile<ELF64BE>::uintX_t getSymVA<ELF64BE>(const SymbolBody &);
-
 template uint32_t getLocalRelTarget(const ObjectFile<ELF32LE> &,
                                     const ELFFile<ELF32LE>::Elf_Rel &,
                                     uint32_t);

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=259404&r1=259403&r2=259404&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Mon Feb  1 15:00:35 2016
@@ -47,9 +47,6 @@ getAddend(const typename llvm::object::E
   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,
@@ -118,7 +115,6 @@ public:
   bool addDynTlsEntry(SymbolBody *Sym);
   bool addCurrentModuleTlsIndex();
   bool empty() const { return MipsLocalEntries == 0 && Entries.empty(); }
-  uintX_t getEntryAddr(const SymbolBody &B) const;
   uintX_t getMipsLocalFullAddr(const SymbolBody &B);
   uintX_t getMipsLocalPageAddr(uintX_t Addr);
   uintX_t getGlobalDynAddr(const SymbolBody &B) const;
@@ -155,7 +151,6 @@ public:
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   bool empty() const;
-  uintX_t getEntryAddr(const SymbolBody &B) const;
 
 private:
   std::vector<const SymbolBody *> Entries;
@@ -171,7 +166,6 @@ public:
   void writeTo(uint8_t *Buf) override;
   void addEntry(SymbolBody *Sym);
   bool empty() const { return Entries.empty(); }
-  uintX_t getEntryAddr(const SymbolBody &B) const;
 
 private:
   std::vector<std::pair<const SymbolBody *, unsigned>> Entries;

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=259404&r1=259403&r2=259404&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Mon Feb  1 15:00:35 2016
@@ -8,9 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "Symbols.h"
-#include "InputSection.h"
 #include "Error.h"
 #include "InputFiles.h"
+#include "InputSection.h"
+#include "OutputSections.h"
+#include "Target.h"
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Config/config.h"
@@ -26,6 +28,67 @@ using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf2;
 
+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;
+  }
+  case DefinedRegularKind: {
+    auto *D = cast<DefinedRegular<ELFT>>(this);
+    InputSectionBase<ELFT> *SC = D->Section;
+
+    // This is an absolute symbol.
+    if (!SC)
+      return D->Sym.st_value;
+
+    // Symbol offsets for AMDGPU need to be the offset in bytes of the symbol
+    // from the beginning of the section.
+    if (Config->EMachine == EM_AMDGPU)
+      return 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);
+  }
+  case DefinedCommonKind:
+    return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(this)->OffsetInBss;
+  case SharedKind: {
+    auto *SS = cast<SharedSymbol<ELFT>>(this);
+    if (SS->NeedsCopy)
+      return Out<ELFT>::Bss->getVA() + SS->OffsetInBss;
+    return 0;
+  }
+  case UndefinedElfKind:
+  case UndefinedKind:
+    return 0;
+  case LazyKind:
+    assert(isUsedInRegularObj() && "Lazy symbol reached writer");
+    return 0;
+  }
+  llvm_unreachable("Invalid symbol kind");
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::uintX_t SymbolBody::getGotVA() const {
+  return Out<ELFT>::Got->getVA() +
+         (Out<ELFT>::Got->getMipsLocalEntriesNum() + GotIndex) *
+             sizeof(typename ELFFile<ELFT>::uintX_t);
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::uintX_t SymbolBody::getGotPltVA() const {
+  return Out<ELFT>::GotPlt->getVA() +
+         GotPltIndex * sizeof(typename ELFFile<ELFT>::uintX_t);
+}
+
+template <class ELFT>
+typename ELFFile<ELFT>::uintX_t SymbolBody::getPltVA() const {
+  return Out<ELFT>::Plt->getVA() + Target->PltZeroSize +
+         PltIndex * Target->PltEntrySize;
+}
+
 static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
   if (VA == STV_DEFAULT)
     return VB;
@@ -166,6 +229,26 @@ std::string elf2::demangle(StringRef Nam
 #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 getGotVA<ELF32LE>() const;
+template uint32_t SymbolBody::template getGotVA<ELF32BE>() const;
+template uint64_t SymbolBody::template getGotVA<ELF64LE>() const;
+template uint64_t SymbolBody::template getGotVA<ELF64BE>() const;
+
+template uint32_t SymbolBody::template getGotPltVA<ELF32LE>() const;
+template uint32_t SymbolBody::template getGotPltVA<ELF32BE>() const;
+template uint64_t SymbolBody::template getGotPltVA<ELF64LE>() const;
+template uint64_t SymbolBody::template getGotPltVA<ELF64BE>() const;
+
+template uint32_t SymbolBody::template getPltVA<ELF32LE>() const;
+template uint32_t SymbolBody::template getPltVA<ELF32BE>() const;
+template uint64_t SymbolBody::template getPltVA<ELF64LE>() const;
+template uint64_t SymbolBody::template getPltVA<ELF64BE>() const;
+
 template int SymbolBody::compare<ELF32LE>(SymbolBody *Other);
 template int SymbolBody::compare<ELF32BE>(SymbolBody *Other);
 template int SymbolBody::compare<ELF64LE>(SymbolBody *Other);

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=259404&r1=259403&r2=259404&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Mon Feb  1 15:00:35 2016
@@ -101,6 +101,15 @@ public:
   bool isInGot() const { return GotIndex != -1U; }
   bool isInPlt() const { return PltIndex != -1U; }
 
+  template <class ELFT>
+  typename llvm::object::ELFFile<ELFT>::uintX_t getVA() const;
+  template <class ELFT>
+  typename llvm::object::ELFFile<ELFT>::uintX_t getGotVA() const;
+  template <class ELFT>
+  typename llvm::object::ELFFile<ELFT>::uintX_t getGotPltVA() const;
+  template <class ELFT>
+  typename llvm::object::ELFFile<ELFT>::uintX_t getPltVA() const;
+
   // A SymbolBody has a backreference to a Symbol. Originally they are
   // doubly-linked. A backreference will never change. But the pointer
   // in the Symbol may be mutated by the resolver. If you have a

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=259404&r1=259403&r2=259404&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Feb  1 15:00:35 2016
@@ -1257,8 +1257,8 @@ static uint32_t getELFFlags() {
 template <class ELFT>
 static typename ELFFile<ELFT>::uintX_t getEntryAddr() {
   if (Config->EntrySym) {
-    if (SymbolBody *E = Config->EntrySym->repl())
-      return getSymVA<ELFT>(*E);
+    if (SymbolBody *B = Config->EntrySym->repl())
+      return B->getVA<ELFT>();
     return 0;
   }
   if (Config->EntryAddr != uint64_t(-1))




More information about the llvm-commits mailing list