Don't demangle Rust symbols by default, but allow linking to rust-demangle.

The Rust compiler uses GCC C++ name mangling, but it has another layer of
encoding so abi::cxa_demangle doesn't produce great results. This patch
changes dump_syms to dump unmangled names by default so that consumers can
demangle them after-the-fact.

It also adds a tiny bit of support for linking against a Rust library I wrote
that can demangle Rust symbols nicely:
https://github.com/luser/rust-demangle-capi

BUG=

Change-Id: I63a425035ebb7ac516f067fed2aa782849ea9604
Reviewed-on: https://chromium-review.googlesource.com/402308
Reviewed-by: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Ted Mielczarek 2016-10-24 15:16:28 -04:00
parent e6d1c032ba
commit 2ecb2baba8
9 changed files with 552 additions and 55 deletions

View file

@ -544,6 +544,7 @@ enum DwarfLanguage
DW_LANG_ObjC_plus_plus =0x0011,
DW_LANG_UPC =0x0012,
DW_LANG_D =0x0013,
DW_LANG_Rust =0x001c,
DW_LANG_Swift =0x001e,
// Implementation-defined language code range.
DW_LANG_lo_user = 0x8000,

View file

@ -777,6 +777,10 @@ void DwarfCUToModule::SetLanguage(DwarfLanguage language) {
cu_context_->language = Language::Swift;
break;
case dwarf2reader::DW_LANG_Rust:
cu_context_->language = Language::Rust;
break;
// DWARF has no generic language code for assembly language; this is
// what the GNU toolchain uses.
case dwarf2reader::DW_LANG_Mips_Assembler:

View file

@ -1205,6 +1205,7 @@ TEST_F(Specifications, Function) {
}
TEST_F(Specifications, MangledName) {
// Language defaults to C++, so no need to set it here.
PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);
StartCU();
@ -1221,6 +1222,53 @@ TEST_F(Specifications, MangledName) {
0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}
TEST_F(Specifications, MangledNameSwift) {
// Swift mangled names should pass through untouched.
SetLanguage(dwarf2reader::DW_LANG_Swift);
PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);
StartCU();
const string kName = "_TFC9swifttest5Shape17simpleDescriptionfS0_FT_Si";
DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
dwarf2reader::DW_TAG_subprogram, "declaration-name",
kName);
DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
0xcd3c51b946fb1eeeLL, "",
0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
root_handler_.Finish();
TestFunctionCount(1);
TestFunction(0, kName,
0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}
TEST_F(Specifications, MangledNameRust) {
SetLanguage(dwarf2reader::DW_LANG_Rust);
PushLine(0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL, "line-file", 54883661);
StartCU();
const string kName = "_ZN14rustc_demangle8demangle17h373defa94bffacdeE";
DeclarationDIE(&root_handler_, 0xcd3c51b946fb1eeeLL,
dwarf2reader::DW_TAG_subprogram, "declaration-name",
kName);
DefinitionDIE(&root_handler_, dwarf2reader::DW_TAG_subprogram,
0xcd3c51b946fb1eeeLL, "",
0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
root_handler_.Finish();
TestFunctionCount(1);
TestFunction(0,
#ifndef HAVE_RUST_DEMANGLE
// Rust mangled names should pass through untouched if not
// using rust-demangle.
kName,
#else
// If rust-demangle is available this should be properly
// demangled.
"rustc_demangle::demangle",
#endif
0x93cd3dfc1aa10097ULL, 0x0397d47a0b4ca0d4ULL);
}
TEST_F(Specifications, MemberFunction) {
PushLine(0x3341a248634e7170ULL, 0x5f6938ee5553b953ULL, "line-file", 18116691);

View file

@ -40,6 +40,10 @@
#include <cxxabi.h>
#endif
#if defined(HAVE_RUST_DEMANGLE)
#include <rust_demangle.h>
#endif
#include <limits>
namespace {
@ -136,6 +140,40 @@ class SwiftLanguage: public Language {
SwiftLanguage SwiftLanguageSingleton;
// Rust language-specific operations.
class RustLanguage: public Language {
public:
RustLanguage() {}
string MakeQualifiedName(const string &parent_name,
const string &name) const {
return MakeQualifiedNameWithSeparator(parent_name, ".", name);
}
virtual DemangleResult DemangleName(const string& mangled,
std::string* demangled) const {
// Rust names use GCC C++ name mangling, but demangling them with
// abi_demangle doesn't produce stellar results due to them having
// another layer of encoding.
// If callers provide rustc-demangle, use that.
#if defined(HAVE_RUST_DEMANGLE)
char* rust_demangled = rust_demangle(mangled.c_str());
if (rust_demangled == nullptr) {
return kDemangleFailure;
}
demangled->assign(rust_demangled);
free_rust_demangled_name(rust_demangled);
#else
// Otherwise, pass through the mangled name so callers can demangle
// after the fact.
demangled->assign(mangled);
#endif
return kDemangleSuccess;
}
};
RustLanguage RustLanguageSingleton;
// Assembler language-specific operations.
class AssemblerLanguage: public Language {
public:
@ -153,6 +191,7 @@ AssemblerLanguage AssemblerLanguageSingleton;
const Language * const Language::CPlusPlus = &CPPLanguageSingleton;
const Language * const Language::Java = &JavaLanguageSingleton;
const Language * const Language::Swift = &SwiftLanguageSingleton;
const Language * const Language::Rust = &RustLanguageSingleton;
const Language * const Language::Assembler = &AssemblerLanguageSingleton;
} // namespace google_breakpad

View file

@ -96,6 +96,7 @@ class Language {
static const Language * const CPlusPlus,
* const Java,
* const Swift,
* const Rust,
* const Assembler;
};