[lld] r309152 - Detemplate SymbolTable.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 26 11:42:48 PDT 2017


Author: rafael
Date: Wed Jul 26 11:42:48 2017
New Revision: 309152

URL: http://llvm.org/viewvc/llvm-project?rev=309152&view=rev
Log:
Detemplate SymbolTable.

NFC, just makes it easier to access from non templated code.

Modified:
    lld/trunk/ELF/Arch/MipsArchTree.cpp
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/LinkerScript.cpp
    lld/trunk/ELF/MapFile.cpp
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/ELF/Writer.h

Modified: lld/trunk/ELF/Arch/MipsArchTree.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Arch/MipsArchTree.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/Arch/MipsArchTree.cpp (original)
+++ lld/trunk/ELF/Arch/MipsArchTree.cpp Wed Jul 26 11:42:48 2017
@@ -283,7 +283,7 @@ static uint32_t getArchFlags(ArrayRef<Fi
 
 template <class ELFT> uint32_t elf::getMipsEFlags() {
   std::vector<FileFlags> V;
-  for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
+  for (elf::ObjectFile<ELFT> *F : ObjectFile<ELFT>::Instances)
     V.push_back({F->getName(), F->getObj().getHeader()->e_flags});
   if (V.empty())
     return 0;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Jul 26 11:42:48 2017
@@ -80,6 +80,7 @@ bool elf::link(ArrayRef<const char *> Ar
   Config = make<Configuration>();
   Driver = make<LinkerDriver>();
   Script = make<LinkerScript>();
+  Symtab = make<SymbolTable>();
   Config->Argv = {Args.begin(), Args.end()};
 
   Driver->main(Args, CanExitEarly);
@@ -948,8 +949,6 @@ static void excludeLibs(opt::InputArgLis
 // Do actual linking. Note that when this function is called,
 // all linker scripts have already been parsed.
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
-  SymbolTable<ELFT> Symtab;
-  elf::Symtab<ELFT>::X = &Symtab;
   Target = getTarget();
 
   Config->MaxPageSize = getMaxPageSize(Args);
@@ -979,64 +978,64 @@ template <class ELFT> void LinkerDriver:
 
   // Handle --trace-symbol.
   for (auto *Arg : Args.filtered(OPT_trace_symbol))
-    Symtab.trace(Arg->getValue());
+    Symtab->trace(Arg->getValue());
 
   // Add all files to the symbol table. This will add almost all
   // symbols that we need to the symbol table.
   for (InputFile *F : Files)
-    Symtab.addFile(F);
+    Symtab->addFile<ELFT>(F);
 
   // If an entry symbol is in a static archive, pull out that file now
   // to complete the symbol table. After this, no new names except a
   // few linker-synthesized ones will be added to the symbol table.
-  if (Symtab.find(Config->Entry))
-    Symtab.addUndefined(Config->Entry);
+  if (Symtab->find(Config->Entry))
+    Symtab->addUndefined<ELFT>(Config->Entry);
 
   // Return if there were name resolution errors.
   if (ErrorCount)
     return;
 
   // Handle the `--undefined <sym>` options.
-  Symtab.scanUndefinedFlags();
+  Symtab->scanUndefinedFlags<ELFT>();
 
   // Handle undefined symbols in DSOs.
-  Symtab.scanShlibUndefined();
+  Symtab->scanShlibUndefined<ELFT>();
 
   // Handle the -exclude-libs option.
   if (Args.hasArg(OPT_exclude_libs))
     excludeLibs(Args, Files);
 
   // Apply version scripts.
-  Symtab.scanVersionScript();
+  Symtab->scanVersionScript();
 
   // Create wrapped symbols for -wrap option.
   for (auto *Arg : Args.filtered(OPT_wrap))
-    Symtab.addSymbolWrap(Arg->getValue());
+    Symtab->addSymbolWrap<ELFT>(Arg->getValue());
 
   // Create alias symbols for -defsym option.
   for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
-    Symtab.addSymbolAlias(Def.first, Def.second);
+    Symtab->addSymbolAlias<ELFT>(Def.first, Def.second);
 
-  Symtab.addCombinedLTOObject();
+  Symtab->addCombinedLTOObject<ELFT>();
   if (ErrorCount)
     return;
 
   // Some symbols (such as __ehdr_start) are defined lazily only when there
   // are undefined symbols for them, so we add these to trigger that logic.
   for (StringRef Sym : Script->Opt.ReferencedSymbols)
-    Symtab.addUndefined(Sym);
+    Symtab->addUndefined<ELFT>(Sym);
 
   // Apply symbol renames for -wrap and -defsym
-  Symtab.applySymbolRenames();
+  Symtab->applySymbolRenames();
 
   // Now that we have a complete list of input files.
   // Beyond this point, no new files are added.
   // Aggregate all input sections into one place.
-  for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles())
+  for (elf::ObjectFile<ELFT> *F : ObjectFile<ELFT>::Instances)
     for (InputSectionBase *S : F->getSections())
       if (S && S != &InputSection::Discarded)
         InputSections.push_back(S);
-  for (BinaryFile *F : Symtab.getBinaryFiles())
+  for (BinaryFile *F : BinaryFile::Instances)
     for (InputSectionBase *S : F->getSections())
       InputSections.push_back(cast<InputSection>(S));
 

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed Jul 26 11:42:48 2017
@@ -587,15 +587,15 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
 
   switch (Sym->st_shndx) {
   case SHN_UNDEF:
-    return elf::Symtab<ELFT>::X
-        ->addUndefined(Name, /*IsLocal=*/false, Binding, StOther, Type,
-                       /*CanOmitFromDynSym=*/false, this)
+    return elf::Symtab
+        ->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, StOther, Type,
+                             /*CanOmitFromDynSym=*/false, this)
         ->body();
   case SHN_COMMON:
     if (Value == 0 || Value >= UINT32_MAX)
       fatal(toString(this) + ": common symbol '" + Name +
             "' has invalid alignment: " + Twine(Value));
-    return elf::Symtab<ELFT>::X
+    return elf::Symtab
         ->addCommon(Name, Size, Value, Binding, StOther, Type, this)
         ->body();
   }
@@ -607,12 +607,12 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
   case STB_WEAK:
   case STB_GNU_UNIQUE:
     if (Sec == &InputSection::Discarded)
-      return elf::Symtab<ELFT>::X
-          ->addUndefined(Name, /*IsLocal=*/false, Binding, StOther, Type,
-                         /*CanOmitFromDynSym=*/false, this)
+      return elf::Symtab
+          ->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, StOther, Type,
+                               /*CanOmitFromDynSym=*/false, this)
           ->body();
-    return elf::Symtab<ELFT>::X
-        ->addRegular(Name, StOther, Type, Value, Size, Binding, Sec, this)
+    return elf::Symtab
+        ->addRegular<ELFT>(Name, StOther, Type, Value, Size, Binding, Sec, this)
         ->body();
   }
 }
