Skip to content

Commit d6b9028

Browse files
authored
[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.
1 parent d12a8da commit d6b9028

File tree

6 files changed

+131
-3
lines changed

6 files changed

+131
-3
lines changed

lldb/include/lldb/Symbol/Type.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,9 @@ FLAGS_ENUM(TypeQueryOptions){
8484
/// matching type is found. When false, the type query should find all
8585
/// matching types.
8686
e_find_one = (1u << 4),
87+
// If set, treat TypeQuery::m_name as a mangled name that should be
88+
// searched.
89+
e_search_by_mangled_name = (1u << 5),
8790
};
8891
LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
8992

@@ -300,6 +303,19 @@ class TypeQuery {
300303
m_options &= ~e_find_one;
301304
}
302305

306+
/// Returns true if the type query is supposed to treat the name to be
307+
/// searched as a mangled name.
308+
bool GetSearchByMangledName() const {
309+
return (m_options & e_search_by_mangled_name) != 0;
310+
}
311+
312+
void SetSearchByMangledName(bool b) {
313+
if (b)
314+
m_options |= e_search_by_mangled_name;
315+
else
316+
m_options &= ~e_search_by_mangled_name;
317+
}
318+
303319
/// Access the internal compiler context array.
304320
///
305321
/// Clients can use this to populate the context manually.

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
199199
return result;
200200
}
201201

202-
const char *DWARFDIE::GetMangledName() const {
202+
const char *DWARFDIE::GetMangledName(bool substitute_name_allowed) const {
203203
if (IsValid())
204-
return m_die->GetMangledName(m_cu);
204+
return m_die->GetMangledName(m_cu, substitute_name_allowed);
205205
else
206206
return nullptr;
207207
}

lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class DWARFDIE : public DWARFBaseDIE {
2828
// Accessors
2929

3030
// Accessing information about a DIE
31-
const char *GetMangledName() const;
31+
const char *GetMangledName(bool substitute_name_allowed = true) const;
3232

3333
const char *GetPubname() const;
3434

lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2758,6 +2758,20 @@ void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
27582758
return true; // Keep iterating over index types, language mismatch.
27592759
}
27602760

2761+
// Since mangled names are unique, we only need to check if the names are
2762+
// the same.
2763+
if (query.GetSearchByMangledName()) {
2764+
if (die.GetMangledName(/*substitute_name_allowed=*/false) !=
2765+
query.GetTypeBasename().GetStringRef())
2766+
return true; // Keep iterating over index types, mangled name mismatch.
2767+
if (Type *matching_type = ResolveType(die, true, true)) {
2768+
results.InsertUnique(matching_type->shared_from_this());
2769+
return !results.Done(query); // Keep iterating if we aren't done.
2770+
}
2771+
return true; // Keep iterating over index types, weren't able to resolve
2772+
// this type
2773+
}
2774+
27612775
// Check the context matches
27622776
std::vector<lldb_private::CompilerContext> die_context;
27632777
if (query.GetModuleSearch())
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
; Test finding types by CompilerContext.
2+
; REQUIRES: aarch64
3+
; RUN: llc %s -filetype=obj -o %t.o
4+
; RUN: lldb-test symbols %t.o -find=type --mangled-name=UniqueDifferentName | FileCheck %s
5+
;
6+
; NORESULTS: Found 0 types
7+
; CHECK: Found 1 types:
8+
; CHECK: struct DifferentName {
9+
; CHECK-NEXT: int i;
10+
; CHECK-NEXT: }
11+
12+
source_filename = "t.c"
13+
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"
14+
target triple = "arm64-unknown-linux-gnu"
15+
16+
%struct.SameName = type { i32 }
17+
%struct.DifferentName = type { i32 }
18+
19+
; Function Attrs: noinline nounwind optnone uwtable
20+
define dso_local i32 @main() #0 !dbg !10 {
21+
entry:
22+
%retval = alloca i32, align 4
23+
%s = alloca %struct.SameName, align 4
24+
%d = alloca %struct.DifferentName, align 4
25+
store i32 0, ptr %retval, align 4
26+
#dbg_declare(ptr %s, !16, !DIExpression(), !20)
27+
#dbg_declare(ptr %d, !21, !DIExpression(), !25)
28+
ret i32 0, !dbg !26
29+
}
30+
31+
attributes #0 = { noinline optnone }
32+
33+
!llvm.dbg.cu = !{!0}
34+
!llvm.module.flags = !{!2, !3, !4, !5, !6, !7, !8}
35+
!llvm.ident = !{!9}
36+
37+
!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
38+
!1 = !DIFile(filename: "t.c", directory: "/")
39+
!2 = !{i32 7, !"Dwarf Version", i32 5}
40+
!3 = !{i32 2, !"Debug Info Version", i32 3}
41+
!4 = !{i32 1, !"wchar_size", i32 4}
42+
!5 = !{i32 8, !"PIC Level", i32 2}
43+
!6 = !{i32 7, !"PIE Level", i32 2}
44+
!7 = !{i32 7, !"uwtable", i32 2}
45+
!8 = !{i32 7, !"frame-pointer", i32 1}
46+
!9 = !{!""}
47+
!10 = distinct !DISubprogram(name: "main", scope: !11, file: !11, line: 9, type: !12, scopeLine: 9, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !15)
48+
!11 = !DIFile(filename: "t.c", directory: "")
49+
!12 = !DISubroutineType(types: !13)
50+
!13 = !{!14}
51+
!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
52+
!15 = !{}
53+
!16 = !DILocalVariable(name: "s", scope: !10, file: !11, line: 10, type: !17)
54+
!17 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !11, line: 1, size: 32, elements: !18, runtimeLang: DW_LANG_Swift, identifier: "SameName")
55+
!18 = !{!19}
56+
!19 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !17, file: !11, line: 2, baseType: !14, size: 32)
57+
!20 = !DILocation(line: 10, column: 19, scope: !10)
58+
!21 = !DILocalVariable(name: "d", scope: !10, file: !11, line: 11, type: !22)
59+
!22 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !11, line: 5, size: 32, elements: !23, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
60+
!23 = !{!24}
61+
!24 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !22, file: !11, line: 6, baseType: !14, size: 32)
62+
!25 = !DILocation(line: 11, column: 24, scope: !10)
63+
!26 = !DILocation(line: 12, column: 3, scope: !10)

