Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -33,41 +33,13 @@ // 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 SymbolTable { - typedef typename ELFT::Sym Elf_Sym; - +class SymbolTableBase { public: - void addFile(InputFile *File); - void addCombinedLTOObject(); - void addSymbolAlias(StringRef Alias, StringRef Name); - void addSymbolWrap(StringRef Name); void applySymbolRenames(); ArrayRef getSymbols() const { return SymVector; } - ArrayRef *> getObjectFiles() const { return ObjectFiles; } ArrayRef getBinaryFiles() const { return BinaryFiles; } - ArrayRef *> getSharedFiles() const { return SharedFiles; } - - DefinedRegular *addAbsolute(StringRef Name, - uint8_t Visibility = llvm::ELF::STV_HIDDEN, - uint8_t Binding = llvm::ELF::STB_GLOBAL); - DefinedRegular *addIgnored(StringRef Name, - uint8_t Visibility = llvm::ELF::STV_HIDDEN); - - Symbol *addUndefined(StringRef Name); - Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, - uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym, - InputFile *File); - 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 *F, StringRef Name, const Elf_Sym &Sym, - const typename ELFT::Verdef *Verdef); - - Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S); - 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 +52,6 @@ uint8_t Visibility, bool CanOmitFromDynSym, InputFile *File); - void scanUndefinedFlags(); - void scanShlibUndefined(); void scanVersionScript(); SymbolBody *find(StringRef Name); @@ -89,7 +59,7 @@ void trace(StringRef Name); -private: +protected: std::vector findByVersion(SymbolVersion Ver); std::vector findAllByVersion(SymbolVersion Ver); @@ -120,8 +90,6 @@ // is used to uniquify them. llvm::DenseSet ComdatGroups; - std::vector *> ObjectFiles; - std::vector *> SharedFiles; std::vector BitcodeFiles; std::vector BinaryFiles; @@ -138,6 +106,47 @@ std::unique_ptr LTO; }; +template class SymbolTable : public SymbolTableBase { + typedef typename ELFT::Sym Elf_Sym; + +public: + void addFile(InputFile *File); + void addCombinedLTOObject(); + void addSymbolAlias(StringRef Alias, StringRef Name); + void addSymbolWrap(StringRef Name); + + ArrayRef *> getObjectFiles() const { return ObjectFiles; } + ArrayRef *> getSharedFiles() const { return SharedFiles; } + + DefinedRegular *addAbsolute(StringRef Name, + uint8_t Visibility = llvm::ELF::STV_HIDDEN, + uint8_t Binding = llvm::ELF::STB_GLOBAL); + DefinedRegular *addIgnored(StringRef Name, + uint8_t Visibility = llvm::ELF::STV_HIDDEN); + + Symbol *addUndefined(StringRef Name); + Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, + uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym, + InputFile *File); + + 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 *F, StringRef Name, const Elf_Sym &Sym, + const typename ELFT::Verdef *Verdef); + + Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S); + void addLazyObject(StringRef Name, LazyObjectFile &Obj); + + void scanUndefinedFlags(); + void scanShlibUndefined(); + +private: + std::vector *> ObjectFiles; + std::vector *> SharedFiles; +}; + template struct Symtab { static SymbolTable *X; }; template SymbolTable *Symtab::X; Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -150,7 +150,7 @@ // 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 void SymbolTable::trace(StringRef Name) { +void SymbolTableBase::trace(StringRef Name) { Symtab.insert({CachedHashStringRef(Name), {-1, true}}); } @@ -191,7 +191,7 @@ // 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 void SymbolTable::applySymbolRenames() { +void SymbolTableBase::applySymbolRenames() { for (auto &KV : Config->RenamedSymbols) { Symbol *Dst = KV.first; Symbol *Src = KV.second.Target; @@ -209,8 +209,7 @@ } // Find an existing symbol or create and insert a new one. -template -std::pair SymbolTable::insert(StringRef Name) { +std::pair SymbolTableBase::insert(StringRef Name) { // @@ means the symbol is the default version. In that // case @@ will be used to resolve references to . size_t Pos = Name.find("@@"); @@ -246,10 +245,10 @@ // Find an existing symbol or create and insert a new one, then apply the given // attributes. -template -std::pair -SymbolTable::insert(StringRef Name, uint8_t Type, uint8_t Visibility, - bool CanOmitFromDynSym, InputFile *File) { +std::pair SymbolTableBase::insert(StringRef Name, uint8_t Type, + uint8_t Visibility, + bool CanOmitFromDynSym, + InputFile *File) { bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind; Symbol *S; bool WasInserted; @@ -380,11 +379,10 @@ return 0; } -template -Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, - uint32_t Alignment, uint8_t Binding, - uint8_t StOther, uint8_t Type, - InputFile *File) { +Symbol *SymbolTableBase::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), @@ -503,10 +501,9 @@ } } -template -Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding, - uint8_t StOther, uint8_t Type, - bool CanOmitFromDynSym, BitcodeFile *F) { +Symbol *SymbolTableBase::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 +518,7 @@ return S; } -template SymbolBody *SymbolTable::find(StringRef Name) { +SymbolBody *SymbolTableBase::find(StringRef Name) { auto It = Symtab.find(CachedHashStringRef(Name)); if (It == Symtab.end()) return nullptr; @@ -531,8 +528,7 @@ return SymVector[V.Idx]->body(); } -template -SymbolBody *SymbolTable::findInCurrentDSO(StringRef Name) { +SymbolBody *SymbolTableBase::findInCurrentDSO(StringRef Name) { if (SymbolBody *S = find(Name)) if (S->isInCurrentDSO()) return S; @@ -634,8 +630,7 @@ // 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 -StringMap> &SymbolTable::getDemangledSyms() { +StringMap> &SymbolTableBase::getDemangledSyms() { if (!DemangledSyms) { DemangledSyms.emplace(); for (Symbol *Sym : SymVector) { @@ -651,8 +646,7 @@ return *DemangledSyms; } -template -std::vector SymbolTable::findByVersion(SymbolVersion Ver) { +std::vector SymbolTableBase::findByVersion(SymbolVersion Ver) { if (Ver.IsExternCpp) return getDemangledSyms().lookup(Ver.Name); if (SymbolBody *B = find(Ver.Name)) @@ -661,9 +655,7 @@ return {}; } -template -std::vector -SymbolTable::findAllByVersion(SymbolVersion Ver) { +std::vector SymbolTableBase::findAllByVersion(SymbolVersion Ver) { std::vector Res; StringMatcher M(Ver.Name); @@ -685,7 +677,7 @@ // 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 void SymbolTable::handleAnonymousVersion() { +void SymbolTableBase::handleAnonymousVersion() { for (SymbolVersion &Ver : Config->VersionScriptGlobals) assignExactVersion(Ver, VER_NDX_GLOBAL, "global"); for (SymbolVersion &Ver : Config->VersionScriptGlobals) @@ -698,10 +690,8 @@ // Set symbol versions to symbols. This function handles patterns // containing no wildcard characters. -template -void SymbolTable::assignExactVersion(SymbolVersion Ver, - uint16_t VersionId, - StringRef VersionName) { +void SymbolTableBase::assignExactVersion(SymbolVersion Ver, uint16_t VersionId, + StringRef VersionName) { if (Ver.HasWildcard) return; @@ -730,9 +720,8 @@ } } -template -void SymbolTable::assignWildcardVersion(SymbolVersion Ver, - uint16_t VersionId) { +void SymbolTableBase::assignWildcardVersion(SymbolVersion Ver, + uint16_t VersionId) { if (!Ver.HasWildcard) return; @@ -746,7 +735,7 @@ // This function processes version scripts by updating VersionId // member of symbols. -template void SymbolTable::scanVersionScript() { +void SymbolTableBase::scanVersionScript() { // Handle edge cases first. handleAnonymousVersion();