@@ -624,7 +624,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr
 template <class ELFT> void ArchiveFile::parse() {
   Symbols.reserve(File->getNumberOfSymbols());
   for (const Archive::Symbol &Sym : File->symbols())
-    Symbols.push_back(Symtab<ELFT>::X->addLazyArchive(this, Sym));
+    Symbols.push_back(Symtab->addLazyArchive<ELFT>(this, Sym));
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
@@ -787,14 +787,14 @@ template <class ELFT> void SharedFile<EL
         VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex];
 
     if (!Hidden)
-      elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+      elf::Symtab->addShared(this, Name, Sym, V);
 
     // Also add the symbol with the versioned name to handle undefined symbols
     // with explicit versions.
     if (V) {
       StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
       Name = Saver.save(Name + "@" + VerName);
-      elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
+      elf::Symtab->addShared(this, Name, Sym, V);
     }
   }
 }
@@ -833,6 +833,8 @@ static uint8_t getBitcodeMachineKind(Str
   }
 }
 
+std::vector<BitcodeFile *> BitcodeFile::Instances;
+
 BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
                          uint64_t OffsetInArchive)
     : InputFile(BitcodeKind, MB) {
@@ -881,22 +883,20 @@ static Symbol *createBitcodeSymbol(const
 
   int C = ObjSym.getComdatIndex();
   if (C != -1 && !KeptComdats[C])
-    return Symtab<ELFT>::X->addUndefined(NameRef, /*IsLocal=*/false, Binding,
-                                         Visibility, Type, CanOmitFromDynSym,
-                                         F);
+    return Symtab->addUndefined<ELFT>(NameRef, /*IsLocal=*/false, Binding,
+                                      Visibility, Type, CanOmitFromDynSym, F);
 
   if (ObjSym.isUndefined())
-    return Symtab<ELFT>::X->addUndefined(NameRef, /*IsLocal=*/false, Binding,
-                                         Visibility, Type, CanOmitFromDynSym,
-                                         F);
+    return Symtab->addUndefined<ELFT>(NameRef, /*IsLocal=*/false, Binding,
+                                      Visibility, Type, CanOmitFromDynSym, F);
 
   if (ObjSym.isCommon())
-    return Symtab<ELFT>::X->addCommon(NameRef, ObjSym.getCommonSize(),
-                                      ObjSym.getCommonAlignment(), Binding,
-                                      Visibility, STT_OBJECT, F);
+    return Symtab->addCommon(NameRef, ObjSym.getCommonSize(),
+                             ObjSym.getCommonAlignment(), Binding, Visibility,
+                             STT_OBJECT, F);
 
-  return Symtab<ELFT>::X->addBitcode(NameRef, Binding, Visibility, Type,
-                                     CanOmitFromDynSym, F);
+  return Symtab->addBitcode(NameRef, Binding, Visibility, Type,
+                            CanOmitFromDynSym, F);
 }
 
 template <class ELFT>
@@ -929,6 +929,8 @@ static ELFKind getELFKind(MemoryBufferRe
   return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
 }
 
+std::vector<BinaryFile *> BinaryFile::Instances;
+
 template <class ELFT> void BinaryFile::parse() {
   ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());
   auto *Section =
@@ -944,15 +946,13 @@ template <class ELFT> void BinaryFile::p
     if (!isalnum(S[I]))
       S[I] = '_';
 
-  elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_start"), STV_DEFAULT,
-                                   STT_OBJECT, 0, 0, STB_GLOBAL, Section,
-                                   nullptr);
-  elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_end"), STV_DEFAULT,
-                                   STT_OBJECT, Data.size(), 0, STB_GLOBAL,
-                                   Section, nullptr);
-  elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_size"), STV_DEFAULT,
-                                   STT_OBJECT, Data.size(), 0, STB_GLOBAL,
-                                   nullptr, nullptr);
+  elf::Symtab->addRegular<ELFT>(Saver.save(S + "_start"), STV_DEFAULT,
+                                STT_OBJECT, 0, 0, STB_GLOBAL, Section, nullptr);
+  elf::Symtab->addRegular<ELFT>(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
+                                Data.size(), 0, STB_GLOBAL, Section, nullptr);
+  elf::Symtab->addRegular<ELFT>(Saver.save(S + "_size"), STV_DEFAULT,
+                                STT_OBJECT, Data.size(), 0, STB_GLOBAL, nullptr,
+                                nullptr);
 }
 
 static bool isBitcode(MemoryBufferRef MB) {
@@ -1010,7 +1010,7 @@ InputFile *LazyObjectFile::fetch() {
 
 template <class ELFT> void LazyObjectFile::parse() {
   for (StringRef Sym : getSymbols())
-    Symtab<ELFT>::X->addLazyObject(Sym, *this);
+    Symtab->addLazyObject<ELFT>(Sym, *this);
 }
 
 template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() {

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Wed Jul 26 11:42:48 2017
@@ -155,6 +155,8 @@ public:
     return F->kind() == Base::ObjectKind;
   }
 
+  static std::vector<ObjectFile<ELFT> *> Instances;
+
   ArrayRef<SymbolBody *> getSymbols();
   ArrayRef<SymbolBody *> getLocalSymbols();
 
@@ -216,6 +218,9 @@ private:
   llvm::once_flag InitDwarfLine;
 };
 
+template <class ELFT>
+std::vector<ObjectFile<ELFT> *> ObjectFile<ELFT>::Instances;
+
 // LazyObjectFile is analogous to ArchiveFile in the sense that
 // the file contains lazy symbols. The difference is that
 // LazyObjectFile wraps a single file instead of multiple files.
@@ -277,6 +282,7 @@ public:
   void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
   ArrayRef<Symbol *> getSymbols() { return Symbols; }
   std::unique_ptr<llvm::lto::InputFile> Obj;
+  static std::vector<BitcodeFile *> Instances;
 
 private:
   std::vector<Symbol *> Symbols;
@@ -299,6 +305,8 @@ template <class ELFT> class SharedFile :
 public:
   std::string SoName;
 
+  static std::vector<SharedFile<ELFT> *> Instances;
+
   const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
   llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
 
@@ -330,11 +338,15 @@ public:
   bool isNeeded() const { return !AsNeeded || IsUsed; }
 };
 
