diff --git a/src/dasm_cache/dasm_cache.c b/src/dasm_cache/dasm_cache.c index ab61ce07..a58536b2 100644 --- a/src/dasm_cache/dasm_cache.c +++ b/src/dasm_cache/dasm_cache.c @@ -134,6 +134,36 @@ dasm_inst_from_code(Arena *arena, Architecture arch, U64 vaddr, String8 code, DA return inst; } +//////////////////////////////// +//~ rjf: Control Flow Analysis + +internal DASM_CtrlFlowInfo +dasm_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code) +{ + Temp scratch = scratch_begin(&arena, 1); + DASM_CtrlFlowInfo info = {0}; + for(U64 offset = 0; offset < code.size;) + { + DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, vaddr+offset, str8_skip(code, offset), DASM_Syntax_Intel); + U64 inst_vaddr = vaddr+offset; + offset += inst.size; + info.total_size += inst.size; + if(inst.flags & exit_points_mask) + { + DASM_CtrlFlowPoint point = {0}; + point.inst_flags = inst.flags; + point.vaddr = inst_vaddr; + point.jump_dest_vaddr = inst.jump_dest_vaddr; + DASM_CtrlFlowPointNode *node = push_array(arena, DASM_CtrlFlowPointNode, 1); + node->v = point; + SLLQueuePush(info.exit_points.first, info.exit_points.last, node); + info.exit_points.count += 1; + } + } + scratch_end(scratch); + return info; +} + //////////////////////////////// //~ rjf: Parameter Type Functions diff --git a/src/dasm_cache/dasm_cache.h b/src/dasm_cache/dasm_cache.h index 378fba5b..4f054055 100644 --- a/src/dasm_cache/dasm_cache.h +++ b/src/dasm_cache/dasm_cache.h @@ -40,6 +40,39 @@ struct DASM_Inst U64 jump_dest_vaddr; }; +//////////////////////////////// +//~ rjf: Control Flow Analysis Types + +typedef struct DASM_CtrlFlowPoint DASM_CtrlFlowPoint; +struct DASM_CtrlFlowPoint +{ + U64 vaddr; + U64 jump_dest_vaddr; + DASM_InstFlags inst_flags; +}; + +typedef struct DASM_CtrlFlowPointNode DASM_CtrlFlowPointNode; +struct DASM_CtrlFlowPointNode +{ + DASM_CtrlFlowPointNode *next; + DASM_CtrlFlowPoint v; +}; + +typedef struct DASM_CtrlFlowPointList DASM_CtrlFlowPointList; +struct DASM_CtrlFlowPointList +{ + DASM_CtrlFlowPointNode *first; + DASM_CtrlFlowPointNode *last; + U64 count; +}; + +typedef struct DASM_CtrlFlowInfo DASM_CtrlFlowInfo; +struct DASM_CtrlFlowInfo +{ + DASM_CtrlFlowPointList exit_points; + U64 total_size; +}; + //////////////////////////////// //~ rjf: Disassembly Text Decoration Types @@ -249,6 +282,11 @@ global DASM_Shared *dasm_shared = 0; internal DASM_Inst dasm_inst_from_code(Arena *arena, Architecture arch, U64 vaddr, String8 code, DASM_Syntax syntax); +//////////////////////////////// +//~ rjf: Control Flow Analysis + +internal DASM_CtrlFlowInfo dasm_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code); + //////////////////////////////// //~ rjf: Parameter Type Functions diff --git a/src/dbg_engine/dbg_engine_core.c b/src/dbg_engine/dbg_engine_core.c index 4a07328b..998c1685 100644 --- a/src/dbg_engine/dbg_engine_core.c +++ b/src/dbg_engine/dbg_engine_core.c @@ -471,36 +471,6 @@ d_line_list_copy(Arena *arena, D_LineList *list) return dst; } -//////////////////////////////// -//~ rjf: Control Flow Analysis Functions - -internal D_CtrlFlowInfo -d_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code) -{ - Temp scratch = scratch_begin(&arena, 1); - D_CtrlFlowInfo info = {0}; - for(U64 offset = 0; offset < code.size;) - { - DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, vaddr+offset, str8_skip(code, offset), DASM_Syntax_Intel); - U64 inst_vaddr = vaddr+offset; - offset += inst.size; - info.total_size += inst.size; - if(inst.flags & exit_points_mask) - { - D_CtrlFlowPoint point = {0}; - point.inst_flags = inst.flags; - point.vaddr = inst_vaddr; - point.jump_dest_vaddr = inst.jump_dest_vaddr; - D_CtrlFlowPointNode *node = push_array(arena, D_CtrlFlowPointNode, 1); - node->v = point; - SLLQueuePush(info.exit_points.first, info.exit_points.last, node); - info.exit_points.count += 1; - } - } - scratch_end(scratch); - return info; -} - //////////////////////////////// //~ rjf: Command Type Pure Functions @@ -2396,22 +2366,21 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread) } // rjf: machine code => ctrl flow analysis - D_CtrlFlowInfo ctrl_flow_info = {0}; + DASM_CtrlFlowInfo ctrl_flow_info = {0}; if(good_line_info) { - ctrl_flow_info = d_ctrl_flow_info_from_arch_vaddr_code(scratch.arena, - DASM_InstFlag_Call| - DASM_InstFlag_Branch| - DASM_InstFlag_UnconditionalJump| - DASM_InstFlag_ChangesStackPointer| - DASM_InstFlag_Return, - arch, - line_vaddr_rng.min, - machine_code); + ctrl_flow_info = dasm_ctrl_flow_info_from_arch_vaddr_code(scratch.arena, + DASM_InstFlag_Call| + DASM_InstFlag_Branch| + DASM_InstFlag_UnconditionalJump| + DASM_InstFlag_ChangesStackPointer| + DASM_InstFlag_Return, + arch, + line_vaddr_rng.min, + machine_code); LogInfoNamedBlockF("ctrl_flow_info") { - log_infof("flags: %x\n", ctrl_flow_info.flags); - LogInfoNamedBlockF("exit_points") for(D_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) + LogInfoNamedBlockF("exit_points") for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) { log_infof("{vaddr:0x%I64x, jump_dest_vaddr:0x%I64x, inst_flags:%x}\n", n->v.vaddr, n->v.jump_dest_vaddr, n->v.inst_flags); } @@ -2419,9 +2388,9 @@ d_trap_net_from_thread__step_over_line(Arena *arena, D_Entity *thread) } // rjf: push traps for all exit points - if(good_line_info) for(D_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) + if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) { - D_CtrlFlowPoint *point = &n->v; + DASM_CtrlFlowPoint *point = &n->v; CTRL_TrapFlags flags = 0; B32 add = 1; U64 trap_addr = point->vaddr; @@ -2537,24 +2506,24 @@ d_trap_net_from_thread__step_into_line(Arena *arena, D_Entity *thread) } // rjf: machine code => ctrl flow analysis - D_CtrlFlowInfo ctrl_flow_info = {0}; + DASM_CtrlFlowInfo ctrl_flow_info = {0}; if(good_line_info) { - ctrl_flow_info = d_ctrl_flow_info_from_arch_vaddr_code(scratch.arena, - DASM_InstFlag_Call| - DASM_InstFlag_Branch| - DASM_InstFlag_UnconditionalJump| - DASM_InstFlag_ChangesStackPointer| - DASM_InstFlag_Return, - arch, - line_vaddr_rng.min, - machine_code); + ctrl_flow_info = dasm_ctrl_flow_info_from_arch_vaddr_code(scratch.arena, + DASM_InstFlag_Call| + DASM_InstFlag_Branch| + DASM_InstFlag_UnconditionalJump| + DASM_InstFlag_ChangesStackPointer| + DASM_InstFlag_Return, + arch, + line_vaddr_rng.min, + machine_code); } // rjf: push traps for all exit points - if(good_line_info) for(D_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) + if(good_line_info) for(DASM_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next) { - D_CtrlFlowPoint *point = &n->v; + DASM_CtrlFlowPoint *point = &n->v; CTRL_TrapFlags flags = 0; B32 add = 1; U64 trap_addr = point->vaddr; diff --git a/src/dbg_engine/dbg_engine_core.h b/src/dbg_engine/dbg_engine_core.h index 15fc4977..085b3a18 100644 --- a/src/dbg_engine/dbg_engine_core.h +++ b/src/dbg_engine/dbg_engine_core.h @@ -128,46 +128,6 @@ typedef enum D_RunKind } D_RunKind; -//////////////////////////////// -//~ rjf: Control Flow Analysis Types - -typedef U32 D_CtrlFlowFlags; -enum -{ - D_CtrlFlowFlag_StackPointerChangesVariably = (1<<0), -}; - -typedef struct D_CtrlFlowPoint D_CtrlFlowPoint; -struct D_CtrlFlowPoint -{ - U64 vaddr; - U64 jump_dest_vaddr; - DASM_InstFlags inst_flags; -}; - -typedef struct D_CtrlFlowPointNode D_CtrlFlowPointNode; -struct D_CtrlFlowPointNode -{ - D_CtrlFlowPointNode *next; - D_CtrlFlowPoint v; -}; - -typedef struct D_CtrlFlowPointList D_CtrlFlowPointList; -struct D_CtrlFlowPointList -{ - D_CtrlFlowPointNode *first; - D_CtrlFlowPointNode *last; - U64 count; -}; - -typedef struct D_CtrlFlowInfo D_CtrlFlowInfo; -struct D_CtrlFlowInfo -{ - D_CtrlFlowFlags flags; - D_CtrlFlowPointList exit_points; - U64 total_size; -}; - //////////////////////////////// //~ rjf: View Rule Hook Types @@ -1198,11 +1158,6 @@ internal D_CfgVal *d_cfg_val_from_string(D_CfgTable *table, String8 string); internal D_LineList d_line_list_copy(Arena *arena, D_LineList *list); -//////////////////////////////// -//~ rjf: Control Flow Analysis Pure Functions - -internal D_CtrlFlowInfo d_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DASM_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code); - //////////////////////////////// //~ rjf: Command Type Pure Functions