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.
//
B->symbol()->VersionId = VER_NDX_GLOBAL;
}
+// Set symbol versions to symbols. This function handles patterns
+// containing no wildcard characters.
+template <class ELFT>
+void SymbolTable<ELFT>::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<SymbolBody *> 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 <class ELFT>
void SymbolTable<ELFT>::assignWildcardVersion(SymbolVersion Ver,
size_t VersionId) {
// 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.