diff --git a/demangle.cc b/demangle.cc index aa084881..9b77f57d 100644 --- a/demangle.cc +++ b/demangle.cc @@ -7,23 +7,34 @@ namespace mold { std::string_view demangle(std::string_view name) { - if (name.starts_with("_Z")) { - static thread_local char *buf; - if (buf) - free(buf); + static thread_local char *buf; + if (buf) + free(buf); - int status; - buf = abi::__cxa_demangle(std::string(name).c_str(), nullptr, nullptr, - &status); - if (status == 0) - return buf; - - buf = rust_demangle(std::string(name).c_str(), 0); - if (buf) - return buf; - } + // Try to demangle as a Rust symbol. + buf = rust_demangle(std::string(name).c_str(), 0); + if (buf) + return buf; + // Try to demangle as a C++ symbol. + if (std::optional s = cpp_demangle(name)) + return *s; return name; } +std::optional cpp_demangle(std::string_view name) { + static thread_local char *buf; + static thread_local size_t buflen; + + if (name.starts_with("_Z")) { + int status; + char *p = abi::__cxa_demangle(std::string(name).c_str(), buf, &buflen, &status); + if (status == 0) { + buf = p; + return p; + } + } + return {}; +} + } // namespace mold diff --git a/elf/passes.cc b/elf/passes.cc index 004bb097..52fb2045 100644 --- a/elf/passes.cc +++ b/elf/passes.cc @@ -1092,8 +1092,9 @@ void apply_version_script(Context &ctx) { } if (!cpp_matcher.empty()) - if (std::optional ver = cpp_matcher.find(demangle(name))) - sym->ver_idx = *ver; + if (std::optional s = cpp_demangle(name)) + if (std::optional ver = cpp_matcher.find(*s)) + sym->ver_idx = *ver; } }); } diff --git a/mold.h b/mold.h index 2f96c8d1..ea37bbe9 100644 --- a/mold.h +++ b/mold.h @@ -554,6 +554,7 @@ std::filesystem::path to_abs_path(std::filesystem::path path); // std::string_view demangle(std::string_view name); +std::optional cpp_demangle(std::string_view name); // // compress.cc