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:
Ryan Fleury
2024-07-23 16:23:29 -07:00
parent 926b5e3546
commit ccf8504dd1
28 changed files with 2531 additions and 12967 deletions
+26 -216
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+17 -17
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff