Index: lld/trunk/ELF/Config.h =================================================================== --- lld/trunk/ELF/Config.h +++ lld/trunk/ELF/Config.h @@ -38,8 +38,9 @@ // This struct contains symbols version definition that // can be found in version script if it is used for link. struct Version { - Version(llvm::StringRef Name) : Name(Name) {} + Version(llvm::StringRef Name, size_t Id) : Name(Name), Id(Id) {} llvm::StringRef Name; + size_t Id; std::vector Globals; size_t NameOff; // Offset in string table. }; Index: lld/trunk/ELF/SymbolListFile.h =================================================================== --- lld/trunk/ELF/SymbolListFile.h +++ lld/trunk/ELF/SymbolListFile.h @@ -16,6 +16,8 @@ namespace lld { namespace elf { +size_t defineSymbolVersion(StringRef Version); + void parseDynamicList(MemoryBufferRef MB); void parseVersionScript(MemoryBufferRef MB); Index: lld/trunk/ELF/SymbolListFile.cpp =================================================================== --- lld/trunk/ELF/SymbolListFile.cpp +++ lld/trunk/ELF/SymbolListFile.cpp @@ -82,9 +82,17 @@ void parseVersionSymbols(StringRef Version); }; +size_t elf::defineSymbolVersion(StringRef Version) { + // Identifiers start at 2 because 0 and 1 are reserved + // for VER_NDX_LOCAL and VER_NDX_GLOBAL constants. + size_t VersionId = Config->SymbolVersions.size() + 2; + Config->SymbolVersions.push_back(elf::Version(Version, VersionId)); + return VersionId; +} + void VersionScriptParser::parseVersion(StringRef Version) { expect("{"); - Config->SymbolVersions.push_back(elf::Version(Version)); + defineSymbolVersion(Version); if (peek() == "global:") { next(); parseVersionSymbols(Version); Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -19,6 +19,7 @@ #include "Error.h" #include "LinkerScript.h" #include "Strings.h" +#include "SymbolListFile.h" #include "Symbols.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/StringSaver.h" @@ -180,20 +181,18 @@ if (Default) Version = Version.drop_front(); - size_t I = 2; - for (elf::Version &V : Config->SymbolVersions) { + for (elf::Version &V : Config->SymbolVersions) if (V.Name == Version) - return Default ? I : (I | VERSYM_HIDDEN); - ++I; - } + return Default ? V.Id : (V.Id | VERSYM_HIDDEN); + // If we are not building shared and version script // is not specified, then it is not a error, it is // in common not to use script for linking executables. // In this case we just create new version. if (!Config->Shared && !Config->HasVersionScript) { - Config->SymbolVersions.push_back(elf::Version(Version)); - return Default ? I : (I | VERSYM_HIDDEN); + size_t Id = defineSymbolVersion(Version); + return Default ? Id : (Id | VERSYM_HIDDEN); } error("symbol " + Name + " has undefined version " + Version); @@ -608,7 +607,7 @@ if (B->symbol()->VersionId != VER_NDX_GLOBAL && B->symbol()->VersionId != VER_NDX_LOCAL) warning("duplicate symbol " + Name + " in version script"); - B->symbol()->VersionId = I + 2; + B->symbol()->VersionId = V.Id; } } @@ -621,7 +620,7 @@ for (SymbolBody *B : findAll(Name)) if (B->symbol()->VersionId == VER_NDX_GLOBAL || B->symbol()->VersionId == VER_NDX_LOCAL) - B->symbol()->VersionId = I + 2; + B->symbol()->VersionId = V.Id; } } }