Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -45,6 +45,7 @@ struct SymbolVersion { llvm::StringRef Name; bool IsExternCpp; + bool HasWildcards; }; // This struct contains symbols version definition that Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -750,12 +750,18 @@ } } +static StringRef unquote(StringRef S) { + if (!S.startswith("\"")) + return S; + return S.substr(1, S.size() - 2); +} + void ScriptParser::readAsNeeded() { expect("("); bool Orig = Config->AsNeeded; Config->AsNeeded = true; while (!Error && !skip(")")) - addFile(next()); + addFile(unquote(next())); Config->AsNeeded = Orig; } @@ -781,7 +787,7 @@ if (Tok == "AS_NEEDED") readAsNeeded(); else - addFile(Tok); + addFile(unquote(Tok)); } } @@ -970,7 +976,7 @@ expect("("); Expr E = readExpr(); expect(","); - StringRef Msg = next(); + StringRef Msg = unquote(next()); expect(")"); return [=](uint64_t Dot) { uint64_t V = E(Dot); @@ -1431,7 +1437,8 @@ for (;;) { if (peek() == "}" || Error) break; - Globals->push_back({next(), true}); + bool HasWildcard = !peek().startswith("\"") && hasWildcard(peek()); + Globals->push_back({unquote(next()), true, HasWildcard}); expect(";"); } @@ -1454,7 +1461,7 @@ if (Cur == "}" || Cur == "local:" || Error) return; next(); - Globals->push_back({Cur, false}); + Globals->push_back({unquote(Cur), false, hasWildcard(Cur)}); expect(";"); } } Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -67,7 +67,7 @@ error("unclosed quote"); return {}; } - Ret.push_back(S.substr(1, E - 1)); + Ret.push_back(S.take_front(E + 1)); S = S.substr(E + 1); continue; } Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -18,7 +18,6 @@ #include "Config.h" #include "Error.h" #include "LinkerScript.h" -#include "Strings.h" #include "SymbolListFile.h" #include "Symbols.h" #include "llvm/Bitcode/ReaderWriter.h" @@ -666,7 +665,7 @@ // i.e. version definitions not containing any glob meta-characters. for (VersionDefinition &V : Config->VersionDefinitions) { for (SymbolVersion Sym : V.Globals) { - if (hasWildcard(Sym.Name)) + if (Sym.HasWildcards) continue; StringRef N = Sym.Name; SymbolBody *B = Sym.IsExternCpp ? findDemangled(Demangled, N) : find(N); @@ -681,7 +680,7 @@ for (size_t I = Config->VersionDefinitions.size() - 1; I != (size_t)-1; --I) { VersionDefinition &V = Config->VersionDefinitions[I]; for (SymbolVersion &Sym : V.Globals) { - if (!hasWildcard(Sym.Name)) + if (!Sym.HasWildcards) continue; Regex Re = compileGlobPatterns({Sym.Name}); std::vector Syms = Index: test/ELF/version-script-extern-exact.s =================================================================== --- test/ELF/version-script-extern-exact.s +++ test/ELF/version-script-extern-exact.s @@ -0,0 +1,25 @@ +# REQUIRES: shell + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "LIBSAMPLE_1.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: \"aaa*\"; \ +# RUN: }; \ +# RUN: }; " > %t.script +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck %s + +# CHECK-NOT: _Z3aaaPf@@LIBSAMPLE_1.0 +# CHECK-NOT: _Z3aaaPi@@LIBSAMPLE_1.0 + +.text +.globl _Z3aaaPi +.type _Z3aaaPi,@function +_Z3aaaPi: +retq + +.globl _Z3aaaPf +.type _Z3aaaPf,@function +_Z3aaaPf: +retq