diff options
-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 |