Merge branch 'dev' of https://github.com/EpicGamesExt/raddebugger into inline_merge

This commit is contained in:
Ryan Fleury
2024-05-29 12:35:49 -07:00
11 changed files with 341 additions and 84 deletions
+2 -1
View File
@@ -69,7 +69,8 @@ dasm_inst_array_idx_from_code_off__linear_scan(DASM_InstArray *array, U64 off)
U64 result = 0;
for(U64 idx = 0; idx < array->count; idx += 1)
{
if(array->v[idx].code_off == off)
U64 next_off = (idx+1 < array->count ? array->v[idx+1].code_off : max_U64);
if(array->v[idx].code_off <= off && off < next_off)
{
result = idx;
break;
+13 -3
View File
@@ -1900,7 +1900,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
//
case EXCEPTION_DEBUG_EVENT:
{
// NOTE(rjf): Notes on multithreaded breakpoint events
//- NOTE(rjf): Notes on multithreaded breakpoint events
// (2021/11/1):
//
// When many threads are simultaneously running, multiple threads
@@ -1928,7 +1928,17 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
// #B. If the actual unmodified instruction is an int 3, then this
// becomes a trap event and we do not reset RIP.
// NOTE(rjf): The exception record struct has a 32-bit version and a
//- NOTE(rjf): Further notes on MULTITHREADED STEPPING ACCESS VIOLATION
// EVENTS! @rjf @rjf @rjf
// (2024/05/29):
//
// Just adding another comment here to document that the above long
// comment went completely unnoticed by me during a pass over demon,
// and I had removed the proper rollback stuff here without reading
// the above comment. So this comment just serves to make that
// original comment even heftier.
//- NOTE(rjf): The exception record struct has a 32-bit version and a
// 64-bit version. We only currently handle the 64-bit version.
//- rjf: unpack
@@ -1981,7 +1991,7 @@ dmn_ctrl_run(Arena *arena, DMN_CtrlCtx *ctx, DMN_RunCtrls *ctrls)
}
//- rjf: determine whether to roll back instruction pointer
B32 should_do_rollback = (hit_user_trap);
B32 should_do_rollback = (hit_user_trap || (is_trap && !hit_explicit_trap));
//- rjf: roll back thread's instruction pointer
U64 post_trap_rip = 0;
+13 -5
View File
@@ -4473,6 +4473,7 @@ df_string_from_ascii_value(Arena *arena, U8 val)
case '\'':{result = str8_lit("\\'");}break;
case '\\':{result = str8_lit("\\\\");}break;
default:
if(32 <= val && val < 255)
{
result = push_str8f(arena, "%c", val);
}break;
@@ -4511,14 +4512,21 @@ df_string_from_simple_typed_eval(Arena *arena, TG_Graph *graph, RDI_Parsed *rdi,
case TG_Kind_UChar32:
{
String8 char_str = df_string_from_ascii_value(arena, eval.imm_s64);
if(flags & DF_EvalVizStringFlag_ReadOnlyDisplayRules)
if(char_str.size != 0)
{
String8 imm_string = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator);
result = push_str8f(arena, "'%S' (%S)", char_str, imm_string);
if(flags & DF_EvalVizStringFlag_ReadOnlyDisplayRules)
{
String8 imm_string = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator);
result = push_str8f(arena, "'%S' (%S)", char_str, imm_string);
}
else
{
result = push_str8f(arena, "'%S'", char_str);
}
}
else
{
result = push_str8f(arena, "'%S'", char_str);
result = str8_from_s64(arena, eval.imm_s64, radix, 0, digit_group_separator);
}
}break;
@@ -6206,8 +6214,8 @@ df_query_cached_unwind_from_thread(DF_Entity *thread)
{
node = push_array_no_zero(df_state->arena, DF_UnwindCacheNode, 1);
}
DLLPushBack(slot->first, slot->last, node);
MemoryZeroStruct(node);
DLLPushBack(slot->first, slot->last, node);
node->arena = arena_alloc();
node->thread = handle;
}
+195 -22
View File
@@ -2903,6 +2903,13 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_Entity);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread));
}break;
case DF_EntityKind_Target:
{
DF_CmdParams params = df_cmd_params_from_window(ws);
params.entity = df_handle_from_entity(entity);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_Entity);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget));
}break;
}
}break;
case DF_CoreCmdKind_SpawnEntityView:
@@ -5992,7 +5999,7 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
//- rjf: calculate width of exp row
if(row == viz_rows.first)
{
expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*0.5f;
expr_column_width_px = f_dim_from_tag_size_string(ui_top_font(), ui_top_font_size(), 0, ui_top_tab_size(), row->display_expr).x + ui_top_font_size()*2.5f;
expr_column_width_px = Max(expr_column_width_px, ui_top_font_size()*10.f);
}
@@ -10424,9 +10431,9 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions)
// rjf: draw line before next-to-execute line
{
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
box->parent->rect.y0 - box->font_size*0.125f,
box->rect.x0 + box->font_size*260*u->alive_t,
box->parent->parent->parent->rect.x0 + box->font_size*260*u->alive_t,
box->parent->rect.y0 + box->font_size*0.125f),
v4f32(u->thread_color.x, u->thread_color.y, u->thread_color.z, 0),
0, 0, 1);
@@ -10451,9 +10458,9 @@ internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions)
{
Vec4F32 weak_thread_color = u->thread_color;
weak_thread_color.w *= 0.3f;
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
box->parent->rect.y0,
box->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
box->parent->rect.y1),
v4f32(0, 0, 0, 0),
0, 0, 1);
@@ -10491,9 +10498,9 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions)
// rjf: draw line before next-to-execute line
{
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
box->parent->rect.y0 - box->font_size*0.125f,
box->rect.x0 + ui_top_font_size()*250.f*u->alive_t,
box->parent->parent->parent->rect.x0 + ui_top_font_size()*250.f*u->alive_t,
box->parent->rect.y0 + box->font_size*0.125f),
v4f32(u->color.x, u->color.y, u->color.z, 0),
0, 0, 1.f);
@@ -10504,9 +10511,9 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions)
{
Vec4F32 weak_thread_color = u->color;
weak_thread_color.w *= 0.3f;
R_Rect2DInst *inst = d_rect(r2f32p(box->rect.x0,
R_Rect2DInst *inst = d_rect(r2f32p(box->parent->parent->parent->rect.x0,
box->parent->rect.y0,
box->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
box->parent->parent->parent->rect.x0 + ui_top_font_size()*22.f*u->alive_t,
box->parent->rect.y1),
v4f32(0, 0, 0, 0),
0, 0, 1);
@@ -10677,24 +10684,24 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
}
//////////////////////////////
//- rjf: build margins
//- rjf: build priority margin
//
UI_Box *margin_container_box = &ui_g_nil_box;
if(params->flags & DF_CodeSliceFlag_Margin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build margins")
UI_Box *priority_margin_container_box = &ui_g_nil_box;
if(params->flags & DF_CodeSliceFlag_PriorityMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build priority margins")
{
if(params->margin_float_off_px != 0)
{
ui_set_next_pref_width(ui_px(params->margin_width_px, 1));
ui_set_next_pref_width(ui_px(params->priority_margin_width_px, 1));
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
ui_build_box_from_key(0, ui_key_zero());
ui_set_next_fixed_x(params->margin_float_off_px);
ui_set_next_flags(UI_BoxFlag_DrawBackground);
}
ui_set_next_pref_width(ui_px(params->margin_width_px, 1));
ui_set_next_pref_width(ui_px(params->priority_margin_width_px, 1));
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
ui_set_next_child_layout_axis(Axis2_Y);
margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("margin_container"));
UI_Parent(margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f))
priority_margin_container_box = ui_build_box_from_string(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("priority_margin_container"));
UI_Parent(priority_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f))
{
U64 line_idx = 0;
for(S64 line_num = params->line_num_range.min;
@@ -10702,8 +10709,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
line_num += 1, line_idx += 1)
{
DF_EntityList line_ips = params->line_ips[line_idx];
DF_EntityList line_bps = params->line_bps[line_idx];
DF_EntityList line_pins = params->line_pins[line_idx];
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
ui_set_next_background_color(v4f32(0, 0, 0, 0));
UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num);
@@ -10714,6 +10719,175 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
{
// rjf: unpack thread
DF_Entity *thread = n->entity;
if(thread != selected_thread)
{
continue;
}
U64 unwind_count = (thread == selected_thread) ? ctrl_ctx->unwind_count : 0;
U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
DF_Entity *module = df_module_from_process_vaddr(process, thread_rip_vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
U64 thread_rip_voff = df_voff_from_vaddr(module, thread_rip_vaddr);
// rjf: thread info => color
Vec4F32 color = v4f32(1, 1, 1, 1);
{
if(unwind_count != 0)
{
color = df_rgba_from_theme_color(DF_ThemeColor_ThreadUnwound);
}
else if(thread == stopper_thread &&
(stop_event.cause == CTRL_EventCause_InterruptedByHalt ||
stop_event.cause == CTRL_EventCause_InterruptedByTrap ||
stop_event.cause == CTRL_EventCause_InterruptedByException))
{
color = df_rgba_from_theme_color(DF_ThemeColor_FailureBackground);
}
else if(thread->flags & DF_EntityFlag_HasColor)
{
color = df_rgba_from_entity(thread);
}
if(df_ctrl_targets_running() && df_ctrl_last_run_frame_idx() < df_frame_index())
{
color.w *= 0.5f;
}
if(thread != selected_thread)
{
color.w *= 0.8f;
}
}
// rjf: build thread box
ui_set_next_hover_cursor(OS_Cursor_UpDownLeftRight);
ui_set_next_font(ui_icon_font());
ui_set_next_font_size(params->font_size);
ui_set_next_pref_width(ui_pct(1, 0));
ui_set_next_pref_height(ui_pct(1, 0));
ui_set_next_text_color(color);
ui_set_next_text_alignment(UI_TextAlign_Center);
UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%p", thread);
UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
UI_BoxFlag_DrawText,
thread_box_key);
ui_box_equip_display_string(thread_box, df_g_icon_kind_text_table[DF_IconKind_RightArrow]);
UI_Signal thread_sig = ui_signal_from_box(thread_box);
// rjf: custom draw
{
DF_ThreadBoxDrawExtData *u = push_array(ui_build_arena(), DF_ThreadBoxDrawExtData, 1);
u->thread_color = color;
u->alive_t = thread->alive_t;
u->is_selected = (thread == selected_thread);
u->is_frozen = df_entity_is_frozen(thread);
ui_box_equip_custom_draw(thread_box, df_thread_box_draw_extensions, u);
// rjf: fill out progress t (progress into range of current line's
// voff range)
if(params->line_src2dasm[line_idx].first != 0)
{
DF_TextLineSrc2DasmInfoList *line_info_list = &params->line_src2dasm[line_idx];
DF_TextLineSrc2DasmInfo *line_info = 0;
for(DF_TextLineSrc2DasmInfoNode *n = line_info_list->first;
n != 0;
n = n->next)
{
if(di_key_match(&n->v.dbgi_key, &dbgi_key))
{
line_info = &n->v;
break;
}
}
if(line_info != 0)
{
Rng1U64 line_voff_rng = line_info->voff_range;
Vec4F32 weak_thread_color = color;
weak_thread_color.w *= 0.4f;
F32 progress_t = (line_voff_rng.max != line_voff_rng.min) ? ((F32)(thread_rip_voff - line_voff_rng.min) / (F32)(line_voff_rng.max - line_voff_rng.min)) : 0;
progress_t = Clamp(0, progress_t, 1);
u->progress_t = progress_t;
}
}
}
// rjf: hover tooltips
if(ui_hovering(thread_sig))
{
df_entity_tooltips(thread);
}
// rjf: ip right-click menu
if(ui_right_clicked(thread_sig))
{
DF_Handle handle = df_handle_from_entity(thread);
if(ui_ctx_menu_is_open(ws->entity_ctx_menu_key) && df_handle_match(ws->entity_ctx_menu_entity, handle))
{
ui_ctx_menu_close();
}
else
{
ui_ctx_menu_open(ws->entity_ctx_menu_key, thread_box->key, v2f32(0, thread_box->rect.y1-thread_box->rect.y0));
ws->entity_ctx_menu_entity = handle;
}
}
// rjf: drag start
if(ui_dragging(thread_sig) && !contains_2f32(thread_box->rect, ui_mouse()))
{
DF_DragDropPayload payload = {0};
payload.key = thread_box->key;
payload.entity = df_handle_from_entity(thread);
df_drag_begin(&payload);
}
}
}
}
}
}
//////////////////////////////
//- rjf: build catchall margin
//
UI_Box *catchall_margin_container_box = &ui_g_nil_box;
if(params->flags & DF_CodeSliceFlag_CatchallMargin) UI_Focus(UI_FocusKind_Off) UI_Parent(top_container_box) ProfScope("build catchall margins")
{
if(params->margin_float_off_px != 0)
{
ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1));
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
ui_build_box_from_key(0, ui_key_zero());
ui_set_next_fixed_x(params->margin_float_off_px + params->priority_margin_width_px);
ui_set_next_flags(UI_BoxFlag_DrawBackground);
}
ui_set_next_pref_width(ui_px(params->catchall_margin_width_px, 1));
ui_set_next_pref_height(ui_px(params->line_height_px*(dim_1s64(params->line_num_range)+1), 1.f));
ui_set_next_child_layout_axis(Axis2_Y);
catchall_margin_container_box = ui_build_box_from_string(UI_BoxFlag_DrawSideLeft|UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable), str8_lit("catchall_margin_container"));
UI_Parent(catchall_margin_container_box) UI_PrefHeight(ui_px(params->line_height_px, 1.f))
{
U64 line_idx = 0;
for(S64 line_num = params->line_num_range.min;
line_num <= params->line_num_range.max;
line_num += 1, line_idx += 1)
{
DF_EntityList line_ips = params->line_ips[line_idx];
DF_EntityList line_bps = params->line_bps[line_idx];
DF_EntityList line_pins = params->line_pins[line_idx];
ui_set_next_hover_cursor(OS_Cursor_HandPoint);
ui_set_next_background_color(v4f32(0, 0, 0, 0));
UI_Box *line_margin_box = ui_build_box_from_stringf(UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawActiveEffects, "line_margin_%I64x", line_num);
UI_Parent(line_margin_box)
{
//- rjf: build margin thread ip ui
for(DF_EntityNode *n = line_ips.first; n != 0; n = n->next)
{
// rjf: unpack thread
DF_Entity *thread = n->entity;
if(thread == selected_thread)
{
continue;
}
U64 unwind_count = (thread == selected_thread) ? ctrl_ctx->unwind_count : 0;
U64 thread_rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
@@ -10760,7 +10934,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
UI_Key thread_box_key = ui_key_from_stringf(top_container_box->key, "###ip_%p", thread);
UI_Box *thread_box = ui_build_box_from_key(UI_BoxFlag_DisableTextTrunc|
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
UI_BoxFlag_AnimatePosX|
UI_BoxFlag_DrawText,
thread_box_key);
ui_box_equip_display_string(thread_box, df_g_icon_kind_text_table[DF_IconKind_RightArrow]);
@@ -10831,6 +11004,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
params.entity = df_handle_from_entity(thread);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_Entity);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectThread));
ui_kill_action();
}
// rjf: drag start
@@ -10884,7 +11058,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
UI_BoxFlag_DrawActiveEffects|
UI_BoxFlag_DrawHotEffects|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_AnimatePosX|
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
UI_BoxFlag_DisableTextTrunc,
"%S##bp_%p",
@@ -10953,7 +11126,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
UI_BoxFlag_DrawHotEffects|
UI_BoxFlag_DrawBorder|
UI_BoxFlag_Clickable*!!(params->flags & DF_CodeSliceFlag_Clickable)|
UI_BoxFlag_AnimatePosX|
UI_BoxFlag_DisableTextTrunc,
"%S##watch_%p",
df_g_icon_kind_text_table[DF_IconKind_Pin],
@@ -11236,7 +11408,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
//////////////////////////////
//- rjf: interact with margin box & text box
//
UI_Signal margin_container_sig = ui_signal_from_box(margin_container_box);
UI_Signal priority_margin_container_sig = ui_signal_from_box(priority_margin_container_box);
UI_Signal catchall_margin_container_sig = ui_signal_from_box(catchall_margin_container_box);
UI_Signal text_container_sig = ui_signal_from_box(text_container_box);
DF_Entity *line_drag_entity = &df_g_nil_entity;
{
+6 -4
View File
@@ -388,9 +388,10 @@ enum
typedef U32 DF_CodeSliceFlags;
enum
{
DF_CodeSliceFlag_Clickable = (1<<0),
DF_CodeSliceFlag_Margin = (1<<1),
DF_CodeSliceFlag_LineNums = (1<<2),
DF_CodeSliceFlag_Clickable = (1<<0),
DF_CodeSliceFlag_PriorityMargin = (1<<1),
DF_CodeSliceFlag_CatchallMargin = (1<<2),
DF_CodeSliceFlag_LineNums = (1<<3),
};
typedef struct DF_CodeSliceParams DF_CodeSliceParams;
@@ -415,7 +416,8 @@ struct DF_CodeSliceParams
F32 tab_size;
String8 search_query;
F32 line_height_px;
F32 margin_width_px;
F32 priority_margin_width_px;
F32 catchall_margin_width_px;
F32 line_num_width_px;
F32 line_text_max_width_px;
DF_EntityList flash_ranges;
+4 -2
View File
@@ -570,7 +570,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
code_slice_params.font_size = ui_top_font_size();
code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f;
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
code_slice_params.margin_width_px = 0;
code_slice_params.priority_margin_width_px = 0;
code_slice_params.catchall_margin_width_px = 0;
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*info.lines_max_size;
}
@@ -731,7 +732,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
code_slice_params.font_size = ui_top_font_size();
code_slice_params.tab_size = f_column_size_from_tag_size(code_slice_params.font, code_slice_params.font_size)*4.f;
code_slice_params.line_height_px = ui_top_font_size()*1.5f;
code_slice_params.margin_width_px = 0;
code_slice_params.priority_margin_width_px = 0;
code_slice_params.catchall_margin_width_px = 0;
code_slice_params.line_num_width_px = ui_top_font_size()*5.f;
code_slice_params.line_text_max_width_px = ui_top_font_size()*2.f*dasm_text_info.lines_max_size;
}
+64 -38
View File
@@ -3867,13 +3867,7 @@ DF_VIEW_UI_FUNCTION_DEF(Targets)
UI_FocusHot((row_selected && cursor.x == 0) ? UI_FocusKind_On : UI_FocusKind_Off)
{
UI_Signal sig = df_icon_buttonf(target->b32 ? DF_IconKind_CheckFilled : DF_IconKind_CheckHollow, 0, "###ebl_%p", target);
if(ui_clicked(sig) && sig.event_flags == 0)
{
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
p.entity = df_handle_from_entity(target);
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SelectTarget));
}
else if(ui_clicked(sig) && sig.event_flags == OS_EventFlag_Ctrl)
if(ui_clicked(sig))
{
DF_CmdParams p = df_cmd_params_from_view(ws, panel, view);
p.entity = df_handle_from_entity(target);
@@ -4835,6 +4829,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
{
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
DI_Scope *scope = di_scope_open();
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_view(ws, view);
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
U64 selected_unwind_count = ctrl_ctx.unwind_count;
@@ -4915,20 +4910,33 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
{
continue;
}
U64 frame_idx = row_num-1;
CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx];
// rjf: determine selection
B32 row_selected = (cs->cursor.y == row_num);
// rjf: regs => rip
// rjf: unpack frame
U64 frame_idx = row_num-1;
CTRL_UnwindFrame *frame = &unwind.frames.v[frame_idx];
U64 rip_vaddr = regs_rip_from_arch_block(thread->arch, frame->regs);
// rjf: rip_vaddr => module
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
// rjf: rip => validity?
B32 frame_valid = (rip_vaddr != 0);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
String8 symbol_name = {0};
String8 symbol_type_string = {0};
if(rdi->scope_vmap != 0)
{
U64 scope_idx = rdi_vmap_idx_from_voff(rdi->scope_vmap, rdi->scope_vmap_count, rip_voff);
RDI_Scope *scope = rdi_element_from_idx(rdi, scopes, scope_idx);
U64 proc_idx = scope->proc_idx;
RDI_Procedure *procedure = &rdi->procedures[proc_idx];
RDI_TypeNode *type_node = rdi_element_from_idx(rdi, type_nodes, procedure->type_idx);
TG_Key type_key = tg_key_ext(tg_kind_from_rdi_type_kind(type_node->kind), procedure->type_idx);
U64 name_size = 0;
U8 *name_ptr = rdi_string_from_idx(rdi, procedure->name_string_idx, &name_size);
TG_Graph *graph = tg_graph_begin(rdi_addr_size_from_arch(rdi->top_level_info->architecture), 256);
symbol_name = str8(name_ptr, name_size);
symbol_type_string = tg_string_from_key(scratch.arena, graph, rdi, type_key);
}
// rjf: build row
if(frame_valid) UI_NamedTableVectorF("###callstack_%p_%I64x", view, frame_idx)
@@ -4981,21 +4989,32 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
}
}
// rjf: build cell for function name
// rjf: build cell for function header
UI_TableCell UI_Font(df_font_from_slot(DF_FontSlot_Code))
UI_FocusHot((row_selected && cs->cursor.x == 2) ? UI_FocusKind_On : UI_FocusKind_Off)
{
String8 symbol = df_symbol_name_from_process_vaddr(scratch.arena, process, rip_vaddr);
if(symbol.size == 0)
ui_set_next_child_layout_axis(Axis2_X);
UI_Box *box = ui_build_box_from_stringf(UI_BoxFlag_Clickable|UI_BoxFlag_Clip, "frame_%I64x", frame_idx);
UI_Parent(box)
{
symbol = str8_lit("[external code]");
ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_WeakText));
if(symbol_name.size == 0)
{
ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_WeakText));
ui_label(str8_lit("[unknown symbol]"));
}
else UI_WidthFill
{
D_FancyStringList symbol_name_fstrs = df_fancy_string_list_from_code_string(scratch.arena, 1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeFunction), symbol_name);
D_FancyStringList symbol_type_fstrs = df_fancy_string_list_from_code_string(scratch.arena, 0.5f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeDefault), symbol_type_string);
D_FancyStringList fstrs = {0};
d_fancy_string_list_concat_in_place(&fstrs, &symbol_name_fstrs);
D_FancyString sep = {ui_top_font(), str8_lit(": "), df_rgba_from_theme_color(DF_ThemeColor_WeakText), ui_top_font_size()};
d_fancy_string_list_push(scratch.arena, &fstrs, &sep);
d_fancy_string_list_concat_in_place(&fstrs, &symbol_type_fstrs);
UI_Box *label = ui_build_box_from_key(UI_BoxFlag_DrawText, ui_key_zero());
ui_box_equip_display_fancy_strings(label, 0, &fstrs);
}
}
else
{
ui_set_next_text_color(df_rgba_from_theme_color(DF_ThemeColor_CodeFunction));
}
UI_Box *box = ui_build_box_from_string(UI_BoxFlag_DrawText|UI_BoxFlag_Clickable, symbol);
UI_Signal sig = ui_signal_from_box(box);
if(ui_pressed(sig))
{
@@ -5046,6 +5065,7 @@ DF_VIEW_UI_FUNCTION_DEF(CallStack)
}
}
di_scope_close(scope);
scratch_end(scratch);
ProfEnd();
}
@@ -5819,7 +5839,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
//////////////////////////////
//- rjf: calculate line-range-dependent info
//
F32 margin_width_px = big_glyph_advance*3.5f;
F32 priority_margin_width_px = big_glyph_advance*3.5f;
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &text_info, data, visible_line_num_range);
@@ -5847,7 +5868,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
if(text_info_is_ready)
{
// rjf: fill basics
code_slice_params.flags = DF_CodeSliceFlag_Margin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
code_slice_params.line_num_range = visible_line_num_range;
code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count);
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count);
@@ -5862,7 +5883,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
code_slice_params.tab_size = code_tab_size;
code_slice_params.line_height_px = code_line_height;
code_slice_params.search_query = search_query;
code_slice_params.margin_width_px = margin_width_px;
code_slice_params.priority_margin_width_px = priority_margin_width_px;
code_slice_params.catchall_margin_width_px = catchall_margin_width_px;
code_slice_params.line_num_width_px = line_num_width_px;
code_slice_params.line_text_max_width_px = (F32)line_size_x;
code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker);
@@ -6382,7 +6404,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
if(snap[Axis2_X])
{
String8 cursor_line = str8_substr(data, text_info.lines_ranges[tv->cursor.line-1]);
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px);
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px);
Rng1S64 visible_pixel_range =
{
view->scroll_pos.x.idx,
@@ -6390,7 +6412,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
};
Rng1S64 cursor_pixel_range =
{
cursor_off - (S64)(big_glyph_advance*4) - (S64)(margin_width_px + line_num_width_px),
cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px),
cursor_off + (S64)(big_glyph_advance*4),
};
S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min);
@@ -6895,7 +6917,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
//////////////////////////////
//- rjf: calculate line-range-dependent info
//
F32 margin_width_px = big_glyph_advance*3.5f;
F32 priority_margin_width_px = big_glyph_advance*3.5f;
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
TXT_LineTokensSlice slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &dasm_text_info, dasm_text_data, visible_line_num_range);
@@ -6936,7 +6959,7 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
if(has_disasm)
{
// rjf: fill basics
code_slice_params.flags = DF_CodeSliceFlag_Margin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
code_slice_params.flags = DF_CodeSliceFlag_PriorityMargin|DF_CodeSliceFlag_CatchallMargin|DF_CodeSliceFlag_LineNums|DF_CodeSliceFlag_Clickable;
code_slice_params.line_num_range = visible_line_num_range;
code_slice_params.line_text = push_array(scratch.arena, String8, visible_line_count);
code_slice_params.line_ranges = push_array(scratch.arena, Rng1U64, visible_line_count);
@@ -6951,7 +6974,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
code_slice_params.tab_size = code_tab_size;
code_slice_params.line_height_px = code_line_height;
code_slice_params.search_query = search_query;
code_slice_params.margin_width_px = margin_width_px;
code_slice_params.priority_margin_width_px = priority_margin_width_px;
code_slice_params.catchall_margin_width_px = catchall_margin_width_px;
code_slice_params.line_num_width_px = line_num_width_px;
code_slice_params.line_text_max_width_px = (F32)line_size_x;
code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, process, DF_EntityKind_FlashMarker);
@@ -7750,7 +7774,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
//////////////////////////////
//- rjf: calculate line-range-dependent info
//
F32 margin_width_px = big_glyph_advance*3.5f;
F32 priority_margin_width_px = big_glyph_advance*3.5f;
F32 catchall_margin_width_px = big_glyph_advance*3.5f;
F32 line_num_width_px = big_glyph_advance * (log10(visible_line_num_range.max) + 3);
TXTI_Slice slice = txti_slice_from_handle_line_range(scratch.arena, txti_handle, visible_line_num_range);
@@ -7793,7 +7818,8 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
code_slice_params.tab_size = code_tab_size;
code_slice_params.line_height_px = code_line_height;
code_slice_params.search_query = search_query;
code_slice_params.margin_width_px = margin_width_px;
code_slice_params.priority_margin_width_px = priority_margin_width_px;
code_slice_params.catchall_margin_width_px = catchall_margin_width_px;
code_slice_params.line_num_width_px = line_num_width_px;
code_slice_params.line_text_max_width_px = (F32)line_size_x;
code_slice_params.flash_ranges = df_push_entity_child_list_with_kind(scratch.arena, entity, DF_EntityKind_FlashMarker);
@@ -8079,7 +8105,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
if(snap[Axis2_X])
{
String8 cursor_line = txti_string_from_handle_line_num(scratch.arena, txti_handle, tv->cursor.line);
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + margin_width_px + line_num_width_px);
S64 cursor_off = (S64)(f_dim_from_tag_size_string(code_font, code_font_size, 0, code_tab_size, str8_prefix(cursor_line, tv->cursor.column-1)).x + priority_margin_width_px + catchall_margin_width_px + line_num_width_px);
Rng1S64 visible_pixel_range =
{
view->scroll_pos.x.idx,
@@ -8087,7 +8113,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
};
Rng1S64 cursor_pixel_range =
{
cursor_off - (S64)(big_glyph_advance*4) - (S64)(margin_width_px + line_num_width_px),
cursor_off - (S64)(big_glyph_advance*4) - (S64)(priority_margin_width_px + catchall_margin_width_px + line_num_width_px),
cursor_off + (S64)(big_glyph_advance*4),
};
S64 min_delta = Min(0, cursor_pixel_range.min - visible_pixel_range.min);
+17
View File
@@ -54,6 +54,23 @@ d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *s
list->total_size += str->string.size;
}
internal void
d_fancy_string_list_concat_in_place(D_FancyStringList *dst, D_FancyStringList *to_push)
{
if(dst->last != 0 && to_push->first != 0)
{
dst->last->next = to_push->first;
dst->last = to_push->last;
dst->node_count += to_push->node_count;
dst->total_size += to_push->total_size;
}
else if(to_push->first != 0)
{
MemoryCopyStruct(dst, to_push);
}
MemoryZeroStruct(to_push);
}
internal String8
d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list)
{
+1
View File
@@ -109,6 +109,7 @@ internal U64 d_hash_from_string(String8 string);
//~ rjf: Fancy String Type Functions
internal void d_fancy_string_list_push(Arena *arena, D_FancyStringList *list, D_FancyString *str);
internal void d_fancy_string_list_concat_in_place(D_FancyStringList *dst, D_FancyStringList *to_push);
internal String8 d_string_from_fancy_string_list(Arena *arena, D_FancyStringList *list);
internal D_FancyRunList d_fancy_run_list_from_fancy_string_list(Arena *arena, F32 tab_size_px, D_FancyStringList *strs);
internal D_FancyRunList d_fancy_run_list_copy(Arena *arena, D_FancyRunList *src);
+1 -1
View File
@@ -180,7 +180,7 @@ global read_only TG_Type tg_type_nil =
{
/* kind */ TG_Kind_Null,
/* flags */ 0,
/* name */ {(U8*)"<nil>",5},
/* name */ {(U8*)"???",3},
};
global read_only TG_Type tg_type_variadic =
+25 -8
View File
@@ -1155,7 +1155,13 @@ ui_end_build(void)
//- rjf: ensure special floating roots are within screen bounds
UI_Box *floating_roots[] = {ui_state->tooltip_root, ui_state->ctx_menu_root};
B32 force_contain[] = {0, 1};
B32 force_contain[] =
{
(ui_key_match(ui_active_key(UI_MouseButtonKind_Left), ui_key_zero()) &&
ui_key_match(ui_active_key(UI_MouseButtonKind_Right), ui_key_zero()) &&
ui_key_match(ui_active_key(UI_MouseButtonKind_Middle), ui_key_zero())),
1,
};
for(U64 idx = 0; idx < ArrayCount(floating_roots); idx += 1)
{
UI_Box *root = floating_roots[idx];
@@ -1164,11 +1170,10 @@ ui_end_build(void)
Rng2F32 window_rect = os_client_rect_from_window(ui_window());
Vec2F32 window_dim = dim_2f32(window_rect);
Rng2F32 root_rect = root->rect;
Vec2F32 root_rect_dim = dim_2f32(root_rect);
Vec2F32 shift =
{
-ClampBot(0, root_rect.x1 - window_rect.x1) * (root_rect_dim.x < root->font_size*15.f || force_contain[idx]),
-ClampBot(0, root_rect.y1 - window_rect.y1) * (root_rect_dim.y < root->font_size*15.f || force_contain[idx]),
-ClampBot(0, root_rect.x1 - window_rect.x1) * (force_contain[idx]),
-ClampBot(0, root_rect.y1 - window_rect.y1) * (force_contain[idx]),
};
Rng2F32 new_root_rect = shift_2f32(root_rect, shift);
root->fixed_position = new_root_rect.p0;
@@ -1420,14 +1425,22 @@ ui_end_build(void)
{
if(b->flags & UI_BoxFlag_DrawText && !(b->flags & UI_BoxFlag_DisableTextTrunc))
{
Rng2F32 rect = b->rect;
for(UI_Box *p = b->parent; !ui_box_is_nil(p); p = p->parent)
{
if(p->flags & UI_BoxFlag_Clip)
{
rect = intersect_2f32(rect, p->rect);
}
}
String8 box_display_string = ui_box_display_string(b);
Vec2F32 text_pos = ui_box_text_position(b);
Vec2F32 drawn_text_dim = b->display_string_runs.dim;
B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > b->rect.x1);
B32 text_is_truncated = (drawn_text_dim.x + text_pos.x > rect.x1);
B32 mouse_is_hovering = contains_2f32(r2f32p(text_pos.x,
b->rect.y0,
Min(text_pos.x+drawn_text_dim.x, b->rect.x1),
b->rect.y1),
rect.y0,
Min(text_pos.x+drawn_text_dim.x, rect.x1),
rect.y1),
ui_state->mouse);
if(text_is_truncated && mouse_is_hovering)
{
@@ -1443,6 +1456,10 @@ ui_end_build(void)
goto break_all_hover_string;
}
}
if(b != box && ui_key_match(b->key, ui_hot_key()))
{
goto break_all_hover_string;
}
if(b != box && contains_2f32(b->rect, ui_state->mouse) && b->flags & UI_BoxFlag_DrawText)
{
goto break_all_hover_string;