Skip to content

Commit 9535e31

Browse files
[lldb][nfc] Create helper functions in SwiftLanguageRuntimeNames
These will be useful to reuse code in upcoming commits.
1 parent c1d18ab commit 9535e31

File tree

1 file changed

+60
-37
lines changed

1 file changed

+60
-37
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeNames.cpp

Lines changed: 60 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -419,6 +419,59 @@ CreateRunThroughTaskSwitchingTrampolines(Thread &thread,
419419
return nullptr;
420420
}
421421

422+
/// Demangle `symbol_name` and extracts the text at the node described by
423+
/// `node_path`, if it exists; otherwise, returns an empty string.
424+
static std::string FindClassName(StringRef symbol_name,
425+
llvm::ArrayRef<Node::Kind> node_path) {
426+
swift::Demangle::Context ctx;
427+
NodePointer demangled_node =
428+
SwiftLanguageRuntime::DemangleSymbolAsNode(symbol_name, ctx);
429+
430+
NodePointer class_node = childAtPath(demangled_node, node_path);
431+
if (!class_node || !class_node->hasText()) {
432+
std::string node_str = getNodeTreeAsString(demangled_node);
433+
LLDB_LOGF(GetLog(LLDBLog::Step),
434+
"SwiftLanguageRuntime: failed to extract name from "
435+
"demangle node: %s",
436+
node_str.c_str());
437+
return "";
438+
}
439+
return class_node->getText().str();
440+
}
441+
442+
/// If sc_list is non-empty, returns a plan that runs to any of its addresses.
443+
/// Otherwise, returns nullptr.
444+
static ThreadPlanSP
445+
CreateThreadPlanRunToSCInList(Thread &thread, const SymbolContextList &sc_list,
446+
bool stop_others) {
447+
std::vector<addr_t> load_addresses;
448+
Target &target = thread.GetProcess()->GetTarget();
449+
for (const SymbolContext &sc : sc_list) {
450+
const Symbol *ctor_symbol = sc.symbol;
451+
if (ctor_symbol)
452+
load_addresses.push_back(ctor_symbol->GetLoadAddress(&target));
453+
}
454+
455+
if (load_addresses.empty()) {
456+
LLDB_LOG(GetLog(LLDBLog::Step),
457+
"SwiftLanguageRuntime: empty sc_list found.");
458+
return {};
459+
}
460+
return std::make_shared<ThreadPlanRunToAddress>(thread, load_addresses,
461+
stop_others);
462+
}
463+
464+
/// Search all modules for `target_func` and creates a RunToAddress plan
465+
/// targeting all symbols found.
466+
static ThreadPlanSP CreateRunToAddressPlan(StringRef target_func,
467+
Thread &thread, bool stop_others) {
468+
ModuleList modules = thread.GetProcess()->GetTarget().GetImages();
469+
SymbolContextList sc_list;
470+
modules.FindFunctionSymbols(ConstString(target_func), eFunctionNameTypeFull,
471+
sc_list);
472+
return CreateThreadPlanRunToSCInList(thread, sc_list, stop_others);
473+
}
474+
422475
static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
423476
bool stop_others) {
424477
// Here are the trampolines we have at present.
@@ -475,19 +528,7 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
475528
log->Printf(
476529
"Stepped to thunk \"%s\" (kind: %s) stepping to target: \"%s\".",
477530
symbol_name, GetThunkKindName(thunk_kind), thunk_target.c_str());
478-
479-
ModuleList modules = thread.GetProcess()->GetTarget().GetImages();
480-
SymbolContextList sc_list;
481-
modules.FindFunctionSymbols(ConstString(thunk_target),
482-
eFunctionNameTypeFull, sc_list);
483-
if (sc_list.GetSize() == 1 && sc_list[0].symbol) {
484-
Symbol &thunk_symbol = *sc_list[0].symbol;
485-
Address target_address = thunk_symbol.GetAddress();
486-
if (target_address.IsValid())
487-
return std::make_shared<ThreadPlanRunToAddress>(thread, target_address,
488-
stop_others);
489-
}
490-
return nullptr;
531+
return CreateRunToAddressPlan(thunk_target, thread, stop_others);
491532
}
492533
case ThunkAction::StepIntoConformance: {
493534
// The TTW symbols encode the protocol conformance requirements
@@ -582,37 +623,19 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
582623
}
583624
case ThunkAction::StepIntoAllocatingInit: {
584625
LLDB_LOGF(log, "Stepping into allocating init: \"%s\"", symbol_name);
585-
swift::Demangle::Context ctx;
586-
NodePointer demangled_node =
587-
SwiftLanguageRuntime::DemangleSymbolAsNode(symbol_name, ctx);
588-
589626
using Kind = Node::Kind;
590-
NodePointer class_node = childAtPath(
591-
demangled_node, {Kind::Allocator, Kind::Class, Kind::Identifier});
592-
if (!class_node || !class_node->hasText()) {
593-
std::string node_str = getNodeTreeAsString(demangled_node);
594-
LLDB_LOGF(log,
595-
"Failed to extract constructor name from demangle node: %s",
596-
node_str.c_str());
627+
static constexpr auto class_path = {Kind::Allocator, Kind::Class,
628+
Kind::Identifier};
629+
std::string class_name = FindClassName(symbol_name, class_path);
630+
if (class_name.empty())
597631
return nullptr;
598-
}
599632

600633
ModuleFunctionSearchOptions options{/*include_symbols*/ true,
601634
/*include_inlines*/ true};
602-
std::string ctor_name = llvm::formatv("{0}.init", class_node->getText());
635+
std::string ctor_name = llvm::formatv("{0}.init", class_name);
603636
SymbolContextList sc_list;
604637
sc.module_sp->FindFunctions(RegularExpression(ctor_name), options, sc_list);
605-
std::vector<addr_t> load_addresses;
606-
Target &target = thread.GetProcess()->GetTarget();
607-
for (const SymbolContext &ctor_sc : sc_list) {
608-
const Symbol *ctor_symbol = ctor_sc.symbol;
609-
if (ctor_symbol)
610-
load_addresses.push_back(ctor_symbol->GetLoadAddress(&target));
611-
}
612-
if (load_addresses.empty())
613-
return nullptr;
614-
return std::make_shared<ThreadPlanRunToAddress>(thread, load_addresses,
615-
stop_others);
638+
return CreateThreadPlanRunToSCInList(thread, sc_list, stop_others);
616639
}
617640
case ThunkAction::StepThrough: {
618641
if (log)

0 commit comments

Comments
 (0)