mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-10-07 08:25:41 +00:00
add support for CFA in the eval system
Canonical Frame Address is a DWARF-only concept encoded in the unwind info. Debugger must store this data for each call frame and provide it to the eval system based on selected stack frame. To abstract over format details, we introduce a "Frame Unwind Context". For DWARF, this context maintains the intermediate unwind state and exposes the CFA, whereas for PE, it remains empty.
This commit is contained in:
+23
-12
@@ -237,18 +237,14 @@ dw_cfi_row_from_pc(Arena *arena, Arch arch, DW_CIE *cie, DW_FDE *fde, DW_DecodeP
|
||||
}
|
||||
|
||||
internal DW_UnwindStatus
|
||||
dw_cfi_apply_register_rules(Arch arch,
|
||||
DW_CIE *cie,
|
||||
DW_CFI_Row *row,
|
||||
DW_MemRead *mem_read_func, void *mem_read_ud,
|
||||
DW_RegRead *reg_read_func, void *reg_read_ud,
|
||||
DW_RegWrite *reg_write_func, void *reg_write_ud)
|
||||
dw_compute_cfa(Arch arch,
|
||||
DW_CFI_Row *row,
|
||||
DW_MemRead *mem_read_func, void *mem_read_ud,
|
||||
DW_RegRead *reg_read_func, void *reg_read_ud,
|
||||
U64 *cfa_out)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
DW_UnwindStatus unwind_status = DW_UnwindStatus_Ok;
|
||||
DW_UnwindStatus unwind_status = DW_UnwindStatus_Fail;
|
||||
|
||||
// establish CFA
|
||||
U64 cfa = 0;
|
||||
switch (row->cfa.rule) {
|
||||
case DW_CFA_Rule_Null: break;
|
||||
case DW_CFA_Rule_RegOff: {
|
||||
@@ -257,14 +253,29 @@ dw_cfi_apply_register_rules(Arch arch,
|
||||
U64 reg_size = dw_reg_size_from_code(arch, row->cfa.reg);
|
||||
AssertAlways(reg_size <= sizeof(cfa_reg_value));
|
||||
unwind_status = reg_read_func(row->cfa.reg, &cfa_reg_value, reg_size, reg_read_ud);
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { goto exit; }
|
||||
cfa = cfa_reg_value + row->cfa.off;
|
||||
if (unwind_status != DW_UnwindStatus_Ok) { break; }
|
||||
*cfa_out = cfa_reg_value + row->cfa.off;
|
||||
} break;
|
||||
case DW_CFA_Rule_Expression: {
|
||||
// TODO: evaluate expression
|
||||
NotImplemented;
|
||||
} break;
|
||||
}
|
||||
|
||||
return unwind_status;
|
||||
}
|
||||
|
||||
internal DW_UnwindStatus
|
||||
dw_cfi_apply_register_rules(Arch arch,
|
||||
U64 cfa,
|
||||
DW_CFI_Row *row,
|
||||
DW_MemRead *mem_read_func, void *mem_read_ud,
|
||||
DW_RegRead *reg_read_func, void *reg_read_ud,
|
||||
DW_RegWrite *reg_write_func, void *reg_write_ud)
|
||||
{
|
||||
Temp scratch = scratch_begin(0,0);
|
||||
DW_UnwindStatus unwind_status = DW_UnwindStatus_Ok;
|
||||
|
||||
U64 max_reg_size = dw_reg_max_size_from_arch(arch);
|
||||
void *reg_buffer = push_array(scratch.arena, U8, max_reg_size);
|
||||
|
||||
|
||||
@@ -89,7 +89,7 @@ internal DW_CFI_Unwind * dw_cfi_unwind_init(Arena *arena, Arch arch, DW_CIE *cie
|
||||
internal B32 dw_cfi_next_row(Arena *arena, DW_CFI_Unwind *uw);
|
||||
|
||||
internal DW_CFI_Row * dw_cfi_row_from_pc(Arena *arena, Arch arch, struct DW_CIE *cie, struct DW_FDE *fde, DW_DecodePtr *decode_ptr_func, void *decode_ptr_ctx, U64 pc);
|
||||
internal DW_UnwindStatus dw_cfi_apply_register_rules(Arch arch, DW_CIE *cie, DW_CFI_Row *row, DW_MemRead *mem_read_func, void *mem_read_ud, DW_RegRead *reg_read_func, void *reg_read_ud, DW_RegWrite *reg_write_func, void *reg_write_ud);
|
||||
internal DW_UnwindStatus dw_cfi_apply_register_rules(Arch arch, U64 cfa, DW_CFI_Row *row, DW_MemRead *mem_read_func, void *mem_read_ud, DW_RegRead *reg_read_func, void *reg_read_ud, DW_RegWrite *reg_write_func, void *reg_write_ud);
|
||||
|
||||
#endif // DWARF_UNWIND_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user