Skip to content

Commit 130728a

Browse files
fixup! Use proper register domain conversion
1 parent 312cf91 commit 130728a

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

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

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
25902592
static std::optional<addr_t> ReadRegisterAsAddress(RegisterContext &regctx,
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.
26152620
static std::optional<addr_t> GetCFA(Process &process, RegisterContext &regctx,
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

Comments
 (0)