@@ -45,6 +45,7 @@ enum class ThunkKind {
45
45
AllocatingInit,
46
46
PartialApply,
47
47
ObjCAttribute,
48
+ NonObjCAttributeOnCtor,
48
49
Reabstraction,
49
50
ProtocolConformance,
50
51
};
@@ -55,6 +56,7 @@ enum class ThunkAction {
55
56
StepIntoConformance,
56
57
StepIntoAllocatingInit,
57
58
StepThrough,
59
+ RunToObjcCInteropCtor,
58
60
};
59
61
60
62
} // namespace
@@ -313,6 +315,10 @@ static ThunkKind GetThunkKind(Symbol *symbol) {
313
315
switch (main_node->getKind ()) {
314
316
case Node::Kind::ObjCAttribute:
315
317
return ThunkKind::ObjCAttribute;
318
+ case Node::Kind::NonObjCAttribute:
319
+ if (hasChild (nodes, Node::Kind::Constructor))
320
+ return ThunkKind::NonObjCAttributeOnCtor;
321
+ break ;
316
322
case Node::Kind::ProtocolWitness:
317
323
if (hasChild (main_node, Node::Kind::ProtocolConformance))
318
324
return ThunkKind::ProtocolConformance;
@@ -342,6 +348,8 @@ static const char *GetThunkKindName(ThunkKind kind) {
342
348
return " GetThunkTarget" ;
343
349
case ThunkKind::ObjCAttribute:
344
350
return " GetThunkTarget" ;
351
+ case ThunkKind::NonObjCAttributeOnCtor:
352
+ return " RunToObjcCInteropCtor" ;
345
353
case ThunkKind::Reabstraction:
346
354
return " GetThunkTarget" ;
347
355
case ThunkKind::ProtocolConformance:
@@ -363,6 +371,8 @@ static ThunkAction GetThunkAction(ThunkKind kind) {
363
371
return ThunkAction::StepThrough;
364
372
case ThunkKind::ProtocolConformance:
365
373
return ThunkAction::StepIntoConformance;
374
+ case ThunkKind::NonObjCAttributeOnCtor:
375
+ return ThunkAction::RunToObjcCInteropCtor;
366
376
}
367
377
}
368
378
@@ -419,6 +429,66 @@ CreateRunThroughTaskSwitchingTrampolines(Thread &thread,
419
429
return nullptr ;
420
430
}
421
431
432
+ // / Demangle `symbol_name` and extracts the text at the node described by
433
+ // / `node_path`, if it exists; otherwise, returns an empty string.
434
+ static std::string FindClassName (StringRef symbol_name,
435
+ llvm::ArrayRef<Node::Kind> node_path) {
436
+ swift::Demangle::Context ctx;
437
+ NodePointer demangled_node =
438
+ SwiftLanguageRuntime::DemangleSymbolAsNode (symbol_name, ctx);
439
+
440
+ if (!demangled_node) {
441
+ std::string symbol_name_str = symbol_name.str ();
442
+ LLDB_LOGF (GetLog (LLDBLog::Step),
443
+ " SwiftLanguageRuntime: failed to demangle %s." ,
444
+ symbol_name_str.c_str ());
445
+ return " " ;
446
+ }
447
+ NodePointer class_node = childAtPath (demangled_node, node_path);
448
+ if (!class_node || !class_node->hasText ()) {
449
+ std::string node_str = getNodeTreeAsString (demangled_node);
450
+ LLDB_LOGF (GetLog (LLDBLog::Step),
451
+ " SwiftLanguageRuntime: failed to extract name from "
452
+ " demangle node: %s" ,
453
+ node_str.c_str ());
454
+ return " " ;
455
+ }
456
+ return class_node->getText ().str ();
457
+ }
458
+
459
+ // / If sc_list is non-empty, returns a plan that runs to any of its addresses.
460
+ // / Otherwise, returns nullptr.
461
+ static ThreadPlanSP
462
+ CreateThreadPlanRunToSCInList (Thread &thread, const SymbolContextList &sc_list,
463
+ bool stop_others) {
464
+ std::vector<addr_t > load_addresses;
465
+ Target &target = thread.GetProcess ()->GetTarget ();
466
+ for (const SymbolContext &sc : sc_list) {
467
+ const Symbol *ctor_symbol = sc.symbol ;
468
+ if (ctor_symbol)
469
+ load_addresses.push_back (ctor_symbol->GetLoadAddress (&target));
470
+ }
471
+
472
+ if (load_addresses.empty ()) {
473
+ LLDB_LOG (GetLog (LLDBLog::Step),
474
+ " SwiftLanguageRuntime: empty sc_list found." );
475
+ return {};
476
+ }
477
+ return std::make_shared<ThreadPlanRunToAddress>(thread, load_addresses,
478
+ stop_others);
479
+ }
480
+
481
+ // / Search all modules for `target_func` and creates a RunToAddress plan
482
+ // / targeting all symbols found.
483
+ static ThreadPlanSP CreateRunToAddressPlan (StringRef target_func,
484
+ Thread &thread, bool stop_others) {
485
+ ModuleList modules = thread.GetProcess ()->GetTarget ().GetImages ();
486
+ SymbolContextList sc_list;
487
+ modules.FindFunctionSymbols (ConstString (target_func), eFunctionNameTypeFull,
488
+ sc_list);
489
+ return CreateThreadPlanRunToSCInList (thread, sc_list, stop_others);
490
+ }
491
+
422
492
static lldb::ThreadPlanSP GetStepThroughTrampolinePlan (Thread &thread,
423
493
bool stop_others) {
424
494
// Here are the trampolines we have at present.
@@ -475,19 +545,32 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
475
545
log->Printf (
476
546
" Stepped to thunk \" %s\" (kind: %s) stepping to target: \" %s\" ." ,
477
547
symbol_name, GetThunkKindName (thunk_kind), thunk_target.c_str ());
548
+ return CreateRunToAddressPlan (thunk_target, thread, stop_others);
549
+ }
550
+ case ThunkAction::RunToObjcCInteropCtor: {
551
+ static constexpr auto class_path = {
552
+ Node::Kind::Constructor, Node::Kind::Class, Node::Kind::Identifier};
553
+ std::string class_name = FindClassName (symbol_name, class_path);
554
+ if (class_name.empty ()) {
555
+ LLDB_LOGF (log,
556
+ " SwiftLanguageRuntime: could not derive class name from symbol "
557
+ " \" %s\" ." ,
558
+ symbol_name);
559
+ return nullptr ;
560
+ }
561
+ std::string ctor_name = llvm::formatv (" {0} init" , class_name);
562
+ LLDB_LOGF (log,
563
+ " SwiftLanguageRuntime: running to objective C constructor \" %s\" "
564
+ " from swift." ,
565
+ ctor_name.c_str ());
478
566
479
- ModuleList modules = thread.GetProcess ()->GetTarget ().GetImages ();
480
567
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 ;
568
+ ModuleFunctionSearchOptions options{/* include_symbols*/ true ,
569
+ /* include_inlines*/ true };
570
+ ModuleList modules = thread.GetProcess ()->GetTarget ().GetImages ();
571
+ modules.FindFunctions (RegularExpression (ctor_name), options, sc_list);
572
+
573
+ return CreateThreadPlanRunToSCInList (thread, sc_list, stop_others);
491
574
}
492
575
case ThunkAction::StepIntoConformance: {
493
576
// The TTW symbols encode the protocol conformance requirements
@@ -582,37 +665,19 @@ static lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread,
582
665
}
583
666
case ThunkAction::StepIntoAllocatingInit: {
584
667
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
-
589
668
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 ());
669
+ static constexpr auto class_path = {Kind::Allocator, Kind::Class,
670
+ Kind::Identifier};
671
+ std::string class_name = FindClassName (symbol_name, class_path);
672
+ if (class_name.empty ())
597
673
return nullptr ;
598
- }
599
674
600
675
ModuleFunctionSearchOptions options{/* include_symbols*/ true ,
601
676
/* include_inlines*/ true };
602
- std::string ctor_name = llvm::formatv (" {0}.init" , class_node-> getText () );
677
+ std::string ctor_name = llvm::formatv (" {0}.init" , class_name );
603
678
SymbolContextList sc_list;
604
679
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);
680
+ return CreateThreadPlanRunToSCInList (thread, sc_list, stop_others);
616
681
}
617
682
case ThunkAction::StepThrough: {
618
683
if (log)
0 commit comments