Skip to content

Commit 0bc7407

Browse files
[lldb][swift][nfc] Factor out code into helper function
This will make subsequent patches easier to diff.
1 parent e64c775 commit 0bc7407

File tree

1 file changed

+38
-42
lines changed

1 file changed

+38
-42
lines changed

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

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2582,6 +2582,37 @@ lldb::addr_t SwiftLanguageRuntime::GetAsyncContext(RegisterContext *regctx) {
25822582
return LLDB_INVALID_ADDRESS;
25832583
}
25842584

2585+
/// Creates an expression accessing (fp - 8), with an optional dereference
2586+
/// operation. This is only valid for x86_64 or aarch64.
2587+
llvm::ArrayRef<uint8_t>
2588+
GetAsyncRegFromFramePointerDWARFExpr(llvm::Triple::ArchType triple,
2589+
bool with_deref) {
2590+
assert(triple == llvm::Triple::x86_64 || triple == llvm::Triple::aarch64);
2591+
2592+
// These expressions must have static storage, due to how UnwindPlan::Row
2593+
// works.
2594+
static const uint8_t g_cfa_dwarf_expression_x86_64[] = {
2595+
llvm::dwarf::DW_OP_breg6, // DW_OP_breg6, register 6 == rbp
2596+
0x78, // sleb128 -8 (ptrsize)
2597+
llvm::dwarf::DW_OP_deref,
2598+
};
2599+
static const uint8_t g_cfa_dwarf_expression_arm64[] = {
2600+
llvm::dwarf::DW_OP_breg29, // DW_OP_breg29, register 29 == fp
2601+
0x78, // sleb128 -8 (ptrsize)
2602+
llvm::dwarf::DW_OP_deref,
2603+
};
2604+
2605+
const uint8_t *expr = triple == llvm::Triple::x86_64
2606+
? g_cfa_dwarf_expression_x86_64
2607+
: g_cfa_dwarf_expression_arm64;
2608+
auto size = triple == llvm::Triple::x86_64
2609+
? sizeof(g_cfa_dwarf_expression_x86_64)
2610+
: sizeof(g_cfa_dwarf_expression_arm64);
2611+
if (with_deref)
2612+
return llvm::ArrayRef<uint8_t>(expr, size);
2613+
return llvm::ArrayRef<uint8_t>(expr, size - 1);
2614+
}
2615+
25852616
// Examine the register state and detect the transition from a real
25862617
// stack frame to an AsyncContext frame, or a frame in the middle of
25872618
// the AsyncContext chain, and return an UnwindPlan for these situations.
@@ -2671,48 +2702,15 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
26712702
const int32_t ptr_size = 8;
26722703
row->SetOffset(0);
26732704

2674-
// A DWARF Expression to set the CFA.
2675-
// pushes the frame pointer register - 8
2676-
// dereference
2677-
2678-
// FIXME: Row::RegisterLocation::RestoreType doesn't have a
2679-
// deref(reg-value + offset) yet, shortcut around it with
2680-
// a dwarf expression for now.
2681-
// The CFA of an async frame is the address of it's associated AsyncContext.
2682-
// In an async frame currently on the stack, this address is stored right
2683-
// before the saved frame pointer on the stack.
2684-
static const uint8_t g_cfa_dwarf_expression_x86_64[] = {
2685-
llvm::dwarf::DW_OP_breg6, // DW_OP_breg6, register 6 == rbp
2686-
0x78, // sleb128 -8 (ptrsize)
2687-
llvm::dwarf::DW_OP_deref,
2688-
};
2689-
static const uint8_t g_cfa_dwarf_expression_arm64[] = {
2690-
llvm::dwarf::DW_OP_breg29, // DW_OP_breg29, register 29 == fp
2691-
0x78, // sleb128 -8 (ptrsize)
2692-
llvm::dwarf::DW_OP_deref,
2693-
};
2694-
2695-
constexpr unsigned expr_size = sizeof(g_cfa_dwarf_expression_arm64);
2696-
2697-
static_assert(sizeof(g_cfa_dwarf_expression_x86_64) ==
2698-
sizeof(g_cfa_dwarf_expression_arm64),
2699-
"Code relies on DWARF expressions being the same size");
2700-
2701-
const uint8_t *expr = nullptr;
2702-
if (arch.GetMachine() == llvm::Triple::x86_64)
2703-
expr = g_cfa_dwarf_expression_x86_64;
2704-
else if (arch.GetMachine() == llvm::Triple::aarch64)
2705-
expr = g_cfa_dwarf_expression_arm64;
2706-
else
2707-
llvm_unreachable("Unsupported architecture");
2708-
27092705
if (in_prologue) {
27102706
if (indirect_context)
27112707
row->GetCFAValue().SetIsRegisterDereferenced(regnums->async_ctx_regnum);
27122708
else
27132709
row->GetCFAValue().SetIsRegisterPlusOffset(regnums->async_ctx_regnum, 0);
27142710
} else {
2715-
row->GetCFAValue().SetIsDWARFExpression(expr, expr_size);
2711+
llvm::ArrayRef<uint8_t> expr = GetAsyncRegFromFramePointerDWARFExpr(
2712+
arch.GetMachine(), true /*with_deref*/);
2713+
row->GetCFAValue().SetIsDWARFExpression(expr.data(), expr.size());
27162714
}
27172715

27182716
if (indirect_context) {
@@ -2723,12 +2721,10 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
27232721
// dereferenced once to get the context. This is reflected in the debug
27242722
// info so we need to account for it and report am async register value
27252723
// that needs to be dereferenced to get to the context.
2726-
// Note that the size passed for the DWARF expression is the size of the
2727-
// array minus one. This skips the last deref for this use.
2728-
assert(expr[expr_size - 1] == llvm::dwarf::DW_OP_deref &&
2729-
"Should skip a deref");
2730-
row->SetRegisterLocationToIsDWARFExpression(regnums->async_ctx_regnum,
2731-
expr, expr_size - 1, false);
2724+
llvm::ArrayRef<uint8_t> expr = GetAsyncRegFromFramePointerDWARFExpr(
2725+
arch.GetMachine(), false /*with_deref*/);
2726+
row->SetRegisterLocationToIsDWARFExpression(
2727+
regnums->async_ctx_regnum, expr.data(), expr.size(), false);
27322728
}
27332729
} else {
27342730
// In the first part of a split async function, the context is passed

0 commit comments

Comments
 (0)