Skip to content

Commit 0a2d4f3

Browse files
asm89Teemperor
authored andcommitted
[lldb] Enable Rust v0 symbol demangling
Rust's v0 name mangling scheme [1] is easy to disambiguate from other name mangling schemes because symbols always start with `_R`. The llvm Demangle library supports demangling the Rust v0 scheme. Use it to demangle Rust symbols. Added unit tests that check simple symbols. Ran LLDB built with this patch to debug some Rust programs compiled with the v0 name mangling scheme. Confirmed symbol names were demangled as expected. Note: enabling the new name mangling scheme requires a nightly toolchain: ``` $ cat main.rs fn main() { println!("Hello world!"); } $ $(rustup which --toolchain nightly rustc) -Z symbol-mangling-version=v0 main.rs -g $ /home/asm/hacking/llvm/build/bin/lldb ./main --one-line 'b main.rs:2' (lldb) target create "./main" Current executable set to '/home/asm/hacking/llvm/rust/main' (x86_64). (lldb) b main.rs:2 Breakpoint 1: where = main`main::main + 4 at main.rs:2:5, address = 0x00000000000076a4 (lldb) r Process 948449 launched: '/home/asm/hacking/llvm/rust/main' (x86_64) warning: (x86_64) /lib64/libgcc_s.so.1 No LZMA support found for reading .gnu_debugdata section Process 948449 stopped * thread #1, name = 'main', stop reason = breakpoint 1.1 frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5 1 fn main() { -> 2 println!("Hello world!"); 3 } (lldb) bt error: need to add support for DW_TAG_base_type '()' encoded with DW_ATE = 0x7, bit_size = 0 * thread #1, name = 'main', stop reason = breakpoint 1.1 * frame #0: 0x000055555555b6a4 main`main::main at main.rs:2:5 frame #1: 0x000055555555b78b main`<fn() as core::ops::function::FnOnce<()>>::call_once((null)=(main`main::main at main.rs:1), (null)=<unavailable>) at function.rs:227:5 frame #2: 0x000055555555b66e main`std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>(f=(main`main::main at main.rs:1)) at backtrace.rs:125:18 frame #3: 0x000055555555b851 main`std::rt::lang_start::<()>::{closure#0} at rt.rs:49:18 frame #4: 0x000055555556c9f9 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] core::ops::function::impls::_$LT$impl$u20$core..ops..function..FnOnce$LT$A$GT$$u20$for$u20$$RF$F$GT$::call_once::h04259e4a34d07c2f at function.rs:259:13 frame #5: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::do_call::hb8da45704d5cfbbf at panicking.rs:401:40 frame #6: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panicking::try::h4beadc19a78fec52 at panicking.rs:365:19 frame #7: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a [inlined] std::panic::catch_unwind::hc58016cd36ba81a4 at panic.rs:433:14 frame #8: 0x000055555556c9f2 main`std::rt::lang_start_internal::hc51399759a90501a at rt.rs:34:21 frame #9: 0x000055555555b830 main`std::rt::lang_start::<()>(main=(main`main::main at main.rs:1), argc=1, argv=0x00007fffffffcb18) at rt.rs:48:5 frame #10: 0x000055555555b6fc main`main + 28 frame #11: 0x00007ffff73f2493 libc.so.6`__libc_start_main + 243 frame #12: 0x000055555555b59e main`_start + 46 (lldb) ``` [1]: rust-lang/rust#60705 Reviewed By: clayborg, teemperor Differential Revision: https://reviews.llvm.org/D104054
1 parent 9699442 commit 0a2d4f3

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

Diff for: lldb/include/lldb/Core/Mangled.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class Mangled {
4343
enum ManglingScheme {
4444
eManglingSchemeNone = 0,
4545
eManglingSchemeMSVC,
46-
eManglingSchemeItanium
46+
eManglingSchemeItanium,
47+
eManglingSchemeRustV0
4748
};
4849

4950
/// Default constructor.

Diff for: lldb/source/Core/Mangled.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) {
7272
if (name.startswith("?"))
7373
return Mangled::eManglingSchemeMSVC;
7474

75+
if (name.startswith("_R"))
76+
return Mangled::eManglingSchemeRustV0;
77+
7578
if (name.startswith("_Z"))
7679
return Mangled::eManglingSchemeItanium;
7780

@@ -199,6 +202,19 @@ static char *GetItaniumDemangledStr(const char *M) {
199202
return demangled_cstr;
200203
}
201204

205+
static char *GetRustV0DemangledStr(const char *M) {
206+
char *demangled_cstr = llvm::rustDemangle(M, nullptr, nullptr, nullptr);
207+
208+
if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
209+
if (demangled_cstr && demangled_cstr[0])
210+
LLDB_LOG(log, "demangled rustv0: {0} -> \"{1}\"", M, demangled_cstr);
211+
else
212+
LLDB_LOG(log, "demangled rustv0: {0} -> error: failed to demangle", M);
213+
}
214+
215+
return demangled_cstr;
216+
}
217+
202218
// Explicit demangling for scheduled requests during batch processing. This
203219
// makes use of ItaniumPartialDemangler's rich demangle info
204220
bool Mangled::DemangleWithRichManglingInfo(
@@ -256,6 +272,10 @@ bool Mangled::DemangleWithRichManglingInfo(
256272
return context.FromCxxMethodName(m_demangled);
257273
}
258274
}
275+
276+
case eManglingSchemeRustV0:
277+
// Rich demangling scheme is not supported for Rust
278+
return false;
259279
}
260280
llvm_unreachable("Fully covered switch above!");
261281
}
@@ -284,6 +304,9 @@ ConstString Mangled::GetDemangledName() const {
284304
demangled_name = GetItaniumDemangledStr(mangled_name);
285305
break;
286306
}
307+
case eManglingSchemeRustV0:
308+
demangled_name = GetRustV0DemangledStr(mangled_name);
309+
break;
287310
case eManglingSchemeNone:
288311
llvm_unreachable("eManglingSchemeNone was handled already");
289312
}

Diff for: lldb/source/Symbol/Symtab.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ static bool lldb_skip_name(llvm::StringRef mangled,
251251
case Mangled::eManglingSchemeMSVC:
252252
return false;
253253

254+
// No filters for this scheme yet. Include all names in indexing.
255+
case Mangled::eManglingSchemeRustV0:
256+
return false;
257+
254258
// Don't try and demangle things we can't categorize.
255259
case Mangled::eManglingSchemeNone:
256260
return true;

Diff for: lldb/unittests/Core/MangledTest.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,23 @@ TEST(MangledTest, EmptyForInvalidName) {
5555
EXPECT_STREQ("", TheDemangled.GetCString());
5656
}
5757

58+
TEST(MangledTest, ResultForValidRustV0Name) {
59+
ConstString mangled_name("_RNvC1a4main");
60+
Mangled the_mangled(mangled_name);
61+
ConstString the_demangled = the_mangled.GetDemangledName();
62+
63+
ConstString expected_result("a::main");
64+
EXPECT_STREQ(expected_result.GetCString(), the_demangled.GetCString());
65+
}
66+
67+
TEST(MangledTest, EmptyForInvalidRustV0Name) {
68+
ConstString mangled_name("_RRR");
69+
Mangled the_mangled(mangled_name);
70+
ConstString the_demangled = the_mangled.GetDemangledName();
71+
72+
EXPECT_STREQ("", the_demangled.GetCString());
73+
}
74+
5875
TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
5976
SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
6077
subsystems;

0 commit comments

Comments
 (0)