@@ -2582,6 +2582,37 @@ lldb::addr_t SwiftLanguageRuntime::GetAsyncContext(RegisterContext *regctx) {
2582
2582
return LLDB_INVALID_ADDRESS;
2583
2583
}
2584
2584
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
+
2585
2616
// Examine the register state and detect the transition from a real
2586
2617
// stack frame to an AsyncContext frame, or a frame in the middle of
2587
2618
// the AsyncContext chain, and return an UnwindPlan for these situations.
@@ -2671,48 +2702,15 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
2671
2702
const int32_t ptr_size = 8 ;
2672
2703
row->SetOffset (0 );
2673
2704
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
-
2709
2705
if (in_prologue) {
2710
2706
if (indirect_context)
2711
2707
row->GetCFAValue ().SetIsRegisterDereferenced (regnums->async_ctx_regnum );
2712
2708
else
2713
2709
row->GetCFAValue ().SetIsRegisterPlusOffset (regnums->async_ctx_regnum , 0 );
2714
2710
} 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 ());
2716
2714
}
2717
2715
2718
2716
if (indirect_context) {
@@ -2723,12 +2721,10 @@ SwiftLanguageRuntime::GetRuntimeUnwindPlan(ProcessSP process_sp,
2723
2721
// dereferenced once to get the context. This is reflected in the debug
2724
2722
// info so we need to account for it and report am async register value
2725
2723
// 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 );
2732
2728
}
2733
2729
} else {
2734
2730
// In the first part of a split async function, the context is passed
0 commit comments