[ELF] - Add Id field to Version struct.

That helps to avoid expressions like I + 2 in code
that assigns version number to symbols.

Change was suggested by Rui Ueyama.

Differential revision: http://reviews.llvm.org/D22086

llvm-svn: 275159
This commit is contained in:
George Rimar 2016-07-12 07:44:40 +00:00
parent eda81a1b86
commit 7899d48dff
4 changed files with 21 additions and 11 deletions

View File

@ -38,8 +38,9 @@ enum class UnresolvedPolicy { NoUndef, Error, Warn, Ignore };
// 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<llvm::StringRef> Globals;
size_t NameOff; // Offset in string table.
};

View File

@ -82,9 +82,17 @@ private:
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);

View File

@ -16,6 +16,8 @@
namespace lld {
namespace elf {
size_t defineSymbolVersion(StringRef Version);
void parseDynamicList(MemoryBufferRef MB);
void parseVersionScript(MemoryBufferRef MB);

View File

@ -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 @@ static uint16_t getVersionId(Symbol *Sym, StringRef Name) {
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 @@ template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
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 @@ template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
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;
}
}
}