diff --git a/src/ctrl/ctrl_core.c b/src/ctrl/ctrl_core.c index 5d487bd6..a3ce899c 100644 --- a/src/ctrl/ctrl_core.c +++ b/src/ctrl/ctrl_core.c @@ -904,6 +904,21 @@ ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind) return result; } +internal CTRL_Entity * +ctrl_process_from_entity(CTRL_Entity *entity) +{ + CTRL_Entity *result = &ctrl_entity_nil; + if(entity->kind == CTRL_EntityKind_Process) + { + result = entity; + } + else + { + result = ctrl_entity_ancestor_from_kind(entity, CTRL_EntityKind_Process); + } + return result; +} + internal CTRL_Entity * ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr) { diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 5e02713c..1a14f23f 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -20,11 +20,13 @@ typedef struct CTRL_MetaEvalFrame CTRL_MetaEvalFrame; struct CTRL_MetaEvalFrame { U64 vaddr; + U64 inline_depth; }; ptr_type(CTRL_MetaEvalFrame__vaddr_type, type(void), .flags = TypeFlag_IsExternal, .size = sizeof(U64)); struct_members(CTRL_MetaEvalFrame) { - member_lit_comp(CTRL_MetaEvalFrame, &CTRL_MetaEvalFrame__vaddr_type, vaddr), + member_lit_comp(CTRL_MetaEvalFrame, type(U64), vaddr), + member_lit_comp(CTRL_MetaEvalFrame, type(U64), inline_depth), }; struct_type(CTRL_MetaEvalFrame); typedef struct CTRL_MetaEvalFrameArray CTRL_MetaEvalFrameArray; @@ -33,7 +35,7 @@ struct CTRL_MetaEvalFrameArray U64 count; CTRL_MetaEvalFrame *v; }; -ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, &CTRL_MetaEvalFrame__vaddr_type, .count_delimiter_name = str8_lit_comp("count")); +ptr_type(CTRL_MetaEvalFrameArray__v_ptr_type, type(CTRL_MetaEvalFrame), .count_delimiter_name = str8_lit_comp("count")); struct_members(CTRL_MetaEvalFrameArray) { member_lit_comp(CTRL_MetaEvalFrameArray, type(U64), count, .pretty_name = str8_lit_comp("Frame Count")), @@ -836,6 +838,7 @@ internal void ctrl_entity_equip_string(CTRL_EntityStore *store, CTRL_Entity *ent internal CTRL_Entity *ctrl_entity_from_handle(CTRL_EntityStore *store, CTRL_Handle handle); internal CTRL_Entity *ctrl_entity_child_from_kind(CTRL_Entity *parent, CTRL_EntityKind kind); internal CTRL_Entity *ctrl_entity_ancestor_from_kind(CTRL_Entity *entity, CTRL_EntityKind kind); +internal CTRL_Entity *ctrl_process_from_entity(CTRL_Entity *entity); internal CTRL_Entity *ctrl_module_from_process_vaddr(CTRL_Entity *process, U64 vaddr); internal DI_Key ctrl_dbgi_key_from_module(CTRL_Entity *module); internal CTRL_EntityList ctrl_modules_from_dbgi_key(Arena *arena, CTRL_EntityStore *store, DI_Key *dbgi_key); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 1daf3f40..b9468608 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1413,8 +1413,7 @@ ev_string_from_simple_typed_eval(Arena *arena, EV_StringFlags flags, U32 radix, case E_TypeKind_U32: case E_TypeKind_U64: { - U64 min_digits = (radix == 16) ? type_byte_size*2 : 0; - result = str8_from_u64(arena, eval.value.u64, radix, min_digits, digit_group_separator); + result = str8_from_u64(arena, eval.value.u64, radix, 0, digit_group_separator); }break; case E_TypeKind_U128: diff --git a/src/lib_rdi_format/rdi_format_parse.c b/src/lib_rdi_format/rdi_format_parse.c index 937aca78..ab371fec 100644 --- a/src/lib_rdi_format/rdi_format_parse.c +++ b/src/lib_rdi_format/rdi_format_parse.c @@ -636,6 +636,13 @@ rdi_scope_from_voff(RDI_Parsed *rdi, RDI_U64 voff) return scope; } +RDI_PROC RDI_Scope * +rdi_parent_from_scope(RDI_Parsed *rdi, RDI_Scope *scope) +{ + RDI_Scope *parent = rdi_element_from_name_idx(rdi, Scopes, scope->parent_scope_idx); + return parent; +} + RDI_PROC RDI_Procedure * rdi_procedure_from_scope(RDI_Parsed *rdi, RDI_Scope *scope) { @@ -643,6 +650,13 @@ rdi_procedure_from_scope(RDI_Parsed *rdi, RDI_Scope *scope) return procedure; } +RDI_PROC RDI_InlineSite * +rdi_inline_site_from_scope(RDI_Parsed *rdi, RDI_Scope *scope) +{ + RDI_InlineSite *inline_site = rdi_element_from_name_idx(rdi, InlineSites, scope->inline_site_idx); + return inline_site; +} + //- global variables RDI_PROC RDI_GlobalVariable * diff --git a/src/lib_rdi_format/rdi_format_parse.h b/src/lib_rdi_format/rdi_format_parse.h index 8bb6b9ca..dc948f70 100644 --- a/src/lib_rdi_format/rdi_format_parse.h +++ b/src/lib_rdi_format/rdi_format_parse.h @@ -189,7 +189,9 @@ RDI_PROC RDI_Procedure *rdi_procedure_from_voff(RDI_Parsed *rdi, RDI_U64 voff); RDI_PROC RDI_U64 rdi_first_voff_from_scope(RDI_Parsed *rdi, RDI_Scope *scope); RDI_PROC RDI_U64 rdi_opl_voff_from_scope(RDI_Parsed *rdi, RDI_Scope *scope); RDI_PROC RDI_Scope *rdi_scope_from_voff(RDI_Parsed *rdi, RDI_U64 voff); +RDI_PROC RDI_Scope *rdi_parent_from_scope(RDI_Parsed *rdi, RDI_Scope *scope); RDI_PROC RDI_Procedure *rdi_procedure_from_scope(RDI_Parsed *rdi, RDI_Scope *scope); +RDI_PROC RDI_InlineSite *rdi_inline_site_from_scope(RDI_Parsed *rdi, RDI_Scope *scope); //- global variables RDI_PROC RDI_GlobalVariable *rdi_global_variable_from_voff(RDI_Parsed *rdi, RDI_U64 voff); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 220263bb..392dea7b 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -2016,6 +2016,7 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) for(D_UnwindInlineFrame *f = rich_unwind.frames.v[base_idx].first_inline_frame; f != 0; f = f->next, inline_idx += 1) { meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames.v[base_idx].regs); + meval->callstack.v[idx].inline_depth = inline_idx + 1; idx += 1; } meval->callstack.v[idx].vaddr = regs_rip_from_arch_block(entity->arch, rich_unwind.frames.v[base_idx].regs); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 040c63b7..aee43c36 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -913,14 +913,6 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_Wa { result = ev_view_rule_from_key(ev, row->key); }break; - case RD_WatchViewColumnKind_Module: - { - E_Eval eval = e_eval_from_expr(arena, row->expr); - E_Eval value_eval = e_value_eval_from_eval(eval); - CTRL_Entity *process = ctrl_entity_from_handle(d_state->ctrl_entity_store, rd_regs()->process); - CTRL_Entity *module = ctrl_module_from_process_vaddr(process, value_eval.value.u64); - result = str8_skip_last_slash(module->string); - }break; case RD_WatchViewColumnKind_Member: { Temp scratch = scratch_begin(&arena, 1); @@ -935,6 +927,91 @@ rd_string_from_eval_viz_row_column(Arena *arena, EV_View *ev, EV_Row *row, RD_Wa result = rd_value_string_from_eval(arena, string_flags, default_radix, font, font_size, max_size_px, eval, row->member, view_rules); scratch_end(scratch); }break; + case RD_WatchViewColumnKind_Module: + { + E_Eval eval = e_eval_from_expr(arena, row->expr); + E_Eval value_eval = e_value_eval_from_eval(eval); + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, value_eval.value.u64); + result = push_str8_copy(arena, str8_skip_last_slash(module->string)); + }break; + case RD_WatchViewColumnKind_CallStackFrame: + { + Temp scratch = scratch_begin(&arena, 1); + DI_Scope *di_scope = di_scope_open(); + E_Eval eval = e_eval_from_expr(arena, row->expr); + E_Expr *vaddr_expr = e_expr_ref_member_access(scratch.arena, row->expr, str8_lit("vaddr")); + E_Expr *depth_expr = e_expr_ref_member_access(scratch.arena, row->expr, str8_lit("inline_depth")); + E_Eval vaddr_eval = e_eval_from_expr(scratch.arena, vaddr_expr); + E_Eval depth_eval = e_eval_from_expr(scratch.arena, depth_expr); + E_Eval vaddr_value_eval = e_value_eval_from_eval(vaddr_eval); + E_Eval depth_value_eval = e_value_eval_from_eval(depth_eval); + U64 vaddr = vaddr_value_eval.value.u64; + U64 depth = depth_value_eval.value.u64; + CTRL_Entity *entity = rd_ctrl_entity_from_eval_space(eval.space); + CTRL_Entity *process = ctrl_process_from_entity(entity); + CTRL_Entity *module = ctrl_module_from_process_vaddr(process, vaddr); + DI_Key dbgi = ctrl_dbgi_key_from_module(module); + RDI_Parsed *rdi = di_rdi_from_key(di_scope, &dbgi, 0); + if(rdi != &di_rdi_parsed_nil) + { + U64 voff = ctrl_voff_from_vaddr(module, vaddr); + RDI_Scope *scope = rdi_scope_from_voff(rdi, voff); + RDI_Procedure *procedure = rdi_procedure_from_scope(rdi, scope); + RDI_InlineSite *inline_site = rdi_inline_site_from_scope(rdi, scope); + for(U64 d = 0; d < depth;) + { + scope = rdi_parent_from_scope(rdi, scope); + inline_site = rdi_inline_site_from_scope(rdi, scope); + if(scope->inline_site_idx != 0) + { + d += 1; + } + if(scope->parent_scope_idx == 0) + { + break; + } + } + if(inline_site->name_string_idx != 0 || inline_site->type_idx != 0) + { + String8List parts = {0}; + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, inline_site->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, inline_site->name_string_idx, &name.size); + String8List type_lhs_parts = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &type_lhs_parts, 0, 0); + String8List type_rhs_parts = {0}; + e_type_rhs_string_from_key(scratch.arena, type, &type_rhs_parts, 0); + str8_list_pushf(scratch.arena, &parts, "[inlined] "); + str8_list_concat_in_place(&parts, &type_lhs_parts); + str8_list_push(scratch.arena, &parts, name); + str8_list_concat_in_place(&parts, &type_rhs_parts); + result = str8_list_join(arena, &parts, 0); + } + else if(procedure->name_string_idx != 0 || procedure->type_idx != 0) + { + String8List parts = {0}; + E_TypeKey type = e_type_key_ext(E_TypeKind_Function, procedure->type_idx, e_parse_ctx_module_idx_from_rdi(rdi)); + String8 name = {0}; + name.str = rdi_string_from_idx(rdi, procedure->name_string_idx, &name.size); + String8List type_lhs_parts = {0}; + e_type_lhs_string_from_key(scratch.arena, type, &type_lhs_parts, 0, 0); + String8List type_rhs_parts = {0}; + e_type_rhs_string_from_key(scratch.arena, type, &type_rhs_parts, 0); + str8_list_concat_in_place(&parts, &type_lhs_parts); + str8_list_push(scratch.arena, &parts, name); + str8_list_concat_in_place(&parts, &type_rhs_parts); + result = str8_list_join(arena, &parts, 0); + } + else + { + result = str8_lit("???"); + } + } + di_scope_close(di_scope); + scratch_end(scratch); + }break; } if(col->dequote_string && result.size >= 2 && @@ -2189,7 +2266,6 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo case RD_WatchViewColumnKind_Value: {name = str8_lit("Value");}break; case RD_WatchViewColumnKind_Type: {name = str8_lit("Type");}break; case RD_WatchViewColumnKind_ViewRule:{name = str8_lit("View Rule");}break; - case RD_WatchViewColumnKind_Module: {name = str8_lit("Module");}break; case RD_WatchViewColumnKind_Member: { name = str8(col->string_buffer, col->string_size); @@ -2583,7 +2659,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, RD_WatchViewFlags flags, String8 roo cell_ghost_text = ev_auto_view_rule_from_type_key(row_eval.type_key); } }break; - case RD_WatchViewColumnKind_FrameSelection: + case RD_WatchViewColumnKind_CallStackFrameSelection: { #if 0 // TODO(rjf): @blocks if(semantic_num - 1 == rd_regs()->unwind_count - rd_regs()->inline_depth) @@ -5381,11 +5457,12 @@ RD_VIEW_RULE_UI_FUNCTION_DEF(call_stack) if(!wv->initialized) { rd_watch_view_init(wv); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_FrameSelection, 0.05f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Value, 0.7f); - rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Module, 0.25f, .is_non_code = 1); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_CallStackFrameSelection, 0.05f); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_CallStackFrame, 0.50f, .display_string = str8_lit("Symbol"), .dequote_string = 1); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Member, 0.20f, .string = str8_lit("vaddr"), .display_string = str8_lit("Address")); + rd_watch_view_column_alloc(wv, RD_WatchViewColumnKind_Module, 0.25f, .string = str8_lit("module.str"), .display_string = str8_lit("Module"), .dequote_string = 1, .is_non_code = 1); } - rd_watch_view_build(wv, 0, str8_lit("current_thread.callstack.v"), str8_lit("array:current_thread.callstack.count"), 0, 10, rect); + rd_watch_view_build(wv, 0, str8_lit("current_thread.callstack.v"), str8_lit("array:current_thread.callstack.count, hex"), 0, 10, rect); ProfEnd(); } diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 1d0217fe..9b02542e 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -55,9 +55,10 @@ typedef enum RD_WatchViewColumnKind RD_WatchViewColumnKind_Value, RD_WatchViewColumnKind_Type, RD_WatchViewColumnKind_ViewRule, - RD_WatchViewColumnKind_Module, RD_WatchViewColumnKind_Member, - RD_WatchViewColumnKind_FrameSelection, + RD_WatchViewColumnKind_CallStackFrame, + RD_WatchViewColumnKind_CallStackFrameSelection, + RD_WatchViewColumnKind_Module, RD_WatchViewColumnKind_COUNT } RD_WatchViewColumnKind;