asm created this revision.
asm added reviewers: clayborg, wallace.
Herald added subscribers: pengfei, JDevlieghere.
asm requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

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]: https://github.com/rust-lang/rust/issues/60705


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D104054

Files:
  lldb/include/lldb/Core/Mangled.h
  lldb/source/Core/Mangled.cpp
  lldb/source/Symbol/Symtab.cpp
  lldb/unittests/Core/MangledTest.cpp

Index: lldb/unittests/Core/MangledTest.cpp
===================================================================
--- lldb/unittests/Core/MangledTest.cpp
+++ lldb/unittests/Core/MangledTest.cpp
@@ -55,6 +55,23 @@
   EXPECT_STREQ("", TheDemangled.GetCString());
 }
 
+TEST(MangledTest, ResultForValidRustV0Name) {
+  ConstString MangledName("_RNvC1a4main");
+  Mangled TheMangled(MangledName);
+  ConstString TheDemangled = TheMangled.GetDemangledName();
+
+  ConstString ExpectedResult("a::main");
+  EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());
+}
+
+TEST(MangledTest, EmptyForInvalidRustV0Name) {
+  ConstString MangledName("_RRR");
+  Mangled TheMangled(MangledName);
+  ConstString TheDemangled = TheMangled.GetDemangledName();
+
+  EXPECT_STREQ("", TheDemangled.GetCString());
+}
+
 TEST(MangledTest, NameIndexes_FindFunctionSymbols) {
   SubsystemRAII<FileSystem, HostInfo, ObjectFileELF, SymbolFileSymtab>
       subsystems;
Index: lldb/source/Symbol/Symtab.cpp
===================================================================
--- lldb/source/Symbol/Symtab.cpp
+++ lldb/source/Symbol/Symtab.cpp
@@ -240,6 +240,10 @@
   case Mangled::eManglingSchemeMSVC:
     return false;
 
+  // No filters for this scheme yet. Include all names in indexing.
+  case Mangled::eManglingSchemeRustV0:
+    return false;
+
   // Don't try and demangle things we can't categorize.
   case Mangled::eManglingSchemeNone:
     return true;
Index: lldb/source/Core/Mangled.cpp
===================================================================
--- lldb/source/Core/Mangled.cpp
+++ lldb/source/Core/Mangled.cpp
@@ -72,6 +72,9 @@
   if (name.startswith("?"))
     return Mangled::eManglingSchemeMSVC;
 
+  if (name.startswith("_R"))
+    return Mangled::eManglingSchemeRustV0;
+
   if (name.startswith("_Z"))
     return Mangled::eManglingSchemeItanium;
 
@@ -199,6 +202,20 @@
   return demangled_cstr;
 }
 
+static char *GetRustV0DemangledStr(const char *M) {
+  char *demangled_cstr = llvm::rustDemangle(
+      M, nullptr, nullptr, nullptr);
+
+  if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) {
+    if (demangled_cstr && demangled_cstr[0])
+      LLDB_LOGF(log, "demangled rustv0: %s -> \"%s\"", M, demangled_cstr);
+    else
+      LLDB_LOGF(log, "demangled rustv0: %s -> error: failed to demangle", M);
+  }
+
+  return demangled_cstr;
+}
+
 // Explicit demangling for scheduled requests during batch processing. This
 // makes use of ItaniumPartialDemangler's rich demangle info
 bool Mangled::DemangleWithRichManglingInfo(
@@ -256,6 +273,10 @@
       return context.FromCxxMethodName(m_demangled);
     }
   }
+
+  case eManglingSchemeRustV0:
+    // Rich demangling scheme is not supported for Rust
+    return false;
   }
   llvm_unreachable("Fully covered switch above!");
 }
@@ -284,6 +305,9 @@
         demangled_name = GetItaniumDemangledStr(mangled_name);
         break;
       }
+      case eManglingSchemeRustV0:
+        demangled_name = GetRustV0DemangledStr(mangled_name);
+        break;
       case eManglingSchemeNone:
         llvm_unreachable("eManglingSchemeNone was handled already");
       }
Index: lldb/include/lldb/Core/Mangled.h
===================================================================
--- lldb/include/lldb/Core/Mangled.h
+++ lldb/include/lldb/Core/Mangled.h
@@ -43,7 +43,8 @@
   enum ManglingScheme {
     eManglingSchemeNone = 0,
     eManglingSchemeMSVC,
-    eManglingSchemeItanium
+    eManglingSchemeItanium,
+    eManglingSchemeRustV0
   };
 
   /// Default constructor.
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to