+template <class ELFT>
+std::vector<SharedFile<ELFT> *> SharedFile<ELFT>::Instances;
+
 class BinaryFile : public InputFile {
 public:
   explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
   static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
   template <class ELFT> void parse();
+  static std::vector<BinaryFile *> Instances;
 };
 
 InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",

Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Jul 26 11:42:48 2017
@@ -69,9 +69,9 @@ uint64_t ExprValue::getSecAddr() const {
 template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
   Symbol *Sym;
   uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
-  std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
-      Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
-      /*File*/ nullptr);
+  std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility,
+                                              /*CanOmitFromDynSym*/ false,
+                                              /*File*/ nullptr);
   Sym->Binding = STB_GLOBAL;
   ExprValue Value = Cmd->Expression();
   SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
@@ -142,21 +142,6 @@ void LinkerScript::assignSymbol(SymbolAs
   }
 }
 
-static SymbolBody *findSymbol(StringRef S) {
-  switch (Config->EKind) {
-  case ELF32LEKind:
-    return Symtab<ELF32LE>::X->find(S);
-  case ELF32BEKind:
-    return Symtab<ELF32BE>::X->find(S);
-  case ELF64LEKind:
-    return Symtab<ELF64LE>::X->find(S);
-  case ELF64BEKind:
-    return Symtab<ELF64BE>::X->find(S);
-  default:
-    llvm_unreachable("unknown Config->EKind");
-  }
-}
-
 static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
   switch (Config->EKind) {
   case ELF32LEKind:
@@ -178,7 +163,7 @@ void LinkerScript::addSymbol(SymbolAssig
 
   // If a symbol was in PROVIDE(), we need to define it only when
   // it is a referenced undefined symbol.
-  SymbolBody *B = findSymbol(Cmd->Name);
+  SymbolBody *B = Symtab->find(Cmd->Name);
   if (Cmd->Provide && (!B || B->isDefined()))
     return;
 
@@ -1189,7 +1174,7 @@ template <class ELFT> void OutputSection
 ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
   if (S == ".")
     return {CurAddressState->OutSec, Dot - CurAddressState->OutSec->Addr, Loc};
-  if (SymbolBody *B = findSymbol(S)) {
+  if (SymbolBody *B = Symtab->find(S)) {
     if (auto *D = dyn_cast<DefinedRegular>(B))
       return {D->Section, D->Value, Loc};
     if (auto *C = dyn_cast<DefinedCommon>(B))
@@ -1199,7 +1184,7 @@ ExprValue LinkerScript::getSymbolValue(c
   return 0;
 }
 
-bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
+bool LinkerScript::isDefined(StringRef S) { return Symtab->find(S) != nullptr; }
 
 static const size_t NoPhdr = -1;
 

Modified: lld/trunk/ELF/MapFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MapFile.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/MapFile.cpp (original)
+++ lld/trunk/ELF/MapFile.cpp Wed Jul 26 11:42:48 2017
@@ -51,7 +51,7 @@ static std::string indent(int Depth) { r
 // Returns a list of all symbols that we want to print out.
 template <class ELFT> std::vector<DefinedRegular *> getSymbols() {
   std::vector<DefinedRegular *> V;
-  for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles())
+  for (elf::ObjectFile<ELFT> *File : ObjectFile<ELFT>::Instances)
     for (SymbolBody *B : File->getSymbols())
       if (B->File == File && !B->isSection())
         if (auto *Sym = dyn_cast<DefinedRegular>(B))

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Wed Jul 26 11:42:48 2017
@@ -225,17 +225,17 @@ template <class ELFT> void elf::markLive
   };
 
   // Add GC root symbols.
-  MarkSymbol(Symtab<ELFT>::X->find(Config->Entry));
-  MarkSymbol(Symtab<ELFT>::X->find(Config->Init));
-  MarkSymbol(Symtab<ELFT>::X->find(Config->Fini));
+  MarkSymbol(Symtab->find(Config->Entry));
+  MarkSymbol(Symtab->find(Config->Init));
+  MarkSymbol(Symtab->find(Config->Fini));
   for (StringRef S : Config->Undefined)
-    MarkSymbol(Symtab<ELFT>::X->find(S));
+    MarkSymbol(Symtab->find(S));
   for (StringRef S : Script->Opt.ReferencedSymbols)
-    MarkSymbol(Symtab<ELFT>::X->find(S));
+    MarkSymbol(Symtab->find(S));
 
   // Preserve externally-visible symbols if the symbols defined by this
   // file can interrupt other ELF file's symbols at runtime.
-  for (const Symbol *S : Symtab<ELFT>::X->getSymbols())
+  for (const Symbol *S : Symtab->getSymbols())
     if (S->includeInDynsym())
       MarkSymbol(S->body());
 

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Wed Jul 26 11:42:48 2017
@@ -461,7 +461,7 @@ static std::vector<SharedSymbol *> getSy
     if (S.st_shndx != Shndx || S.st_value != Value)
       continue;
     StringRef Name = check(S.getName(File->getStringTable()));
-    SymbolBody *Sym = Symtab<ELFT>::X->find(Name);
+    SymbolBody *Sym = Symtab->find(Name);
     if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym))
       Ret.push_back(Alias);
   }

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed Jul 26 11:42:48 2017
@@ -29,6 +29,8 @@ using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf;
 
+SymbolTable *elf::Symtab;
+
 // All input object files must be for the same architecture
 // (e.g. it does not make sense to link x86 object files with
 // MIPS object files.) This function checks for that error.
@@ -51,7 +53,7 @@ template <class ELFT> static bool isComp
 }
 
 // Add symbols in File to the symbol table.
-template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
+template <class ELFT> void SymbolTable::addFile(InputFile *File) {
   if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File))
     Config->FirstElf = File;
 
@@ -60,7 +62,7 @@ template <class ELFT> void SymbolTable<E
 
   // Binary file
   if (auto *F = dyn_cast<BinaryFile>(File)) {
-    BinaryFiles.push_back(F);
+    BinaryFile::Instances.push_back(F);
     F->parse<ELFT>();
     return;
   }
@@ -86,21 +88,21 @@ template <class ELFT> void SymbolTable<E
     F->parseSoName();
     if (ErrorCount || !SoNames.insert(F->SoName).second)
       return;
