summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h2
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/SymbolListFile.cpp33
-rw-r--r--lld/ELF/SymbolTable.cpp2
-rw-r--r--lld/test/ELF/version-script.s67
5 files changed, 94 insertions, 11 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 2dbbdbe40d6..be8059b46a9 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -88,7 +88,7 @@ struct Configuration {
bool Threads;
bool Trace;
bool Verbose;
- bool VersionScript = false;
+ bool VersionScriptGlobalByDefault = true;
bool WarnCommon;
bool ZCombreloc;
bool ZDefs;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index b816e7dfe7d..c99b22988ac 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -414,7 +414,6 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->DynamicList.push_back(Arg->getValue());
if (auto *Arg = Args.getLastArg(OPT_version_script)) {
- Config->VersionScript = true;
if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
parseVersionScript(*Buffer);
}
diff --git a/lld/ELF/SymbolListFile.cpp b/lld/ELF/SymbolListFile.cpp
index b8cfdc88f33..3d1377be438 100644
--- a/lld/ELF/SymbolListFile.cpp
+++ b/lld/ELF/SymbolListFile.cpp
@@ -78,24 +78,41 @@ public:
private:
void parseVersion();
+ void parseLocal();
+ void parseVersionSymbols();
};
void VersionScriptParser::parseVersion() {
expect("{");
if (peek() == "global:") {
next();
- while (!Error) {
- Config->VersionScriptGlobals.push_back(next());
- expect(";");
- if (peek() == "local:")
- break;
- }
+ parseVersionSymbols();
}
+ if (peek() == "local:")
+ parseLocal();
+ else
+ parseVersionSymbols();
+
+ expect("}");
+ expect(";");
+}
+
+void VersionScriptParser::parseLocal() {
expect("local:");
expect("*");
expect(";");
- expect("}");
- expect(";");
+ Config->VersionScriptGlobalByDefault = false;
+}
+
+void VersionScriptParser::parseVersionSymbols() {
+ for (;;) {
+ StringRef Cur = peek();
+ if (Cur == "}" || Cur == "local:")
+ return;
+ next();
+ Config->VersionScriptGlobals.push_back(Cur);
+ expect(";");
+ }
}
void VersionScriptParser::run() {
diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp
index e5477140a95..e9cee22c1bf 100644
--- a/lld/ELF/SymbolTable.cpp
+++ b/lld/ELF/SymbolTable.cpp
@@ -175,7 +175,7 @@ std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
Sym->Visibility = STV_DEFAULT;
Sym->IsUsedInRegularObj = false;
Sym->ExportDynamic = false;
- Sym->VersionScriptGlobal = !Config->VersionScript;
+ Sym->VersionScriptGlobal = Config->VersionScriptGlobalByDefault;
SymVector.push_back(Sym);
} else {
Sym = SymVector[P.first->second];
diff --git a/lld/test/ELF/version-script.s b/lld/test/ELF/version-script.s
index acd62f886a1..8310aedb290 100644
--- a/lld/test/ELF/version-script.s
+++ b/lld/test/ELF/version-script.s
@@ -140,6 +140,73 @@
# EXE-NEXT: }
# EXE-NEXT: ]
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld -shared %t.o %t2.so -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
+
+# RUN: echo "{ global: foo1; foo3; };" > %t2.script
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --version-script %t2.script -shared %t.o %t2.so -o %t.so
+# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
+
+# ALL: DynamicSymbols [
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: @
+# ALL-NEXT: Value: 0x0
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Local
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: Undefined
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: _start@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: bar@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: Function
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: Undefined
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: foo1@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: foo2@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: Symbol {
+# ALL-NEXT: Name: foo3@
+# ALL-NEXT: Value:
+# ALL-NEXT: Size: 0
+# ALL-NEXT: Binding: Global
+# ALL-NEXT: Type: None
+# ALL-NEXT: Other: 0
+# ALL-NEXT: Section: .text
+# ALL-NEXT: }
+# ALL-NEXT: ]
+
.globl foo1
foo1:
call bar@PLT
OpenPOWER on IntegriCloud