Skip to content

Commit 5358515

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

File tree

1 file changed

+68
-37
lines changed

1 file changed

+68
-37
lines changed

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

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

422+
// Search all modules for `target_func` and creates a RunToAddress plan if a
423+
// single function is found.
424+
static ThreadPlanSP CreateRunToAddressPlan(StringRef target_func,
425+
Thread &thread, bool stop_others) {
426+
ModuleList modules = thread.GetProcess()->GetTarget().GetImages();
427+
SymbolContextList sc_list;
428+
modules.FindFunctionSymbols(ConstString(target_func), eFunctionNameTypeFull,
429+
sc_list);
430+
if (sc_list.GetSize() != 1 || sc_list[0].symbol == nullptr)
431+
return nullptr;
432+
Symbol &thunk_symbol = *sc_list[0].symbol;
433+
Address target_address = thunk_symbol.GetAddress();
434+
if (target_address.IsValid())
435+
return std::make_shared<ThreadPlanRunToAddress>(thread, target_address,
436+
stop_others);
437+
return nullptr;
438+
}
439+
440+
/// Demangle `symbol_name` and extracts the text at the node described by
441+
/// `node_path`, if it exists.
442+
static std::optional<std::string>
443+
FindClassName(StringRef symbol_name, llvm::ArrayRef<Node::Kind> node_path) {
444+
swift::Demangle::Context ctx;
445+
NodePointer demangled_node =
446+
SwiftLanguageRuntime::DemangleSymbolAsNode(symbol_name, ctx);
447+
448+
NodePointer class_node = childAtPath(demangled_node, node_path);
449+
if (!class_node || !class_node->hasText()) {
450+
std::string node_str = getNodeTreeAsString(demangled_node);
451+
LLDB_LOGF(GetLog(LLDBLog::Step),
452+
"SwiftLanguageRuntime: failed to extract name from "
453+
"demangle node: %s",
454+
node_str.c_str());
455+
return {};
456+
}
457+
return class_node->getText().str();
458+
}
459+
460+
/// If sc_list is non-empty, returns a plan that runs to any of its addresses.
461+
/// Otherwise, returns nullptr.
462+
static ThreadPlanSP CreateThreadPlanRunToAnySc(Thread &thread,
463+
SymbolContextList &sc_list,
464+
bool stop_others) {
465+
std::vector<addr_t> load_addresses;
466+
Target &target = thread.GetProcess()->GetTarget();
467+
for (const SymbolContext &ctor_sc : sc_list) {
468+
const Symbol *ctor_symbol = ctor_sc.symbol;
469+
if (ctor_symbol)
470+
load_addresses.push_back(ctor_symbol->GetLoadAddress(&target));
471+
}
472+
473+
if (load_addresses.empty()) {
474+
LLDB_LOG(GetLog(LLDBLog::Step),
475+
"SwiftLanguageRuntime: empty sc_list found.");
476+
return nullptr;
477+
}
478+
return std::make_shared<ThreadPlanRunToAddress>(thread, load_addresses,
479+
stop_others);
480+
}
481+
422482
static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
423483
bool stop_others) {
424484
// Here are the trampolines we have at present.
@@ -475,19 +535,7 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
475535
log->Printf(
476536
"Stepped to thunk \"%s\" (kind: %s) stepping to target: \"%s\".",
477537
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;
538+
return CreateRunToAddressPlan(thunk_target, thread, stop_others);
491539
}
492540
case ThunkAction::StepIntoConformance: {
493541
// The TTW symbols encode the protocol conformance requirements
@@ -582,37 +630,20 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
582630
}
583631
case ThunkAction::StepIntoAllocatingInit: {
584632
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-
589633
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());
634+
static constexpr auto class_path = {Kind::Allocator, Kind::Class,
635+
Kind::Identifier};
636+
std::optional<std::string> class_name =
637+
FindClassName(symbol_name, class_path);
638+
if (!class_name)
597639
return nullptr;
598-
}
599640

600641
ModuleFunctionSearchOptions options{/*include_symbols*/ true,
601642
/*include_inlines*/ true};
602-
std::string ctor_name = llvm::formatv("{0}.init", class_node->getText());
643+
std::string ctor_name = llvm::formatv("{0}.init", *class_name);
603644
SymbolContextList sc_list;
604645
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);
646+
return CreateThreadPlanRunToAnySc(thread, sc_list, stop_others);
616647
}
617648
case ThunkAction::StepThrough: {
618649
if (log)

0 commit comments

Comments
 (0)