From 645cf46e55bad1ca6c6d9baa19340c29ce36e55b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Wed, 10 Jun 2026 11:57:53 -0700 Subject: [PATCH] explicit process address space evaluation --- src/eval/eval_core.c | 68 ++++++++ src/eval/eval_core.h | 28 ++++ src/eval/eval_interpret.c | 6 +- src/eval/eval_ir.c | 7 + .../eval_visualization_core.c | 7 + .../eval_visualization_core.h | 2 +- src/raddbg/generated/raddbg.meta.c | 2 +- src/raddbg/raddbg.mdesk | 2 +- src/raddbg/raddbg_core.c | 25 ++- src/raddbg/raddbg_core.h | 1 + src/raddbg/raddbg_eval.c | 150 ++++++++++++++++-- src/raddbg/raddbg_eval.h | 8 + src/raddbg/raddbg_views.c | 13 +- 13 files changed, 292 insertions(+), 27 deletions(-) diff --git a/src/eval/eval_core.c b/src/eval/eval_core.c index 615944cd..30dea758 100644 --- a/src/eval/eval_core.c +++ b/src/eval/eval_core.c @@ -869,6 +869,74 @@ e_dbg_info_from_type_key(E_TypeKey type_key) //////////////////////////////// //~ rjf: Cache Accessing Functions +//- rjf: locals/members maps + +internal E_String2NumMap * +e_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff) +{ + if(e_cache->locals_map_map_slots_count == 0) + { + e_cache->locals_map_map_slots_count = 8; + e_cache->locals_map_map_slots = push_array(e_cache->arena, E_LocalMapCacheSlot, e_cache->locals_map_map_slots_count); + } + U64 hash = u64_hash_from_seed_str8(voff, str8_struct(&dbgi_key)); + U64 slot_idx = hash%e_cache->locals_map_map_slots_count; + E_LocalMapCacheSlot *slot = &e_cache->locals_map_map_slots[slot_idx]; + E_LocalMapCacheNode *node = 0; + for(E_LocalMapCacheNode *n = slot->first; n != 0; n = n->next) + { + if(di_key_match(n->dbgi_key, dbgi_key) && n->voff == voff) + { + node = n; + } + } + if(node == 0) + { + Access *access = access_open(); + RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0); + node = push_array(e_cache->arena, E_LocalMapCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->dbgi_key = dbgi_key; + node->voff = voff; + node->map = e_push_locals_map_from_rdi_voff(e_cache->arena, rdi, voff); + access_close(access); + } + return node->map; +} + +internal E_String2NumMap * +e_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff) +{ + if(e_cache->member_map_map_slots_count == 0) + { + e_cache->member_map_map_slots_count = 8; + e_cache->member_map_map_slots = push_array(e_cache->arena, E_LocalMapCacheSlot, e_cache->member_map_map_slots_count); + } + U64 hash = u64_hash_from_seed_str8(voff, str8_struct(&dbgi_key)); + U64 slot_idx = hash%e_cache->member_map_map_slots_count; + E_LocalMapCacheSlot *slot = &e_cache->member_map_map_slots[slot_idx]; + E_LocalMapCacheNode *node = 0; + for(E_LocalMapCacheNode *n = slot->first; n != 0; n = n->next) + { + if(di_key_match(n->dbgi_key, dbgi_key) && n->voff == voff) + { + node = n; + } + } + if(node == 0) + { + Access *access = access_open(); + RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0); + node = push_array(e_cache->arena, E_LocalMapCacheNode, 1); + SLLQueuePush(slot->first, slot->last, node); + node->dbgi_key = dbgi_key; + node->voff = voff; + node->map = e_push_member_map_from_rdi_voff(e_cache->arena, rdi, voff); + access_close(access); + } + return node->map; +} + //- rjf: parent key stack internal E_Key diff --git a/src/eval/eval_core.h b/src/eval/eval_core.h index 925f48f9..b6c0d40e 100644 --- a/src/eval/eval_core.h +++ b/src/eval/eval_core.h @@ -1065,6 +1065,24 @@ struct E_CacheSlot E_CacheNode *last; }; +//- rjf: locals/members cache types + +typedef struct E_LocalMapCacheNode E_LocalMapCacheNode; +struct E_LocalMapCacheNode +{ + E_LocalMapCacheNode *next; + DI_Key dbgi_key; + U64 voff; + E_String2NumMap *map; +}; + +typedef struct E_LocalMapCacheSlot E_LocalMapCacheSlot; +struct E_LocalMapCacheSlot +{ + E_LocalMapCacheNode *first; + E_LocalMapCacheNode *last; +}; + //- rjf: parent stack typedef struct E_CacheParentNode E_CacheParentNode; @@ -1122,6 +1140,12 @@ struct E_Cache U64 type_cache_slots_count; E_TypeCacheSlot *type_cache_slots; + //- rjf: [locals / members] locals/members map maps + E_LocalMapCacheSlot *locals_map_map_slots; + U64 locals_map_map_slots_count; + E_LocalMapCacheSlot *member_map_map_slots; + U64 member_map_map_slots_count; + //- rjf: [ir] ir gen options B32 disallow_autohooks; B32 disallow_chained_fastpaths; @@ -1278,6 +1302,10 @@ internal E_DbgInfo *e_dbg_info_from_type_key(E_TypeKey type_key); // "parent key stack" also implicitly parameterizes all of these (partly // because it is not relevant in 99% of cases). +//- rjf: locals/members maps +internal E_String2NumMap *e_locals_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff); +internal E_String2NumMap *e_member_map_from_dbgi_key_voff(DI_Key dbgi_key, U64 voff); + //- rjf: parent key stack internal E_Key e_parent_key_push(E_Key key); internal E_Key e_parent_key_pop(void); diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 67b07939..4d09aeec 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -339,9 +339,9 @@ e_interpret(String8 bytecode) case RDI_EvalOp_RegRead: { - U8 rdi_reg_code = (imm.u64&0x0000FF)>>0; - U8 byte_size = (imm.u64&0x00FF00)>>8; - U8 byte_off = (imm.u64&0xFF0000)>>16; + U8 rdi_reg_code = (imm.u64&0x0000FF)>>0; + U8 byte_size = (imm.u64&0x00FF00)>>8; + U8 byte_off = (imm.u64&0xFF0000)>>16; Arch arch = e_interpret_ctx->reg_arch; ARCH_Info *arch_info = arch_info_from_arch(arch); ARCH_RegCode base_reg_code = arch_reg_code_from_rdi(arch, rdi_reg_code); diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 34b1742a..ab1974f8 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -1305,6 +1305,13 @@ e_push_irtree_and_type_from_expr(Arena *arena, E_IRTreeAndType *root_parent, E_I int_root = e_irtree_binary_op_u(arena, RDI_EvalOp_Mul, ptr_size, int_root, const_root); } E_TypeKey ptr_type = ptr_tree->type_key; + { + E_Type *ptr_type_info = e_type_from_key(ptr_type); + if(ptr_type_info->flags != 0) + { + ptr_type = e_type_key_cons_ptr(ptr_type_info->arch, ptr_type_info->direct_type_key, 1, 0); + } + } if(ptr_is_decay) { ptr_type = e_type_key_cons_ptr(e_base_ctx->primary_module->arch, direct_type, 1, 0); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 9996b929..8c5eb508 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -1795,6 +1795,13 @@ ev_string_iter_next(Arena *arena, EV_StringIter *it, String8 *out_string) case E_TypeKind_RRef: case E_TypeKind_Array: { + E_Type *type = e_type_from_key(type_key); + if(type->flags & E_TypeFlag_ArrayLikeExpansion) + { + expansion_opener_symbol = str8_lit("["); + expansion_closer_symbol = str8_lit("]"); + goto arrays_and_sets_and_structs; + } if(type_kind == E_TypeKind_Array && it->top_task->redirect_to_sets_and_structs) { expansion_opener_symbol = str8_lit("["); diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index 301ae947..d3a4d35b 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -228,7 +228,7 @@ typedef U32 EV_StringFlags; enum { EV_StringFlag_ReadOnlyDisplayRules = (1<<0), - EV_StringFlag_PrettyNames = (1<<1), + EV_StringFlag_DisablePrettyNames = (1<<1), EV_StringFlag_DisableAddresses = (1<<2), EV_StringFlag_DisableStrings = (1<<3), EV_StringFlag_DisableChars = (1<<4), diff --git a/src/raddbg/generated/raddbg.meta.c b/src/raddbg/generated/raddbg.meta.c index 07538564..2077358e 100644 --- a/src/raddbg/generated/raddbg.meta.c +++ b/src/raddbg/generated/raddbg.meta.c @@ -472,7 +472,7 @@ RD_NameSchemaInfo rd_name_schema_info_table[39] = {str8_lit_comp("type_view"), 0, str8_lit_comp("@collection_commands(add_type_view) @row_commands(remove_cfg) x:{'type':expr_string, 'expr':expr_string}")}, {str8_lit_comp("recent_project"), 0, str8_lit_comp("x:{'path':path, 'name':string}")}, {str8_lit_comp("machine"), 0, str8_lit_comp("x:{'label':code_string, @no_expand 'active':bool, 'unattached_processes':set, 'processes':set}")}, -{str8_lit_comp("process"), 0, str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':set, 'threads':set}")}, +{str8_lit_comp("process"), 0, str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':set, 'threads':set, @query @no_expand 'memory':address_space}")}, {str8_lit_comp("module"), 0, str8_lit_comp("x:{'exe':path, 'dbg':path, 'vaddr_range':vaddr_range}")}, {str8_lit_comp("thread"), 0, str8_lit_comp("x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'call_stack':set}")}, }; diff --git a/src/raddbg/raddbg.mdesk b/src/raddbg/raddbg.mdesk index 5f6d0837..ba14a0bb 100644 --- a/src/raddbg/raddbg.mdesk +++ b/src/raddbg/raddbg.mdesk @@ -806,7 +806,7 @@ RD_VocabTable: //- rjf: @schema process { process, 0, - ```x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':set, 'threads':set}```, + ```x:{'label':code_string, 'id':u64, @no_expand 'active':bool, 'modules':set, 'threads':set, @query @no_expand 'memory':address_space}```, } //- rjf: @schema module diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index b2d5b0d2..68cb2fe6 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -707,6 +707,7 @@ rd_ctrl_entity_from_eval_space(E_Space space) D_Entity *entity = &d_entity_nil; if(space.kind == D_EvalSpaceKind_Entity || space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + space.kind == RD_EvalSpaceKind_MetaCallStack || space.kind == RD_EvalSpaceKind_MetaUnattachedProcess) { D_Handle handle; @@ -2058,11 +2059,16 @@ rd_view_ui(Rng2F32 rect) ////////////////////////////// //- rjf: unpack arguments // + B32 is_autocomplete = cfg_node_child_from_string(view, str8_lit("autocomplete")) != &cfg_nil_node; EV_View *eval_view = rd_view_eval_view(); F32 row_height_px = ui_top_px_height(); S64 num_possible_visible_rows = (S64)(dim_2f32(rect).y/row_height_px); F32 row_string_max_size_px = dim_2f32(rect).x; EV_StringFlags string_flags = EV_StringFlag_ReadOnlyDisplayRules|rd_state->eval_viz_base_string_flags; + if(is_autocomplete) + { + string_flags |= EV_StringFlag_DisablePrettyNames; + } String8 filter = rd_view_query_input(); Vec4F32 pop_background_rgba = {0}; UI_TagF("pop") pop_background_rgba = ui_color_from_name(str8_lit("background")); @@ -3186,8 +3192,7 @@ rd_view_ui(Rng2F32 rect) ////////////////////////////// //- rjf: autocomplete watches -> feed autocompletion info forward // - if(rd_watch_pt_match(ewv->cursor, ewv->mark) && - cfg_node_child_from_string(view, str8_lit("autocomplete")) != &cfg_nil_node) + if(rd_watch_pt_match(ewv->cursor, ewv->mark) && is_autocomplete) { U64 row_num = ev_num_from_key(&block_ranges, ewv->cursor.key); EV_Row *row = ev_row_from_num(scratch.arena, rd_view_eval_view(), &block_ranges, row_num); @@ -3195,7 +3200,7 @@ rd_view_ui(Rng2F32 rect) RD_WatchCell *cell = row_info.cells.first; if(cell != 0) { - RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, 0, &row_info, cell, ui_top_font(), ui_top_font_size(), dim_2f32(rect).y); + RD_WatchRowCellInfo cell_info = rd_info_from_watch_row_cell(scratch.arena, row, string_flags, &row_info, cell, ui_top_font(), ui_top_font_size(), dim_2f32(rect).y); String8 string = dr_string_from_fstrs(ui_build_arena(), &cell_info.eval_fstrs); if(string.size != 0) { @@ -12370,7 +12375,7 @@ rd_frame(void) String8 collection_name = str8_lit("call_stack_tree"); E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = collection_name, - .flags = E_TypeFlag_StubSingleLineExpansion, + .flags = E_TypeFlag_StubSingleLineExpansion|E_TypeFlag_ArrayLikeExpansion, .access = E_TYPE_ACCESS_FUNCTION_NAME(call_stack_tree), .expand = { @@ -12452,6 +12457,18 @@ rd_frame(void) .id_from_num = E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_NAME(peek_types), .num_from_id = E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_NAME(peek_types), })); + e_string2typekey_map_insert(rd_frame_arena(), + rd_state->meta_name2type_map, + str8_lit("call_stack_frame"), + e_type_key_cons(.kind = E_TypeKind_Set, + .name = str8_lit("call_stack_frame"), + .irext = E_TYPE_IREXT_FUNCTION_NAME(call_stack_frame), + .access = E_TYPE_ACCESS_FUNCTION_NAME(call_stack_frame), + .expand = + { + .info = E_TYPE_EXPAND_INFO_FUNCTION_NAME(call_stack_frame), + .range = E_TYPE_EXPAND_RANGE_FUNCTION_NAME(call_stack_frame), + })); e_string2typekey_map_insert(rd_frame_arena(), rd_state->meta_name2type_map, str8_lit("call_stack"), diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 2249fad7..472bcdab 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -16,6 +16,7 @@ enum RD_EvalSpaceKind_MetaTheme, RD_EvalSpaceKind_MetaView, RD_EvalSpaceKind_MetaCtrlEntity, + RD_EvalSpaceKind_MetaCallStack, RD_EvalSpaceKind_MetaUnattachedProcess, RD_EvalSpaceKind_MetaCallStackTree, }; diff --git a/src/raddbg/raddbg_eval.c b/src/raddbg/raddbg_eval.c index 00acd908..f5fc95ca 100644 --- a/src/raddbg/raddbg_eval.c +++ b/src/raddbg/raddbg_eval.c @@ -407,6 +407,8 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) B32 wrap_child_w_meta_expr = 0; B32 is_query_child = md_node_has_tag(child_schema, str8_lit("query"), 0); E_TypeFlags type_flags = (!!is_query_child * E_TypeFlag_IsNotEditable); + B32 is_meta_eval = 1; + E_Mode child_mode = E_Mode_Offset; if(0){} //- rjf: ctrl entity members @@ -476,6 +478,13 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) { child_type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, child_schema->string); } + else if(entity != &d_entity_nil && str8_match(child_schema->first->string, s("address_space"), 0)) + { + D_Entity *process = entity; + child_type_key = e_type_key_cons_ptr(process->arch, e_type_key_basic(E_TypeKind_Void), 1, type_flags|E_TypeFlag_StubSingleLineExpansion|E_TypeFlag_ArrayLikeExpansion); + child_mode = E_Mode_Value; + is_meta_eval = 0; + } //- rjf: extend child type with meta-expression information if(wrap_child_w_meta_expr) @@ -574,14 +583,18 @@ E_TYPE_ACCESS_FUNCTION_DEF(schema) child_eval_space.u64s[0] = cfg->id; child_eval_space.u64s[1] = e_id_from_string(child_schema->string); } - else + else if(is_meta_eval && entity != &d_entity_nil) { child_eval_space = rd_eval_space_from_ctrl_entity(entity, RD_EvalSpaceKind_MetaCtrlEntity); child_eval_space.u64s[2] = e_id_from_string(child_schema->string); } + else if(entity != &d_entity_nil) + { + child_eval_space = rd_eval_space_from_ctrl_entity(entity, D_EvalSpaceKind_Entity); + } irtree.root = e_irtree_set_space(arena, child_eval_space, e_push_irnode(arena, RDI_EvalOp_ConstU64)); irtree.type_key = child_type_key; - irtree.mode = E_Mode_Offset; + irtree.mode = child_mode; } } return irtree; @@ -1061,14 +1074,132 @@ E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs_slice) return num; } +//////////////////////////////// +//~ rjf: `call_stack_frame` Type Hooks + +typedef struct RD_CallStackFrameAccel RD_CallStackFrameAccel; +struct RD_CallStackFrameAccel +{ + Arch arch; + D_Handle thread; + D_Handle process; + U64 frame_index; + D_CallStackFrame *call_stack_frame; +}; + +E_TYPE_IREXT_FUNCTION_DEF(call_stack_frame) +{ + RD_CallStackFrameAccel *accel = push_array(arena, RD_CallStackFrameAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + E_OpList oplist = e_oplist_from_irtree(scratch.arena, irtree->root); + String8 bytecode = e_bytecode_from_oplist(scratch.arena, &oplist); + E_Interpretation interp = e_interpret(bytecode); + D_Entity *entity = rd_ctrl_entity_from_eval_space(interp.space); + U64 frame_index = interp.value.u64; + if(entity->kind == D_EntityKind_Thread) + { + B32 call_stack_high_priority = d_handle_match(entity->handle, rd_base_regs()->thread); + D_CallStack call_stack = d_call_stack_from_thread(rd_state->frame_access, entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); + accel->arch = entity->arch; + accel->thread = entity->handle; + accel->process = d_process_from_entity(entity)->handle; + accel->frame_index = frame_index; + if(frame_index < call_stack.frames_count) + { + accel->call_stack_frame = &call_stack.frames[frame_index]; + } + } + scratch_end(scratch); + } + E_IRExt result = {accel}; + return result; +} + +E_TYPE_ACCESS_FUNCTION_DEF(call_stack_frame) +{ + E_IRTreeAndType result = {&e_irnode_nil}; + if(expr->kind == E_ExprKind_MemberAccess) + { + RD_CallStackFrameAccel *accel = (RD_CallStackFrameAccel *)lhs_irtree->user_data; + if(accel->call_stack_frame != 0) + { + if(str8_match(expr->first->next->string, s("address"), 0)) + { + ARCH_Info *arch_info = arch_info_from_arch(accel->arch); + D_CallStackFrame *f = accel->call_stack_frame; + D_Entity *process = d_entity_from_handle(accel->process); + result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, D_EvalSpaceKind_Entity), e_irtree_const_u(arena, arch_ip_from_reg_block(arch_info, f->regs))); + result.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); + result.mode = E_Mode_Value; + } + else if(str8_match(expr->first->next->string, s("locals"), 0)) + { + D_Entity *thread = d_entity_from_handle(accel->thread); + result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_MetaCallStack), e_irtree_const_u(arena, 0)); + result.type_key = e_type_key_cons(.kind = E_TypeKind_Set, .name = s("locals")); + result.mode = E_Mode_Value; + } + } + } + return result; +} + +typedef struct RD_CallStackFrameExpandAccel RD_CallStackFrameExpandAccel; +struct RD_CallStackFrameExpandAccel +{ + String8Array names; +}; + +E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack_frame) +{ + RD_CallStackFrameExpandAccel *accel = push_array(arena, RD_CallStackFrameExpandAccel, 1); + { + Temp scratch = scratch_begin(&arena, 1); + String8List members_filtered = {0}; + String8 members[] = + { + s("address"), + s("locals"), + }; + for EachElement(idx, members) + { + FuzzyMatchRangeList fuzzy_match_ranges = fuzzy_match_find(scratch.arena, filter, members[idx]); + if(fuzzy_match_ranges.count == fuzzy_match_ranges.needle_part_count) + { + str8_list_push(scratch.arena, &members_filtered, members[idx]); + } + } + accel->names = str8_array_from_list(arena, &members_filtered); + scratch_end(scratch); + } + E_TypeExpandInfo info = {accel, accel->names.count}; + return info; +} + +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(call_stack_frame) +{ + RD_CallStackFrameExpandAccel *accel = (RD_CallStackFrameExpandAccel *)user_data; + Rng1U64 legal_idx_range = r1u64(0, accel->names.count); + Rng1U64 read_range = intersect_1u64(idx_range, legal_idx_range); + U64 read_range_count = dim_1u64(read_range); + for(U64 idx = 0; idx < read_range_count; idx += 1) + { + U64 name_idx = read_range.min + idx; + if(name_idx < accel->names.count) + { + evals_out[idx] = e_eval_wrapf(eval, "$.%S", accel->names.v[name_idx]); + } + } +} + //////////////////////////////// //~ rjf: `call_stack` Type Hooks typedef struct RD_CallStackAccel RD_CallStackAccel; struct RD_CallStackAccel { - Arch arch; - D_Handle process; + D_Handle thread; D_CallStack call_stack; }; @@ -1084,8 +1215,7 @@ E_TYPE_IREXT_FUNCTION_DEF(call_stack) if(entity->kind == D_EntityKind_Thread) { B32 call_stack_high_priority = d_handle_match(entity->handle, rd_base_regs()->thread); - accel->arch = entity->arch; - accel->process = d_process_from_entity(entity)->handle; + accel->thread = entity->handle; accel->call_stack = d_call_stack_from_thread(rd_state->frame_access, entity->handle, call_stack_high_priority, call_stack_high_priority ? rd_state->frame_eval_memread_endt_us : 0); } scratch_end(scratch); @@ -1104,11 +1234,9 @@ E_TYPE_ACCESS_FUNCTION_DEF(call_stack) D_CallStack *call_stack = &accel->call_stack; if(0 <= rhs_value.u64 && rhs_value.u64 < call_stack->frames_count) { - D_Entity *process = d_entity_from_handle(accel->process); - ARCH_Info *arch_info = arch_info_from_arch(accel->arch); - D_CallStackFrame *f = &call_stack->frames[rhs_value.u64]; - result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(process, D_EvalSpaceKind_Entity), e_irtree_const_u(arena, arch_ip_from_reg_block(arch_info, f->regs))); - result.type_key = e_type_key_cons(.arch = process->arch, .kind = E_TypeKind_Ptr, .direct_key = e_type_key_basic(E_TypeKind_Function), .count = 1, .depth = f->inline_depth); + D_Entity *thread = d_entity_from_handle(accel->thread); + result.root = e_irtree_set_space(arena, rd_eval_space_from_ctrl_entity(thread, RD_EvalSpaceKind_MetaCallStack), e_irtree_const_u(arena, rhs_value.u64)); + result.type_key = e_string2typekey_map_lookup(rd_state->meta_name2type_map, s("call_stack_frame")); result.mode = E_Mode_Value; } } diff --git a/src/raddbg/raddbg_eval.h b/src/raddbg/raddbg_eval.h index daba97c3..9ae517dc 100644 --- a/src/raddbg/raddbg_eval.h +++ b/src/raddbg/raddbg_eval.h @@ -73,6 +73,14 @@ E_TYPE_EXPAND_RANGE_FUNCTION_DEF(cfgs_slice); E_TYPE_EXPAND_ID_FROM_NUM_FUNCTION_DEF(cfgs_slice); E_TYPE_EXPAND_NUM_FROM_ID_FUNCTION_DEF(cfgs_slice); +//////////////////////////////// +//~ rjf: `call_stack_frame` Type Hooks + +E_TYPE_IREXT_FUNCTION_DEF(call_stack_frame); +E_TYPE_ACCESS_FUNCTION_DEF(call_stack_frame); +E_TYPE_EXPAND_INFO_FUNCTION_DEF(call_stack_frame); +E_TYPE_EXPAND_RANGE_FUNCTION_DEF(call_stack_frame); + //////////////////////////////// //~ rjf: `call_stack` Type Hooks diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 6062f262..f7b7f018 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1424,7 +1424,7 @@ rd_watch_row_info_from_row(Arena *arena, EV_Row *row) 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_CallStackFrame, row->eval, .default_pct = 0.05f, .pct = take_pct()); - rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, row->eval, .default_pct = 0.75f, .pct = take_pct()); + rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, e_eval_wrapf(row->eval, "$.address"), .default_pct = 0.75f, .pct = take_pct()); rd_watch_cell_list_push_new(arena, &info.cells, RD_WatchCellKind_Eval, (module == &d_entity_nil ? (E_Eval)zero_struct : module_eval), .default_pct = 0.20f, .pct = take_pct()); #undef take_pct @@ -1656,7 +1656,7 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla String8 expr_string = {0}; // rjf: if this cell has a meta-display-name, then use that - if(expr_string.size == 0) + if(expr_string.size == 0 && !(string_flags & EV_StringFlag_DisablePrettyNames)) { for(E_Type *t = e_type_from_key(cell->eval.irtree.type_key); t != &e_type_nil; @@ -1741,10 +1741,11 @@ rd_info_from_watch_row_cell(Arena *arena, EV_Row *row, EV_StringFlags string_fla // do a code-string of ".member_name" String8 member_name = notable_expr->first->next->string; String8 fancy_name = {0}; - if(cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || - cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || - cell->eval.space.kind == E_SpaceKind_File || - cell->eval.space.kind == E_SpaceKind_FileSystem) + if(!(string_flags & EV_StringFlag_DisablePrettyNames) && + (cell->eval.space.kind == RD_EvalSpaceKind_MetaCfg || + cell->eval.space.kind == RD_EvalSpaceKind_MetaCtrlEntity || + cell->eval.space.kind == E_SpaceKind_File || + cell->eval.space.kind == E_SpaceKind_FileSystem)) { fancy_name = rd_display_from_code_name(member_name); }