diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2016-06-17 13:38:09 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2016-06-17 13:38:09 +0000 |
commit | f70fb04e4fb6def2ff1aa9ddc764f43636aa396c (patch) | |
tree | 780e4d5c04a2d840366bcf9e76da6167d37d800f | |
parent | 1d67ac56390adafd0d98cb9d7890e52a2d091158 (diff) | |
download | bcm5719-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.h | 2 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
-rw-r--r-- | lld/ELF/SymbolListFile.cpp | 33 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 2 | ||||
-rw-r--r-- | lld/test/ELF/version-script.s | 67 |
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 |