From 397cd87a69aed2be3ec96a9627bb8e9565abe701 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Tue, 30 Aug 2016 09:35:03 +0000 Subject: [PATCH] [ELF] - Versionscript: support wildcards for extern "c++" tag. Previously for extern keyword only names in quotes (exact match) was supported. Patch adds support for wildcards, so next scripts can be handled properly: LIBSAMPLE_1.0 { global: extern "C++" { foo*; }; }; Differential revision: https://reviews.llvm.org/D23794 llvm-svn: 280067 --- lld/ELF/SymbolTable.cpp | 21 +++++++++- .../ELF/version-script-extern-wildcards.s | 40 +++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 lld/test/ELF/version-script-extern-wildcards.s diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index fcd7686f7e1d..410a8f3c15b1 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -621,6 +621,18 @@ static SymbolBody *findDemangled(const std::map &D, return nullptr; } +static std::vector +findAllDemangled(const std::map &D, + StringRef Pattern) { + std::vector Res; + for (auto &P : D) { + SymbolBody *Body = P.second; + if (!Body->isUndefined() && globMatch(Pattern, P.first)) + Res.push_back(Body); + } + return Res; +} + // This function processes the --version-script option by marking all global // symbols with the VersionScriptGlobal flag, which acts as a filter on the // dynamic symbol table. @@ -665,10 +677,15 @@ template void SymbolTable::scanVersionScript() { 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)) - for (SymbolBody *B : findAll(Sym.Name)) + if (hasWildcard(Sym.Name)) { + std::vector All = + Sym.IsExternCpp ? findAllDemangled(Demangled, Sym.Name) + : findAll(Sym.Name); + + for (SymbolBody *B : All) if (B->symbol()->VersionId == Config->DefaultSymbolVersion) B->symbol()->VersionId = V.Id; + } } } diff --git a/lld/test/ELF/version-script-extern-wildcards.s b/lld/test/ELF/version-script-extern-wildcards.s new file mode 100644 index 000000000000..0ef9c83aae43 --- /dev/null +++ b/lld/test/ELF/version-script-extern-wildcards.s @@ -0,0 +1,40 @@ +# 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: foo*; \ +# RUN: }; \ +# RUN: }; \ +# RUN: LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: zed*; \ +# RUN: bar; \ +# 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: Version symbols { +# CHECK: Symbols [ +# CHECK: Name: _Z3bari@ +# CHECK: Name: _Z3fooi@@LIBSAMPLE_1.0 +# CHECK: Name: _Z3zedi@@LIBSAMPLE_2.0 + +.text +.globl _Z3fooi +.type _Z3fooi,@function +_Z3fooi: +retq + +.globl _Z3bari +.type _Z3bari,@function +_Z3bari: +retq + +.globl _Z3zedi +.type _Z3zedi,@function +_Z3zedi: +retq