Linker script: support VERSION command.
Summary:
VERSION commands define symbol versions. The grammar of the
commnad is as follows
VERSION { version-script-commands }
where version-script-commands is
[ name ] { version-definitions }.
Note that we already support version-script-commands because
it is being used for version script command.
This patch is based on George's patch https://reviews.llvm.org/D23609
Reviewers: grimar
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D24089
llvm-svn: 280284
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9403233..b3a1c45 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -653,6 +653,8 @@
void readPhdrs();
void readSearchDir();
void readSections();
+ void readVersion();
+ void readVersionScriptCommand();
SymbolAssignment *readAssignment(StringRef Name);
OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
@@ -676,7 +678,7 @@
// For parsing version script.
void readExtern(std::vector<SymbolVersion> *Globals);
- void readVersion(StringRef VerStr);
+ void readVersionDeclaration(StringRef VerStr);
void readGlobal(StringRef VerStr);
void readLocal();
@@ -698,29 +700,39 @@
{"PHDRS", &ScriptParser::readPhdrs},
{"SEARCH_DIR", &ScriptParser::readSearchDir},
{"SECTIONS", &ScriptParser::readSections},
+ {"VERSION", &ScriptParser::readVersion},
{";", &ScriptParser::readNothing}};
void ScriptParser::readVersionScript() {
- StringRef Msg = "anonymous version definition is used in "
- "combination with other version definitions";
+ readVersionScriptCommand();
+ if (!atEOF())
+ setError("EOF expected, but got " + next());
+}
+
+void ScriptParser::readVersionScriptCommand() {
if (skip("{")) {
- readVersion("");
- if (!atEOF())
- setError(Msg);
+ readVersionDeclaration("");
return;
}
- while (!atEOF() && !Error) {
+ while (!atEOF() && !Error && peek() != "}") {
StringRef VerStr = next();
if (VerStr == "{") {
- setError(Msg);
+ setError("anonymous version definition is used in "
+ "combination with other version definitions");
return;
}
expect("{");
- readVersion(VerStr);
+ readVersionDeclaration(VerStr);
}
}
+void ScriptParser::readVersion() {
+ expect("{");
+ readVersionScriptCommand();
+ expect("}");
+}
+
void ScriptParser::readLinkerScript() {
while (!atEOF()) {
StringRef Tok = next();
@@ -1377,7 +1389,7 @@
return Ret;
}
-void ScriptParser::readVersion(StringRef VerStr) {
+void ScriptParser::readVersionDeclaration(StringRef VerStr) {
// Identifiers start at 2 because 0 and 1 are reserved
// for VER_NDX_LOCAL and VER_NDX_GLOBAL constants.
size_t VersionId = Config->VersionDefinitions.size() + 2;