diff --git a/src/ctrl/ctrl_core.h b/src/ctrl/ctrl_core.h index 1ccb6a5a..0a966f7d 100644 --- a/src/ctrl/ctrl_core.h +++ b/src/ctrl/ctrl_core.h @@ -51,6 +51,10 @@ X(U64, hit_count)\ X(U64, id)\ X(U32, color)\ X(String8, label)\ +X(String8, exe)\ +X(String8, args)\ +X(String8, working_directory)\ +X(String8, entry_point)\ X(String8, location)\ X(String8, condition)\ X(CTRL_MetaEvalFrameArray, callstack) diff --git a/src/eval/eval_ir.c b/src/eval/eval_ir.c index 92c81386..c4bba2c4 100644 --- a/src/eval/eval_ir.c +++ b/src/eval/eval_ir.c @@ -519,7 +519,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) // rjf: look up member B32 r_found = 0; E_TypeKey r_type = zero_struct; - U32 r_off = 0; + U64 r_value = 0; + B32 r_is_constant_value = 0; { Temp scratch = scratch_begin(&arena, 1); E_MemberArray check_type_members = e_type_data_members_from_key(scratch.arena, check_type_key); @@ -541,7 +542,34 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) { r_found = 1; r_type = match->type_key; - r_off = match->off; + r_value = match->off; + } + if(match == 0) + { + E_Type *type = e_type_from_key(scratch.arena, check_type_key); + if(type->enum_vals != 0) + { + E_EnumVal *enum_val_match = 0; + for EachIndex(idx, type->count) + { + if(str8_match(type->enum_vals[idx].name, exprr->string, 0)) + { + enum_val_match = &type->enum_vals[idx]; + break; + } + else if(str8_match(type->enum_vals[idx].name, exprr->string, StringMatchFlag_CaseInsensitive)) + { + enum_val_match = &type->enum_vals[idx]; + } + } + if(enum_val_match != 0) + { + r_found = 1; + r_type = check_type_key; + r_value = enum_val_match->val; + r_is_constant_value = 1; + } + } } scratch_end(scratch); } @@ -563,7 +591,8 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) } else if(check_type_kind != E_TypeKind_Struct && check_type_kind != E_TypeKind_Class && - check_type_kind != E_TypeKind_Union) + check_type_kind != E_TypeKind_Union && + check_type_kind != E_TypeKind_Enum) { e_msgf(arena, &result.msgs, E_MsgKind_MalformedInput, exprl->location, "Cannot perform member access on this type."); break; @@ -583,12 +612,17 @@ e_irtree_and_type_from_expr(Arena *arena, E_Expr *expr) new_tree = e_irtree_resolve_to_value(arena, l.space, l.mode, new_tree, l_restype); mode = E_Mode_Offset; } - if(r_off != 0) + if(r_value != 0 && !r_is_constant_value) { - E_IRNode *const_tree = e_irtree_const_u(arena, r_off); + E_IRNode *const_tree = e_irtree_const_u(arena, r_value); new_tree = e_irtree_binary_op_u(arena, RDI_EvalOp_Add, new_tree, const_tree); } } + else if(r_is_constant_value) + { + new_tree = e_irtree_const_u(arena, r_value); + mode = E_Mode_Value; + } // rjf: fill result.root = new_tree; diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index be722c7d..bcdc5008 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -437,7 +437,7 @@ e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key) } internal E_TypeKey -e_type_key_cons_base(Type *type, String8 name) +e_type_key_cons_base(Type *type) { E_TypeKey result = e_type_key_zero(); switch(type->kind) @@ -450,12 +450,12 @@ e_type_key_cons_base(Type *type, String8 name) }break; case TypeKind_Ptr: { - E_TypeKey direct_type = e_type_key_cons_base(type->direct, str8_zero()); + E_TypeKey direct_type = e_type_key_cons_base(type->direct); result = e_type_key_cons_ptr(arch_from_context(), direct_type); }break; case TypeKind_Array: { - E_TypeKey direct_type = e_type_key_cons_base(type->direct, str8_zero()); + E_TypeKey direct_type = e_type_key_cons_base(type->direct); result = e_type_key_cons_array(direct_type, type->count); }break; case TypeKind_Struct: @@ -464,13 +464,13 @@ e_type_key_cons_base(Type *type, String8 name) E_MemberList members = {0}; for(U64 idx = 0; idx < type->count; idx += 1) { - E_TypeKey member_type_key = e_type_key_cons_base(type->members[idx].type, str8_zero()); + E_TypeKey member_type_key = e_type_key_cons_base(type->members[idx].type); e_member_list_push_new(scratch.arena, &members, .name = type->members[idx].name, .off = type->members[idx].value, .type_key = member_type_key); } E_MemberArray members_array = e_member_array_from_list(scratch.arena, &members); result = e_type_key_cons(.arch = arch_from_context(), .kind = E_TypeKind_Struct, - .name = name.size ? name : type->name, + .name = type->name, .members = members_array.v, .count = members_array.count); scratch_end(scratch); diff --git a/src/eval/eval_types.h b/src/eval/eval_types.h index 4624b3df..cb05550b 100644 --- a/src/eval/eval_types.h +++ b/src/eval/eval_types.h @@ -243,7 +243,7 @@ internal E_TypeKey e_type_key_cons_(E_ConsTypeParams *params); //- rjf: constructed type construction helpers internal E_TypeKey e_type_key_cons_array(E_TypeKey element_type_key, U64 count); internal E_TypeKey e_type_key_cons_ptr(Arch arch, E_TypeKey element_type_key); -internal E_TypeKey e_type_key_cons_base(Type *type, String8 name); +internal E_TypeKey e_type_key_cons_base(Type *type); //- rjf: basic type key functions internal B32 e_type_key_match(E_TypeKey l, E_TypeKey r); diff --git a/src/eval_visualization/eval_visualization_core.c b/src/eval_visualization/eval_visualization_core.c index 21df6c85..f6733589 100644 --- a/src/eval_visualization/eval_visualization_core.c +++ b/src/eval_visualization/eval_visualization_core.c @@ -62,7 +62,7 @@ ev_hash_from_key(EV_Key key) //- rjf: type info -> expandability/editablity internal B32 -ev_type_key_is_expandable(E_TypeKey type_key) +ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode) { B32 result = 0; for(E_TypeKey t = type_key; !result; t = e_type_unwrap(e_type_direct_from_key(e_type_unwrap(t)))) @@ -76,7 +76,7 @@ ev_type_key_is_expandable(E_TypeKey type_key) kind == E_TypeKind_Union || kind == E_TypeKind_Class || kind == E_TypeKind_Array || - kind == E_TypeKind_Enum) + (kind == E_TypeKind_Enum && mode == E_Mode_Null)) { result = 1; } @@ -1135,7 +1135,7 @@ ev_row_is_expandable(EV_Row *row) { Temp scratch = scratch_begin(0, 0); E_IRTreeAndType irtree = e_irtree_and_type_from_expr(scratch.arena, row->expr); - result = ev_type_key_is_expandable(irtree.type_key); + result = ev_type_key_and_mode_is_expandable(irtree.type_key, irtree.mode); scratch_end(scratch); } } diff --git a/src/eval_visualization/eval_visualization_core.h b/src/eval_visualization/eval_visualization_core.h index c47da3cb..dc6ff24c 100644 --- a/src/eval_visualization/eval_visualization_core.h +++ b/src/eval_visualization/eval_visualization_core.h @@ -321,7 +321,7 @@ internal U64 ev_hash_from_key(EV_Key key); //~ rjf: Type Info Helpers //- rjf: type info -> expandability/editablity -internal B32 ev_type_key_is_expandable(E_TypeKey type_key); +internal B32 ev_type_key_and_mode_is_expandable(E_TypeKey type_key, E_Mode mode); internal B32 ev_type_key_is_editable(E_TypeKey type_key); //////////////////////////////// diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 4b2bfb16..1d8a3092 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -1933,6 +1933,10 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) if(space.kind == RD_EvalSpaceKind_MetaEntity) { RD_Entity *entity = rd_entity_from_eval_space(space); + RD_Entity *exe = rd_entity_child_from_kind(entity, RD_EntityKind_Executable); + RD_Entity *args= rd_entity_child_from_kind(entity, RD_EntityKind_Arguments); + RD_Entity *wdir= rd_entity_child_from_kind(entity, RD_EntityKind_WorkingDirectory); + RD_Entity *entr= rd_entity_child_from_kind(entity, RD_EntityKind_EntryPoint); RD_Entity *loc = rd_entity_child_from_kind(entity, RD_EntityKind_Location); RD_Entity *cnd = rd_entity_child_from_kind(entity, RD_EntityKind_Condition); String8 label_string = push_str8_copy(scratch.arena, entity->string); @@ -1950,6 +1954,10 @@ rd_eval_space_read(void *u, E_Space space, void *out, Rng1U64 range) meval->hit_count = entity->u64; meval->color = u32_from_rgba(rd_rgba_from_entity(entity)); meval->label = label_string; + meval->exe = exe->string; + meval->args = args->string; + meval->working_directory = wdir->string; + meval->entry_point = entr->string; meval->location = loc_string; meval->condition = cnd_string; } @@ -7853,10 +7861,110 @@ rd_window_frame(RD_Window *ws) EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod) { + ////////////////////////////// + //- rjf: targets + // + if(str8_match(string, str8_lit("targets"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList targets = rd_query_cached_entity_list_with_kind(RD_EntityKind_Target); + EV_ViewRuleList top_level_view_rules = {0}; + for(RD_EntityNode *n = targets.first; n != 0; n = n->next) + { + RD_Entity *target = n->entity; + String8 target_expr_string = push_str8f(arena, "$%I64u", target->id); + EV_Key target_parent_key = key; + EV_Key target_key = ev_key_make(ev_hash_from_key(target_parent_key), target->id); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, target_expr_string, target_parent_key, target_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: breakpoints + // + else if(str8_match(string, str8_lit("breakpoints"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList bps = rd_query_cached_entity_list_with_kind(RD_EntityKind_Breakpoint); + EV_ViewRuleList top_level_view_rules = {0}; + for(RD_EntityNode *n = bps.first; n != 0; n = n->next) + { + RD_Entity *bp = n->entity; + String8 bp_expr_string = push_str8f(arena, "$%I64u", bp->id); + EV_Key bp_parent_key = key; + EV_Key bp_key = ev_key_make(ev_hash_from_key(bp_parent_key), bp->id); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, bp_expr_string, bp_parent_key, bp_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: watch_pins + // + else if(str8_match(string, str8_lit("watch_pins"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + RD_EntityList wps = rd_query_cached_entity_list_with_kind(RD_EntityKind_WatchPin); + EV_ViewRuleList top_level_view_rules = {0}; + for(RD_EntityNode *n = wps.first; n != 0; n = n->next) + { + RD_Entity *wp = n->entity; + String8 wp_expr_string = push_str8f(arena, "$%I64u", wp->id); + EV_Key wp_parent_key = key; + EV_Key wp_key = ev_key_make(ev_hash_from_key(wp_parent_key), wp->id); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, wp_expr_string, wp_parent_key, wp_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: threads + // + else if(str8_match(string, str8_lit("threads"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Thread); + EV_ViewRuleList top_level_view_rules = {0}; + for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + String8 entity_expr_string = push_str8f(arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); + EV_Key entity_parent_key = key; + EV_Key entity_key = ev_key_make(ev_hash_from_key(entity_parent_key), d_hash_from_string(entity_expr_string)); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, entity_expr_string, entity_parent_key, entity_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); + } + + ////////////////////////////// + //- rjf: modules + // + else if(str8_match(string, str8_lit("modules"), 0)) + { + Temp scratch = scratch_begin(&arena, 1); + CTRL_EntityList entities = ctrl_entity_list_from_kind(d_state->ctrl_entity_store, CTRL_EntityKind_Module); + EV_ViewRuleList top_level_view_rules = {0}; + for(CTRL_EntityNode *n = entities.first; n != 0; n = n->next) + { + CTRL_Entity *entity = n->v; + String8 entity_expr_string = push_str8f(arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]); + EV_Key entity_parent_key = key; + EV_Key entity_key = ev_key_make(ev_hash_from_key(entity_parent_key), d_hash_from_string(entity_expr_string)); + EV_BlockList blocks = ev_block_list_from_view_expr_keys(arena, view, str8_zero(), &top_level_view_rules, entity_expr_string, entity_parent_key, entity_key, depth); + ev_block_list_concat__in_place(out, &blocks); + } + scratch_end(scratch); + } + ////////////////////////////// //- rjf: locals // - if(str8_match(string, str8_lit("locals"), 0)) + else if(str8_match(string, str8_lit("locals"), 0)) { Temp scratch = scratch_begin(&arena, 1); E_String2NumMapNodeArray nodes = e_string2num_map_node_array_from_map(scratch.arena, e_parse_ctx->locals_map); @@ -7953,7 +8061,7 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod) EV_ExpandNode *root_node = ev_expand_node_from_key(view, key); //- rjf: query all filtered items from dbgi searching system - U128 fuzzy_search_key = {rd_regs()->view.u64[0], rd_regs()->view.u64[1]}; + U128 fuzzy_search_key = {rd_regs()->view.u64[0], d_hash_from_seed_string(ev_hash_from_key(key), string)}; B32 items_stale = 0; FZY_Params params = {fzy_target, dbgi_keys}; FZY_ItemArray items = fzy_items_from_key_params_query(rd_state->frame_fzy_scope, fuzzy_search_key, ¶ms, filter, endt_us, &items_stale); @@ -8024,7 +8132,7 @@ EV_VIEW_RULE_BLOCK_PROD_FUNCTION_DEF(rd_collection_block_prod) } //- rjf: build blocks for all table items, split by sorted sub-expansions - EV_Block *last_vb = ev_block_begin(arena, EV_BlockKind_DebugInfoTable, parent_key, key, depth); + EV_Block *last_vb = ev_block_begin(arena, EV_BlockKind_DebugInfoTable, key, ev_key_make(ev_hash_from_key(key), 0), depth); { last_vb->visual_idx_range = last_vb->semantic_idx_range = r1u64(0, items.count); last_vb->fzy_target = fzy_target; @@ -10486,7 +10594,7 @@ rd_frame(void) //- rjf: build eval IR context // E_TypeKey collection_type_key = e_type_key_cons(.kind = E_TypeKind_Collection, .name = str8_lit("collection")); - E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval), str8_lit("entity")); + E_TypeKey meta_eval_type_key = e_type_key_cons_base(type(CTRL_MetaEval)); E_IRCtx *ir_ctx = push_array(scratch.arena, E_IRCtx, 1); { E_IRCtx *ctx = ir_ctx; @@ -10497,6 +10605,11 @@ rd_frame(void) { String8 collection_names[] = { + str8_lit_comp("targets"), + str8_lit_comp("breakpoints"), + str8_lit_comp("watch_pins"), + str8_lit_comp("threads"), + str8_lit_comp("modules"), str8_lit_comp("locals"), str8_lit_comp("registers"), str8_lit_comp("globals"), @@ -10563,10 +10676,15 @@ rd_frame(void) expr->space = space; expr->mode = E_Mode_Offset; expr->type_key = meta_eval_type_key; + e_string2expr_map_insert(scratch.arena, ctx->macro_map, push_str8f(scratch.arena, "$_%I64x_%I64x", entity->handle.machine_id, entity->handle.dmn_handle.u64[0]), expr); if(entity->string.size != 0) { e_string2expr_map_insert(scratch.arena, ctx->macro_map, entity->string, expr); } + if(kind == CTRL_EntityKind_Thread && ctrl_handle_match(rd_base_regs()->thread, entity->handle)) + { + e_string2expr_map_insert(scratch.arena, ctx->macro_map, str8_lit("current_thread"), expr); + } } } } @@ -10643,7 +10761,7 @@ rd_frame(void) // EV_AutoViewRuleTable *auto_view_rule_table = push_array(scratch.arena, EV_AutoViewRuleTable, 1); { - ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MetaEvalFrameArray), str8_zero()), str8_lit("slice")); + ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, e_type_key_cons_base(type(CTRL_MetaEvalFrameArray)), str8_lit("slice")); ev_auto_view_rule_table_push_new(scratch.arena, auto_view_rule_table, collection_type_key, str8_lit("collection")); } ev_select_auto_view_rule_table(auto_view_rule_table); diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index 0aeb9434..f0fc3dd8 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -1051,7 +1051,7 @@ rd_watch_view_build(RD_WatchViewState *ewv, B32 modifiable, U32 default_radix, R // case RD_WatchViewFillKind_Breakpoints: { - E_TypeKey meta_eval_type = e_type_key_cons_base(type(CTRL_MetaEval), str8_lit("RADDBG_Entity")); + E_TypeKey meta_eval_type = e_type_key_cons_base(type(CTRL_MetaEval)); mutable_entity_kind = RD_EntityKind_Breakpoint; ev_view_rule_list_push_string(scratch.arena, &top_level_view_rules, str8_lit("no_addr")); RD_EntityList bps = rd_query_cached_entity_list_with_kind(mutable_entity_kind);