[lld] r357925 - ELF: De-template SharedFile. NFCI.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 8 10:35:55 PDT 2019


Author: pcc
Date: Mon Apr  8 10:35:55 2019
New Revision: 357925

URL: http://llvm.org/viewvc/llvm-project?rev=357925&view=rev
Log:
ELF: De-template SharedFile. NFCI.

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

Modified:
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Apr  8 10:35:55 2019
@@ -1289,10 +1289,10 @@ template <class ELFT> static void handle
 // to DT_NEEDED. If that happens, we need to eliminate shared symbols
 // created from the DSO. Otherwise, they become dangling references
 // that point to a non-existent DSO.
-template <class ELFT> static void demoteSharedSymbols() {
+static void demoteSharedSymbols() {
   for (Symbol *Sym : Symtab->getSymbols()) {
     if (auto *S = dyn_cast<SharedSymbol>(Sym)) {
-      if (!S->getFile<ELFT>().IsNeeded) {
+      if (!S->getFile().IsNeeded) {
         bool Used = S->Used;
         replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_WEAK, S->StOther,
                                  S->Type);
@@ -1644,7 +1644,7 @@ template <class ELFT> void LinkerDriver:
   // and identical code folding.
   splitSections<ELFT>();
   markLive<ELFT>();
-  demoteSharedSymbols<ELFT>();
+  demoteSharedSymbols();
   mergeSections();
   if (Config->ICF != ICFLevel::None) {
     findKeepUniqueSections<ELFT>(Args);

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Mon Apr  8 10:35:55 2019
@@ -43,7 +43,7 @@ std::vector<BinaryFile *> elf::BinaryFil
 std::vector<BitcodeFile *> elf::BitcodeFiles;
 std::vector<LazyObjFile *> elf::LazyObjFiles;
 std::vector<InputFile *> elf::ObjectFiles;
-std::vector<InputFile *> elf::SharedFiles;
+std::vector<SharedFile *> elf::SharedFiles;
 
 std::unique_ptr<TarWriter> elf::Tar;
 
@@ -869,20 +869,83 @@ InputFile *ArchiveFile::fetch(const Arch
   return File;
 }
 
-template <class ELFT>
-SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
+SharedFile::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
     : ELFFileBase(SharedKind, M), SoName(DefaultSoName),
-      IsNeeded(!Config->AsNeeded) {
-  parseHeader<ELFT>();
+      IsNeeded(!Config->AsNeeded) {}
+
+// Parse the version definitions in the object file if present, and return a
+// vector whose nth element contains a pointer to the Elf_Verdef for version
+// identifier n. Version identifiers that are not definitions map to nullptr.
+template <typename ELFT>
+static std::vector<const void *> parseVerdefs(const uint8_t *Base,
+                                              const typename ELFT::Shdr *Sec) {
+  if (!Sec)
+    return {};
+
+  // We cannot determine the largest verdef identifier without inspecting
+  // every Elf_Verdef, but both bfd and gold assign verdef identifiers
+  // sequentially starting from 1, so we predict that the largest identifier
+  // will be VerdefCount.
+  unsigned VerdefCount = Sec->sh_info;
+  std::vector<const void *> Verdefs(VerdefCount + 1);
+
+  // Build the Verdefs array by following the chain of Elf_Verdef objects
+  // from the start of the .gnu.version_d section.
+  const uint8_t *Verdef = Base + Sec->sh_offset;
+  for (unsigned I = 0; I != VerdefCount; ++I) {
+    auto *CurVerdef = reinterpret_cast<const typename ELFT::Verdef *>(Verdef);
+    Verdef += CurVerdef->vd_next;
+    unsigned VerdefIndex = CurVerdef->vd_ndx;
+    Verdefs.resize(VerdefIndex + 1);
+    Verdefs[VerdefIndex] = CurVerdef;
+  }
+  return Verdefs;
 }
 
-// Partially parse the shared object file so that we can call
-// getSoName on this object.
-template <class ELFT> void SharedFile<ELFT>::parseDynamic() {
+// We do not usually care about alignments of data in shared object
+// files because the loader takes care of it. However, if we promote a
+// DSO symbol to point to .bss due to copy relocation, we need to keep
+// the original alignment requirements. We infer it in this function.
+template <typename ELFT>
+static uint64_t getAlignment(ArrayRef<typename ELFT::Shdr> Sections,
+                             const typename ELFT::Sym &Sym) {
+  uint64_t Ret = UINT64_MAX;
+  if (Sym.st_value)
+    Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
+  if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
+    Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
+  return (Ret > UINT32_MAX) ? 0 : Ret;
+}
+
+// Fully parse the shared object file.
+//
+// This function parses symbol versions. If a DSO has version information,
+// the file has a ".gnu.version_d" section which contains symbol version
+// definitions. Each symbol is associated to one version through a table in
+// ".gnu.version" section. That table is a parallel array for the symbol
+// table, and each table entry contains an index in ".gnu.version_d".
+//
+// The special index 0 is reserved for VERF_NDX_LOCAL and 1 is for
+// VER_NDX_GLOBAL. There's no table entry for these special versions in
+// ".gnu.version_d".
+//
+// The file format for symbol versioning is perhaps a bit more complicated
+// than necessary, but you can easily understand the code if you wrap your
+// head around the data structure described above.
+template <class ELFT> void SharedFile::parse() {
+  using Elf_Dyn = typename ELFT::Dyn;
+  using Elf_Shdr = typename ELFT::Shdr;
+  using Elf_Sym = typename ELFT::Sym;
+  using Elf_Verdef = typename ELFT::Verdef;
+  using Elf_Versym = typename ELFT::Versym;
+
   ArrayRef<Elf_Dyn> DynamicTags;
   const ELFFile<ELFT> Obj = this->getObj<ELFT>();
   ArrayRef<Elf_Shdr> Sections = CHECK(Obj.sections(), this);
 
+  const Elf_Shdr *VersymSec = nullptr;
+  const Elf_Shdr *VerdefSec = nullptr;
+
   // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
   for (const Elf_Shdr &Sec : Sections) {
     switch (Sec.sh_type) {
@@ -896,16 +959,18 @@ template <class ELFT> void SharedFile<EL
           CHECK(Obj.template getSectionContentsAsArray<Elf_Dyn>(&Sec), this);
       break;
     case SHT_GNU_versym:
-      this->VersymSec = &Sec;
+      VersymSec = &Sec;
       break;
     case SHT_GNU_verdef:
-      this->VerdefSec = &Sec;
+      VerdefSec = &Sec;
       break;
     }
   }
 
-  if (this->VersymSec && this->getELFSyms<ELFT>().empty())
+  if (VersymSec && this->getELFSyms<ELFT>().empty()) {
     error("SHT_GNU_versym should be associated with symbol table");
+    return;
+  }
 
   // Search for a DT_SONAME tag to initialize this->SoName.
   for (const Elf_Dyn &Dyn : DynamicTags) {
@@ -921,91 +986,38 @@ template <class ELFT> void SharedFile<EL
       SoName = this->StringTable.data() + Val;
     }
   }
-}
 
-// Parses ".gnu.version" section which is a parallel array for the symbol table.
-// If a given file doesn't have ".gnu.version" section, returns VER_NDX_GLOBAL.
-template <class ELFT> std::vector<uint32_t> SharedFile<ELFT>::parseVersyms() {
-  size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
-  if (!VersymSec)
-    return std::vector<uint32_t>(Size, VER_NDX_GLOBAL);
+  // DSOs are uniquified not by filename but by soname.
+  DenseMap<StringRef, SharedFile *>::iterator It;
+  bool WasInserted;
+  std::tie(It, WasInserted) = Symtab->SoNames.try_emplace(SoName, this);
+
+  // If a DSO appears more than once on the command line with and without
+  // --as-needed, --no-as-needed takes precedence over --as-needed because a
+  // user can add an extra DSO with --no-as-needed to force it to be added to
+  // the dependency list.
+  It->second->IsNeeded |= IsNeeded;
+  if (!WasInserted)
+    return;
 
-  const char *Base = this->MB.getBuffer().data();
-  const Elf_Versym *Versym =
-      reinterpret_cast<const Elf_Versym *>(Base + VersymSec->sh_offset) +
-      this->FirstGlobal;
-
-  std::vector<uint32_t> Ret(Size);
-  for (size_t I = 0; I < Size; ++I)
-    Ret[I] = Versym[I].vs_index;
-  return Ret;
-}
-
-// Parse the version definitions in the object file if present. Returns a vector
-// whose nth element contains a pointer to the Elf_Verdef for version identifier
-// n. Version identifiers that are not definitions map to nullptr.
-template <class ELFT>
-std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {
-  if (!VerdefSec)
-    return {};
+  SharedFiles.push_back(this);
 
-  // We cannot determine the largest verdef identifier without inspecting
-  // every Elf_Verdef, but both bfd and gold assign verdef identifiers
-  // sequentially starting from 1, so we predict that the largest identifier
-  // will be VerdefCount.
-  unsigned VerdefCount = VerdefSec->sh_info;
-  std::vector<const Elf_Verdef *> Verdefs(VerdefCount + 1);
+  Verdefs = parseVerdefs<ELFT>(Obj.base(), VerdefSec);
 
-  // Build the Verdefs array by following the chain of Elf_Verdef objects
-  // from the start of the .gnu.version_d section.
-  const char *Base = this->MB.getBuffer().data();
-  const char *Verdef = Base + VerdefSec->sh_offset;
-  for (unsigned I = 0; I != VerdefCount; ++I) {
-    auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);
-    Verdef += CurVerdef->vd_next;
-    unsigned VerdefIndex = CurVerdef->vd_ndx;
-    Verdefs.resize(VerdefIndex + 1);
-    Verdefs[VerdefIndex] = CurVerdef;
+  // Parse ".gnu.version" section which is a parallel array for the symbol
+  // table. If a given file doesn't have a ".gnu.version" section, we use
+  // VER_NDX_GLOBAL.
+  size_t Size = this->getELFSyms<ELFT>().size() - this->FirstGlobal;
+  std::vector<uint32_t> Versyms(Size, VER_NDX_GLOBAL);
+  if (VersymSec) {
+    ArrayRef<Elf_Versym> Versym =
+        CHECK(Obj.template getSectionContentsAsArray<Elf_Versym>(VersymSec),
+              this)
+            .slice(FirstGlobal);
+    for (size_t I = 0; I < Size; ++I)
+      Versyms[I] = Versym[I].vs_index;
   }
 
-  return Verdefs;
-}
-
-// We do not usually care about alignments of data in shared object
-// files because the loader takes care of it. However, if we promote a
-// DSO symbol to point to .bss due to copy relocation, we need to keep
-// the original alignment requirements. We infer it in this function.
-template <class ELFT>
-uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
-                                        const Elf_Sym &Sym) {
-  uint64_t Ret = UINT64_MAX;
-  if (Sym.st_value)
-    Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
-  if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
-    Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
-  return (Ret > UINT32_MAX) ? 0 : Ret;
-}
-
-// Fully parse the shared object file. This must be called after parseDynamic().
-//
-// This function parses symbol versions. If a DSO has version information,
-// the file has a ".gnu.version_d" section which contains symbol version
-// definitions. Each symbol is associated to one version through a table in
-// ".gnu.version" section. That table is a parallel array for the symbol
-// table, and each table entry contains an index in ".gnu.version_d".
-//
-// The special index 0 is reserved for VERF_NDX_LOCAL and 1 is for
-// VER_NDX_GLOBAL. There's no table entry for these special versions in
-// ".gnu.version_d".
-//
-// The file format for symbol versioning is perhaps a bit more complicated
-// than necessary, but you can easily understand the code if you wrap your
-// head around the data structure described above.
-template <class ELFT> void SharedFile<ELFT>::parseRest() {
-  Verdefs = parseVerdefs();                       // parse .gnu.version_d
-  std::vector<uint32_t> Versyms = parseVersyms(); // parse .gnu.version
-  ArrayRef<Elf_Shdr> Sections = CHECK(this->getObj<ELFT>().sections(), this);
-
   // System libraries can have a lot of symbols with versions. Using a
   // fixed buffer for computing the versions name (foo at ver) can save a
   // lot of allocations.
@@ -1043,9 +1055,9 @@ template <class ELFT> void SharedFile<EL
         Name == "_gp_disp")
       continue;
 
-    uint64_t Alignment = getAlignment(Sections, Sym);
+    uint64_t Alignment = getAlignment<ELFT>(Sections, Sym);
     if (!(Versyms[I] & VERSYM_HIDDEN))
-      Symtab->addShared(Name, *this, Sym, Alignment, Idx);
+      Symtab->addShared<ELFT>(Name, *this, Sym, Alignment, Idx);
 
     // Also add the symbol with the versioned name to handle undefined symbols
     // with explicit versions.
@@ -1060,10 +1072,11 @@ template <class ELFT> void SharedFile<EL
     }
 
     StringRef VerName =
-        this->StringTable.data() + Verdefs[Idx]->getAux()->vda_name;
+        this->StringTable.data() +
+        reinterpret_cast<const Elf_Verdef *>(Verdefs[Idx])->getAux()->vda_name;
     VersionedNameBuffer.clear();
     Name = (Name + "@" + VerName).toStringRef(VersionedNameBuffer);
-    Symtab->addShared(Saver.save(Name), *this, Sym, Alignment, Idx);
+    Symtab->addShared<ELFT>(Saver.save(Name), *this, Sym, Alignment, Idx);
   }
 }
 
@@ -1259,18 +1272,24 @@ InputFile *elf::createObjectFile(MemoryB
 }
 
 InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) {
+  auto *F = make<SharedFile>(MB, DefaultSoName);
   switch (getELFKind(MB, "")) {
   case ELF32LEKind:
-    return make<SharedFile<ELF32LE>>(MB, DefaultSoName);
+    F->parseHeader<ELF32LE>();
+    break;
   case ELF32BEKind:
-    return make<SharedFile<ELF32BE>>(MB, DefaultSoName);
+    F->parseHeader<ELF32BE>();
+    break;
   case ELF64LEKind:
-    return make<SharedFile<ELF64LE>>(MB, DefaultSoName);
+    F->parseHeader<ELF64LE>();
+    break;
   case ELF64BEKind:
-    return make<SharedFile<ELF64BE>>(MB, DefaultSoName);
+    F->parseHeader<ELF64BE>();
+    break;
   default:
     llvm_unreachable("getELFKind");
   }
+  return F;
 }
 
 MemoryBufferRef LazyObjFile::getBuffer() {
@@ -1355,7 +1374,7 @@ template class elf::ObjFile<ELF32BE>;
 template class elf::ObjFile<ELF64LE>;
 template class elf::ObjFile<ELF64BE>;
 
-template class elf::SharedFile<ELF32LE>;
-template class elf::SharedFile<ELF32BE>;
-template class elf::SharedFile<ELF64LE>;
-template class elf::SharedFile<ELF64BE>;
+template void SharedFile::parse<ELF32LE>();
+template void SharedFile::parse<ELF32BE>();
+template void SharedFile::parse<ELF64LE>();
+template void SharedFile::parse<ELF64BE>();

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Mon Apr  8 10:35:55 2019
@@ -328,19 +328,10 @@ public:
 };
 
 // .so file.
-template <class ELFT> class SharedFile : public ELFFileBase {
-  using Elf_Dyn = typename ELFT::Dyn;
-  using Elf_Shdr = typename ELFT::Shdr;
-  using Elf_Sym = typename ELFT::Sym;
-  using Elf_Sym_Range = typename ELFT::SymRange;
-  using Elf_Verdef = typename ELFT::Verdef;
-  using Elf_Versym = typename ELFT::Versym;
-
-  const Elf_Shdr *VersymSec = nullptr;
-  const Elf_Shdr *VerdefSec = nullptr;
-
+class SharedFile : public ELFFileBase {
 public:
-  std::vector<const Elf_Verdef *> Verdefs;
+  // This is actually a vector of Elf_Verdef pointers.
+  std::vector<const void *> Verdefs;
   std::vector<StringRef> DtNeeded;
   std::string SoName;
 
@@ -348,11 +339,7 @@ public:
 
   SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
 
-  void parseDynamic();
-  void parseRest();
-  uint32_t getAlignment(ArrayRef<Elf_Shdr> Sections, const Elf_Sym &Sym);
-  std::vector<const Elf_Verdef *> parseVerdefs();
-  std::vector<uint32_t> parseVersyms();
+  template <typename ELFT> void parse();
 
   struct NeededVer {
     // The string table offset of the version name in the output file.
@@ -364,7 +351,7 @@ public:
 
   // Mapping from Elf_Verdef data structures to information about Elf_Vernaux
   // data structures in the output file.
-  std::map<const Elf_Verdef *, NeededVer> VerdefMap;
+  std::map<const void *, NeededVer> VerdefMap;
 
   // Used for --no-allow-shlib-undefined.
   bool AllNeededIsKnown;
@@ -394,7 +381,7 @@ extern std::vector<BinaryFile *> BinaryF
 extern std::vector<BitcodeFile *> BitcodeFiles;
 extern std::vector<LazyObjFile *> LazyObjFiles;
 extern std::vector<InputFile *> ObjectFiles;
-extern std::vector<InputFile *> SharedFiles;
+extern std::vector<SharedFile *> SharedFiles;
 
 } // namespace elf
 } // namespace lld

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Mon Apr  8 10:35:55 2019
@@ -103,7 +103,7 @@ void MarkLive<ELFT>::resolveReloc(InputS
 
   if (auto *SS = dyn_cast<SharedSymbol>(&Sym))
     if (!SS->isWeak())
-      SS->getFile<ELFT>().IsNeeded = true;
+      SS->getFile().IsNeeded = true;
 
   for (InputSectionBase *Sec : CNamedSections.lookup(Sym.getName()))
     enqueue(Sec, 0);
@@ -276,7 +276,7 @@ template <class ELFT> void elf::markLive
     for (Symbol *Sym : Symtab->getSymbols())
       if (auto *S = dyn_cast<SharedSymbol>(Sym))
         if (S->IsUsedInRegularObj && !S->isWeak())
-          S->getFile<ELFT>().IsNeeded = true;
+          S->getFile().IsNeeded = true;
     return;
   }
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Mon Apr  8 10:35:55 2019
@@ -482,7 +482,7 @@ template <class ELFT> static bool isRead
   using Elf_Phdr = typename ELFT::Phdr;
 
   // Determine if the symbol is read-only by scanning the DSO's program headers.
-  const SharedFile<ELFT> &File = SS.getFile<ELFT>();
+  const SharedFile &File = SS.getFile();
   for (const Elf_Phdr &Phdr :
        check(File.template getObj<ELFT>().program_headers()))
     if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
@@ -501,7 +501,7 @@ template <class ELFT>
 static SmallSet<SharedSymbol *, 4> getSymbolsAt(SharedSymbol &SS) {
   using Elf_Sym = typename ELFT::Sym;
 
-  SharedFile<ELFT> &File = SS.getFile<ELFT>();
+  SharedFile &File = SS.getFile();
 
   SmallSet<SharedSymbol *, 4> Ret;
   for (const Elf_Sym &S : File.template getGlobalELFSyms<ELFT>()) {

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon Apr  8 10:35:55 2019
@@ -90,25 +90,8 @@ template <class ELFT> void SymbolTable::
     message(toString(File));
 
   // .so file
-  if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
-    // DSOs are uniquified not by filename but by soname.
-    F->parseDynamic();
-    if (errorCount())
-      return;
-
-    // If a DSO appears more than once on the command line with and without
-    // --as-needed, --no-as-needed takes precedence over --as-needed because a
-    // user can add an extra DSO with --no-as-needed to force it to be added to
-    // the dependency list.
-    DenseMap<StringRef, InputFile *>::iterator It;
-    bool WasInserted;
-    std::tie(It, WasInserted) = SoNames.try_emplace(F->SoName, F);
-    cast<SharedFile<ELFT>>(It->second)->IsNeeded |= F->IsNeeded;
-    if (!WasInserted)
-      return;
-
-    SharedFiles.push_back(F);
-    F->parseRest();
+  if (auto *F = dyn_cast<SharedFile>(File)) {
+    F->parse<ELFT>();
     return;
   }
 
@@ -485,7 +468,7 @@ Defined *SymbolTable::addDefined(StringR
 }
 
 template <typename ELFT>
-void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> &File,
+void SymbolTable::addShared(StringRef Name, SharedFile &File,
                             const typename ELFT::Sym &Sym, uint32_t Alignment,
                             uint32_t VerdefIndex) {
   // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
@@ -802,15 +785,15 @@ template void SymbolTable::fetchLazy<ELF
 template void SymbolTable::fetchLazy<ELF64LE>(Symbol *);
 template void SymbolTable::fetchLazy<ELF64BE>(Symbol *);
 
-template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile<ELF32LE> &,
+template void SymbolTable::addShared<ELF32LE>(StringRef, SharedFile &,
                                               const typename ELF32LE::Sym &,
                                               uint32_t Alignment, uint32_t);
-template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile<ELF32BE> &,
+template void SymbolTable::addShared<ELF32BE>(StringRef, SharedFile &,
                                               const typename ELF32BE::Sym &,
                                               uint32_t Alignment, uint32_t);
-template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile<ELF64LE> &,
+template void SymbolTable::addShared<ELF64LE>(StringRef, SharedFile &,
                                               const typename ELF64LE::Sym &,
                                               uint32_t Alignment, uint32_t);
-template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile<ELF64BE> &,
+template void SymbolTable::addShared<ELF64BE>(StringRef, SharedFile &,
                                               const typename ELF64BE::Sym &,
                                               uint32_t Alignment, uint32_t);

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Mon Apr  8 10:35:55 2019
@@ -49,9 +49,8 @@ public:
                       SectionBase *Section, InputFile *File);
 
   template <class ELFT>
-  void addShared(StringRef Name, SharedFile<ELFT> &F,
-                 const typename ELFT::Sym &Sym, uint32_t Alignment,
-                 uint32_t VerdefIndex);
+  void addShared(StringRef Name, SharedFile &F, const typename ELFT::Sym &Sym,
+                 uint32_t Alignment, uint32_t VerdefIndex);
 
   template <class ELFT>
   void addLazyArchive(StringRef Name, ArchiveFile &F,
@@ -80,7 +79,7 @@ public:
   void handleDynamicList();
 
   // Set of .so files to not link the same shared object file more than once.
-  llvm::DenseMap<StringRef, InputFile *> SoNames;
+  llvm::DenseMap<StringRef, SharedFile *> SoNames;
 
 private:
   std::pair<Symbol *, bool> insertName(StringRef Name);

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Mon Apr  8 10:35:55 2019
@@ -13,6 +13,7 @@
 #ifndef LLD_ELF_SYMBOLS_H
 #define LLD_ELF_SYMBOLS_H
 
+#include "InputFiles.h"
 #include "InputSection.h"
 #include "lld/Common/LLVM.h"
 #include "lld/Common/Strings.h"
@@ -30,8 +31,6 @@ std::string toString(const elf::InputFil
 
 namespace elf {
 
-template <class ELFT> class SharedFile;
-
 // This is a StringRef-like container that doesn't run strlen().
 //
 // ELF string tables contain a lot of null-terminated strings. Most of them
@@ -266,9 +265,7 @@ public:
       this->Type = llvm::ELF::STT_FUNC;
   }
 
-  template <class ELFT> SharedFile<ELFT> &getFile() const {
-    return *cast<SharedFile<ELFT>>(File);
-  }
+  SharedFile &getFile() const { return *cast<SharedFile>(File); }
 
   uint32_t Alignment;
 

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Mon Apr  8 10:35:55 2019
@@ -1263,11 +1263,9 @@ template <class ELFT> void DynamicSectio
     addInt(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
            In.DynStrTab->addString(Config->Rpath));
 
-  for (InputFile *File : SharedFiles) {
-    SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
-    if (F->IsNeeded)
-      addInt(DT_NEEDED, In.DynStrTab->addString(F->SoName));
-  }
+  for (SharedFile *File : SharedFiles)
+    if (File->IsNeeded)
+      addInt(DT_NEEDED, In.DynStrTab->addString(File->SoName));
   if (!Config->SoName.empty())
     addInt(DT_SONAME, In.DynStrTab->addString(Config->SoName));
 
@@ -2792,7 +2790,7 @@ VersionNeedBaseSection::VersionNeedBaseS
 }
 
 template <class ELFT> void VersionNeedSection<ELFT>::addSymbol(Symbol *SS) {
-  auto &File = cast<SharedFile<ELFT>>(*SS->File);
+  auto &File = cast<SharedFile>(*SS->File);
   if (SS->VerdefIndex == VER_NDX_GLOBAL) {
     SS->VersionId = VER_NDX_GLOBAL;
     return;
@@ -2803,8 +2801,9 @@ template <class ELFT> void VersionNeedSe
   // for the soname.
   if (File.VerdefMap.empty())
     Needed.push_back({&File, In.DynStrTab->addString(File.SoName)});
-  const typename ELFT::Verdef *Ver = File.Verdefs[SS->VerdefIndex];
-  typename SharedFile<ELFT>::NeededVer &NV = File.VerdefMap[Ver];
+  auto *Ver = reinterpret_cast<const typename ELFT::Verdef *>(
+      File.Verdefs[SS->VerdefIndex]);
+  typename SharedFile::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
@@ -2822,7 +2821,7 @@ template <class ELFT> void VersionNeedSe
   auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
   auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Needed.size());
 
-  for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed) {
+  for (std::pair<SharedFile *, size_t> &P : Needed) {
     // Create an Elf_Verneed for this DSO.
     Verneed->vn_version = 1;
     Verneed->vn_cnt = P.first->VerdefMap.size();
@@ -2839,7 +2838,8 @@ template <class ELFT> void VersionNeedSe
     // pointers, but is deterministic because the pointers refer to Elf_Verdef
     // data structures within a single input file.
     for (auto &NV : P.first->VerdefMap) {
-      Vernaux->vna_hash = NV.first->vd_hash;
+      Vernaux->vna_hash =
+          reinterpret_cast<const typename ELFT::Verdef *>(NV.first)->vd_hash;
       Vernaux->vna_flags = 0;
       Vernaux->vna_other = NV.second.Index;
       Vernaux->vna_name = NV.second.StrTab;
@@ -2860,7 +2860,7 @@ template <class ELFT> void VersionNeedSe
 
 template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
   unsigned Size = Needed.size() * sizeof(Elf_Verneed);
-  for (const std::pair<SharedFile<ELFT> *, size_t> &P : Needed)
+  for (const std::pair<SharedFile *, size_t> &P : Needed)
     Size += P.first->VerdefMap.size() * sizeof(Elf_Vernaux);
   return Size;
 }

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Mon Apr  8 10:35:55 2019
@@ -809,7 +809,7 @@ class VersionNeedSection final : public
 
   // A vector of shared files that need Elf_Verneed data structures and the
   // string table offsets of their sonames.
-  std::vector<std::pair<SharedFile<ELFT> *, size_t>> Needed;
+  std::vector<std::pair<SharedFile *, size_t>> Needed;
 
 public:
   void addSymbol(Symbol *Sym) override;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=357925&r1=357924&r2=357925&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Apr  8 10:35:55 2019
@@ -1628,15 +1628,14 @@ template <class ELFT> void Writer<ELFT>:
     // ld.bfd traces all DT_NEEDED to emulate the logic of the dynamic linker to
     // catch more cases. That is too much for us. Our approach resembles the one
     // used in ld.gold, achieves a good balance to be useful but not too smart.
-    for (InputFile *File : SharedFiles) {
-      SharedFile<ELFT> *F = cast<SharedFile<ELFT>>(File);
-      F->AllNeededIsKnown = llvm::all_of(F->DtNeeded, [&](StringRef Needed) {
-        return Symtab->SoNames.count(Needed);
-      });
-    }
+    for (SharedFile *File : SharedFiles)
+      File->AllNeededIsKnown =
+          llvm::all_of(File->DtNeeded, [&](StringRef Needed) {
+            return Symtab->SoNames.count(Needed);
+          });
     for (Symbol *Sym : Symtab->getSymbols())
       if (Sym->isUndefined() && !Sym->isWeak())
-        if (auto *F = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+        if (auto *F = dyn_cast_or_null<SharedFile>(Sym->File))
           if (F->AllNeededIsKnown)
             error(toString(F) + ": undefined reference to " + toString(*Sym));
   }
@@ -1651,7 +1650,7 @@ template <class ELFT> void Writer<ELFT>:
 
     if (Sym->includeInDynsym()) {
       In.DynSymTab->addSymbol(Sym);
-      if (auto *File = dyn_cast_or_null<SharedFile<ELFT>>(Sym->File))
+      if (auto *File = dyn_cast_or_null<SharedFile>(Sym->File))
         if (File->IsNeeded && !Sym->isUndefined())
           In.VerNeed->addSymbol(Sym);
     }




More information about the llvm-commits mailing list