lldb/tools/lldb-test/lldb-test.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
1414
#include "lldb/Breakpoint/BreakpointLocation.h"
1515
#include "lldb/Core/Debugger.h"
16+
#include "lldb/Core/Mangled.h"
1617
#include "lldb/Core/Module.h"
1718
#include "lldb/Core/Section.h"
1819
#include "lldb/Expression/IRMemoryMap.h"
@@ -23,6 +24,7 @@
2324
#include "lldb/Symbol/LineTable.h"
2425
#include "lldb/Symbol/SymbolFile.h"
2526
#include "lldb/Symbol/Symtab.h"
27+
#include "lldb/Symbol/Type.h"
2628
#include "lldb/Symbol/TypeList.h"
2729
#include "lldb/Symbol/TypeMap.h"
2830
#include "lldb/Symbol/VariableList.h"
@@ -179,6 +181,10 @@ static cl::opt<FindType> Find(
179181

180182
static cl::opt<std::string> Name("name", cl::desc("Name to find."),
181183
cl::sub(SymbolsSubcommand));
184+
static cl::opt<std::string> MangledName(
185+
"mangled-name",
186+
cl::desc("Mangled name to find. Only compatible when searching types"),
187+
cl::sub(SymbolsSubcommand));
182188
static cl::opt<bool>
183189
Regex("regex",
184190
cl::desc("Search using regular expressions (available for variables "
@@ -468,6 +474,9 @@ static lldb::DescriptionLevel GetDescriptionLevel() {
468474
}
469475

470476
Error opts::symbols::findFunctions(lldb_private::Module &Module) {
477+
if (!MangledName.empty())
478+
return make_string_error("Cannot search functions by mangled name.");
479+
471480
SymbolFile &Symfile = *Module.GetSymbolFile();
472481
SymbolContextList List;
473482
auto compiler_context = parseCompilerContext();
@@ -529,6 +538,8 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
529538
assert(!Regex);
530539
assert(!File.empty());
531540
assert(Line != 0);
541+
if (!MangledName.empty())
542+
return make_string_error("Cannot search blocks by mangled name.");
532543

533544
SymbolContextList List;
534545

@@ -563,6 +574,9 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
563574
}
564575

565576
Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
577+
if (!MangledName.empty())
578+
return make_string_error("Cannot search namespaces by mangled name.");
579+
566580
SymbolFile &Symfile = *Module.GetSymbolFile();
567581
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
568582
if (!ContextOr)
@@ -585,11 +599,15 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
585599
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
586600
if (!ContextOr)
587601
return ContextOr.takeError();
602+
;
588603

589604
TypeQueryOptions Opts = TypeQueryOptions::e_module_search;
590605
if (FindInAnyModule)
591606
Opts |= TypeQueryOptions::e_ignore_modules;
592607
TypeResults results;
608+
if (!Name.empty() && !MangledName.empty())
609+
return make_string_error("Cannot search by both name and mangled name.");
610+
593611
if (!Name.empty()) {
594612
if (ContextOr->IsValid()) {
595613
TypeQuery query(*ContextOr, ConstString(Name), Opts);
@@ -602,6 +620,20 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
602620
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
603621
Symfile.FindTypes(query, results);
604622
}
623+
} else if (!MangledName.empty()) {
624+
Opts = TypeQueryOptions::e_search_by_mangled_name;
625+
if (ContextOr->IsValid()) {
626+
TypeQuery query(*ContextOr, ConstString(MangledName), Opts);
627+
if (!Language.empty())
628+
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
629+
Symfile.FindTypes(query, results);
630+
} else {
631+
TypeQuery query(MangledName, Opts);
632+
if (!Language.empty())
633+
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
634+
Symfile.FindTypes(query, results);
635+
}
636+
605637
} else {
606638
TypeQuery query(parseCompilerContext(), Opts);
607639
if (!Language.empty())
@@ -619,6 +651,9 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
619651
}
620652

621653
Error opts::symbols::findVariables(lldb_private::Module &Module) {
654+
if (!MangledName.empty())
655+
return make_string_error("Cannot search variables by mangled name.");
656+
622657
SymbolFile &Symfile = *Module.GetSymbolFile();
623658
VariableList List;
624659
if (Regex) {

0 commit comments

Comments
 (0)