diff --git a/elf/main.cc b/elf/main.cc index 1081df472c..00e573f30c 100644 --- a/elf/main.cc +++ b/elf/main.cc @@ -22,12 +22,15 @@ std::string glob_to_regex(std::string_view pattern) { switch (c) { case '.': case '[': case ']': case '^': case '$': case '\\': case '(': case ')': - case '+': case '?': case '|': + case '+': case '|': ss << "\\" << c; break; case '*': ss << ".*"; break; + case '?': + ss << "."; + break; default: ss << c; break; diff --git a/elf/passes.cc b/elf/passes.cc index 2b4aa9cbc1..4f8710534e 100644 --- a/elf/passes.cc +++ b/elf/passes.cc @@ -609,8 +609,9 @@ void apply_version_script(Context &ctx) { for (VersionPattern &elem : ctx.arg.version_patterns) { std::vector vec; + std::regex re_glob("[*?]", std::regex_constants::optimize | std::regex_constants::nosubs); for (std::string_view pat : elem.patterns) { - if (pat.find('*') == pat.npos) { + if (!std::regex_search(pat.begin(), pat.end(), re_glob)) { Symbol *sym = intern(ctx, pat); if (sym->file && !sym->file->is_dso) sym->ver_idx = elem.ver_idx; diff --git a/test/elf/version-script8.sh b/test/elf/version-script8.sh new file mode 100755 index 0000000000..cc6d99db6a --- /dev/null +++ b/test/elf/version-script8.sh @@ -0,0 +1,46 @@ +#!/bin/bash +export LANG= +set -e +cd $(dirname $0) +mold=`pwd`/../../mold +echo -n "Testing $(basename -s .sh $0) ... " +t=$(pwd)/../../out/test/elf/$(basename -s .sh $0) +mkdir -p $t + +cat < $t/a.ver +ver1 { + global: ?oo; + local: *; +}; + +ver2 { + global: b?r; +}; +EOF + +cat < $t/log +fgrep -q 'foo@@ver1' $t/log +fgrep -q 'bar@@ver2' $t/log +! fgrep -q 'baz' $t/log || false + +echo OK