-    SharedFiles.push_back(F);
+    SharedFile<ELFT>::Instances.push_back(F);
     F->parseRest();
     return;
   }
 
   // LLVM bitcode file
   if (auto *F = dyn_cast<BitcodeFile>(File)) {
-    BitcodeFiles.push_back(F);
+    BitcodeFile::Instances.push_back(F);
     F->parse<ELFT>(ComdatGroups);
     return;
   }
 
   // Regular object file
   auto *F = cast<ObjectFile<ELFT>>(File);
-  ObjectFiles.push_back(F);
+  ObjectFile<ELFT>::Instances.push_back(F);
   F->parse(ComdatGroups);
 }
 
@@ -111,58 +113,56 @@ template <class ELFT> void SymbolTable<E
 // using LLVM functions and replaces bitcode symbols with the results.
 // Because all bitcode files that consist of a program are passed
 // to the compiler at once, it can do whole-program optimization.
-template <class ELFT> void SymbolTable<ELFT>::addCombinedLTOObject() {
-  if (BitcodeFiles.empty())
+template <class ELFT> void SymbolTable::addCombinedLTOObject() {
+  if (BitcodeFile::Instances.empty())
     return;
 
   // Compile bitcode files and replace bitcode symbols.
   LTO.reset(new BitcodeCompiler);
-  for (BitcodeFile *F : BitcodeFiles)
+  for (BitcodeFile *F : BitcodeFile::Instances)
     LTO->add(*F);
 
   for (InputFile *File : LTO->compile()) {
     ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File);
     DenseSet<CachedHashStringRef> DummyGroups;
     Obj->parse(DummyGroups);
-    ObjectFiles.push_back(Obj);
+    ObjectFile<ELFT>::Instances.push_back(Obj);
   }
 }
 
 template <class ELFT>
