diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 41cf1080..ca48aee6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -8630,7 +8630,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(thread) { E_Eval eval = e_eval_from_expr(scratch.arena, lhs); CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, eval.space, e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCtrlEntity), e_irtree_leaf_u128(arena, u128_make(entity->handle.machine_id, entity->handle.dmn_handle.u64[0]))); result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("call_stack")); result.irtree_and_type.mode = E_Mode_Offset; } @@ -8734,7 +8734,7 @@ E_LOOKUP_ACCESS_FUNCTION_DEF(target) { E_Eval eval = e_eval_from_expr(scratch.arena, lhs); RD_Cfg *cfg = rd_cfg_from_eval_space(eval.space); - result.irtree_and_type.root = e_irtree_set_space(arena, eval.space, e_irtree_const_u(arena, cfg->id)); + result.irtree_and_type.root = e_irtree_set_space(arena, e_space_make(RD_EvalSpaceKind_MetaCfgCollection), e_irtree_const_u(arena, cfg->id)); result.irtree_and_type.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = str8_lit("environment")); result.irtree_and_type.mode = E_Mode_Offset; } @@ -12487,6 +12487,7 @@ rd_frame(void) String8 collection_name = str8_lit("watches"); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); + expr->space = e_space_make(RD_EvalSpaceKind_MetaCfgCollection); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(watches), @@ -12564,6 +12565,7 @@ rd_frame(void) E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name); E_Expr *expr = e_push_expr(scratch.arena, E_ExprKind_LeafOffset, 0); expr->type_key = collection_type_key; + expr->space = e_space_make(RD_EvalSpaceKind_MetaCfgCollection); e_string2expr_map_insert(scratch.arena, ctx->macro_map, collection_name, expr); e_lookup_rule_map_insert_new(scratch.arena, ctx->lookup_rule_map, collection_name, .info = E_LOOKUP_INFO_FUNCTION_NAME(top_level_cfg), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 7e834b1b..50a44504 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -83,6 +83,7 @@ enum { RD_EvalSpaceKind_CtrlEntity = E_SpaceKind_FirstUserDefined, RD_EvalSpaceKind_MetaCfg, + RD_EvalSpaceKind_MetaCfgCollection, RD_EvalSpaceKind_MetaCtrlEntity, RD_EvalSpaceKind_MetaCmd, }; diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 5740afaf..14e04aa8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -908,6 +908,10 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) EV_Key key = row->key; E_IRTreeAndType parent_irtree = e_irtree_and_type_from_expr(scratch.arena, block->expr); E_Type *parent_type = e_type_from_key__cached(parent_irtree.type_key); + E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); + E_TypeKey block_type_key = block_eval.type_key; + E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); + E_Type *block_type = e_type_from_key__cached(block_type_key); // rjf: fill row's eval info.eval = e_eval_from_expr(arena, row->expr); @@ -934,27 +938,43 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } } - // rjf: determine cfg group name / parent + // rjf: determine call stack info + if(block_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity && block_type_kind == E_TypeKind_Set) { - E_Eval block_eval = e_eval_from_expr(scratch.arena, row->block->expr); - E_TypeKey block_type_key = block_eval.type_key; - E_TypeKind block_type_kind = e_type_kind_from_key(block_type_key); - if(block_type_kind == E_TypeKind_Set) + CTRL_Handle handle = {0}; + handle.machine_id = (CTRL_MachineID)block_eval.value.u128.u64[0]; + handle.dmn_handle.u64[0] = (U64)block_eval.value.u128.u64[1]; + CTRL_Entity *entity = ctrl_entity_from_handle(d_state->ctrl_entity_store, handle); + if(entity->kind == CTRL_EntityKind_Thread) { - info.group_cfg_parent = rd_cfg_from_id(block_eval.value.u64); - E_Type *block_type = e_type_from_key__cached(block_type_key); - String8 singular_name = rd_singular_from_code_name_plural(block_type->name); - if(singular_name.size != 0) + info.callstack_thread = entity; + U64 frame_num = block->lookup_rule->num_from_id(key.child_id, block->lookup_rule_user_data); + CTRL_Unwind unwind = d_query_cached_unwind_from_thread(entity); + CTRL_CallStack call_stack = ctrl_call_stack_from_unwind(scratch.arena, di_scope, ctrl_process_from_entity(entity), &unwind); + if(1 <= frame_num && frame_num <= call_stack.count) { - info.group_cfg_name = singular_name; - } - else - { - info.group_cfg_name = block_type->name; + CTRL_CallStackFrame *f = &call_stack.frames[frame_num-1]; + info.callstack_unwind_index = f->unwind_count; + info.callstack_inline_depth = f->inline_depth; } } } + // rjf: determine cfg group name / parent + if(block_type_kind == E_TypeKind_Set && block_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) + { + info.group_cfg_parent = rd_cfg_from_id(block_eval.value.u64); + String8 singular_name = rd_singular_from_code_name_plural(block_type->name); + if(singular_name.size != 0) + { + info.group_cfg_name = singular_name; + } + else + { + info.group_cfg_name = block_type->name; + } + } + // rjf: determine row's cfg if(info.group_cfg_name.size != 0) { @@ -1023,7 +1043,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) } // rjf: for meta-cfg evaluation spaces, only do expr/value - else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg) + else if(info.eval.space.kind == RD_EvalSpaceKind_MetaCfg || info.eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection) { info.cell_style_key = str8_lit("expr_and_eval"); RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); @@ -1036,6 +1056,20 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) #undef take_pct } + // rjf: callstack frames + else if(info.callstack_thread != &ctrl_entity_nil) + { + info.cell_style_key = str8_lit("call_stack_frame"); + RD_Cfg *view = rd_cfg_from_id(rd_regs()->view); + RD_Cfg *style = rd_cfg_child_from_string(view, info.cell_style_key); + RD_Cfg *w_cfg = style->first; + F32 next_pct = 0; +#define take_pct() (next_pct = (F32)f64_from_str8(w_cfg->string), w_cfg = w_cfg->next, next_pct) + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .default_pct = 0.65f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, .string = str8_lit("(U64)($expr) => hex"), .default_pct = 0.35f, .pct = take_pct()); +#undef take_pct + } + // rjf: default cells else { @@ -1239,6 +1273,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla B32 is_non_code = 0; String8 string = push_str8f(arena, ".%S", member_name); if(row_eval.space.kind == RD_EvalSpaceKind_MetaCfg || + row_eval.space.kind == RD_EvalSpaceKind_MetaCfgCollection || row_eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity) { String8 fancy_name = rd_display_from_code_name(member_name);