ctrl flow analysis -> dasm layer

This commit is contained in:
Ryan Fleury
2024-08-29 10:58:16 -07:00
parent 5907783a2e
commit 9bba4f224c
4 changed files with 93 additions and 101 deletions
+30
View File
@@ -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
+38
View File
@@ -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
+25 -56
View File
@@ -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;
-45
View File
@@ -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