Skip to content

Commit ef06a4a

Browse files
committed
[lldb] Extend FindTypes to optionally search by mangled type name (llvm#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 ed11aa4 commit ef06a4a

File tree

6 files changed

+132
-4
lines changed

6 files changed

+132
-4
lines changed

lldb/include/lldb/Symbol/Type.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ FLAGS_ENUM(TypeQueryOptions){
8282
/// When true, the find types call should stop the query as soon as a single
8383
/// matching type is found. When false, the type query should find all
8484
/// matching types.
85-
e_find_one = (1u << 2),
85+
e_find_one = (1u << 4),
86+
// If set, treat TypeQuery::m_name as a mangled name that should be
87+
// searched.
88+
e_search_by_mangled_name = (1u << 5),
8689
};
8790
LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
8891

@@ -280,6 +283,19 @@ class TypeQuery {
280283
m_options &= (e_exact_match | e_find_one);
281284
}
282285

286+
/// Returns true if the type query is supposed to treat the name to be
287+
/// searched as a mangled name.
288+
bool GetSearchByMangledName() const {
289+
return (m_options & e_search_by_mangled_name) != 0;
290+
}
291+
292+
void SetSearchByMangledName(bool b) {
293+
if (b)
294+
m_options |= e_search_by_mangled_name;
295+
else
296+
m_options &= ~e_search_by_mangled_name;
297+
}
298+
283299
/// Access the internal compiler context array.
284300
///
285301
/// 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
@@ -198,9 +198,9 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const {
198198
return result;
199199
}
200200

201-
const char *DWARFDIE::GetMangledName() const {
201+
const char *DWARFDIE::GetMangledName(bool substitute_name_allowed) const {
202202
if (IsValid())
203-
return m_die->GetMangledName(m_cu);
203+
return m_die->GetMangledName(m_cu, substitute_name_allowed);
204204
else
205205
return nullptr;
206206
}

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
bool IsGenericTrampoline() const;
3434

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

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

2779+
// Since mangled names are unique, we only need to check if the names are
2780+
// the same.
2781+
if (query.GetSearchByMangledName()) {
2782+
if (die.GetMangledName(/*substitute_name_allowed=*/false) !=
2783+
query.GetTypeBasename().GetStringRef())
2784+
return true; // Keep iterating over index types, mangled name mismatch.
2785+
if (Type *matching_type = ResolveType(die, true, true)) {
2786+
results.InsertUnique(matching_type->shared_from_this());
2787+
return !results.Done(query); // Keep iterating if we aren't done.
2788+
}
2789+
return true; // Keep iterating over index types, weren't able to resolve
2790+
// this type
2791+
}
2792+
27792793
// Check the context matches
27802794
std::vector<lldb_private::CompilerContext> die_context;
27812795
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 "
@@ -463,6 +469,9 @@ static lldb::DescriptionLevel GetDescriptionLevel() {
463469
}
464470

465471
Error opts::symbols::findFunctions(lldb_private::Module &Module) {
472+
if (!MangledName.empty())
473+
return make_string_error("Cannot search functions by mangled name.");
474+
466475
SymbolFile &Symfile = *Module.GetSymbolFile();
467476
SymbolContextList List;
468477
auto compiler_context = parseCompilerContext();
@@ -524,6 +533,8 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
524533
assert(!Regex);
525534
assert(!File.empty());
526535
assert(Line != 0);
536+
if (!MangledName.empty())
537+
return make_string_error("Cannot search blocks by mangled name.");
527538

528539
SymbolContextList List;
529540

@@ -558,6 +569,9 @@ Error opts::symbols::findBlocks(lldb_private::Module &Module) {
558569
}
559570

560571
Error opts::symbols::findNamespaces(lldb_private::Module &Module) {
572+
if (!MangledName.empty())
573+
return make_string_error("Cannot search namespaces by mangled name.");
574+
561575
SymbolFile &Symfile = *Module.GetSymbolFile();
562576
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
563577
if (!ContextOr)
@@ -580,8 +594,12 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
580594
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
581595
if (!ContextOr)
582596
return ContextOr.takeError();
597+
;
583598

584599
TypeResults results;
600+
if (!Name.empty() && !MangledName.empty())
601+
return make_string_error("Cannot search by both name and mangled name.");
602+
585603
if (!Name.empty()) {
586604
if (ContextOr->IsValid()) {
587605
TypeQuery query(*ContextOr, ConstString(Name),
@@ -595,6 +613,20 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
595613
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
596614
Symfile.FindTypes(query, results);
597615
}
616+
} else if (!MangledName.empty()) {
617+
Opts = TypeQueryOptions::e_search_by_mangled_name;
618+
if (ContextOr->IsValid()) {
619+
TypeQuery query(*ContextOr, ConstString(MangledName), Opts);
620+
if (!Language.empty())
621+
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
622+
Symfile.FindTypes(query, results);
623+
} else {
624+
TypeQuery query(MangledName, Opts);
625+
if (!Language.empty())
626+
query.AddLanguage(Language::GetLanguageTypeFromString(Language));
627+
Symfile.FindTypes(query, results);
628+
}
629+
598630
} else {
599631
TypeQuery query(parseCompilerContext(), TypeQueryOptions::e_module_search);
600632
if (!Language.empty())
@@ -612,6 +644,9 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
612644
}
613645

614646
Error opts::symbols::findVariables(lldb_private::Module &Module) {
647+
if (!MangledName.empty())
648+
return make_string_error("Cannot search variables by mangled name.");
649+
615650
SymbolFile &Symfile = *Module.GetSymbolFile();
616651
VariableList List;
617652
if (Regex) {

0 commit comments

Comments
 (0)