[Lldb-commits] [lldb] d6b9028 - [lldb] Extend FindTypes to optionally search by mangled type name (#113007)

via lldb-commits lldb-commits at lists.llvm.org
Thu Oct 31 09:46:01 PDT 2024


Author: Augusto Noronha
Date: 2024-10-31T09:45:58-07:00
New Revision: d6b90282578f607dc18e23197d9494ebbb899437

URL: https://github.com/llvm/llvm-project/commit/d6b90282578f607dc18e23197d9494ebbb899437
DIFF: https://github.com/llvm/llvm-project/commit/d6b90282578f607dc18e23197d9494ebbb899437.diff

LOG: [lldb] Extend FindTypes to optionally search by mangled type name (#113007)

Swift types have mangled type names. This adds functionality to look up
those types through the FindTypes API by searching for the mangled type
name instead of the regular name.

Added: 
    lldb/test/Shell/SymbolFile/DWARF/debug-types-mangled-name.ll

Modified: 
    lldb/include/lldb/Symbol/Type.h
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
    lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/tools/lldb-test/lldb-test.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 03d9f927997476..91188fe6ea4830 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -84,6 +84,9 @@ FLAGS_ENUM(TypeQueryOptions){
     /// matching type is found. When false, the type query should find all
     /// matching types.
     e_find_one = (1u << 4),
+    // If set, treat TypeQuery::m_name as a mangled name that should be
+    // searched.
+    e_search_by_mangled_name = (1u << 5),
 };
 LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
 
@@ -300,6 +303,19 @@ class TypeQuery {
       m_options &= ~e_find_one;
   }
 
+  /// Returns true if the type query is supposed to treat the name to be
+  /// searched as a mangled name.
+  bool GetSearchByMangledName() const {
+    return (m_options & e_search_by_mangled_name) != 0;
+  }
+
+  void SetSearchByMangledName(bool b) {
+    if (b)
+      m_options |= e_search_by_mangled_name;
+    else
+      m_options &= ~e_search_by_mangled_name;
+  }
+
   /// Access the internal compiler context array.
   ///
   /// Clients can use this to populate the context manually.

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index d83740f8e2113b..4c9f1d8505f6e6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -199,9 +199,9 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
   return result;
 }
 
-const char *DWARFDIE::GetMangledName() const {
+const char *DWARFDIE::GetMangledName(bool substitute_name_allowed) const {
   if (IsValid())
-    return m_die->GetMangledName(m_cu);
+    return m_die->GetMangledName(m_cu, substitute_name_allowed);
   else
     return nullptr;
 }

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index e1318953a384cd..077b78eb26d0c3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -28,7 +28,7 @@ class DWARFDIE : public DWARFBaseDIE {
   // Accessors
 
   // Accessing information about a DIE
-  const char *GetMangledName() const;
+  const char *GetMangledName(bool substitute_name_allowed = true) const;
 
   const char *GetPubname() const;
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index f23f8cc3d781d0..f39189b6cead42 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2758,6 +2758,20 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
         return true; // Keep iterating over index types, language mismatch.
     }
 
+    // Since mangled names are unique, we only need to check if the names are
+    // the same.
+    if (query.GetSearchByMangledName()) {
+      if (die.GetMangledName(/*substitute_name_allowed=*/false) !=
+          query.GetTypeBasename().GetStringRef())
+        return true; // Keep iterating over index types, mangled name mismatch.
+      if (Type *matching_type = ResolveType(die, true, true)) {
+        results.InsertUnique(matching_type->shared_from_this());
+        return !results.Done(query); // Keep iterating if we aren't done.
+      }
+      return true; // Keep iterating over index types, weren't able to resolve
+                   // this type
+    }
+
     // Check the context matches
     std::vector<lldb_private::CompilerContext> die_context;
     if (query.GetModuleSearch())

diff  --git a/lldb/test/Shell/SymbolFile/DWARF/debug-types-mangled-name.ll b/lldb/test/Shell/SymbolFile/DWARF/debug-types-mangled-name.ll
new file mode 100644
index 00000000000000..06dd817fc0f392
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/debug-types-mangled-name.ll
@@ -0,0 +1,63 @@
+; Test finding types by CompilerContext.
+; REQUIRES: aarch64
+; RUN: llc %s -filetype=obj -o %t.o
+; RUN: lldb-test symbols %t.o -find=type --mangled-name=UniqueDifferentName | FileCheck %s 
+;
+; NORESULTS: Found 0 types
+; CHECK: Found 1 types:
+; CHECK: struct DifferentName {
+; CHECK-NEXT:     int i;
+; CHECK-NEXT: }
+
+source_filename = "t.c"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "arm64-unknown-linux-gnu"
+
+%struct.SameName = type { i32 }
+%struct.DifferentName = type { i32 }
+
+; Function Attrs: noinline nounwind optnone uwtable
+define dso_local i32 @main() #0 !dbg !10 {
+entry:
+  %retval = alloca i32, align 4
+  %s = alloca %struct.SameName, align 4
+  %d = alloca %struct.DifferentName, align 4
+  store i32 0, ptr %retval, align 4
+    #dbg_declare(ptr %s, !16, !DIExpression(), !20)
+    #dbg_declare(ptr %d, !21, !DIExpression(), !25)
+  ret i32 0, !dbg !26
+}
+
+attributes #0 = { noinline  optnone  }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
+!llvm.ident = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "t.c", directory: "/")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 8, !"PIC Level", i32 2}
+!6 = !{i32 7, !"PIE Level", i32 2}
+!7 = !{i32 7, !"uwtable", i32 2}
+!8 = !{i32 7, !"frame-pointer", i32 1}
+!9 = !{!""}
+!10 = distinct !DISubprogram(name: "main", scope: !11, file: !11, line: 9, type: !12, scopeLine: 9, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !15)
+!11 = !DIFile(filename: "t.c", directory: "")
+!12 = !DISubroutineType(types: !13)
+!13 = !{!14}
+!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!15 = !{}
+!16 = !DILocalVariable(name: "s", scope: !10, file: !11, line: 10, type: !17)
+!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !11, line: 1, size: 32, elements: !18, runtimeLang: DW_LANG_Swift, identifier: "SameName")
+!18 = !{!19}
+!19 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !17, file: !11, line: 2, baseType: !14, size: 32)
+!20 = !DILocation(line: 10, column: 19, scope: !10)
+!21 = !DILocalVariable(name: "d", scope: !10, file: !11, line: 11, type: !22)
+!22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !11, line: 5, size: 32, elements: !23, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
+!23 = !{!24}
+!24 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !22, file: !11, line: 6, baseType: !14, size: 32)
+!25 = !DILocation(line: 11, column: 24, scope: !10)
+!26 = !DILocation(line: 12, column: 3, scope: !10)

