@@ -2544,6 +2544,8 @@ struct AsyncUnwindRegisterNumbers {
25442544 // / frames below us as they need to react differently. There is no good way to
25452545 // / expose this, so we set another dummy register to communicate this state.
25462546 uint32_t dummy_regnum;
2547+
2548+ RegisterKind GetRegisterKind () const { return lldb::eRegisterKindDWARF; }
25472549};
25482550} // namespace
25492551
@@ -2588,8 +2590,11 @@ lldb::addr_t SwiftLanguageRuntime::GetAsyncContext(RegisterContext *regctx) {
25882590
25892591// / Functional wrapper to read a register as an address.
25902592static std::optional<addr_t > ReadRegisterAsAddress (RegisterContext ®ctx,
2593+ RegisterKind regkind,
25912594 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);
25932598 if (reg != LLDB_INVALID_ADDRESS)
25942599 return reg;
25952600 return {};
@@ -2613,12 +2618,14 @@ ReadPtrFromAddr(Process &process, std::optional<addr_t> addr, int offset = 0) {
26132618// / simplified version of the methods in RegisterContextUnwind, since plumbing
26142619// / access to those here would be challenging.
26152620static std::optional<addr_t > GetCFA (Process &process, RegisterContext ®ctx,
2621+ RegisterKind regkind,
26162622 UnwindPlan::Row::FAValue cfa_loc) {
26172623 using ValueType = UnwindPlan::Row::FAValue::ValueType;
26182624 switch (cfa_loc.GetValueType ()) {
26192625 case ValueType::isRegisterPlusOffset: {
26202626 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))
26222629 return *regvalue + cfa_loc.GetOffset ();
26232630 break ;
26242631 }
@@ -2651,31 +2658,44 @@ static std::optional<addr_t> ReadAsyncContextRegisterFromUnwind(
26512658 if (!unwind_plan)
26522659 return {};
26532660
2661+ const RegisterKind unwind_regkind = unwind_plan->GetRegisterKind ();
26542662 UnwindPlan::RowSP row = unwind_plan->GetRowForFunctionOffset (
26552663 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 {};
26572672
26582673 // If the plan doesn't have information about the async register, we can use
26592674 // 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 );
26622679
26632680 // Handle the few abstract locations we are likely to encounter.
26642681 using RestoreType = UnwindPlan::Row::AbstractRegisterLocation::RestoreType;
26652682 RestoreType loctype = regloc.GetLocationType ();
26662683 switch (loctype) {
26672684 case RestoreType::same:
2685+ return ReadRegisterAsAddress (regctx, regnums.GetRegisterKind (),
2686+ regnums.async_ctx_regnum );
26682687 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);
26722690 }
26732691 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 ());
26752694 return ReadPtrFromAddr (process, cfa, regloc.GetOffset ());
26762695 }
26772696 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 ());
26792699 if (!cfa)
26802700 return {};
26812701 return *cfa + regloc.GetOffset ();
0 commit comments