From 94bcfae26da1ff5155368d6887fa56f61355f425 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Thu, 17 Nov 2016 02:09:42 +0000 Subject: [PATCH] Split scanVersionScript. NFC. llvm-svn: 287191 --- lld/ELF/SymbolTable.cpp | 64 ++++++++++++++++++++++++------------------------- lld/ELF/SymbolTable.h | 2 ++ 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index a003fcd..6465013 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -581,23 +581,6 @@ template void SymbolTable::scanDynamicList() { B->symbol()->ExportDynamic = true; } -// A helper function to set a version to a symbol. -// Essentially, assigning two different versions to the same symbol is an error. -static void setVersionId(SymbolBody *Body, StringRef VersionName, - StringRef Name, uint16_t Version) { - if (!Body || Body->isUndefined()) { - if (Config->NoUndefinedVersion) - error("version script assignment of '" + VersionName + "' to symbol " + - Name + " failed: symbol not defined"); - return; - } - - Symbol *Sym = Body->symbol(); - if (Sym->VersionId != Config->DefaultSymbolVersion) - warn("duplicate symbol " + Name + " in version script"); - Sym->VersionId = Version; -} - // Initialize DemangledSyms with a map from demangled symbols to symbol // objects. Used to handle "extern C++" directive in version scripts. // @@ -668,6 +651,36 @@ template void SymbolTable::handleAnonymousVersion() { B->symbol()->VersionId = VER_NDX_GLOBAL; } +// Set symbol versions to symbols. This function handles patterns +// containing no wildcard characters. +template +void SymbolTable::assignExactVersion(SymbolVersion Ver, size_t VersionId, + StringRef VersionName) { + if (Ver.HasWildcards) + return; + + // Get a list of symbols which we need to assign the version to. + std::vector Syms; + if (Ver.IsExternCpp) + Syms = findDemangled(Ver.Name); + else + Syms.push_back(find(Ver.Name)); + + // Assign the version. + for (SymbolBody *B : Syms) { + if (!B || B->isUndefined()) { + if (Config->NoUndefinedVersion) + error("version script assignment of '" + VersionName + "' to symbol " + + Ver.Name + " failed: symbol not defined"); + continue; + } + + if (B->symbol()->VersionId != Config->DefaultSymbolVersion) + warn("duplicate symbol " + Ver.Name + " in version script"); + B->symbol()->VersionId = VersionId; + } +} + template void SymbolTable::assignWildcardVersion(SymbolVersion Ver, size_t VersionId) { @@ -701,26 +714,13 @@ template void SymbolTable::scanVersionScript() { // Each version definition has a glob pattern, and all symbols that match // with the pattern get that version. - auto assignVersion = [&](SymbolVersion &Ver, size_t Version, - StringRef VerName) { - if (Ver.HasWildcards) - return; - - if (Ver.IsExternCpp) { - for (SymbolBody *B : findDemangled(Ver.Name)) - setVersionId(B, VerName, Ver.Name, Version); - return; - } - setVersionId(find(Ver.Name), VerName, Ver.Name, Version); - }; - // First, we assign versions to exact matching symbols, // i.e. version definitions not containing any glob meta-characters. for (SymbolVersion Sym : Config->VersionScriptLocals) - assignVersion(Sym, VER_NDX_LOCAL, "local"); + assignExactVersion(Sym, VER_NDX_LOCAL, "local"); for (VersionDefinition &V : Config->VersionDefinitions) for (SymbolVersion Sym : V.Globals) - assignVersion(Sym, V.Id, V.Name); + assignExactVersion(Sym, V.Id, V.Name); // Next, we assign versions to fuzzy matching symbols, // i.e. version definitions containing glob meta-characters. diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index 8a637f8..995fde1 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -103,6 +103,8 @@ private: void initDemangledSyms(); void handleAnonymousVersion(); + void assignExactVersion(SymbolVersion Ver, size_t VersionId, + StringRef VersionName); void assignWildcardVersion(SymbolVersion Ver, size_t VersionId); struct SymIndex { -- 2.7.4