[lld] r296303 - De-template SharedSymbol.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 26 15:35:34 PST 2017


Author: ruiu
Date: Sun Feb 26 17:35:34 2017
New Revision: 296303

URL: http://llvm.org/viewvc/llvm-project?rev=296303&view=rev
Log:
De-template SharedSymbol.

Differential Revision: https://reviews.llvm.org/D30351

Modified:
    lld/trunk/ELF/OutputSections.h
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Sun Feb 26 17:35:34 2017
@@ -30,7 +30,7 @@ template <class ELFT> class MergeInputSe
 class OutputSection;
 template <class ELFT> class ObjectFile;
 template <class ELFT> class SharedFile;
-template <class ELFT> class SharedSymbol;
+class SharedSymbol;
 template <class ELFT> class DefinedRegular;
 
 // This represents a section in an output file.

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Sun Feb 26 17:35:34 2017
@@ -387,23 +387,13 @@ static RelExpr fromPlt(RelExpr Expr) {
   return Expr;
 }
 
-template <class ELFT> static uint32_t getAlignment(SharedSymbol<ELFT> *SS) {
-  typedef typename ELFT::uint uintX_t;
-
-  uintX_t SecAlign = SS->file()->getSection(SS->Sym)->sh_addralign;
-  uintX_t SymValue = SS->Sym.st_value;
-  int TrailingZeros =
-      std::min(countTrailingZeros(SecAlign), countTrailingZeros(SymValue));
-  return 1 << TrailingZeros;
-}
-
-template <class ELFT> static bool isReadOnly(SharedSymbol<ELFT> *SS) {
-  typedef typename ELFT::uint uintX_t;
+template <class ELFT> static bool isReadOnly(SharedSymbol *SS) {
   typedef typename ELFT::Phdr Elf_Phdr;
+  uint64_t Value = SS->getValue<ELFT>();
 
   // Determine if the symbol is read-only by scanning the DSO's program headers.
-  uintX_t Value = SS->Sym.st_value;
-  for (const Elf_Phdr &Phdr : check(SS->file()->getObj().program_headers()))
+  auto *File = cast<SharedFile<ELFT>>(SS->File);
+  for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
     if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
         !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr &&
         Value < Phdr.p_vaddr + Phdr.p_memsz)
@@ -417,16 +407,20 @@ template <class ELFT> static bool isRead
 // them are copied by a copy relocation, all of them need to be copied.
 // Otherwise, they would refer different places at runtime.
 template <class ELFT>
-static std::vector<SharedSymbol<ELFT> *> getSymbolsAt(SharedSymbol<ELFT> *SS) {
+static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) {
   typedef typename ELFT::Sym Elf_Sym;
 
-  std::vector<SharedSymbol<ELFT> *> Ret;
-  for (const Elf_Sym &S : SS->file()->getGlobalSymbols()) {
-    if (S.st_shndx != SS->Sym.st_shndx || S.st_value != SS->Sym.st_value)
+  auto *File = cast<SharedFile<ELFT>>(SS->File);
+  uint64_t Shndx = SS->getShndx<ELFT>();
+  uint64_t Value = SS->getValue<ELFT>();
+
+  std::vector<SharedSymbol *> Ret;
+  for (const Elf_Sym &S : File->getGlobalSymbols()) {
+    if (S.st_shndx != Shndx || S.st_value != Value)
       continue;
-    StringRef Name = check(S.getName(SS->file()->getStringTable()));
+    StringRef Name = check(S.getName(File->getStringTable()));
     SymbolBody *Sym = Symtab<ELFT>::X->find(Name);
-    if (auto *Alias = dyn_cast_or_null<SharedSymbol<ELFT>>(Sym))
+    if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym))
       Ret.push_back(Alias);
   }
   return Ret;
@@ -474,7 +468,7 @@ static std::vector<SharedSymbol<ELFT> *>
 // to the variable in .bss. This kind of issue is sometimes very hard to
 // debug. What's a solution? Instead of exporting a varaible V from a DSO,
 // define an accessor getV().
-template <class ELFT> static void addCopyRelSymbol(SharedSymbol<ELFT> *SS) {
+template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
   typedef typename ELFT::uint uintX_t;
 
   // Copy relocation against zero-sized symbol doesn't make sense.
@@ -484,18 +478,18 @@ template <class ELFT> static void addCop
 
   // See if this symbol is in a read-only segment. If so, preserve the symbol's
   // memory protection by reserving space in the .bss.rel.ro section.
-  bool IsReadOnly = isReadOnly(SS);
+  bool IsReadOnly = isReadOnly<ELFT>(SS);
   OutputSection *OSec = IsReadOnly ? Out<ELFT>::BssRelRo : Out<ELFT>::Bss;
 
   // Create a SyntheticSection in Out to hold the .bss and the Copy Reloc.
   auto *ISec =
-      make<CopyRelSection<ELFT>>(IsReadOnly, getAlignment(SS), SymSize);
+      make<CopyRelSection<ELFT>>(IsReadOnly, SS->getAlignment<ELFT>(), SymSize);
   OSec->addSection(ISec);
 
   // Look through the DSO's dynamic symbol table for aliases and create a
   // dynamic symbol for each one. This causes the copy relocation to correctly
   // interpose any aliases.
-  for (SharedSymbol<ELFT> *Sym : getSymbolsAt(SS)) {
+  for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
     Sym->NeedsCopy = true;
     Sym->Section = ISec;
     Sym->symbol()->IsUsedInRegularObj = true;
@@ -540,14 +534,14 @@ static RelExpr adjustExpr(const elf::Obj
   }
   if (Body.isObject()) {
     // Produce a copy relocation.
-    auto *B = cast<SharedSymbol<ELFT>>(&Body);
+    auto *B = cast<SharedSymbol>(&Body);
     if (!B->NeedsCopy) {
       if (Config->ZNocopyreloc)
         error(S.getLocation<ELFT>(RelOff) + ": unresolvable relocation " +
               toString(Type) + " against symbol '" + toString(*B) +
               "'; recompile with -fPIC or remove '-z nocopyreloc'");
 
-      addCopyRelSymbol(B);
+      addCopyRelSymbol<ELFT>(B);
     }
     return Expr;
   }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Sun Feb 26 17:35:34 2017
@@ -262,8 +262,8 @@ Symbol *SymbolTable<ELFT>::addUndefined(
   if (Binding != STB_WEAK) {
     if (S->body()->isShared() || S->body()->isLazy())
       S->Binding = Binding;
-    if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(S->body()))
-      SS->file()->IsUsed = true;
+    if (auto *SS = dyn_cast<SharedSymbol>(S->body()))
+      cast<SharedFile<ELFT>>(SS->File)->IsUsed = true;
   }
   if (auto *L = dyn_cast<Lazy>(S->body())) {
     // An undefined weak will not fetch archive members, but we have to remember
@@ -413,7 +413,7 @@ Symbol *SymbolTable<ELFT>::addSynthetic(
 }
 
 template <typename ELFT>
-void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *F, StringRef Name,
+void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *File, StringRef Name,
                                   const Elf_Sym &Sym,
                                   const typename ELFT::Verdef *Verdef) {
   // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
@@ -421,15 +421,17 @@ void SymbolTable<ELFT>::addShared(Shared
   // unchanged.
   Symbol *S;
   bool WasInserted;
-  std::tie(S, WasInserted) =
-      insert(Name, Sym.getType(), STV_DEFAULT, /*CanOmitFromDynSym*/ true, F);
+  std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
+                                    /*CanOmitFromDynSym*/ true, File);
   // Make sure we preempt DSO symbols with default visibility.
   if (Sym.getVisibility() == STV_DEFAULT)
     S->ExportDynamic = true;
+
   if (WasInserted || isa<Undefined>(S->body())) {
-    replaceBody<SharedSymbol<ELFT>>(S, F, Name, Sym, Verdef);
+    replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), &Sym,
+                              Verdef);
     if (!S->isWeak())
-      F->IsUsed = true;
+      File->IsUsed = true;
   }
 }
 

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Sun Feb 26 17:35:34 2017
@@ -78,7 +78,7 @@ static typename ELFT::uint getSymVA(cons
     return In<ELFT>::Common->OutSec->Addr + In<ELFT>::Common->OutSecOff +
            cast<DefinedCommon>(Body).Offset;
   case SymbolBody::SharedKind: {
-    auto &SS = cast<SharedSymbol<ELFT>>(Body);
+    auto &SS = cast<SharedSymbol>(Body);
     if (SS.NeedsCopy)
       return SS.Section->OutSec->Addr + SS.Section->OutSecOff;
     if (SS.NeedsPltAddr)
@@ -167,8 +167,8 @@ template <class ELFT> typename ELFT::uin
     return C->Size;
   if (const auto *DR = dyn_cast<DefinedRegular<ELFT>>(this))
     return DR->Size;
-  if (const auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
-    return S->Sym.st_size;
+  if (const auto *S = dyn_cast<SharedSymbol>(this))
+    return S->getSize<ELFT>();
   return 0;
 }
 
@@ -237,6 +237,17 @@ DefinedCommon::DefinedCommon(StringRef N
   this->File = File;
 }
 
+// If a shared symbol is referred via a copy relocation, its alignment
+// becomes part of the ABI. This function returns a symbol alignment.
+// Because symbols don't have alignment attributes, we need to infer that.
+template <class ELFT> uint64_t SharedSymbol::getAlignment() const {
+  auto *File = cast<SharedFile<ELFT>>(this->File);
+  uint64_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
+  uint64_t SymValue = getSym<ELFT>().st_value;
+  uint64_t SymAlign = uint64_t(1) << countTrailingZeros(SymValue);
+  return std::min(SecAlign, SymAlign);
+}
+
 InputFile *Lazy::fetch() {
   if (auto *S = dyn_cast<LazyArchive>(this))
     return S->fetch();
@@ -348,12 +359,12 @@ template uint32_t SymbolBody::template g
 template uint64_t SymbolBody::template getSize<ELF64LE>() const;
 template uint64_t SymbolBody::template getSize<ELF64BE>() const;
 
-template class elf::SharedSymbol<ELF32LE>;
-template class elf::SharedSymbol<ELF32BE>;
-template class elf::SharedSymbol<ELF64LE>;
-template class elf::SharedSymbol<ELF64BE>;
-
 template class elf::DefinedRegular<ELF32LE>;
 template class elf::DefinedRegular<ELF32BE>;
 template class elf::DefinedRegular<ELF64LE>;
 template class elf::DefinedRegular<ELF64BE>;
+
+template uint64_t SharedSymbol::template getAlignment<ELF32LE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF32BE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF64LE>() const;
+template uint64_t SharedSymbol::template getAlignment<ELF64BE>() const;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Sun Feb 26 17:35:34 2017
@@ -241,36 +241,48 @@ public:
   }
 };
 
-template <class ELFT> class SharedSymbol : public Defined {
-  typedef typename ELFT::Sym Elf_Sym;
-  typedef typename ELFT::Verdef Elf_Verdef;
-  typedef typename ELFT::uint uintX_t;
-
+class SharedSymbol : public Defined {
 public:
   static bool classof(const SymbolBody *S) {
     return S->kind() == SymbolBody::SharedKind;
   }
 
-  SharedSymbol(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
-               const Elf_Verdef *Verdef)
-      : Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, Sym.st_other,
-                Sym.getType()),
-        Sym(Sym), Verdef(Verdef) {
+  SharedSymbol(InputFile *File, StringRef Name, uint8_t StOther, uint8_t Type,
+               const void *ElfSym, const void *Verdef)
+      : Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, StOther, Type),
+        Verdef(Verdef), ElfSym(ElfSym) {
     // IFuncs defined in DSOs are treated as functions by the static linker.
     if (isGnuIFunc())
       Type = llvm::ELF::STT_FUNC;
-    this->File = F;
+    this->File = File;
+  }
+
+  template <class ELFT> uint64_t getShndx() const {
+    return getSym<ELFT>().st_shndx;
+  }
+
+  template <class ELFT> uint64_t getValue() const {
+    return getSym<ELFT>().st_value;
   }
 
-  SharedFile<ELFT> *file() { return (SharedFile<ELFT> *)this->File; }
+  template <class ELFT> uint64_t getSize() const {
+    return getSym<ELFT>().st_size;
+  }
 
-  const Elf_Sym &Sym;
+  template <class ELFT> uint64_t getAlignment() const;
 
   // This field is a pointer to the symbol's version definition.
-  const Elf_Verdef *Verdef;
+  const void *Verdef;
 
   // Section is significant only when NeedsCopy is true.
   InputSection *Section = nullptr;
+
+private:
+  template <class ELFT> const typename ELFT::Sym &getSym() const {
+    return *(const typename ELFT::Sym *)ElfSym;
+  }
+
+  const void *ElfSym;
 };
 
 // This class represents a symbol defined in an archive file. It is
@@ -405,7 +417,7 @@ struct Symbol {
   // ELFT, and we verify this with the static_asserts in replaceBody.
   llvm::AlignedCharArrayUnion<
       DefinedCommon, DefinedRegular<llvm::object::ELF64LE>, DefinedSynthetic,
-      Undefined, SharedSymbol<llvm::object::ELF64LE>, LazyArchive, LazyObject>
+      Undefined, SharedSymbol, LazyArchive, LazyObject>
       Body;
 
   SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Sun Feb 26 17:35:34 2017
@@ -1455,7 +1455,7 @@ SymbolTableSection<ELFT>::getOutputSecti
       return nullptr;
     return In<ELFT>::Common->OutSec;
   case SymbolBody::SharedKind: {
-    auto &SS = cast<SharedSymbol<ELFT>>(*Sym);
+    auto &SS = cast<SharedSymbol>(*Sym);
     if (SS.NeedsCopy)
       return SS.Section->OutSec;
     break;
@@ -2003,24 +2003,27 @@ VersionNeedSection<ELFT>::VersionNeedSec
 }
 
 template <class ELFT>
-void VersionNeedSection<ELFT>::addSymbol(SharedSymbol<ELFT> *SS) {
-  if (!SS->Verdef) {
+void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) {
+  auto *Ver = reinterpret_cast<const typename ELFT::Verdef *>(SS->Verdef);
+  if (!Ver) {
     SS->symbol()->VersionId = VER_NDX_GLOBAL;
     return;
   }
-  SharedFile<ELFT> *F = SS->file();
+
+  auto *File = cast<SharedFile<ELFT>>(SS->File);
+
   // If we don't already know that we need an Elf_Verneed for this DSO, prepare
   // to create one by adding it to our needed list and creating a dynstr entry
   // for the soname.
-  if (F->VerdefMap.empty())
-    Needed.push_back({F, In<ELFT>::DynStrTab->addString(F->getSoName())});
-  typename SharedFile<ELFT>::NeededVer &NV = F->VerdefMap[SS->Verdef];
+  if (File->VerdefMap.empty())
+    Needed.push_back({File, In<ELFT>::DynStrTab->addString(File->getSoName())});
+  typename SharedFile<ELFT>::NeededVer &NV = File->VerdefMap[Ver];
   // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef,
   // prepare to create one by allocating a version identifier and creating a
   // dynstr entry for the version name.
   if (NV.Index == 0) {
-    NV.StrTab = In<ELFT>::DynStrTab->addString(
-        SS->file()->getStringTable().data() + SS->Verdef->getAux()->vda_name);
+    NV.StrTab = In<ELFT>::DynStrTab->addString(File->getStringTable().data() +
+                                               Ver->getAux()->vda_name);
     NV.Index = NextIndex++;
   }
   SS->symbol()->VersionId = NV.Index;

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Sun Feb 26 17:35:34 2017
@@ -668,7 +668,7 @@ class VersionNeedSection final : public
 
 public:
   VersionNeedSection();
-  void addSymbol(SharedSymbol<ELFT> *SS);
+  void addSymbol(SharedSymbol *SS);
   void finalize() override;
   void writeTo(uint8_t *Buf) override;
   size_t getSize() const override;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=296303&r1=296302&r2=296303&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sun Feb 26 17:35:34 2017
@@ -1112,8 +1112,8 @@ template <class ELFT> void Writer<ELFT>:
 
     if (In<ELFT>::DynSymTab && S->includeInDynsym()) {
       In<ELFT>::DynSymTab->addGlobal(Body);
-      if (auto *SS = dyn_cast<SharedSymbol<ELFT>>(Body))
-        if (SS->file()->isNeeded())
+      if (auto *SS = dyn_cast<SharedSymbol>(Body))
+        if (cast<SharedFile<ELFT>>(SS->File)->isNeeded())
           In<ELFT>::VerNeed->addSymbol(SS);
     }
   }




More information about the llvm-commits mailing list