aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTed Mielczarek <ted@mielczarek.org>2016-10-24 15:16:28 -0400
committerTed Mielczarek <ted@mielczarek.org>2016-10-25 10:43:00 +0000
commit2ecb2baba829a7ed4fff4bc60edf0c1643dc129c (patch)
tree4106bbadd878c7148c9393e33d5bf5cbb3024f2b /src
parentFix iterating over the MDXStateFeature entries on 32-bit hosts (diff)
downloadbreakpad-2ecb2baba829a7ed4fff4bc60edf0c1643dc129c.tar.xz
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>
Diffstat (limited to 'src')
-rw-r--r--src/common/dwarf/dwarf2enums.h1
-rw-r--r--src/common/dwarf_cu_to_module.cc4
-rw-r--r--src/common/dwarf_cu_to_module_unittest.cc48
-rw-r--r--src/common/language.cc39
-rw-r--r--src/common/language.h1
5 files changed, 93 insertions, 0 deletions
diff --git a/src/common/dwarf/dwarf2enums.h b/src/common/dwarf/dwarf2enums.h
index 09567555..4316a89c 100644
--- a/src/common/dwarf/dwarf2enums.h
+++ b/src/common/dwarf/dwarf2enums.h
@@ -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,
diff --git a/src/common/dwarf_cu_to_module.cc b/src/common/dwarf_cu_to_module.cc
index 100f3962..8d874366 100644
--- a/src/common/dwarf_cu_to_module.cc
+++ b/src/common/dwarf_cu_to_module.cc
@@ -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:
diff --git a/src/common/dwarf_cu_to_module_unittest.cc b/src/common/dwarf_cu_to_module_unittest.cc
index e789f9da..2ce4a609 100644
--- a/src/common/dwarf_cu_to_module_unittest.cc
+++ b/src/common/dwarf_cu_to_module_unittest.cc
@@ -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);
diff --git a/src/common/language.cc b/src/common/language.cc
index 087395e9..09eaceb6 100644
--- a/src/common/language.cc
+++ b/src/common/language.cc
@@ -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
diff --git a/src/common/language.h b/src/common/language.h
index 05786199..4ebea1ab 100644
--- a/src/common/language.h
+++ b/src/common/language.h
@@ -96,6 +96,7 @@ class Language {
static const Language * const CPlusPlus,
* const Java,
* const Swift,
+ * const Rust,
* const Assembler;
};