diff  --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index 50b85d4b51209c..1960240dc41514 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -13,6 +13,7 @@
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
 #include "lldb/Breakpoint/BreakpointLocation.h"
 #include "lldb/Core/Debugger.h"
+#include "lldb/Core/Mangled.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Expression/IRMemoryMap.h"
@@ -23,6 +24,7 @@
 #include "lldb/Symbol/LineTable.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/Symtab.h"
+#include "lldb/Symbol/Type.h"
 #include "lldb/Symbol/TypeList.h"
 #include "lldb/Symbol/TypeMap.h"
 #include "lldb/Symbol/VariableList.h"
@@ -179,6 +181,10 @@ static cl::opt<FindType> Find(
 
 static cl::opt<std::string> Name("name", cl::desc("Name to find."),
                                  cl::sub(SymbolsSubcommand));
+static cl::opt<std::string> MangledName(
+    "mangled-name",
+    cl::desc("Mangled name to find. Only compatible when searching types"),
+    cl::sub(SymbolsSubcommand));
 static cl::opt<bool>
     Regex("regex",
           cl::desc("Search using regular expressions (available for variables "
@@ -468,6 +474,9 @@ static lldb::DescriptionLevel GetDescriptionLevel() {
 }
 
 Error opts::symbols::findFunctions(lldb_private::Module &Module) {
+  if (!MangledName.empty())
+    return make_string_error("Cannot search functions by mangled name.");
+
   SymbolFile &Symfile = *Module.GetSymbolFile();
   SymbolContextList List;
   auto compiler_context = parseCompilerContext();
@@ -529,6 +538,8 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
   assert(!Regex);
   assert(!File.empty());
   assert(Line != 0);
+  if (!MangledName.empty())
+    return make_string_error("Cannot search blocks by mangled name.");
 
   SymbolContextList List;
 
@@ -563,6 +574,9 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
 }
 
 Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
+  if (!MangledName.empty())
+    return make_string_error("Cannot search namespaces by mangled name.");
+
   SymbolFile &Symfile = *Module.GetSymbolFile();
   Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
   if (!ContextOr)
@@ -585,11 +599,15 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
   Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
   if (!ContextOr)
     return ContextOr.takeError();
+  ;
 
   TypeQueryOptions Opts = TypeQueryOptions::e_module_search;
   if (FindInAnyModule)
     Opts |= TypeQueryOptions::e_ignore_modules;
   TypeResults results;
+  if (!Name.empty() && !MangledName.empty())
+    return make_string_error("Cannot search by both name and mangled name.");
+
   if (!Name.empty()) {
     if (ContextOr->IsValid()) {
       TypeQuery query(*ContextOr, ConstString(Name), Opts);
@@ -602,6 +620,20 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
         query.AddLanguage(Language::GetLanguageTypeFromString(Language));
       Symfile.FindTypes(query, results);
     }
+  } else if (!MangledName.empty()) {
+    Opts = TypeQueryOptions::e_search_by_mangled_name;
+    if (ContextOr->IsValid()) {
+      TypeQuery query(*ContextOr, ConstString(MangledName), Opts);
+      if (!Language.empty())
+        query.AddLanguage(Language::GetLanguageTypeFromString(Language));
+      Symfile.FindTypes(query, results);
+    } else {
+      TypeQuery query(MangledName, Opts);
+      if (!Language.empty())
+        query.AddLanguage(Language::GetLanguageTypeFromString(Language));
+      Symfile.FindTypes(query, results);
+    }
+
   } else {
     TypeQuery query(parseCompilerContext(), Opts);
     if (!Language.empty())
@@ -619,6 +651,9 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
 }
 
 Error opts::symbols::findVariables(lldb_private::Module &Module) {
+  if (!MangledName.empty())
+    return make_string_error("Cannot search variables by mangled name.");
+
   SymbolFile &Symfile = *Module.GetSymbolFile();
   VariableList List;
   if (Regex) {


        


More information about the lldb-commits mailing list