Skip to content

Commit 7fc51bb

Browse files
committed
[lldb] Extend FindTypes to optionally search by mangled type name
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 ca1154d commit 7fc51bb

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 nounwind optnone uwtable "frame-pointer"="non-leaf" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fp-armv8,+neon,+v8a,-fmv" }
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)