summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2016-06-17 13:38:09 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2016-06-17 13:38:09 +0000
commitf70fb04e4fb6def2ff1aa9ddc764f43636aa396c (patch)
tree780e4d5c04a2d840366bcf9e76da6167d37d800f
parent1d67ac56390adafd0d98cb9d7890e52a2d091158 (diff)
downloadbcm5719-llvm-f70fb04e4fb6def2ff1aa9ddc764f43636aa396c.tar.gz
bcm5719-llvm-f70fb04e4fb6def2ff1aa9ddc764f43636aa396c.zip
Make local: optional.
Doing that in an anonymous version is a bit silly, but this opens the way for supporting it in general. Since we don't support actual versions, for now we just disable the version script if we detect that it is missing a local. llvm-svn: 273000
-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