@@ -2544,6 +2544,8 @@ struct AsyncUnwindRegisterNumbers {
2544
2544
// / frames below us as they need to react differently. There is no good way to
2545
2545
// / expose this, so we set another dummy register to communicate this state.
2546
2546
uint32_t dummy_regnum;
2547
+
2548
+ RegisterKind GetRegisterKind () const { return lldb::eRegisterKindDWARF; }
2547
2549
};
2548
2550
} // namespace
2549
2551
@@ -2588,8 +2590,11 @@ lldb::addr_t SwiftLanguageRuntime::GetAsyncContext(RegisterContext *regctx) {
2588
2590
2589
2591
// / Functional wrapper to read a register as an address.
2590
2592
static std::optional<addr_t > ReadRegisterAsAddress (RegisterContext ®ctx,
2593
+ RegisterKind regkind,
2591
2594
unsigned regnum) {
2592
- auto reg = regctx.ReadRegisterAsUnsigned (regnum, LLDB_INVALID_ADDRESS);
2595
+ unsigned lldb_regnum =
2596
+ regctx.ConvertRegisterKindToRegisterNumber (regkind, regnum);
2597
+ auto reg = regctx.ReadRegisterAsUnsigned (lldb_regnum, LLDB_INVALID_ADDRESS);
2593
2598
if (reg != LLDB_INVALID_ADDRESS)
2594
2599
return reg;
2595
2600
return {};
@@ -2613,12 +2618,14 @@ ReadPtrFromAddr(Process &process, std::optional<addr_t> addr, int offset = 0) {
2613
2618
// / simplified version of the methods in RegisterContextUnwind, since plumbing
2614
2619
// / access to those here would be challenging.
2615
2620
static std::optional<addr_t > GetCFA (Process &process, RegisterContext ®ctx,
2621
+ RegisterKind regkind,
2616
2622
UnwindPlan::Row::FAValue cfa_loc) {
2617
2623
using ValueType = UnwindPlan::Row::FAValue::ValueType;
2618
2624
switch (cfa_loc.GetValueType ()) {
2619
2625
case ValueType::isRegisterPlusOffset: {
2620
2626
unsigned regnum = cfa_loc.GetRegisterNumber ();
2621
- if (std::optional<addr_t > regvalue = ReadRegisterAsAddress (regctx, regnum))
2627
+ if (std::optional<addr_t > regvalue =
2628
+ ReadRegisterAsAddress (regctx, regkind, regnum))
2622
2629
return *regvalue + cfa_loc.GetOffset ();
2623
2630
break ;
2624
2631
}
@@ -2651,31 +2658,44 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
2651
2658
if (!unwind_plan)
2652
2659
return {};
2653
2660
2661
+ const RegisterKind unwind_regkind = unwind_plan->GetRegisterKind ();
2654
2662
UnwindPlan::RowSP row = unwind_plan->GetRowForFunctionOffset (
2655
2663
pc.GetFileAddress () - func_start_addr.GetFileAddress ());
2656
- UnwindPlan::Row::AbstractRegisterLocation regloc;
2664
+
2665
+ // To request info about a register from the unwind plan, the register must
2666
+ // be in the same domain as the unwind plan's registers.
2667
+ uint32_t async_reg_unwind_regdomain;
2668
+ if (!regctx.ConvertBetweenRegisterKinds (
2669
+ regnums.GetRegisterKind (), regnums.async_ctx_regnum , unwind_regkind,
2670
+ async_reg_unwind_regdomain))
2671
+ return {};
2657
2672
2658
2673
// If the plan doesn't have information about the async register, we can use
2659
2674
// its current value, as this is a callee saved register.
2660
- if (!row->GetRegisterInfo (regnums.async_ctx_regnum , regloc))
2661
- return ReadRegisterAsAddress (regctx, regnums.async_ctx_regnum );
2675
+ UnwindPlan::Row::AbstractRegisterLocation regloc;
2676
+ if (!row->GetRegisterInfo (async_reg_unwind_regdomain, regloc))
2677
+ return ReadRegisterAsAddress (regctx, regnums.GetRegisterKind (),
2678
+ regnums.async_ctx_regnum );
2662
2679
2663
2680
// Handle the few abstract locations we are likely to encounter.
2664
2681
using RestoreType = UnwindPlan::Row::AbstractRegisterLocation::RestoreType;
2665
2682
RestoreType loctype = regloc.GetLocationType ();
2666
2683
switch (loctype) {
2667
2684
case RestoreType::same:
2685
+ return ReadRegisterAsAddress (regctx, regnums.GetRegisterKind (),
2686
+ regnums.async_ctx_regnum );
2668
2687
case RestoreType::inOtherRegister: {
2669
- unsigned regnum = loctype == RestoreType::same ? regnums.async_ctx_regnum
2670
- : regloc.GetRegisterNumber ();
2671
- return ReadRegisterAsAddress (regctx, regnum);
2688
+ unsigned regnum = regloc.GetRegisterNumber ();
2689
+ return ReadRegisterAsAddress (regctx, unwind_regkind, regnum);
2672
2690
}
2673
2691
case RestoreType::atCFAPlusOffset: {
2674
- std::optional<addr_t > cfa = GetCFA (process, regctx, row->GetCFAValue ());
2692
+ std::optional<addr_t > cfa =
2693
+ GetCFA (process, regctx, unwind_regkind, row->GetCFAValue ());
2675
2694
return ReadPtrFromAddr (process, cfa, regloc.GetOffset ());
2676
2695
}
2677
2696
case RestoreType::isCFAPlusOffset: {
2678
- std::optional<addr_t > cfa = GetCFA (process, regctx, row->GetCFAValue ());
2697
+ std::optional<addr_t > cfa =
2698
+ GetCFA (process, regctx, unwind_regkind, row->GetCFAValue ());
2679
2699
if (!cfa)
2680
2700
return {};
2681
2701
return *cfa + regloc.GetOffset ();
0 commit comments