forked from OSchip/llvm-project
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
This commit is contained in:
parent
6c978aa9da
commit
95769b4a29
|
@ -653,6 +653,8 @@ private:
|
|||
void readPhdrs();
|
||||
void readSearchDir();
|
||||
void readSections();
|
||||
void readVersion();
|
||||
void readVersionScriptCommand();
|
||||
|
||||
SymbolAssignment *readAssignment(StringRef Name);
|
||||
OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
|
||||
|
@ -676,7 +678,7 @@ private:
|
|||
|
||||
// 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 @@ const StringMap<elf::ScriptParser::Handler> elf::ScriptParser::Cmd = {
|
|||
{"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 @@ unsigned ScriptParser::readPhdrType() {
|
|||
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;
|
||||
|
|
|
@ -101,6 +101,14 @@
|
|||
# MAIN-NEXT: SHT_GNU_verdef {
|
||||
# MAIN-NEXT: }
|
||||
|
||||
# RUN: echo "VERSION { \
|
||||
# RUN: LIBSAMPLE_1.0 { global: a; local: *; }; \
|
||||
# RUN: LIBSAMPLE_2.0 { global: b; local: *; }; \
|
||||
# RUN: LIBSAMPLE_3.0 { global: c; local: *; }; \
|
||||
# RUN: }" > %t.script
|
||||
# RUN: ld.lld --script %t.script -shared -soname shared %t.o -o %t2.so
|
||||
# RUN: llvm-readobj -V -dyn-symbols %t2.so | FileCheck --check-prefix=DSO %s
|
||||
|
||||
.globl a
|
||||
.type a,@function
|
||||
a:
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
# RUN: global: foo3; \
|
||||
# RUN: local: *; }; " > %t5.script
|
||||
# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=ERR %s
|
||||
# ERR: anonymous version definition is used in combination with other version definitions
|
||||
# RUN: FileCheck -check-prefix=ERR1 %s
|
||||
# ERR1: anonymous version definition is used in combination with other version definitions
|
||||
|
||||
# RUN: echo "{ \
|
||||
# RUN: global: foo1; \
|
||||
|
@ -45,7 +45,8 @@
|
|||
# RUN: global: foo3; \
|
||||
# RUN: local: *; }; " > %t5.script
|
||||
# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
|
||||
# RUN: FileCheck -check-prefix=ERR %s
|
||||
# RUN: FileCheck -check-prefix=ERR2 %s
|
||||
# ERR2: EOF expected, but got VERSION_2.0
|
||||
|
||||
# RUN: echo "VERSION_1.0{ \
|
||||
# RUN: global: foo1; \
|
||||
|
|
Loading…
Reference in New Issue