mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-07-11 12:01:26 -07:00
switch ctrl flow analysis etc. to zydis from udis86; unify disassembling path in dasm_cache layer, use single instruction decode path in frontend for ctrl flow analysis; use in dasm cache layer for disassembly textualization
This commit is contained in:
+26
-216
@@ -668,175 +668,6 @@ df_string_from_cfg_node_key(DF_CfgNode *node, String8 key, StringMatchFlags flag
|
||||
return child->first->string;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembling
|
||||
|
||||
#include "third_party/udis86/config.h"
|
||||
#include "third_party/udis86/udis86.h"
|
||||
#include "third_party/udis86/libudis86/syn.h"
|
||||
|
||||
internal DF_Inst
|
||||
df_single_inst_from_machine_code__x64(Arena *arena, U64 start_voff, String8 string)
|
||||
{
|
||||
Architecture arch = Architecture_x64;
|
||||
|
||||
//- rjf: prep ud state
|
||||
struct ud ud_ctx_;
|
||||
struct ud *ud_ctx = &ud_ctx_;
|
||||
ud_init(ud_ctx);
|
||||
ud_set_mode(ud_ctx, bit_size_from_arch(arch));
|
||||
ud_set_pc(ud_ctx, start_voff);
|
||||
ud_set_input_buffer(ud_ctx, string.str, string.size);
|
||||
ud_set_vendor(ud_ctx, UD_VENDOR_ANY);
|
||||
ud_set_syntax(ud_ctx, UD_SYN_INTEL);
|
||||
|
||||
//- rjf: disassembly + get info
|
||||
U32 bytes_disassembled = ud_disassemble(ud_ctx);
|
||||
struct ud_operand *first_op = (struct ud_operand *)ud_insn_opr(ud_ctx, 0);
|
||||
U64 rel_voff = (first_op != 0 && first_op->type == UD_OP_JIMM) ? ud_syn_rel_target(ud_ctx, first_op) : 0;
|
||||
DF_InstFlags flags = 0;
|
||||
enum ud_mnemonic_code code = ud_insn_mnemonic(ud_ctx);
|
||||
switch(code)
|
||||
{
|
||||
case UD_Icall:
|
||||
{
|
||||
flags |= DF_InstFlag_Call;
|
||||
}break;
|
||||
|
||||
/* TODO(wonchun)
|
||||
case UD_Iiretd:
|
||||
case UD_Iiretw:
|
||||
*/
|
||||
|
||||
case UD_Ija:
|
||||
case UD_Ijae:
|
||||
case UD_Ijb:
|
||||
case UD_Ijbe:
|
||||
case UD_Ijcxz:
|
||||
case UD_Ijecxz:
|
||||
case UD_Ijg:
|
||||
case UD_Ijge:
|
||||
case UD_Ijl:
|
||||
case UD_Ijle:
|
||||
{
|
||||
flags |= DF_InstFlag_Branch;
|
||||
}break;
|
||||
|
||||
case UD_Ijmp:
|
||||
{
|
||||
flags |= DF_InstFlag_UnconditionalJump;
|
||||
}break;
|
||||
|
||||
case UD_Ijno:
|
||||
case UD_Ijnp:
|
||||
case UD_Ijns:
|
||||
case UD_Ijnz:
|
||||
case UD_Ijo:
|
||||
case UD_Ijp:
|
||||
case UD_Ijrcxz:
|
||||
case UD_Ijs:
|
||||
case UD_Ijz:
|
||||
case UD_Iloop:
|
||||
case UD_Iloope:
|
||||
case UD_Iloopne:
|
||||
{
|
||||
flags |= DF_InstFlag_Branch;
|
||||
}break;
|
||||
|
||||
case UD_Iret:
|
||||
case UD_Iretf:
|
||||
{
|
||||
flags |= DF_InstFlag_Return;
|
||||
}break;
|
||||
|
||||
/* TODO(wonchun)
|
||||
case UD_Isyscall:
|
||||
case UD_Isysenter:
|
||||
case UD_Isysexit:
|
||||
case UD_Isysret:
|
||||
case UD_Ivmcall:
|
||||
case UD_Ivmmcall:
|
||||
*/
|
||||
default:
|
||||
{
|
||||
flags |= DF_InstFlag_NonFlow;
|
||||
}break;
|
||||
}
|
||||
|
||||
//- rjf: check for stack pointer modifications
|
||||
S64 sp_delta = 0;
|
||||
{
|
||||
struct ud_operand *dst_op = (struct ud_operand *)ud_insn_opr(ud_ctx, 0);
|
||||
struct ud_operand *src_op = (struct ud_operand *)ud_insn_opr(ud_ctx, 1);
|
||||
|
||||
// rjf: direct additions/subtractions to RSP
|
||||
if(dst_op && src_op && dst_op->base == UD_R_RSP && dst_op->type == UD_OP_REG)
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointer;
|
||||
// TODO(rjf): does the library report constant changes to the stack pointer
|
||||
// as UD_OP_CONST too? what does UD_OP_JIMM refer to?
|
||||
if(src_op->base == UD_NONE && src_op->type == UD_OP_IMM && code == UD_Isub)
|
||||
{
|
||||
S64 sign = -1;
|
||||
sp_delta = sign * src_op->lval.sqword;
|
||||
}
|
||||
else if(src_op->base == UD_NONE && src_op->type == UD_OP_IMM && code == UD_Iadd)
|
||||
{
|
||||
S64 sign = +1;
|
||||
sp_delta = sign * src_op->lval.sqword;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointerVariably;
|
||||
}
|
||||
}
|
||||
|
||||
// rjf: push/pop
|
||||
if(code == UD_Ipush)
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointer;
|
||||
sp_delta = -8;
|
||||
}
|
||||
else if(code == UD_Ipop)
|
||||
{
|
||||
flags |= DF_InstFlag_ChangesStackPointer;
|
||||
sp_delta = +8;
|
||||
}
|
||||
|
||||
// rjf: mark extra flags
|
||||
if(ud_ctx->pfx_rep != 0 ||
|
||||
ud_ctx->pfx_repe != 0 ||
|
||||
ud_ctx->pfx_repne != 0)
|
||||
{
|
||||
flags |= DF_InstFlag_Repeats;
|
||||
}
|
||||
}
|
||||
|
||||
//- rjf: fill+return
|
||||
DF_Inst inst = {0};
|
||||
inst.size = bytes_disassembled;
|
||||
inst.string = push_str8_copy(arena, str8_cstring((char *)ud_insn_asm(ud_ctx)));
|
||||
inst.rel_voff = rel_voff;
|
||||
inst.sp_delta = sp_delta;
|
||||
inst.flags = flags;
|
||||
return inst;
|
||||
}
|
||||
|
||||
internal DF_Inst
|
||||
df_single_inst_from_machine_code(Arena *arena, Architecture arch, U64 start_voff, String8 string)
|
||||
{
|
||||
DF_Inst result = {0};
|
||||
switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
result = df_single_inst_from_machine_code__x64(arena, start_voff, string);
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug Info Extraction Type Pure Functions
|
||||
|
||||
@@ -859,15 +690,14 @@ df_line_list_copy(Arena *arena, DF_LineList *list)
|
||||
//~ rjf: Control Flow Analysis Functions
|
||||
|
||||
internal DF_CtrlFlowInfo
|
||||
df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_mask, U64 vaddr, String8 code)
|
||||
df_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);
|
||||
DF_CtrlFlowInfo info = {0};
|
||||
for(U64 offset = 0; offset < code.size;)
|
||||
{
|
||||
DF_Inst inst = df_single_inst_from_machine_code__x64(scratch.arena, 0, str8_skip(code, offset));
|
||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, vaddr+offset, str8_skip(code, offset), DASM_Syntax_Intel);
|
||||
U64 inst_vaddr = vaddr+offset;
|
||||
info.cumulative_sp_delta += inst.sp_delta;
|
||||
offset += inst.size;
|
||||
info.total_size += inst.size;
|
||||
if(inst.flags & exit_points_mask)
|
||||
@@ -875,12 +705,7 @@ df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_ma
|
||||
DF_CtrlFlowPoint point = {0};
|
||||
point.inst_flags = inst.flags;
|
||||
point.vaddr = inst_vaddr;
|
||||
point.jump_dest_vaddr = 0;
|
||||
point.expected_sp_delta = info.cumulative_sp_delta;
|
||||
if(inst.rel_voff != 0)
|
||||
{
|
||||
point.jump_dest_vaddr = (U64)(point.vaddr + (S64)((S32)inst.rel_voff));
|
||||
}
|
||||
point.jump_dest_vaddr = inst.jump_dest_vaddr;
|
||||
DF_CtrlFlowPointNode *node = push_array(arena, DF_CtrlFlowPointNode, 1);
|
||||
node->v = point;
|
||||
SLLQueuePush(info.exit_points.first, info.exit_points.last, node);
|
||||
@@ -891,21 +716,6 @@ df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_ma
|
||||
return info;
|
||||
}
|
||||
|
||||
internal DF_CtrlFlowInfo
|
||||
df_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DF_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code)
|
||||
{
|
||||
DF_CtrlFlowInfo result = {0};
|
||||
switch(arch)
|
||||
{
|
||||
default:{}break;
|
||||
case Architecture_x64:
|
||||
{
|
||||
result = df_ctrl_flow_info_from_vaddr_code__x64(arena, exit_points_mask, vaddr, code);
|
||||
}break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Command Type Pure Functions
|
||||
|
||||
@@ -2833,10 +2643,10 @@ df_trap_net_from_thread__step_over_inst(Arena *arena, DF_Entity *thread)
|
||||
if(machine_code.size != 0)
|
||||
{
|
||||
// rjf: decode instruction
|
||||
DF_Inst inst = df_single_inst_from_machine_code(scratch.arena, arch, ip_vaddr, machine_code);
|
||||
DASM_Inst inst = dasm_inst_from_code(scratch.arena, arch, ip_vaddr, machine_code, DASM_Syntax_Intel);
|
||||
|
||||
// rjf: call => run until call returns
|
||||
if(inst.flags & DF_InstFlag_Call || inst.flags & DF_InstFlag_Repeats)
|
||||
if(inst.flags & DASM_InstFlag_Call || inst.flags & DASM_InstFlag_Repeats)
|
||||
{
|
||||
CTRL_Trap trap = {CTRL_TrapFlag_EndStepping, ip_vaddr+inst.size};
|
||||
ctrl_trap_list_push(arena, &result, &trap);
|
||||
@@ -2925,11 +2735,11 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
if(good_line_info)
|
||||
{
|
||||
ctrl_flow_info = df_ctrl_flow_info_from_arch_vaddr_code(scratch.arena,
|
||||
DF_InstFlag_Call|
|
||||
DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_ChangesStackPointer|
|
||||
DF_InstFlag_Return,
|
||||
DASM_InstFlag_Call|
|
||||
DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_ChangesStackPointer|
|
||||
DASM_InstFlag_Return,
|
||||
arch,
|
||||
line_vaddr_rng.min,
|
||||
machine_code);
|
||||
@@ -2938,7 +2748,7 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
log_infof("flags: %x\n", ctrl_flow_info.flags);
|
||||
LogInfoNamedBlockF("exit_points") for(DF_CtrlFlowPointNode *n = ctrl_flow_info.exit_points.first; n != 0; n = n->next)
|
||||
{
|
||||
log_infof("{vaddr:0x%I64x, jump_dest_vaddr:0x%I64x, expected_sp_delta:0x%I64x, inst_flags:%x}\n", n->v.vaddr, n->v.jump_dest_vaddr, n->v.expected_sp_delta, n->v.inst_flags);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2952,9 +2762,9 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
U64 trap_addr = point->vaddr;
|
||||
|
||||
// rjf: branches/jumps/returns => single-step & end, OR trap @ destination.
|
||||
if(point->inst_flags & (DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_Return))
|
||||
if(point->inst_flags & (DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_Return))
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_EndStepping);
|
||||
|
||||
@@ -2974,13 +2784,13 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
|
||||
}
|
||||
|
||||
// rjf: call => place spoof at return spot in stack, single-step after hitting
|
||||
else if(point->inst_flags & DF_InstFlag_Call)
|
||||
else if(point->inst_flags & DASM_InstFlag_Call)
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_BeginSpoofMode|CTRL_TrapFlag_SingleStepAfterHit);
|
||||
}
|
||||
|
||||
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
|
||||
else if(point->inst_flags & DF_InstFlag_ChangesStackPointer)
|
||||
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_SaveStackPointer);
|
||||
}
|
||||
@@ -3066,11 +2876,11 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
if(good_line_info)
|
||||
{
|
||||
ctrl_flow_info = df_ctrl_flow_info_from_arch_vaddr_code(scratch.arena,
|
||||
DF_InstFlag_Call|
|
||||
DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_ChangesStackPointer|
|
||||
DF_InstFlag_Return,
|
||||
DASM_InstFlag_Call|
|
||||
DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_ChangesStackPointer|
|
||||
DASM_InstFlag_Return,
|
||||
arch,
|
||||
line_vaddr_rng.min,
|
||||
machine_code);
|
||||
@@ -3085,10 +2895,10 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
U64 trap_addr = point->vaddr;
|
||||
|
||||
// rjf: branches/jumps/returns => single-step & end, OR trap @ destination.
|
||||
if(point->inst_flags & (DF_InstFlag_Call|
|
||||
DF_InstFlag_Branch|
|
||||
DF_InstFlag_UnconditionalJump|
|
||||
DF_InstFlag_Return))
|
||||
if(point->inst_flags & (DASM_InstFlag_Call|
|
||||
DASM_InstFlag_Branch|
|
||||
DASM_InstFlag_UnconditionalJump|
|
||||
DASM_InstFlag_Return))
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_EndStepping|CTRL_TrapFlag_IgnoreStackPointerCheck);
|
||||
|
||||
@@ -3107,7 +2917,7 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
|
||||
}
|
||||
|
||||
// rjf: instruction changes stack pointer => save off the stack pointer, single-step over, keep stepping
|
||||
else if(point->inst_flags & DF_InstFlag_ChangesStackPointer)
|
||||
else if(point->inst_flags & DASM_InstFlag_ChangesStackPointer)
|
||||
{
|
||||
flags |= (CTRL_TrapFlag_SingleStepAfterHit|CTRL_TrapFlag_SaveStackPointer);
|
||||
}
|
||||
|
||||
+2
-74
@@ -138,69 +138,6 @@ typedef enum DF_RunKind
|
||||
}
|
||||
DF_RunKind;
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Types
|
||||
|
||||
typedef U32 DF_InstFlags;
|
||||
enum
|
||||
{
|
||||
DF_InstFlag_Call = (1<<0),
|
||||
DF_InstFlag_Branch = (1<<1),
|
||||
DF_InstFlag_UnconditionalJump = (1<<2),
|
||||
DF_InstFlag_Return = (1<<3),
|
||||
DF_InstFlag_NonFlow = (1<<4),
|
||||
DF_InstFlag_Repeats = (1<<5),
|
||||
DF_InstFlag_ChangesStackPointer = (1<<6),
|
||||
DF_InstFlag_ChangesStackPointerVariably = (1<<7),
|
||||
};
|
||||
|
||||
typedef struct DF_Inst DF_Inst;
|
||||
struct DF_Inst
|
||||
{
|
||||
DF_InstFlags flags;
|
||||
U64 size;
|
||||
String8 string;
|
||||
U64 rel_voff;
|
||||
S64 sp_delta;
|
||||
};
|
||||
|
||||
typedef struct DF_InstNode DF_InstNode;
|
||||
struct DF_InstNode
|
||||
{
|
||||
DF_InstNode *next;
|
||||
DF_Inst inst;
|
||||
};
|
||||
|
||||
typedef struct DF_InstList DF_InstList;
|
||||
struct DF_InstList
|
||||
{
|
||||
DF_InstNode *first;
|
||||
DF_InstNode *last;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DF_InstArray DF_InstArray;
|
||||
struct DF_InstArray
|
||||
{
|
||||
DF_InstArray *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
typedef struct DF_InstMemVOffTuple DF_InstMemVOffTuple;
|
||||
struct DF_InstMemVOffTuple
|
||||
{
|
||||
DF_Inst inst;
|
||||
String8 mem;
|
||||
U64 voff;
|
||||
};
|
||||
|
||||
typedef struct DF_InstMemVOffTupleArray DF_InstMemVOffTupleArray;
|
||||
struct DF_InstMemVOffTupleArray
|
||||
{
|
||||
DF_InstMemVOffTuple *v;
|
||||
U64 count;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Control Flow Analysis Types
|
||||
|
||||
@@ -215,8 +152,7 @@ struct DF_CtrlFlowPoint
|
||||
{
|
||||
U64 vaddr;
|
||||
U64 jump_dest_vaddr;
|
||||
S64 expected_sp_delta;
|
||||
DF_InstFlags inst_flags;
|
||||
DASM_InstFlags inst_flags;
|
||||
};
|
||||
|
||||
typedef struct DF_CtrlFlowPointNode DF_CtrlFlowPointNode;
|
||||
@@ -240,7 +176,6 @@ struct DF_CtrlFlowInfo
|
||||
DF_CtrlFlowFlags flags;
|
||||
DF_CtrlFlowPointList exit_points;
|
||||
U64 total_size;
|
||||
S64 cumulative_sp_delta;
|
||||
};
|
||||
|
||||
////////////////////////////////
|
||||
@@ -1456,12 +1391,6 @@ internal String8 df_string_from_cfg_node_children(Arena *arena, DF_CfgNode *node
|
||||
internal Vec4F32 df_hsva_from_cfg_node(DF_CfgNode *node);
|
||||
internal String8 df_string_from_cfg_node_key(DF_CfgNode *node, String8 key, StringMatchFlags flags);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Disassembly Pure Functions
|
||||
|
||||
internal DF_Inst df_single_inst_from_machine_code__x64(Arena *arena, U64 start_voff, String8 string);
|
||||
internal DF_Inst df_single_inst_from_machine_code(Arena *arena, Architecture arch, U64 start_voff, String8 string);
|
||||
|
||||
////////////////////////////////
|
||||
//~ rjf: Debug Info Extraction Type Pure Functions
|
||||
|
||||
@@ -1470,8 +1399,7 @@ internal DF_LineList df_line_list_copy(Arena *arena, DF_LineList *list);
|
||||
////////////////////////////////
|
||||
//~ rjf: Control Flow Analysis Pure Functions
|
||||
|
||||
internal DF_CtrlFlowInfo df_ctrl_flow_info_from_vaddr_code__x64(Arena *arena, DF_InstFlags exit_points_mask, U64 vaddr, String8 code);
|
||||
internal DF_CtrlFlowInfo df_ctrl_flow_info_from_arch_vaddr_code(Arena *arena, DF_InstFlags exit_points_mask, Architecture arch, U64 vaddr, String8 code);
|
||||
internal DF_CtrlFlowInfo df_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
|
||||
|
||||
+1444
-1444
File diff suppressed because it is too large
Load Diff
+17
-17
@@ -410,7 +410,7 @@ df_code_view_init(DF_CodeViewState *cv, DF_View *view)
|
||||
}
|
||||
|
||||
internal void
|
||||
df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, String8 text_data, TXT_TextInfo *text_info, DASM_InstArray *dasm_insts, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
{
|
||||
for(DF_CmdNode *n = cmds->first; n != 0; n = n->next)
|
||||
{
|
||||
@@ -459,7 +459,7 @@ df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewStat
|
||||
}
|
||||
|
||||
internal DF_CodeViewBuildResult
|
||||
df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_InstArray *dasm_insts, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(&arena, 1);
|
||||
@@ -669,7 +669,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: find live threads mapping to disasm
|
||||
if(dasm_insts) ProfScope("find live threads mapping to this disassembly")
|
||||
if(dasm_lines) ProfScope("find live threads mapping to this disassembly")
|
||||
{
|
||||
DF_Entity *selected_thread = df_entity_from_handle(ctrl_ctx.thread);
|
||||
DF_EntityList threads = df_query_cached_entity_list_with_kind(DF_EntityKind_Thread);
|
||||
@@ -681,7 +681,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
if(df_entity_ancestor_from_kind(thread, DF_EntityKind_Process) == process && contains_1u64(dasm_vaddr_range, rip_vaddr))
|
||||
{
|
||||
U64 rip_off = rip_vaddr - dasm_vaddr_range.min;
|
||||
S64 line_num = dasm_inst_array_idx_from_code_off__linear_scan(dasm_insts, rip_off)+1;
|
||||
S64 line_num = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, rip_off)+1;
|
||||
if(contains_1s64(visible_line_num_range, line_num))
|
||||
{
|
||||
U64 slice_line_idx = (line_num-visible_line_num_range.min);
|
||||
@@ -692,7 +692,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: find breakpoints mapping to this disasm
|
||||
if(dasm_insts) ProfScope("find breakpoints mapping to this disassembly")
|
||||
if(dasm_lines) ProfScope("find breakpoints mapping to this disassembly")
|
||||
{
|
||||
DF_EntityList bps = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint);
|
||||
for(DF_EntityNode *n = bps.first; n != 0; n = n->next)
|
||||
@@ -701,7 +701,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
if(bp->flags & DF_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, bp->vaddr))
|
||||
{
|
||||
U64 off = bp->vaddr-dasm_vaddr_range.min;
|
||||
U64 idx = dasm_inst_array_idx_from_code_off__linear_scan(dasm_insts, off);
|
||||
U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off);
|
||||
S64 line_num = (S64)(idx+1);
|
||||
if(contains_1s64(visible_line_num_range, line_num))
|
||||
{
|
||||
@@ -713,7 +713,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: find watch pins mapping to this disasm
|
||||
if(dasm_insts) ProfScope("find watch pins mapping to this disassembly")
|
||||
if(dasm_lines) ProfScope("find watch pins mapping to this disassembly")
|
||||
{
|
||||
DF_EntityList pins = df_query_cached_entity_list_with_kind(DF_EntityKind_WatchPin);
|
||||
for(DF_EntityNode *n = pins.first; n != 0; n = n->next)
|
||||
@@ -722,7 +722,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
if(pin->flags & DF_EntityFlag_HasVAddr && contains_1u64(dasm_vaddr_range, pin->vaddr))
|
||||
{
|
||||
U64 off = pin->vaddr-dasm_vaddr_range.min;
|
||||
U64 idx = dasm_inst_array_idx_from_code_off__linear_scan(dasm_insts, off);
|
||||
U64 idx = dasm_line_array_idx_from_code_off__linear_scan(dasm_lines, off);
|
||||
S64 line_num = (S64)(idx+1);
|
||||
if(contains_1s64(visible_line_num_range, line_num))
|
||||
{
|
||||
@@ -734,13 +734,13 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: fill dasm -> src info
|
||||
if(dasm_insts)
|
||||
if(dasm_lines)
|
||||
{
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, dasm_vaddr_range.min);
|
||||
DI_Key dbgi_key = df_dbgi_key_from_module(module);
|
||||
for(S64 line_num = visible_line_num_range.min; line_num < visible_line_num_range.max; line_num += 1)
|
||||
{
|
||||
U64 vaddr = dasm_vaddr_range.min + dasm_inst_array_code_off_from_idx(dasm_insts, line_num-1);
|
||||
U64 vaddr = dasm_vaddr_range.min + dasm_line_array_code_off_from_idx(dasm_lines, line_num-1);
|
||||
U64 voff = df_voff_from_vaddr(module, vaddr);
|
||||
U64 slice_idx = line_num-visible_line_num_range.min;
|
||||
code_slice_params.line_vaddrs[slice_idx] = vaddr;
|
||||
@@ -749,7 +749,7 @@ df_code_view_build(Arena *arena, DF_Window *ws, DF_Panel *panel, DF_View *view,
|
||||
}
|
||||
|
||||
// rjf: add dasm dbgi key to relevant dbgis
|
||||
if(dasm_insts != 0)
|
||||
if(dasm_lines != 0)
|
||||
{
|
||||
di_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, &dasm_dbgi_key);
|
||||
}
|
||||
@@ -6691,7 +6691,7 @@ DF_VIEW_CMD_FUNCTION_DEF(Disassembly)
|
||||
String8 dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
|
||||
|
||||
//- rjf: process general code-view commands
|
||||
df_code_view_cmds(ws, panel, view, &dv->cv, cmds, dasm_text_data, &dasm_text_info, &dasm_info.insts, dasm_vaddr_range, dasm_dbgi_key);
|
||||
df_code_view_cmds(ws, panel, view, &dv->cv, cmds, dasm_text_data, &dasm_text_info, &dasm_info.lines, dasm_vaddr_range, dasm_dbgi_key);
|
||||
|
||||
//- rjf: process disassembly-specific commands
|
||||
for(DF_CmdNode *n = cmds->first; n != 0; n = n->next)
|
||||
@@ -6798,7 +6798,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
U128 dasm_text_hash = {0};
|
||||
TXT_TextInfo dasm_text_info = txt_text_info_from_key_lang(txt_scope, df_interact_regs()->text_key, df_interact_regs()->lang_kind, &dasm_text_hash);
|
||||
String8 dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
|
||||
B32 has_disasm = (dasm_info.insts.count != 0 && dasm_text_info.lines_count != 0);
|
||||
B32 has_disasm = (dasm_info.lines.count != 0 && dasm_text_info.lines_count != 0);
|
||||
B32 is_loading = (!has_disasm && !df_entity_is_nil(process) && dim_1u64(dasm_vaddr_range) != 0);
|
||||
|
||||
//////////////////////////////
|
||||
@@ -6816,7 +6816,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
{
|
||||
U64 vaddr = dv->goto_vaddr;
|
||||
dv->goto_vaddr = 0;
|
||||
U64 line_idx = dasm_inst_array_idx_from_code_off__linear_scan(&dasm_info.insts, vaddr-dasm_vaddr_range.min);
|
||||
U64 line_idx = dasm_line_array_idx_from_code_off__linear_scan(&dasm_info.lines, vaddr-dasm_vaddr_range.min);
|
||||
S64 line_num = (S64)(line_idx+1);
|
||||
cv->goto_line_num = line_num;
|
||||
}
|
||||
@@ -6826,7 +6826,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//
|
||||
if(!is_loading && has_disasm)
|
||||
{
|
||||
df_code_view_build(scratch.arena, ws, panel, view, cv, DF_CodeViewBuildFlag_All, code_area_rect, dasm_text_data, &dasm_text_info, &dasm_info.insts, dasm_vaddr_range, dasm_dbgi_key);
|
||||
df_code_view_build(scratch.arena, ws, panel, view, cv, DF_CodeViewBuildFlag_All, code_area_rect, dasm_text_data, &dasm_text_info, &dasm_info.lines, dasm_vaddr_range, dasm_dbgi_key);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
@@ -6834,7 +6834,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
//
|
||||
if(!is_loading && has_disasm)
|
||||
{
|
||||
U64 off = dasm_inst_array_code_off_from_idx(&dasm_info.insts, df_interact_regs()->cursor.line-1);
|
||||
U64 off = dasm_line_array_code_off_from_idx(&dasm_info.lines, df_interact_regs()->cursor.line-1);
|
||||
df_interact_regs()->vaddr_range = r1u64(dasm_base_vaddr+off, dasm_base_vaddr+off);
|
||||
df_interact_regs()->voff_range = df_voff_range_from_vaddr_range(dasm_module, df_interact_regs()->vaddr_range);
|
||||
df_interact_regs()->lines = df_lines_from_dbgi_key_voff(df_frame_arena(), &dasm_dbgi_key, df_interact_regs()->voff_range.min);
|
||||
@@ -6854,7 +6854,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
|
||||
DF_Font(ws, DF_FontSlot_Code)
|
||||
{
|
||||
DF_Entity *module = df_module_from_process_vaddr(process, dasm_vaddr_range.min);
|
||||
U64 cursor_vaddr = (1 <= view->cursor.line && view->cursor.line <= dasm_info.insts.count) ? (dasm_vaddr_range.min+dasm_info.insts.v[view->cursor.line-1].code_off) : 0;
|
||||
U64 cursor_vaddr = (1 <= view->cursor.line && view->cursor.line <= dasm_info.lines.count) ? (dasm_vaddr_range.min+dasm_info.lines.v[view->cursor.line-1].code_off) : 0;
|
||||
ui_labelf("%S", path_normalized_from_string(scratch.arena, module->name));
|
||||
ui_spacer(ui_em(1.5f, 1));
|
||||
ui_labelf("Address: 0x%I64x, Line: %I64d, Column: %I64d", cursor_vaddr, view->cursor.line, view->cursor.column);
|
||||
|
||||
+571
-571
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user