-DefinedRegular *SymbolTable<ELFT>::addAbsolute(StringRef Name,
-                                               uint8_t Visibility,
-                                               uint8_t Binding) {
-  Symbol *Sym =
-      addRegular(Name, Visibility, STT_NOTYPE, 0, 0, Binding, nullptr, nullptr);
+DefinedRegular *SymbolTable::addAbsolute(StringRef Name, uint8_t Visibility,
+                                         uint8_t Binding) {
+  Symbol *Sym = addRegular<ELFT>(Name, Visibility, STT_NOTYPE, 0, 0, Binding,
+                                 nullptr, nullptr);
   return cast<DefinedRegular>(Sym->body());
 }
 
 // Add Name as an "ignored" symbol. An ignored symbol is a regular
 // linker-synthesized defined symbol, but is only defined if needed.
 template <class ELFT>
-DefinedRegular *SymbolTable<ELFT>::addIgnored(StringRef Name,
-                                              uint8_t Visibility) {
+DefinedRegular *SymbolTable::addIgnored(StringRef Name, uint8_t Visibility) {
   SymbolBody *S = find(Name);
   if (!S || S->isInCurrentDSO())
     return nullptr;
-  return addAbsolute(Name, Visibility);
+  return addAbsolute<ELFT>(Name, Visibility);
 }
 
 // Set a flag for --trace-symbol so that we can print out a log message
 // if a new symbol with the same name is inserted into the symbol table.
-template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) {
+void SymbolTable::trace(StringRef Name) {
   Symtab.insert({CachedHashStringRef(Name), {-1, true}});
 }
 
 // Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
 // Used to implement --wrap.
-template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) {
+template <class ELFT> void SymbolTable::addSymbolWrap(StringRef Name) {
   SymbolBody *B = find(Name);
   if (!B)
     return;
   Symbol *Sym = B->symbol();
-  Symbol *Real = addUndefined(Saver.save("__real_" + Name));
-  Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name));
+  Symbol *Real = addUndefined<ELFT>(Saver.save("__real_" + Name));
+  Symbol *Wrap = addUndefined<ELFT>(Saver.save("__wrap_" + Name));
 
   // Tell LTO not to eliminate this symbol
   Wrap->IsUsedInRegularObj = true;
@@ -173,14 +173,14 @@ template <class ELFT> void SymbolTable<E
 
 // Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
 template <class ELFT>
-void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias, StringRef Name) {
+void SymbolTable::addSymbolAlias(StringRef Alias, StringRef Name) {
   SymbolBody *B = find(Name);
   if (!B) {
     error("-defsym: undefined symbol: " + Name);
     return;
   }
   Symbol *Sym = B->symbol();
-  Symbol *AliasSym = addUndefined(Alias);
+  Symbol *AliasSym = addUndefined<ELFT>(Alias);
 
   // Tell LTO not to eliminate this symbol
   Sym->IsUsedInRegularObj = true;
@@ -191,7 +191,7 @@ void SymbolTable<ELFT>::addSymbolAlias(S
 // before LTO in addSymbolWrap() and addSymbolAlias() to have a chance to inform
 // LTO (if LTO is running) not to include these symbols in IPO. Now that the
 // symbols are finalized, we can perform the replacement.
-template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() {
+void SymbolTable::applySymbolRenames() {
   for (auto &KV : Config->RenamedSymbols) {
     Symbol *Dst = KV.first;
     Symbol *Src = KV.second.Target;
@@ -209,8 +209,7 @@ static uint8_t getMinVisibility(uint8_t
 }
 
 // Find an existing symbol or create and insert a new one.
-template <class ELFT>
-std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
   // <name>@@<version> means the symbol is the default version. In that
   // case <name>@@<version> will be used to resolve references to <name>.
   size_t Pos = Name.find("@@");
@@ -246,10 +245,10 @@ std::pair<Symbol *, bool> SymbolTable<EL
 
 // Find an existing symbol or create and insert a new one, then apply the given
 // attributes.
-template <class ELFT>
-std::pair<Symbol *, bool>
-SymbolTable<ELFT>::insert(StringRef Name, uint8_t Type, uint8_t Visibility,
-                          bool CanOmitFromDynSym, InputFile *File) {
+std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type,
+                                              uint8_t Visibility,
+                                              bool CanOmitFromDynSym,
+                                              InputFile *File) {
   bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind;
   Symbol *S;
   bool WasInserted;
@@ -274,19 +273,18 @@ SymbolTable<ELFT>::insert(StringRef Name
   return {S, WasInserted};
 }
 
-template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) {
-  return addUndefined(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT,
-                      /*Type*/ 0,
-                      /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
+template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) {
+  return addUndefined<ELFT>(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT,
+                            /*Type*/ 0,
+                            /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
 }
 
 static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
 
 template <class ELFT>
-Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, bool IsLocal,
-                                        uint8_t Binding, uint8_t StOther,
-                                        uint8_t Type, bool CanOmitFromDynSym,
-                                        InputFile *File) {
+Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
+                                  uint8_t StOther, uint8_t Type,
+                                  bool CanOmitFromDynSym, InputFile *File) {
   Symbol *S;
   bool WasInserted;
   uint8_t Visibility = getVisibility(StOther);
@@ -313,7 +311,7 @@ Symbol *SymbolTable<ELFT>::addUndefined(
     if (S->isWeak())
       L->Type = Type;
     else if (InputFile *F = L->fetch())
-      addFile(F);
+      addFile<ELFT>(F);
   }
   return S;
 }
@@ -380,11 +378,9 @@ static int compareDefinedNonCommon(Symbo
   return 0;
 }
 
-template <class ELFT>
-Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size,
-                                     uint32_t Alignment, uint8_t Binding,
-                                     uint8_t StOther, uint8_t Type,
-                                     InputFile *File) {
+Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
+                               uint8_t Binding, uint8_t StOther, uint8_t Type,
+                               InputFile *File) {
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
@@ -457,10 +453,9 @@ static void reportDuplicate(SymbolBody *
 }
 
 template <typename ELFT>
-Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther,
-                                      uint8_t Type, uint64_t Value,
-                                      uint64_t Size, uint8_t Binding,
-                                      SectionBase *Section, InputFile *File) {
+Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
+                                uint64_t Value, uint64_t Size, uint8_t Binding,
+                                SectionBase *Section, InputFile *File) {
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
@@ -477,9 +472,9 @@ Symbol *SymbolTable<ELFT>::addRegular(St
 }
 
 template <typename ELFT>
-void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *File, StringRef Name,
-                                  const Elf_Sym &Sym,
-                                  const typename ELFT::Verdef *Verdef) {
+void SymbolTable::addShared(SharedFile<ELFT> *File, StringRef Name,
+                            const typename ELFT::Sym &Sym,
+                            const typename ELFT::Verdef *Verdef) {
   // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
   // as the visibility, which will leave the visibility in the symbol table
   // unchanged.
@@ -503,10 +498,9 @@ void SymbolTable<ELFT>::addShared(Shared
   }
 }
 
-template <class ELFT>
-Symbol *SymbolTable<ELFT>::addBitcode(StringRef Name, uint8_t Binding,
-                                      uint8_t StOther, uint8_t Type,
-                                      bool CanOmitFromDynSym, BitcodeFile *F) {
+Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding,
+                                uint8_t StOther, uint8_t Type,
+                                bool CanOmitFromDynSym, BitcodeFile *F) {
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) =
@@ -521,7 +515,7 @@ Symbol *SymbolTable<ELFT>::addBitcode(St
   return S;
 }
 
-template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
+SymbolBody *SymbolTable::find(StringRef Name) {
   auto It = Symtab.find(CachedHashStringRef(Name));
   if (It == Symtab.end())
     return nullptr;
@@ -531,8 +525,7 @@ template <class ELFT> SymbolBody *Symbol
   return SymVector[V.Idx]->body();
 }
 
-template <class ELFT>
-SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) {
+SymbolBody *SymbolTable::findInCurrentDSO(StringRef Name) {
   if (SymbolBody *S = find(Name))
     if (S->isInCurrentDSO())
       return S;
@@ -540,8 +533,8 @@ SymbolBody *SymbolTable<ELFT>::findInCur
 }
 
 template <class ELFT>
-Symbol *SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
-                                          const object::Archive::Symbol Sym) {
+Symbol *SymbolTable::addLazyArchive(ArchiveFile *F,
+                                    const object::Archive::Symbol Sym) {
   Symbol *S;
   bool WasInserted;
   StringRef Name = Sym.getName();
@@ -566,12 +559,12 @@ Symbol *SymbolTable<ELFT>::addLazyArchiv
   }
   std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym);
   if (!MBInfo.first.getBuffer().empty())
-    addFile(createObjectFile(MBInfo.first, F->getName(), MBInfo.second));
+    addFile<ELFT>(createObjectFile(MBInfo.first, F->getName(), MBInfo.second));
   return S;
 }
 
 template <class ELFT>
-void SymbolTable<ELFT>::addLazyObject(StringRef Name, LazyObjectFile &Obj) {
+void SymbolTable::addLazyObject(StringRef Name, LazyObjectFile &Obj) {
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name);
@@ -586,15 +579,15 @@ void SymbolTable<ELFT>::addLazyObject(St
   if (S->isWeak())
     replaceBody<LazyObject>(S, Name, Obj, S->body()->Type);
   else if (InputFile *F = Obj.fetch())
-    addFile(F);
+    addFile<ELFT>(F);
 }
 
 // Process undefined (-u) flags by loading lazy symbols named by those flags.
-template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() {
+template <class ELFT> void SymbolTable::scanUndefinedFlags() {
   for (StringRef S : Config->Undefined)
     if (auto *L = dyn_cast_or_null<Lazy>(find(S)))
       if (InputFile *File = L->fetch())
-        addFile(File);
+        addFile<ELFT>(File);
 }
 
 // This function takes care of the case in which shared libraries depend on
@@ -604,8 +597,8 @@ template <class ELFT> void SymbolTable<E
 // We need to put such symbols to the main program's .dynsym so that
 // shared libraries can find them.
 // Except this, we ignore undefined symbols in DSOs.
-template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() {
-  for (SharedFile<ELFT> *File : SharedFiles) {
+template <class ELFT> void SymbolTable::scanShlibUndefined() {
+  for (SharedFile<ELFT> *File : SharedFile<ELFT>::Instances) {
     for (StringRef U : File->getUndefinedSymbols()) {
       SymbolBody *Sym = find(U);
       if (!Sym || !Sym->isDefined())
@@ -634,8 +627,7 @@ template <class ELFT> void SymbolTable<E
 // other than trying to match a pattern against all demangled symbols.
 // So, if "extern C++" feature is used, we need to demangle all known
 // symbols.
-template <class ELFT>
-StringMap<std::vector<SymbolBody *>> &SymbolTable<ELFT>::getDemangledSyms() {
+StringMap<std::vector<SymbolBody *>> &SymbolTable::getDemangledSyms() {
   if (!DemangledSyms) {
     DemangledSyms.emplace();
     for (Symbol *Sym : SymVector) {
@@ -651,8 +643,7 @@ StringMap<std::vector<SymbolBody *>> &Sy
   return *DemangledSyms;
 }
 
-template <class ELFT>
-std::vector<SymbolBody *> SymbolTable<ELFT>::findByVersion(SymbolVersion Ver) {
+std::vector<SymbolBody *> SymbolTable::findByVersion(SymbolVersion Ver) {
   if (Ver.IsExternCpp)
     return getDemangledSyms().lookup(Ver.Name);
   if (SymbolBody *B = find(Ver.Name))
@@ -661,9 +652,7 @@ std::vector<SymbolBody *> SymbolTable<EL
   return {};
 }
 
-template <class ELFT>
-std::vector<SymbolBody *>
-SymbolTable<ELFT>::findAllByVersion(SymbolVersion Ver) {
+std::vector<SymbolBody *> SymbolTable::findAllByVersion(SymbolVersion Ver) {
   std::vector<SymbolBody *> Res;
   StringMatcher M(Ver.Name);
 
@@ -685,7 +674,7 @@ SymbolTable<ELFT>::findAllByVersion(Symb
 // If there's only one anonymous version definition in a version
 // script file, the script does not actually define any symbol version,
 // but just specifies symbols visibilities.
-template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() {
+void SymbolTable::handleAnonymousVersion() {
   for (SymbolVersion &Ver : Config->VersionScriptGlobals)
     assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
   for (SymbolVersion &Ver : Config->VersionScriptGlobals)
@@ -698,10 +687,8 @@ template <class ELFT> void SymbolTable<E
 
 // Set symbol versions to symbols. This function handles patterns
 // containing no wildcard characters.
-template <class ELFT>
-void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver,
-                                           uint16_t VersionId,
-                                           StringRef VersionName) {
+void SymbolTable::assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
+                                     StringRef VersionName) {
   if (Ver.HasWildcard)
     return;
 
@@ -730,9 +717,7 @@ void SymbolTable<ELFT>::assignExactVersi
   }
 }
 
-template <class ELFT>
-void SymbolTable<ELFT>::assignWildcardVersion(SymbolVersion Ver,
-                                              uint16_t VersionId) {
+void SymbolTable::assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId) {
   if (!Ver.HasWildcard)
     return;
 
@@ -746,7 +731,7 @@ void SymbolTable<ELFT>::assignWildcardVe
 
 // This function processes version scripts by updating VersionId
 // member of symbols.
-template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
+void SymbolTable::scanVersionScript() {
   // Handle edge cases first.
   handleAnonymousVersion();
 
@@ -775,7 +760,90 @@ template <class ELFT> void SymbolTable<E
     Sym->body()->parseSymbolVersion();
 }
 
-template class elf::SymbolTable<ELF32LE>;
-template class elf::SymbolTable<ELF32BE>;
-template class elf::SymbolTable<ELF64LE>;
-template class elf::SymbolTable<ELF64BE>;
+template void SymbolTable::addSymbolWrap<ELF32LE>(StringRef);
+template void SymbolTable::addSymbolWrap<ELF32BE>(StringRef);
+template void SymbolTable::addSymbolWrap<ELF64LE>(StringRef);
+template void SymbolTable::addSymbolWrap<ELF64BE>(StringRef);
+
+template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef);
+template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef);
+template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef);
+template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef);
+
+template void SymbolTable::addSymbolAlias<ELF32LE>(StringRef, StringRef);
+template void SymbolTable::addSymbolAlias<ELF32BE>(StringRef, StringRef);
+template void SymbolTable::addSymbolAlias<ELF64LE>(StringRef, StringRef);
+template void SymbolTable::addSymbolAlias<ELF64BE>(StringRef, StringRef);
+
+template void SymbolTable::addCombinedLTOObject<ELF32LE>();
+template void SymbolTable::addCombinedLTOObject<ELF32BE>();
+template void SymbolTable::addCombinedLTOObject<ELF64LE>();
+template void SymbolTable::addCombinedLTOObject<ELF64BE>();
+
+template Symbol *SymbolTable::addRegular<ELF32LE>(StringRef, uint8_t, uint8_t,
+                                                  uint64_t, uint64_t, uint8_t,
+                                                  SectionBase *, InputFile *);
+template Symbol *SymbolTable::addRegular<ELF32BE>(StringRef, uint8_t, uint8_t,
+                                                  uint64_t, uint64_t, uint8_t,
+                                                  SectionBase *, InputFile *);
+template Symbol *SymbolTable::addRegular<ELF64LE>(StringRef, uint8_t, uint8_t,
+                                                  uint64_t, uint64_t, uint8_t,
+                                                  SectionBase *, InputFile *);
+template Symbol *SymbolTable::addRegular<ELF64BE>(StringRef, uint8_t, uint8_t,
+                                                  uint64_t, uint64_t, uint8_t,
+                                                  SectionBase *, InputFile *);
+
+template DefinedRegular *SymbolTable::addAbsolute<ELF32LE>(StringRef, uint8_t,
+                                                           uint8_t);
+template DefinedRegular *SymbolTable::addAbsolute<ELF32BE>(StringRef, uint8_t,
+                                                           uint8_t);
+template DefinedRegular *SymbolTable::addAbsolute<ELF64LE>(StringRef, uint8_t,
+                                                           uint8_t);
+template DefinedRegular *SymbolTable::addAbsolute<ELF64BE>(StringRef, uint8_t,
+                                                           uint8_t);
+
+template DefinedRegular *SymbolTable::addIgnored<ELF32LE>(StringRef, uint8_t);
+template DefinedRegular *SymbolTable::addIgnored<ELF32BE>(StringRef, uint8_t);
+template DefinedRegular *SymbolTable::addIgnored<ELF64LE>(StringRef, uint8_t);
+template DefinedRegular *SymbolTable::addIgnored<ELF64BE>(StringRef, uint8_t);
+
+template Symbol *
+SymbolTable::addLazyArchive<ELF32LE>(ArchiveFile *,
+                                     const object::Archive::Symbol);
+template Symbol *
+SymbolTable::addLazyArchive<ELF32BE>(ArchiveFile *,
+                                     const object::Archive::Symbol);
+template Symbol *
+SymbolTable::addLazyArchive<ELF64LE>(ArchiveFile *,
+                                     const object::Archive::Symbol);
+template Symbol *
+SymbolTable::addLazyArchive<ELF64BE>(ArchiveFile *,
+                                     const object::Archive::Symbol);
+
+template void SymbolTable::addLazyObject<ELF32LE>(StringRef, LazyObjectFile &);
+template void SymbolTable::addLazyObject<ELF32BE>(StringRef, LazyObjectFile &);
+template void SymbolTable::addLazyObject<ELF64LE>(StringRef, LazyObjectFile &);
+template void SymbolTable::addLazyObject<ELF64BE>(StringRef, LazyObjectFile &);
+
+template void SymbolTable::addShared<ELF32LE>(SharedFile<ELF32LE> *, StringRef,
+                                              const typename ELF32LE::Sym &,
+                                              const typename ELF32LE::Verdef *);
+template void SymbolTable::addShared<ELF32BE>(SharedFile<ELF32BE> *, StringRef,
+                                              const typename ELF32BE::Sym &,
+                                              const typename ELF32BE::Verdef *);
+template void SymbolTable::addShared<ELF64LE>(SharedFile<ELF64LE> *, StringRef,
+                                              const typename ELF64LE::Sym &,
+                                              const typename ELF64LE::Verdef *);
+template void SymbolTable::addShared<ELF64BE>(SharedFile<ELF64BE> *, StringRef,
+                                              const typename ELF64BE::Sym &,
+                                              const typename ELF64BE::Verdef *);
+
+template void SymbolTable::scanUndefinedFlags<ELF32LE>();
+template void SymbolTable::scanUndefinedFlags<ELF32BE>();
+template void SymbolTable::scanUndefinedFlags<ELF64LE>();
+template void SymbolTable::scanUndefinedFlags<ELF64BE>();
+
+template void SymbolTable::scanShlibUndefined<ELF32LE>();
+template void SymbolTable::scanShlibUndefined<ELF32BE>();
+template void SymbolTable::scanShlibUndefined<ELF64LE>();
+template void SymbolTable::scanShlibUndefined<ELF64BE>();

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Wed Jul 26 11:42:48 2017
@@ -33,41 +33,43 @@ struct Symbol;
 // to replace the lazy symbol. The logic is implemented in the
 // add*() functions, which are called by input files as they are parsed. There
 // is one add* function per symbol type.
-template <class ELFT> class SymbolTable {
-  typedef typename ELFT::Sym Elf_Sym;
-
+class SymbolTable {
 public:
-  void addFile(InputFile *File);
-  void addCombinedLTOObject();
-  void addSymbolAlias(StringRef Alias, StringRef Name);
-  void addSymbolWrap(StringRef Name);
+  template <class ELFT> void addFile(InputFile *File);
+  template <class ELFT> void addCombinedLTOObject();
+  template <class ELFT> void addSymbolAlias(StringRef Alias, StringRef Name);
+  template <class ELFT> void addSymbolWrap(StringRef Name);
   void applySymbolRenames();
 
   ArrayRef<Symbol *> getSymbols() const { return SymVector; }
-  ArrayRef<ObjectFile<ELFT> *> getObjectFiles() const { return ObjectFiles; }
-  ArrayRef<BinaryFile *> getBinaryFiles() const { return BinaryFiles; }
-  ArrayRef<SharedFile<ELFT> *> getSharedFiles() const { return SharedFiles; }
 
+  template <class ELFT>
   DefinedRegular *addAbsolute(StringRef Name,
                               uint8_t Visibility = llvm::ELF::STV_HIDDEN,
                               uint8_t Binding = llvm::ELF::STB_GLOBAL);
+  template <class ELFT>
   DefinedRegular *addIgnored(StringRef Name,
                              uint8_t Visibility = llvm::ELF::STV_HIDDEN);
 
-  Symbol *addUndefined(StringRef Name);
+  template <class ELFT> Symbol *addUndefined(StringRef Name);
+  template <class ELFT>
   Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
                        uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym,
                        InputFile *File);
-
+  template <class ELFT>
   Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
                      uint64_t Value, uint64_t Size, uint8_t Binding,
                      SectionBase *Section, InputFile *File);
 
-  void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
+  template <class ELFT>
+  void addShared(SharedFile<ELFT> *F, StringRef Name,
+                 const typename ELFT::Sym &Sym,
                  const typename ELFT::Verdef *Verdef);
 
+  template <class ELFT>
   Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
-  void addLazyObject(StringRef Name, LazyObjectFile &Obj);
+  template <class ELFT> void addLazyObject(StringRef Name, LazyObjectFile &Obj);
+
   Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
                      uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File);
 
@@ -80,8 +82,8 @@ public:
                                    uint8_t Visibility, bool CanOmitFromDynSym,
                                    InputFile *File);
 
-  void scanUndefinedFlags();
-  void scanShlibUndefined();
+  template <class ELFT> void scanUndefinedFlags();
+  template <class ELFT> void scanShlibUndefined();
   void scanVersionScript();
 
   SymbolBody *find(StringRef Name);
@@ -120,11 +122,6 @@ private:
   // is used to uniquify them.
   llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
 
-  std::vector<ObjectFile<ELFT> *> ObjectFiles;
-  std::vector<SharedFile<ELFT> *> SharedFiles;
-  std::vector<BitcodeFile *> BitcodeFiles;
-  std::vector<BinaryFile *> BinaryFiles;
-
   // Set of .so files to not link the same shared object file more than once.
   llvm::DenseSet<StringRef> SoNames;
 
@@ -138,9 +135,7 @@ private:
   std::unique_ptr<BitcodeCompiler> LTO;
 };
 
-template <class ELFT> struct Symtab { static SymbolTable<ELFT> *X; };
-template <class ELFT> SymbolTable<ELFT> *Symtab<ELFT>::X;
-
+extern SymbolTable *Symtab;
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Jul 26 11:42:48 2017
@@ -56,7 +56,7 @@ uint64_t SyntheticSection::getVA() const
 
 template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
   std::vector<DefinedCommon *> V;
-  for (Symbol *S : Symtab<ELFT>::X->getSymbols())
+  for (Symbol *S : Symtab->getSymbols())
     if (auto *B = dyn_cast<DefinedCommon>(S->body()))
       V.push_back(B);
   return V;
@@ -1027,7 +1027,7 @@ template <class ELFT> void DynamicSectio
   if (!Config->Rpath.empty())
     add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
          InX::DynStrTab->addString(Config->Rpath)});
-  for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
+  for (SharedFile<ELFT> *F : SharedFile<ELFT>::Instances)
     if (F->isNeeded())
       add({DT_NEEDED, InX::DynStrTab->addString(F->SoName)});
   if (!Config->SoName.empty())
@@ -1132,9 +1132,9 @@ template <class ELFT> void DynamicSectio
     add({DT_FINI_ARRAYSZ, Out::FiniArray, Entry::SecSize});
   }
 
-  if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Init))
+  if (SymbolBody *B = Symtab->findInCurrentDSO(Config->Init))
     add({DT_INIT, B});
-  if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Fini))
+  if (SymbolBody *B = Symtab->findInCurrentDSO(Config->Fini))
     add({DT_FINI, B});
 
   bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jul 26 11:42:48 2017
@@ -118,7 +118,7 @@ StringRef elf::getOutputSectionName(Stri
 }
 
 template <class ELFT> static bool needsInterpSection() {
-  return !Symtab<ELFT>::X->getSharedFiles().empty() &&
+  return !SharedFile<ELFT>::Instances.empty() &&
          !Config->DynamicLinker.empty() && !Script->ignoreInterpSection();
 }
 
@@ -318,8 +318,8 @@ template <class ELFT> void Writer<ELFT>:
   Add(InX::BssRelRo);
 
   // Add MIPS-specific sections.
-  bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() ||
-                      Config->Pic || Config->ExportDynamic;
+  bool HasDynSymTab = !SharedFile<ELFT>::Instances.empty() || Config->Pic ||
+                      Config->ExportDynamic;
   if (Config->EMachine == EM_MIPS) {
     if (!Config->Shared && HasDynSymTab) {
       InX::MipsRldMap = make<MipsRldMapSection>();
@@ -471,7 +471,7 @@ static bool includeInSymtab(const Symbol
 template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
   if (!InX::SymTab)
     return;
-  for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
+  for (elf::ObjectFile<ELFT> *F : ObjectFile<ELFT>::Instances) {
     for (SymbolBody *B : F->getLocalSymbols()) {
       if (!B->IsLocal)
         fatal(toString(F) +
@@ -760,16 +760,16 @@ static Symbol *addRegular(StringRef Name
                           uint8_t Binding = STB_WEAK) {
   // The linker generated symbols are added as STB_WEAK to allow user defined
   // ones to override them.
-  return Symtab<ELFT>::X->addRegular(Name, StOther, STT_NOTYPE, Value,
-                                     /*Size=*/0, Binding, Sec,
-                                     /*File=*/nullptr);
+  return Symtab->addRegular<ELFT>(Name, StOther, STT_NOTYPE, Value,
+                                  /*Size=*/0, Binding, Sec,
+                                  /*File=*/nullptr);
 }
 
 template <class ELFT>
 static DefinedRegular *
 addOptionalRegular(StringRef Name, SectionBase *Sec, uint64_t Val,
                    uint8_t StOther = STV_HIDDEN, uint8_t Binding = STB_GLOBAL) {
-  SymbolBody *S = Symtab<ELFT>::X->find(Name);
+  SymbolBody *S = Symtab->find(Name);
   if (!S)
     return nullptr;
   if (S->isInCurrentDSO())
@@ -803,21 +803,21 @@ template <class ELFT> void Writer<ELFT>:
     // to GOT. Default offset is 0x7ff0.
     // See "Global Data Symbols" in Chapter 6 in the following document:
     // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
-    ElfSym::MipsGp = Symtab<ELFT>::X->addAbsolute("_gp", STV_HIDDEN, STB_LOCAL);
+    ElfSym::MipsGp = Symtab->addAbsolute<ELFT>("_gp", STV_HIDDEN, STB_LOCAL);
 
     // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
     // start of function and 'gp' pointer into GOT.
-    if (Symtab<ELFT>::X->find("_gp_disp"))
+    if (Symtab->find("_gp_disp"))
       ElfSym::MipsGpDisp =
-          Symtab<ELFT>::X->addAbsolute("_gp_disp", STV_HIDDEN, STB_LOCAL);
+          Symtab->addAbsolute<ELFT>("_gp_disp", STV_HIDDEN, STB_LOCAL);
 
     // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
     // pointer. This symbol is used in the code generated by .cpload pseudo-op
     // in case of using -mno-shared option.
     // https://sourceware.org/ml/binutils/2004-12/msg00094.html
-    if (Symtab<ELFT>::X->find("__gnu_local_gp"))
+    if (Symtab->find("__gnu_local_gp"))
       ElfSym::MipsLocalGp =
-          Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
+          Symtab->addAbsolute<ELFT>("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
   }
 
   // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
@@ -833,7 +833,7 @@ template <class ELFT> void Writer<ELFT>:
   // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
   // to avoid the undefined symbol error.
   if (!InX::DynSymTab)
-    Symtab<ELFT>::X->addIgnored("__tls_get_addr");
+    Symtab->addIgnored<ELFT>("__tls_get_addr");
 
   // __ehdr_start is the location of ELF file headers. Note that we define
   // this symbol unconditionally even when using a linker script, which
@@ -893,7 +893,7 @@ template <class ELFT> static void sortBy
 
   // Build a map from sections to their priorities.
   DenseMap<SectionBase *, int> SectionOrder;
-  for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) {
+  for (elf::ObjectFile<ELFT> *File : ObjectFile<ELFT>::Instances) {
     for (SymbolBody *Body : File->getSymbols()) {
       auto *D = dyn_cast<DefinedRegular>(Body);
       if (!D || !D->Section)
@@ -1224,7 +1224,7 @@ template <class ELFT> void Writer<ELFT>:
 
   // Now that we have defined all possible global symbols including linker-
   // synthesized ones. Visit all symbols to give the finishing touches.
-  for (Symbol *S : Symtab<ELFT>::X->getSymbols()) {
+  for (Symbol *S : Symtab->getSymbols()) {
     SymbolBody *Body = S->body();
 
     if (!includeInSymtab(*Body))
@@ -1689,7 +1689,7 @@ template <class ELFT> void Writer<ELFT>:
 template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() {
   // Case 1, 2 or 3. As a special case, if the symbol is actually
   // a number, we'll use that number as an address.
-  if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Entry))
+  if (SymbolBody *B = Symtab->find(Config->Entry))
     return B->getVA();
   uint64_t Addr;
   if (to_integer(Config->Entry, Addr))

Modified: lld/trunk/ELF/Writer.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.h?rev=309152&r1=309151&r2=309152&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.h (original)
+++ lld/trunk/ELF/Writer.h Wed Jul 26 11:42:48 2017
@@ -21,7 +21,7 @@ class InputFile;
 class OutputSection;
 class InputSectionBase;
 template <class ELFT> class ObjectFile;
-template <class ELFT> class SymbolTable;
+class SymbolTable;
 template <class ELFT> void writeResult();
 template <class ELFT> void markLive();
 




More information about the llvm-commits mailing list