checkpoint on unified code ctx menu & all of its operations

This commit is contained in:
Ryan Fleury
2024-06-25 16:31:31 -07:00
parent 010d5609c6
commit 6fa8af5e1a
11 changed files with 947 additions and 513 deletions
+336 -197
View File
@@ -837,6 +837,24 @@ df_single_inst_from_machine_code(Arena *arena, Architecture arch, U64 start_voff
return result;
}
////////////////////////////////
//~ rjf: Debug Info Extraction Type Pure Functions
internal DF_LineList
df_line_list_copy(Arena *arena, DF_LineList *list)
{
DF_LineList dst = {0};
for(DF_LineNode *src_n = list->first; src_n != 0; src_n = src_n->next)
{
DF_LineNode *dst_n = push_array(arena, DF_LineNode, 1);
MemoryCopyStruct(dst_n, src_n);
dst_n->v.dbgi_key = di_key_copy(arena, &src_n->v.dbgi_key);
SLLQueuePush(dst.first, dst.last, dst_n);
dst.count += 1;
}
return dst;
}
////////////////////////////////
//~ rjf: Control Flow Analysis Functions
@@ -2862,14 +2880,17 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
Rng1U64 line_vaddr_rng = {0};
{
U64 ip_voff = df_voff_from_vaddr(module, ip_vaddr);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, ip_voff, 0);
Rng1U64 line_voff_rng = line_info.voff_range;
if(line_voff_rng.max != 0)
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, ip_voff);
Rng1U64 line_voff_rng = {0};
if(lines.first != 0)
{
line_voff_rng = lines.first->v.voff_range;
line_vaddr_rng = df_vaddr_range_from_voff_range(module, line_voff_rng);
DF_Entity *file = df_entity_from_handle(lines.first->v.file);
log_infof("line: {%S:%I64i}\n", file->name, lines.first->v.pt.line);
}
log_infof("line: {%S:%I64i}\n", line_info.file->name, line_info.pt.line);
log_infof("voff_range: {0x%I64x, 0x%I64x}\n", line_info.voff_range.min, line_info.voff_range.max);
log_infof("voff_range: {0x%I64x, 0x%I64x}\n", line_voff_rng.min, line_voff_rng.max);
log_infof("vaddr_range: {0x%I64x, 0x%I64x}\n", line_vaddr_rng.min, line_vaddr_rng.max);
}
// rjf: opl line_vaddr_rng -> 0xf00f00 or 0xfeefee? => include in line vaddr range
@@ -2878,10 +2899,10 @@ df_trap_net_from_thread__step_over_line(Arena *arena, DF_Entity *thread)
// is enabled. This is enabled by default normally.
{
U64 opl_line_voff_rng = df_voff_from_vaddr(module, line_vaddr_rng.max);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, opl_line_voff_rng, 0);
if(line_info.pt.line == 0xf00f00 || line_info.pt.line == 0xfeefee)
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, opl_line_voff_rng);
if(lines.first != 0 && (lines.first->v.pt.line == 0xf00f00 || lines.first->v.pt.line == 0xfeefee))
{
line_vaddr_rng.max = df_vaddr_from_voff(module, line_info.voff_range.max);
line_vaddr_rng.max = df_vaddr_from_voff(module, lines.first->v.voff_range.max);
}
}
@@ -3020,10 +3041,11 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
Rng1U64 line_vaddr_rng = {0};
{
U64 ip_voff = df_voff_from_vaddr(module, ip_vaddr);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, ip_voff, 0);
Rng1U64 line_voff_rng = line_info.voff_range;
if(line_voff_rng.max != 0)
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, ip_voff);
Rng1U64 line_voff_rng = {0};
if(lines.first != 0)
{
line_voff_rng = lines.first->v.voff_range;
line_vaddr_rng = df_vaddr_range_from_voff_range(module, line_voff_rng);
}
}
@@ -3034,10 +3056,10 @@ df_trap_net_from_thread__step_into_line(Arena *arena, DF_Entity *thread)
// is enabled. This is enabled by default normally.
{
U64 opl_line_voff_rng = df_voff_from_vaddr(module, line_vaddr_rng.max);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, opl_line_voff_rng, 0);
if(line_info.pt.line == 0xf00f00 || line_info.pt.line == 0xfeefee)
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, opl_line_voff_rng);
if(lines.first != 0 && (lines.first->v.pt.line == 0xf00f00 || lines.first->v.pt.line == 0xfeefee))
{
line_vaddr_rng.max = df_vaddr_from_voff(module, line_info.voff_range.max);
line_vaddr_rng.max = df_vaddr_from_voff(module, lines.first->v.voff_range.max);
}
}
@@ -3247,186 +3269,6 @@ df_symbol_name_from_process_vaddr(Arena *arena, DF_Entity *process, U64 vaddr)
return result;
}
//- rjf: src -> voff lookups
internal DF_TextLineSrc2DasmInfoListArray
df_text_line_src2dasm_info_list_array_from_src_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range)
{
DF_TextLineSrc2DasmInfoListArray src2dasm_array = {0};
{
src2dasm_array.count = dim_1s64(line_num_range)+1;
src2dasm_array.v = push_array(arena, DF_TextLineSrc2DasmInfoList, src2dasm_array.count);
}
Temp scratch = scratch_begin(&arena, 1);
DI_Scope *scope = di_scope_open();
DI_KeyList dbgi_keys = df_push_active_dbgi_key_list(scratch.arena);
DF_EntityList overrides = df_possible_overrides_from_entity(scratch.arena, file);
for(DF_EntityNode *override_n = overrides.first;
override_n != 0;
override_n = override_n->next)
{
DF_Entity *override = override_n->entity;
String8 file_path = df_full_path_from_entity(scratch.arena, override);
String8 file_path_normalized = lower_from_str8(scratch.arena, file_path);
for(DI_KeyNode *dbgi_key_n = dbgi_keys.first;
dbgi_key_n != 0;
dbgi_key_n = dbgi_key_n->next)
{
// rjf: binary -> rdi
DI_Key key = dbgi_key_n->v;
RDI_Parsed *rdi = di_rdi_from_key(scope, &key, 0);
// rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0;
U32 src_id = 0;
if(rdi != &di_rdi_parsed_nil)
{
RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths);
RDI_ParsedNameMap map = {0};
rdi_parsed_from_name_map(rdi, mapptr, &map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, file_path_normalized.str, file_path_normalized.size);
if(node != 0)
{
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
good_src_id = 1;
src_id = ids[0];
}
}
}
// rjf: good src-id -> look up line info for visible range
if(good_src_id)
{
RDI_SourceFile *src = rdi_element_from_name_idx(rdi, SourceFiles, src_id);
RDI_SourceLineMap *src_line_map = rdi_element_from_name_idx(rdi, SourceLineMaps, src->source_line_map_idx);
RDI_ParsedSourceLineMap line_map = {0};
rdi_parsed_from_source_line_map(rdi, src_line_map, &line_map);
U64 line_idx = 0;
for(S64 line_num = line_num_range.min;
line_num <= line_num_range.max;
line_num += 1, line_idx += 1)
{
DF_TextLineSrc2DasmInfoList *src2dasm_list = &src2dasm_array.v[line_idx];
U32 voff_count = 0;
U64 *voffs = rdi_line_voffs_from_num(&line_map, u32_from_u64_saturate((U64)line_num), &voff_count);
for(U64 idx = 0; idx < voff_count; idx += 1)
{
U64 base_voff = voffs[idx];
U64 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, base_voff);
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
RDI_ParsedLineTable unit_line_info = {0};
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, base_voff);
if(unit_line_info.voffs != 0)
{
Rng1U64 range = r1u64(base_voff, unit_line_info.voffs[line_info_idx+1]);
S64 actual_line = (S64)unit_line_info.lines[line_info_idx].line_num;
DF_TextLineSrc2DasmInfoNode *src2dasm_n = push_array(arena, DF_TextLineSrc2DasmInfoNode, 1);
src2dasm_n->v.voff_range = range;
src2dasm_n->v.remap_line = (S64)actual_line;
src2dasm_n->v.dbgi_key = key;
SLLQueuePush(src2dasm_list->first, src2dasm_list->last, src2dasm_n);
src2dasm_list->count += 1;
}
}
}
}
// rjf: good src id -> push to relevant dbgi keys
if(good_src_id)
{
di_key_list_push(arena, &src2dasm_array.dbgi_keys, &key);
}
}
}
di_scope_close(scope);
scratch_end(scratch);
return src2dasm_array;
}
//- rjf: voff -> src lookups
internal DF_TextLineDasm2SrcInfo
df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff, U64 inline_unwind_idx)
{
Temp scratch = scratch_begin(0, 0);
DI_Scope *scope = di_scope_open();
RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0);
DF_TextLineDasm2SrcInfo result = {0};
result.file = &df_g_nil_entity;
{
RDI_Unit *unit = rdi_unit_from_voff(rdi, voff);
RDI_LineTable *unit_line_table = rdi_line_table_from_unit(rdi, unit);
typedef struct LineTableNode LineTableNode;
struct LineTableNode
{
LineTableNode *next;
RDI_ParsedLineTable parsed_line_table;
};
LineTableNode start_line_table = {0};
rdi_parsed_from_line_table(rdi, unit_line_table, &start_line_table.parsed_line_table);
LineTableNode *top_line_table = &start_line_table;
RDI_Scope *scope = rdi_scope_from_voff(rdi, voff);
{
U64 idx = 0;
for(RDI_Scope *s = scope;
s->inline_site_idx != 0 && idx <= inline_unwind_idx;
s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx), idx += 1)
{
if(idx == inline_unwind_idx)
{
RDI_InlineSite *inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
if(inline_site->line_table_idx != 0)
{
LineTableNode *n = push_array(scratch.arena, LineTableNode, 1);
SLLStackPush(top_line_table, n);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, inline_site->line_table_idx);
rdi_parsed_from_line_table(rdi, line_table, &n->parsed_line_table);
}
break;
}
}
}
for(LineTableNode *n = top_line_table; n == top_line_table; n = n->next)
{
RDI_ParsedLineTable parsed_line_table = n->parsed_line_table;
U64 line_info_idx = rdi_line_info_idx_from_voff(&parsed_line_table, voff);
if(line_info_idx < parsed_line_table.count)
{
RDI_Line *line = &parsed_line_table.lines[line_info_idx];
RDI_Column *column = (line_info_idx < parsed_line_table.col_count) ? &parsed_line_table.cols[line_info_idx] : 0;
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
String8 file_normalized_full_path = {0};
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
MemoryCopyStruct(&result.dbgi_key, dbgi_key);
if(line->file_idx != 0 && file_normalized_full_path.size != 0)
{
result.file = df_entity_from_path(file_normalized_full_path, DF_EntityFromPathFlag_All);
}
result.pt = txt_pt(line->line_num, column ? column->col_first : 1);
result.voff_range = r1u64(parsed_line_table.voffs[line_info_idx], parsed_line_table.voffs[line_info_idx+1]);
}
}
for(LineTableNode *n = top_line_table->next; n != 0; n = n->next)
{
RDI_ParsedLineTable parsed_line_table = n->parsed_line_table;
U64 line_info_idx = rdi_line_info_idx_from_voff(&parsed_line_table, voff);
if(line_info_idx < parsed_line_table.count)
{
Rng1U64 voff_range = r1u64(parsed_line_table.voffs[line_info_idx], parsed_line_table.voffs[line_info_idx+1]);
result.voff_range = intersect_1u64(result.voff_range, voff_range);
}
}
}
di_scope_close(scope);
scratch_end(scratch);
return result;
}
//- rjf: symbol -> voff lookups
internal U64
@@ -3549,6 +3391,298 @@ df_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name)
return result;
}
//- rjf: voff -> line info
internal DF_LineList
df_lines_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff)
{
Temp scratch = scratch_begin(&arena, 1);
DI_Scope *scope = di_scope_open();
RDI_Parsed *rdi = di_rdi_from_key(scope, dbgi_key, 0);
DF_LineList result = {0};
{
//- rjf: gather line tables
typedef struct LineTableNode LineTableNode;
struct LineTableNode
{
LineTableNode *next;
RDI_ParsedLineTable parsed_line_table;
};
LineTableNode start_line_table = {0};
RDI_Unit *unit = rdi_unit_from_voff(rdi, voff);
RDI_LineTable *unit_line_table = rdi_line_table_from_unit(rdi, unit);
rdi_parsed_from_line_table(rdi, unit_line_table, &start_line_table.parsed_line_table);
LineTableNode *top_line_table = &start_line_table;
RDI_Scope *scope = rdi_scope_from_voff(rdi, voff);
{
for(RDI_Scope *s = scope;
s->inline_site_idx != 0;
s = rdi_element_from_name_idx(rdi, Scopes, s->parent_scope_idx))
{
RDI_InlineSite *inline_site = rdi_element_from_name_idx(rdi, InlineSites, s->inline_site_idx);
if(inline_site->line_table_idx != 0)
{
LineTableNode *n = push_array(scratch.arena, LineTableNode, 1);
SLLStackPush(top_line_table, n);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, inline_site->line_table_idx);
rdi_parsed_from_line_table(rdi, line_table, &n->parsed_line_table);
}
}
}
//- rjf: gather lines in each line table
Rng1U64 shallowest_voff_range = {0};
for(LineTableNode *n = top_line_table; n != 0; n = n->next)
{
RDI_ParsedLineTable parsed_line_table = n->parsed_line_table;
U64 line_info_idx = rdi_line_info_idx_from_voff(&parsed_line_table, voff);
if(line_info_idx < parsed_line_table.count)
{
RDI_Line *line = &parsed_line_table.lines[line_info_idx];
RDI_Column *column = (line_info_idx < parsed_line_table.col_count) ? &parsed_line_table.cols[line_info_idx] : 0;
RDI_SourceFile *file = rdi_element_from_name_idx(rdi, SourceFiles, line->file_idx);
String8 file_normalized_full_path = {0};
file_normalized_full_path.str = rdi_string_from_idx(rdi, file->normal_full_path_string_idx, &file_normalized_full_path.size);
DF_LineNode *n = push_array(arena, DF_LineNode, 1);
SLLQueuePush(result.first, result.last, n);
result.count += 1;
if(line->file_idx != 0 && file_normalized_full_path.size != 0)
{
n->v.file = df_handle_from_entity(df_entity_from_path(file_normalized_full_path, DF_EntityFromPathFlag_All));
}
n->v.pt = txt_pt(line->line_num, column ? column->col_first : 1);
n->v.voff_range = r1u64(parsed_line_table.voffs[line_info_idx], parsed_line_table.voffs[line_info_idx+1]);
n->v.dbgi_key = *dbgi_key;
shallowest_voff_range = n->v.voff_range;
}
}
//- rjf: clamp all lines from all tables by shallowest (most unwound) range
for(DF_LineNode *n = result.first; n != 0; n = n->next)
{
n->v.voff_range = intersect_1u64(n->v.voff_range, shallowest_voff_range);
}
}
di_scope_close(scope);
scratch_end(scratch);
return result;
}
//- rjf: file:line -> line info
internal DF_LineListArray
df_lines_array_from_file_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range)
{
DF_LineListArray array = {0};
{
array.count = dim_1s64(line_num_range)+1;
array.v = push_array(arena, DF_LineList, array.count);
}
Temp scratch = scratch_begin(&arena, 1);
DI_Scope *scope = di_scope_open();
DI_KeyList dbgi_keys = df_push_active_dbgi_key_list(scratch.arena);
DF_EntityList overrides = df_possible_overrides_from_entity(scratch.arena, file);
for(DF_EntityNode *override_n = overrides.first;
override_n != 0;
override_n = override_n->next)
{
DF_Entity *override = override_n->entity;
String8 file_path = df_full_path_from_entity(scratch.arena, override);
String8 file_path_normalized = lower_from_str8(scratch.arena, file_path);
for(DI_KeyNode *dbgi_key_n = dbgi_keys.first;
dbgi_key_n != 0;
dbgi_key_n = dbgi_key_n->next)
{
// rjf: binary -> rdi
DI_Key key = dbgi_key_n->v;
RDI_Parsed *rdi = di_rdi_from_key(scope, &key, 0);
// rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0;
U32 src_id = 0;
if(rdi != &di_rdi_parsed_nil)
{
RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths);
RDI_ParsedNameMap map = {0};
rdi_parsed_from_name_map(rdi, mapptr, &map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, file_path_normalized.str, file_path_normalized.size);
if(node != 0)
{
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
good_src_id = 1;
src_id = ids[0];
}
}
}
// rjf: good src-id -> look up line info for visible range
if(good_src_id)
{
RDI_SourceFile *src = rdi_element_from_name_idx(rdi, SourceFiles, src_id);
RDI_SourceLineMap *src_line_map = rdi_element_from_name_idx(rdi, SourceLineMaps, src->source_line_map_idx);
RDI_ParsedSourceLineMap line_map = {0};
rdi_parsed_from_source_line_map(rdi, src_line_map, &line_map);
U64 line_idx = 0;
for(S64 line_num = line_num_range.min;
line_num <= line_num_range.max;
line_num += 1, line_idx += 1)
{
DF_LineList *list = &array.v[line_idx];
U32 voff_count = 0;
U64 *voffs = rdi_line_voffs_from_num(&line_map, u32_from_u64_saturate((U64)line_num), &voff_count);
for(U64 idx = 0; idx < voff_count; idx += 1)
{
U64 base_voff = voffs[idx];
U64 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, base_voff);
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
RDI_ParsedLineTable unit_line_info = {0};
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, base_voff);
if(unit_line_info.voffs != 0)
{
Rng1U64 range = r1u64(base_voff, unit_line_info.voffs[line_info_idx+1]);
S64 actual_line = (S64)unit_line_info.lines[line_info_idx].line_num;
DF_LineNode *n = push_array(arena, DF_LineNode, 1);
n->v.voff_range = range;
n->v.pt.line = (S64)actual_line;
n->v.pt.column = 1;
n->v.dbgi_key = key;
SLLQueuePush(list->first, list->last, n);
list->count += 1;
}
}
}
}
// rjf: good src id -> push to relevant dbgi keys
if(good_src_id)
{
di_key_list_push(arena, &array.dbgi_keys, &key);
}
}
}
di_scope_close(scope);
scratch_end(scratch);
return array;
}
internal DF_LineList
df_lines_from_file_line_num(Arena *arena, DF_Entity *file, S64 line_num)
{
DF_LineListArray array = df_lines_array_from_file_line_range(arena, file, r1s64(line_num, line_num+1));
DF_LineList list = {0};
if(array.count != 0)
{
list = array.v[0];
}
return list;
}
//- rjf: src -> voff lookups
internal DF_TextLineSrc2DasmInfoListArray
df_text_line_src2dasm_info_list_array_from_src_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range)
{
DF_TextLineSrc2DasmInfoListArray src2dasm_array = {0};
{
src2dasm_array.count = dim_1s64(line_num_range)+1;
src2dasm_array.v = push_array(arena, DF_TextLineSrc2DasmInfoList, src2dasm_array.count);
}
Temp scratch = scratch_begin(&arena, 1);
DI_Scope *scope = di_scope_open();
DI_KeyList dbgi_keys = df_push_active_dbgi_key_list(scratch.arena);
DF_EntityList overrides = df_possible_overrides_from_entity(scratch.arena, file);
for(DF_EntityNode *override_n = overrides.first;
override_n != 0;
override_n = override_n->next)
{
DF_Entity *override = override_n->entity;
String8 file_path = df_full_path_from_entity(scratch.arena, override);
String8 file_path_normalized = lower_from_str8(scratch.arena, file_path);
for(DI_KeyNode *dbgi_key_n = dbgi_keys.first;
dbgi_key_n != 0;
dbgi_key_n = dbgi_key_n->next)
{
// rjf: binary -> rdi
DI_Key key = dbgi_key_n->v;
RDI_Parsed *rdi = di_rdi_from_key(scope, &key, 0);
// rjf: file_path_normalized * rdi -> src_id
B32 good_src_id = 0;
U32 src_id = 0;
if(rdi != &di_rdi_parsed_nil)
{
RDI_NameMap *mapptr = rdi_element_from_name_idx(rdi, NameMaps, RDI_NameMapKind_NormalSourcePaths);
RDI_ParsedNameMap map = {0};
rdi_parsed_from_name_map(rdi, mapptr, &map);
RDI_NameMapNode *node = rdi_name_map_lookup(rdi, &map, file_path_normalized.str, file_path_normalized.size);
if(node != 0)
{
U32 id_count = 0;
U32 *ids = rdi_matches_from_map_node(rdi, node, &id_count);
if(id_count > 0)
{
good_src_id = 1;
src_id = ids[0];
}
}
}
// rjf: good src-id -> look up line info for visible range
if(good_src_id)
{
RDI_SourceFile *src = rdi_element_from_name_idx(rdi, SourceFiles, src_id);
RDI_SourceLineMap *src_line_map = rdi_element_from_name_idx(rdi, SourceLineMaps, src->source_line_map_idx);
RDI_ParsedSourceLineMap line_map = {0};
rdi_parsed_from_source_line_map(rdi, src_line_map, &line_map);
U64 line_idx = 0;
for(S64 line_num = line_num_range.min;
line_num <= line_num_range.max;
line_num += 1, line_idx += 1)
{
DF_TextLineSrc2DasmInfoList *src2dasm_list = &src2dasm_array.v[line_idx];
U32 voff_count = 0;
U64 *voffs = rdi_line_voffs_from_num(&line_map, u32_from_u64_saturate((U64)line_num), &voff_count);
for(U64 idx = 0; idx < voff_count; idx += 1)
{
U64 base_voff = voffs[idx];
U64 unit_idx = rdi_vmap_idx_from_section_kind_voff(rdi, RDI_SectionKind_UnitVMap, base_voff);
RDI_Unit *unit = rdi_element_from_name_idx(rdi, Units, unit_idx);
RDI_LineTable *line_table = rdi_element_from_name_idx(rdi, LineTables, unit->line_table_idx);
RDI_ParsedLineTable unit_line_info = {0};
rdi_parsed_from_line_table(rdi, line_table, &unit_line_info);
U64 line_info_idx = rdi_line_info_idx_from_voff(&unit_line_info, base_voff);
if(unit_line_info.voffs != 0)
{
Rng1U64 range = r1u64(base_voff, unit_line_info.voffs[line_info_idx+1]);
S64 actual_line = (S64)unit_line_info.lines[line_info_idx].line_num;
DF_TextLineSrc2DasmInfoNode *src2dasm_n = push_array(arena, DF_TextLineSrc2DasmInfoNode, 1);
src2dasm_n->v.voff_range = range;
src2dasm_n->v.remap_line = (S64)actual_line;
src2dasm_n->v.dbgi_key = key;
SLLQueuePush(src2dasm_list->first, src2dasm_list->last, src2dasm_n);
src2dasm_list->count += 1;
}
}
}
}
// rjf: good src id -> push to relevant dbgi keys
if(good_src_id)
{
di_key_list_push(arena, &src2dasm_array.dbgi_keys, &key);
}
}
}
di_scope_close(scope);
scratch_end(scratch);
return src2dasm_array;
}
////////////////////////////////
//~ rjf: Process/Thread/Module Info Lookups
@@ -6886,7 +7020,6 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
DF_Entity *module = df_module_from_process_vaddr(process, stop_thread_vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
U64 stop_thread_voff = df_voff_from_vaddr(module, stop_thread_vaddr);
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, stop_thread_voff, 0);
DF_EntityList user_bps = df_query_cached_entity_list_with_kind(DF_EntityKind_Breakpoint);
for(DF_EntityNode *n = user_bps.first; n != 0; n = n->next)
{
@@ -6898,9 +7031,14 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
if(bp->flags & DF_EntityFlag_HasTextPoint)
{
DF_Entity *bp_file = df_entity_ancestor_from_kind(bp, DF_EntityKind_File);
if(bp_file == dasm2src_info.file && bp->text_point.line == dasm2src_info.pt.line)
DF_LineList lines = df_lines_from_file_line_num(scratch.arena, bp_file, bp_file->text_point.line);
for(DF_LineNode *n = lines.first; n != 0; n = n->next)
{
bp->u64 += 1;
if(contains_1u64(n->v.voff_range, stop_thread_voff))
{
bp->u64 += 1;
break;
}
}
}
}
@@ -7631,6 +7769,7 @@ df_core_begin_frame(Arena *arena, DF_CmdList *cmds, F32 dt)
{
DF_Entity *bp = df_entity_alloc(0, df_entity_root(), DF_EntityKind_Breakpoint);
bp->flags |= DF_EntityFlag_DiesOnRunStop;
df_entity_equip_b32(bp, 1);
df_entity_equip_vaddr(bp, params.vaddr);
df_entity_equip_cfg_src(bp, DF_CfgSrc_Transient);
DF_CmdParams p = df_cmd_params_zero();
+50 -6
View File
@@ -556,6 +556,41 @@ struct DF_Unwind
DF_UnwindFrameArray frames;
};
////////////////////////////////
//~ rjf: Line Info Types
typedef struct DF_Line DF_Line;
struct DF_Line
{
DF_Handle file;
TxtPt pt;
Rng1U64 voff_range;
DI_Key dbgi_key;
};
typedef struct DF_LineNode DF_LineNode;
struct DF_LineNode
{
DF_LineNode *next;
DF_Line v;
};
typedef struct DF_LineList DF_LineList;
struct DF_LineList
{
DF_LineNode *first;
DF_LineNode *last;
U64 count;
};
typedef struct DF_LineListArray DF_LineListArray;
struct DF_LineListArray
{
DF_LineList *v;
U64 count;
DI_KeyList dbgi_keys;
};
////////////////////////////////
//~ rjf: Source <-> Disasm Types
@@ -1391,6 +1426,11 @@ internal String8 df_string_from_cfg_node_key(DF_CfgNode *node, String8 key, Stri
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
internal DF_LineList df_line_list_copy(Arena *arena, DF_LineList *list);
////////////////////////////////
//~ rjf: Control Flow Analysis Pure Functions
@@ -1582,16 +1622,20 @@ internal Rng1U64 df_vaddr_range_from_voff_range(DF_Entity *module, Rng1U64 voff_
internal String8 df_symbol_name_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff);
internal String8 df_symbol_name_from_process_vaddr(Arena *arena, DF_Entity *process, U64 vaddr);
//- rjf: src -> voff lookups
internal DF_TextLineSrc2DasmInfoListArray df_text_line_src2dasm_info_list_array_from_src_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range);
//- rjf: voff -> src lookups
internal DF_TextLineDasm2SrcInfo df_text_line_dasm2src_info_from_dbgi_key_voff(DI_Key *dbgi_key, U64 voff, U64 inline_unwind_idx);
//- rjf: symbol -> voff lookups
internal U64 df_voff_from_dbgi_key_symbol_name(DI_Key *dbgi_key, String8 symbol_name);
internal U64 df_type_num_from_dbgi_key_name(DI_Key *dbgi_key, String8 name);
//- rjf: voff -> line info
internal DF_LineList df_lines_from_dbgi_key_voff(Arena *arena, DI_Key *dbgi_key, U64 voff);
//- rjf: file:line -> line info
internal DF_LineListArray df_lines_array_from_file_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range);
internal DF_LineList df_lines_from_file_line_num(Arena *arena, DF_Entity *file, S64 line_num);
//- rjf: src -> voff lookups
internal DF_TextLineSrc2DasmInfoListArray df_text_line_src2dasm_info_list_array_from_src_line_range(Arena *arena, DF_Entity *file, Rng1S64 line_num_range);
////////////////////////////////
//~ rjf: Process/Thread/Module Info Lookups
+4
View File
@@ -222,6 +222,10 @@ DF_CoreCmdTable:// | | |
{Switch 0 Entity File 0 0 0 0 0 1 FileOutline "switch" "Switch" "Switches to a loaded file." "code,source,file" }
{SwitchToPartnerFile 0 Null Nil 0 0 0 0 0 0 FileOutline "switch_to_partner_file" "Switch To Partner File" "Switches to the focused file's partner; or from header to implementation or vice versa." "code,source,file" }
//- rjf: source <-> disasm
{GoToDisassembly 0 Null Nil 0 0 0 0 0 0 Glasses "go_to_disassembly" "Go To Disassembly" "Goes to the disassembly, if any, for a given source code line." "code,source,disassembly,disasm" }
{GoToSource 0 Null Nil 0 0 0 0 0 0 FileOutline "go_to_source" "Go To Source" "Goes to the source code, if any, for a given disassembly line." "code,source,disassembly,disasm" }
//- rjf: override file links
{SetFileOverrideLinkSrc 1 Null Nil 0 0 0 0 0 0 Null "set_file_override_link_src" "Set File Override Link Source" "Sets the source path for an override file link." "" }
{SetFileOverrideLinkDst 1 Null Nil 0 0 0 0 0 0 Null "set_file_override_link_dst" "Set File Override Link Destination" "Sets the destination path for an override file link." "" }
+3 -1
View File
@@ -209,7 +209,7 @@ DF_CoreCmdKind_Null,
DF_CoreCmdKind_Null,
};
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[218] =
DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[220] =
{
{ str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), str8_lit_comp(""), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("exit"), str8_lit_comp("Exits the debugger."), str8_lit_comp("quit,close,abort"), str8_lit_comp("Exit"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_X},
@@ -294,6 +294,8 @@ DF_CmdSpecInfo df_g_core_cmd_kind_spec_info_table[218] =
{ str8_lit_comp("open"), str8_lit_comp("Opens a file."), str8_lit_comp("code,source,file"), str8_lit_comp("Open"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_FilePath, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*1)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("switch"), str8_lit_comp("Switches to a loaded file."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Entity, DF_EntityKind_File, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*1)}, DF_IconKind_FileOutline},
{ str8_lit_comp("switch_to_partner_file"), str8_lit_comp("Switches to the focused file's partner; or from header to implementation or vice versa."), str8_lit_comp("code,source,file"), str8_lit_comp("Switch To Partner File"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("go_to_disassembly"), str8_lit_comp("Goes to the disassembly, if any, for a given source code line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("Go To Disassembly"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Glasses},
{ str8_lit_comp("go_to_source"), str8_lit_comp("Goes to the source code, if any, for a given disassembly line."), str8_lit_comp("code,source,disassembly,disasm"), str8_lit_comp("Go To Source"), (DF_CmdSpecFlag_OmitFromLists*0), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_FileOutline},
{ str8_lit_comp("set_file_override_link_src"), str8_lit_comp("Sets the source path for an override file link."), str8_lit_comp(""), str8_lit_comp("Set File Override Link Source"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("set_file_override_link_dst"), str8_lit_comp("Sets the destination path for an override file link."), str8_lit_comp(""), str8_lit_comp("Set File Override Link Destination"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
{ str8_lit_comp("set_file_replacement_path"), str8_lit_comp("Sets the path which should be used as the replacement for the passed file."), str8_lit_comp(""), str8_lit_comp("Set File Replacement Path"), (DF_CmdSpecFlag_OmitFromLists*1), {DF_CmdParamSlot_Null, DF_EntityKind_Nil, (DF_CmdQueryFlag_AllowFiles*0)|(DF_CmdQueryFlag_AllowFolders*0)|(DF_CmdQueryFlag_CodeInput*0)|(DF_CmdQueryFlag_KeepOldInput*0)|(DF_CmdQueryFlag_SelectOldInput*0)|(DF_CmdQueryFlag_Required*0)}, DF_IconKind_Null},
+2
View File
@@ -130,6 +130,8 @@ DF_CoreCmdKind_SetCurrentPath,
DF_CoreCmdKind_Open,
DF_CoreCmdKind_Switch,
DF_CoreCmdKind_SwitchToPartnerFile,
DF_CoreCmdKind_GoToDisassembly,
DF_CoreCmdKind_GoToSource,
DF_CoreCmdKind_SetFileOverrideLinkSrc,
DF_CoreCmdKind_SetFileOverrideLinkDst,
DF_CoreCmdKind_SetFileReplacementPath,
+278 -232
View File
@@ -1029,6 +1029,7 @@ df_window_open(Vec2F32 size, OS_Handle preferred_monitor, DF_CfgSrc cfg_src)
window->code_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_code_ctx_menu_"));
window->entity_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_entity_ctx_menu_"));
window->tab_ctx_menu_key = ui_key_from_string(ui_key_zero(), str8_lit("_tab_ctx_menu_"));
window->code_ctx_menu_arena = arena_alloc();
window->hover_eval_arena = arena_alloc();
window->autocomp_lister_params_arena = arena_alloc();
window->free_panel = &df_g_nil_panel;
@@ -2585,13 +2586,25 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
DI_Key dbgi_key = df_dbgi_key_from_module(module);
RDI_Parsed *rdi = di_rdi_from_key(scope, &dbgi_key, 0);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, rip_voff, inline_unwind_index);
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
DF_Line line = {0};
{
U64 idx = 0;
for(DF_LineNode *n = lines.first; n != 0; n = n->next, idx += 1)
{
line = n->v;
if(idx == inline_unwind_index)
{
break;
}
}
}
// rjf: snap to resolved line
B32 missing_rip = (rip_vaddr == 0);
B32 dbgi_missing = (dbgi_key.min_timestamp == 0 || dbgi_key.path.size == 0);
B32 dbgi_pending = !dbgi_missing && rdi == &di_rdi_parsed_nil;
B32 has_line_info = (line_info.voff_range.max != line_info.voff_range.min);
B32 has_line_info = (line.voff_range.max != line.voff_range.min);
B32 has_module = !df_entity_is_nil(module);
B32 has_dbg_info = has_module && !dbgi_missing;
if(!dbgi_pending && (has_line_info || has_module))
@@ -2599,8 +2612,8 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
DF_CmdParams params = df_cmd_params_from_window(ws);
if(has_line_info)
{
params.file_path = df_full_path_from_entity(scratch.arena, line_info.file);
params.text_point = line_info.pt;
params.file_path = df_full_path_from_entity(scratch.arena, df_entity_from_handle(line.file));
params.text_point = line.pt;
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_FilePath);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_TextPoint);
}
@@ -2783,28 +2796,31 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
// rjf: name resolved to voff * dbg info
if(name_resolved != 0 && voff != 0)
{
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&voff_dbgi_key, voff, 0);
DF_CmdParams p = params;
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &voff_dbgi_key, voff);
if(lines.first != 0)
{
p.file_path = df_full_path_from_entity(scratch.arena, dasm2src_info.file);
p.text_point = dasm2src_info.pt;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_FilePath);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_TextPoint);
if(voff_dbgi_key.path.size != 0)
DF_CmdParams p = params;
{
DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &voff_dbgi_key);
DF_Entity *module = df_first_entity_from_list(&modules);
DF_Entity *process = df_entity_ancestor_from_kind(module, DF_EntityKind_Process);
if(!df_entity_is_nil(process))
p.file_path = df_full_path_from_entity(scratch.arena, df_entity_from_handle(lines.first->v.file));
p.text_point = lines.first->v.pt;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_FilePath);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_TextPoint);
if(voff_dbgi_key.path.size != 0)
{
p.entity = df_handle_from_entity(process);
p.vaddr = module->vaddr_rng.min + dasm2src_info.voff_range.min;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Entity);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_VirtualAddr);
DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &voff_dbgi_key);
DF_Entity *module = df_first_entity_from_list(&modules);
DF_Entity *process = df_entity_ancestor_from_kind(module, DF_EntityKind_Process);
if(!df_entity_is_nil(process))
{
p.entity = df_handle_from_entity(process);
p.vaddr = module->vaddr_rng.min + lines.first->v.voff_range.min;
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_Entity);
df_cmd_params_mark_slot(&p, DF_CmdParamSlot_VirtualAddr);
}
}
}
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
}
df_cmd_list_push(arena, cmds, &p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
}
// rjf: name resolved to a file
@@ -3694,9 +3710,154 @@ df_window_update_and_render(Arena *arena, DF_Window *ws, DF_CmdList *cmds)
UI_PrefWidth(ui_em(30.f, 1.f))
DF_Palette(DF_PaletteCode_ImplicitButton)
{
ui_buttonf("Foo");
ui_buttonf("Bar");
ui_buttonf("Baz");
TXT_Scope *txt_scope = txt_scope_open();
HS_Scope *hs_scope = hs_scope_open();
DF_CtrlCtx ctrl_ctx = df_ctrl_ctx_from_window(ws);
TxtRng range = ws->code_ctx_menu_range;
DF_LineList lines = ws->code_ctx_menu_lines;
if(!txt_pt_match(range.min, range.max) && ui_clicked(df_cmd_spec_button(df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Copy))))
{
U128 hash = {0};
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, ws->code_ctx_menu_text_key, ws->code_ctx_menu_lang_kind, &hash);
String8 data = hs_data_from_hash(hs_scope, hash);
String8 copy_data = txt_string_from_info_data_txt_rng(&info, data, ws->code_ctx_menu_range);
os_set_clipboard_text(copy_data);
ui_ctx_menu_close();
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_RightArrow, 0, "Move Thread Here")))
{
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
U64 new_rip_vaddr = ws->code_ctx_menu_vaddr;
if(!df_entity_is_nil(df_entity_from_handle(ws->code_ctx_menu_file)))
{
for(DF_LineNode *n = lines.first; n != 0; n = n->next)
{
DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
DF_Entity *module = df_module_from_thread_candidates(thread, &modules);
if(!df_entity_is_nil(module))
{
new_rip_vaddr = df_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
}
DF_CmdParams p = df_cmd_params_from_window(ws);
p.entity = df_handle_from_entity(thread);
p.vaddr = new_rip_vaddr;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SetThreadIP));
ui_ctx_menu_close();
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_Play, 0, "Run To Line")))
{
if(!df_entity_is_nil(df_entity_from_handle(ws->code_ctx_menu_file)))
{
DF_CmdParams p = df_cmd_params_from_window(ws);
p.entity = ws->code_ctx_menu_file;
p.text_point = range.min;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunToLine));
}
else
{
DF_CmdParams p = df_cmd_params_from_window(ws);
p.vaddr = ws->code_ctx_menu_vaddr;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_RunToAddress));
}
ui_ctx_menu_close();
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_Null, 0, "Go To Name")))
{
U128 hash = {0};
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, ws->code_ctx_menu_text_key, ws->code_ctx_menu_lang_kind, &hash);
String8 data = hs_data_from_hash(hs_scope, hash);
Rng1U64 expr_off_range = {0};
if(range.min.column != range.max.column)
{
expr_off_range = r1u64(txt_off_from_info_pt(&info, range.min), txt_off_from_info_pt(&info, range.max));
}
else
{
expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min);
}
String8 expr = str8_substr(data, expr_off_range);
DF_CmdParams p = df_cmd_params_from_window(ws);
p.string = expr;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_GoToName));
ui_ctx_menu_close();
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_CircleFilled, 0, "Toggle Breakpoint")))
{
if(ws->code_ctx_menu_vaddr != 0)
{
DF_CmdParams p = df_cmd_params_from_window(ws);
p.vaddr = ws->code_ctx_menu_vaddr;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_AddressBreakpoint));
}
else
{
DF_CmdParams p = df_cmd_params_from_window(ws);
p.entity = ws->code_ctx_menu_file;
p.text_point = range.min;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_TextBreakpoint));
}
ui_ctx_menu_close();
}
if(range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_Binoculars, 0, "Toggle Watch Expression")))
{
U128 hash = {0};
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, ws->code_ctx_menu_text_key, ws->code_ctx_menu_lang_kind, &hash);
String8 data = hs_data_from_hash(hs_scope, hash);
Rng1U64 expr_off_range = {0};
if(range.min.column != range.max.column)
{
expr_off_range = r1u64(txt_off_from_info_pt(&info, range.min), txt_off_from_info_pt(&info, range.max));
}
else
{
expr_off_range = txt_expr_off_range_from_info_data_pt(&info, data, range.min);
}
String8 expr = str8_substr(data, expr_off_range);
DF_CmdParams p = df_cmd_params_from_window(ws);
p.string = expr;
df_push_cmd__root(&p, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpression));
ui_ctx_menu_close();
}
if(df_entity_is_nil(df_entity_from_handle(ws->code_ctx_menu_file)) && range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_FileOutline, 0, "Go To Source")))
{
if(lines.first != 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
params.file_path = df_full_path_from_entity(scratch.arena, df_entity_from_handle(lines.first->v.file));
params.text_point = lines.first->v.pt;
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_FilePath);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_TextPoint);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
}
ui_ctx_menu_close();
}
if(!df_entity_is_nil(df_entity_from_handle(ws->code_ctx_menu_file)) && range.min.line == range.max.line && ui_clicked(df_icon_buttonf(DF_IconKind_FileOutline, 0, "Go To Disassembly")))
{
DF_Entity *thread = df_entity_from_handle(ctrl_ctx.thread);
U64 vaddr = 0;
for(DF_LineNode *n = lines.first; n != 0; n = n->next)
{
DF_EntityList modules = df_modules_from_dbgi_key(scratch.arena, &n->v.dbgi_key);
DF_Entity *module = df_module_from_thread_candidates(thread, &modules);
if(!df_entity_is_nil(module))
{
vaddr = df_vaddr_from_voff(module, n->v.voff_range.min);
break;
}
}
DF_CmdParams params = df_cmd_params_from_window(ws);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_Entity);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_VirtualAddr);
params.entity = df_handle_from_entity(thread);
params.vaddr = vaddr;
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
ui_ctx_menu_close();
}
hs_scope_close(hs_scope);
txt_scope_close(txt_scope);
}
//- rjf: entity menu
@@ -10607,7 +10768,7 @@ internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions)
}
internal DF_CodeSliceSignal
df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string)
df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeCtx *code_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string)
{
DF_CodeSliceSignal result = {0};
ProfBeginFunction();
@@ -10674,82 +10835,6 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
}
}
//////////////////////////////
//- rjf: build per-line context menus
//
UI_Key *ctx_menu_keys = push_array(scratch.arena, UI_Key, dim_1s64(params->line_num_range)+1);
{
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)
{
ctx_menu_keys[line_idx] = ui_key_from_stringf(top_container_box->key, "line_ctx_%I64d", line_num);
DF_Palette(DF_PaletteCode_Floating)
UI_CtxMenu(ctx_menu_keys[line_idx])
DF_Palette(DF_PaletteCode_ImplicitButton)
UI_PrefWidth(ui_em(37.f, 1.f))
{
DF_TextLineSrc2DasmInfoList *line_src2dasm_list = &params->line_src2dasm[line_idx];
DF_TextLineDasm2SrcInfoList *line_dasm2src_list = &params->line_dasm2src[line_idx];
//- rjf: copy selection
if(!txt_pt_match(*cursor, *mark) && ui_clicked(df_cmd_spec_button(df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_Copy))))
{
result.copy_range = txt_rng(*cursor, *mark);
ui_ctx_menu_close();
}
//- rjf: watch selection
if(ui_clicked(df_cmd_spec_button(df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpressionAtCursor))))
{
result.toggle_cursor_watch = 1;
ui_ctx_menu_close();
}
//- rjf: set-next-statement
if(ui_clicked(df_cmd_spec_button(df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SetNextStatement))))
{
result.set_next_statement_line_num = line_num;
ui_ctx_menu_close();
}
//- rjf: run-to-line
if(ui_clicked(df_icon_buttonf(DF_IconKind_Play, 0, "Run To Line")))
{
result.run_to_line_num = line_num;
ui_ctx_menu_close();
}
//- rjf: breakpoint placing
if((params->line_bps[line_idx].count == 0 &&
ui_clicked(df_icon_buttonf(DF_IconKind_CircleFilled, 0, "Place Breakpoint"))) ||
(params->line_bps[line_idx].count != 0 &&
ui_clicked(df_icon_buttonf(DF_IconKind_CircleFilled, 0, "Remove Breakpoint"))))
{
result.clicked_margin_line_num = line_num;
ui_ctx_menu_close();
}
//- rjf: go from src -> disasm
if(line_src2dasm_list->first != 0 &&
ui_clicked(df_icon_buttonf(DF_IconKind_Find, 0, "Go To Disassembly")))
{
result.goto_disasm_line_num = line_num;
ui_ctx_menu_close();
}
//- rjf: go from disasm -> src
if(line_dasm2src_list->first != 0 &&
ui_clicked(df_icon_buttonf(DF_IconKind_Find, 0, "Go To Source")))
{
result.goto_src_line_num = line_num;
ui_ctx_menu_close();
}
}
}
}
//////////////////////////////
//- rjf: build priority margin
//
@@ -10851,23 +10936,21 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
// rjf: fill out progress t (progress into range of current line's
// voff range)
if(params->line_src2dasm[line_idx].first != 0)
if(params->line_infos[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)
DF_LineList *lines = &params->line_infos[line_idx];
DF_Line *line = 0;
for(DF_LineNode *n = lines->first; n != 0; n = n->next)
{
if(di_key_match(&n->v.dbgi_key, &dbgi_key))
{
line_info = &n->v;
line = &n->v;
break;
}
}
if(line_info != 0)
if(line != 0)
{
Rng1U64 line_voff_rng = line_info->voff_range;
Rng1U64 line_voff_rng = line->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;
@@ -11008,23 +11091,21 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
// rjf: fill out progress t (progress into range of current line's
// voff range)
if(params->line_src2dasm[line_idx].first != 0)
if(code_ctx->file != &df_g_nil_entity && params->line_infos[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)
DF_LineList *lines = &params->line_infos[line_idx];
DF_Line *line = 0;
for(DF_LineNode *n = lines->first; n != 0; n = n->next)
{
if(di_key_match(&n->v.dbgi_key, &dbgi_key))
{
line_info = &n->v;
line = &n->v;
break;
}
}
if(line_info != 0)
if(line != 0)
{
Rng1U64 line_voff_rng = line_info->voff_range;
Rng1U64 line_voff_rng = line->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;
@@ -11086,17 +11167,20 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
DF_BreakpointBoxDrawExtData *bp_draw = push_array(ui_build_arena(), DF_BreakpointBoxDrawExtData, 1);
{
bp_draw->color = bp_color;
DF_TextLineSrc2DasmInfoList *src2dasm_list = &params->line_src2dasm[line_idx];
for(DF_TextLineSrc2DasmInfoNode *n = src2dasm_list->first; n != 0; n = n->next)
bp_draw->alive_t = bp->alive_t;
if(code_ctx->file != &df_g_nil_entity)
{
S64 remap_line = (S64)n->v.remap_line;
if(remap_line != line_num)
DF_LineList *lines = &params->line_infos[line_idx];
for(DF_LineNode *n = lines->first; n != 0; n = n->next)
{
bp_draw->remap_px_delta = (remap_line - line_num) * params->line_height_px;
break;
S64 remap_line = n->v.pt.line;
if(remap_line != line_num)
{
bp_draw->remap_px_delta = (remap_line - line_num) * params->line_height_px;
break;
}
}
}
bp_draw->alive_t = bp->alive_t;
}
// rjf: build box for breakpoint
@@ -11248,33 +11332,17 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
// rjf: line info on this line -> adjust bg color to visualize
B32 has_line_info = 0;
{
U64 best_stamp = 0;
S64 line_info_line_num = 0;
F32 line_info_t = 0;
DF_TextLineSrc2DasmInfoList *src2dasm_list = &params->line_src2dasm[line_idx];
DF_TextLineDasm2SrcInfoList *dasm2src_list = &params->line_dasm2src[line_idx];
if(src2dasm_list->first != 0)
F32 line_info_t = selected_thread_module->alive_t;
DF_LineList *lines = &params->line_infos[line_idx];
for(DF_LineNode *n = lines->first; n != 0; n = n->next)
{
has_line_info = (src2dasm_list->first->v.remap_line == line_num);
line_info_line_num = line_num;
line_info_t = selected_thread_module->alive_t;
}
if(dasm2src_list->first != 0)
{
DF_TextLineDasm2SrcInfo *dasm2src_info = 0;
U64 best_stamp = 0;
for(DF_TextLineDasm2SrcInfoNode *n = dasm2src_list->first; n != 0; n = n->next)
if(n->v.dbgi_key.min_timestamp >= best_stamp)
{
if(n->v.file->timestamp > best_stamp)
{
dasm2src_info = &n->v;
best_stamp = n->v.file->timestamp;
}
}
if(dasm2src_info != 0)
{
has_line_info = 1;
line_info_line_num = dasm2src_info->pt.line;
line_info_t = selected_thread_module->alive_t;
has_line_info = (n->v.pt.line == line_num || code_ctx->file == &df_g_nil_entity);
line_info_line_num = n->v.pt.line;
best_stamp = n->v.dbgi_key.min_timestamp;
}
}
if(has_line_info)
@@ -11575,42 +11643,26 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
*preferred_column = cursor->column;
}
//- rjf: right-click => active context menu for line
//- rjf: right-click => code context menu
if(ui_right_clicked(text_container_sig))
{
S64 line_idx = mouse_pt.line-params->line_num_range.min;
if(0 <= line_idx && line_idx < dim_1s64(params->line_num_range))
if(txt_pt_match(*cursor, *mark))
{
ui_ctx_menu_open(ctx_menu_keys[line_idx], ui_key_zero(), sub_2f32(ui_mouse(), v2f32(2, 2)));
if(txt_pt_match(*cursor, *mark))
{
*cursor = *mark = mouse_pt;
}
*cursor = *mark = mouse_pt;
}
}
//- rjf: hovering text container & ctrl+scroll -> change font size
if(ui_hovering(text_container_sig))
{
UI_EventList *events = ui_events();
for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next)
ui_ctx_menu_open(ws->code_ctx_menu_key, ui_key_zero(), sub_2f32(ui_mouse(), v2f32(2, 2)));
arena_clear(ws->code_ctx_menu_arena);
ws->code_ctx_menu_file = df_handle_from_entity(code_ctx->file);
ws->code_ctx_menu_text_key = code_ctx->text_key;
ws->code_ctx_menu_lang_kind = code_ctx->lang_kind;
ws->code_ctx_menu_range = txt_rng(*cursor, *mark);
if(params->line_num_range.min <= cursor->line && cursor->line < params->line_num_range.max)
{
next = n->next;
UI_Event *event = &n->v;
if(event->kind == UI_EventKind_Scroll && event->modifiers & OS_EventFlag_Ctrl)
{
ui_eat_event(events, n);
if(event->delta_2f32.y < 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_IncCodeFontScale));
}
else if(event->delta_2f32.y > 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_DecCodeFontScale));
}
}
ws->code_ctx_menu_vaddr = params->line_vaddrs[cursor->line - params->line_num_range.min];
}
if(params->line_num_range.min <= cursor->line && cursor->line < params->line_num_range.max)
{
ws->code_ctx_menu_lines = df_line_list_copy(ws->code_ctx_menu_arena, &params->line_infos[cursor->line - params->line_num_range.min]);
}
}
@@ -11629,6 +11681,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
}
//- rjf: drop target is dropped -> process
// TODO(rjf): @src_collapse
#if 0
{
DF_DragDropPayload payload = {0};
if(!df_entity_is_nil(line_drag_entity) && df_drag_drop(&payload))
@@ -11637,6 +11691,7 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
result.dropped_entity_line_num = mouse_pt.line;
}
}
#endif
//- rjf: commit text container signal to main output
result.base = text_container_sig;
@@ -11645,6 +11700,8 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
//////////////////////////////
//- rjf: mouse -> expression range info
//
TxtRng mouse_expr_rng = {0};
Vec2F32 mouse_expr_baseline_pos = {0};
if(ui_hovering(text_container_sig) && contains_1s64(params->line_num_range, mouse_pt.line)) ProfScope("mouse -> expression range")
{
TxtRng selected_rng = txt_rng(*cursor, *mark);
@@ -11655,9 +11712,9 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
U64 line_slice_idx = mouse_pt.line-params->line_num_range.min;
String8 line_text = params->line_text[line_slice_idx];
F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, str8_prefix(line_text, selected_rng.min.column-1)).x;
result.mouse_expr_rng = selected_rng;
result.mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px,
text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f);
result.mouse_expr_rng = mouse_expr_rng = selected_rng;
result.mouse_expr_baseline_pos = mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px,
text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f);
}
else
{
@@ -11670,9 +11727,9 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
if(expr_off_rng.max != expr_off_rng.min)
{
F32 expr_hoff_px = params->line_num_width_px + f_dim_from_tag_size_string(params->font, params->font_size, 0, params->tab_size, str8_prefix(line_text, expr_off_rng.min-line_range.min)).x;
result.mouse_expr_rng = txt_rng(txt_pt(mouse_pt.line, 1+(expr_off_rng.min-line_range.min)), txt_pt(mouse_pt.line, 1+(expr_off_rng.max-line_range.min)));
result.mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px,
text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f);
result.mouse_expr_rng = mouse_expr_rng = txt_rng(txt_pt(mouse_pt.line, 1+(expr_off_rng.min-line_range.min)), txt_pt(mouse_pt.line, 1+(expr_off_rng.max-line_range.min)));
result.mouse_expr_baseline_pos = mouse_expr_baseline_pos = v2f32(text_container_box->rect.x0+expr_hoff_px,
text_container_box->rect.y0+line_slice_idx*params->line_height_px + params->line_height_px*0.85f);
}
}
}
@@ -11683,29 +11740,38 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
if(ui_hovering(text_container_sig) && contains_1s64(params->line_num_range, mouse_pt.line) && (ui_mouse().x - text_container_box->rect.x0 < params->line_num_width_px + line_num_padding_px))
{
U64 line_slice_idx = mouse_pt.line-params->line_num_range.min;
if(params->line_src2dasm[line_slice_idx].first != 0 &&
params->line_src2dasm[line_slice_idx].first->v.remap_line == mouse_pt.line)
DF_LineList *lines = &params->line_infos[line_slice_idx];
if(lines->first != 0 && (code_ctx->file == &df_g_nil_entity || lines->first->v.pt.line == mouse_pt.line))
{
DF_RichHoverInfo info = {0};
info.process = df_handle_from_entity(selected_thread_process);
info.vaddr_range = df_vaddr_range_from_voff_range(selected_thread_module, params->line_src2dasm[line_slice_idx].first->v.voff_range);
info.vaddr_range = df_vaddr_range_from_voff_range(selected_thread_module, lines->first->v.voff_range);
info.module = df_handle_from_entity(selected_thread_module);
info.dbgi_key = params->line_src2dasm[line_slice_idx].first->v.dbgi_key;
info.voff_range = params->line_src2dasm[line_slice_idx].first->v.voff_range;
df_set_rich_hover_info(&info);
}
if(params->line_dasm2src[line_slice_idx].first != 0)
{
DF_RichHoverInfo info = {0};
info.process = df_handle_from_entity(selected_thread_process);
info.vaddr_range = df_vaddr_range_from_voff_range(selected_thread_module, params->line_dasm2src[line_slice_idx].first->v.voff_range);
info.module = df_handle_from_entity(selected_thread_module);
info.dbgi_key = params->line_dasm2src[line_slice_idx].first->v.dbgi_key;
info.voff_range = params->line_dasm2src[line_slice_idx].first->v.voff_range;
info.dbgi_key = lines->first->v.dbgi_key;
info.voff_range = lines->first->v.voff_range;
df_set_rich_hover_info(&info);
}
}
//////////////////////////////
//- rjf: hover eval
//
#if 0
if(!ui_dragging(text_container_sig) && sig.mouse_expr_rng.min.line != 0 && sig.base.event_flags == 0)
{
TxtRng expr_rng = mouse_expr_rng;
String8 expr = txt_string_from_info_data_txt_rng(&text_info, data, expr_rng);
if(expr.size != 0)
{
DF_Eval eval = df_eval_from_string(scratch.arena, di_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr);
if(eval.mode != EVAL_EvalMode_NULL)
{
df_set_hover_eval(ws, mouse_expr_baseline_pos, ctrl_ctx, entity, sig.mouse_pt, 0, expr);
}
}
}
#endif
//////////////////////////////
//- rjf: dragging entity which applies to lines over this slice -> visualize
//
@@ -12048,37 +12114,16 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
{
B32 matches = 0;
S64 line_info_line_num = 0;
DF_TextLineSrc2DasmInfoList *src2dasm_list = &params->line_src2dasm[line_idx];
DF_TextLineDasm2SrcInfoList *dasm2src_list = &params->line_dasm2src[line_idx];
// rjf: check src2dasm
if(src2dasm_list->first != 0)
DF_LineList *lines = &params->line_infos[line_idx];
for(DF_LineNode *n = lines->first; n != 0; n = n->next)
{
for(DF_TextLineSrc2DasmInfoNode *n = src2dasm_list->first; n != 0; n = n->next)
if((n->v.pt.line == line_num || code_ctx->file == &df_g_nil_entity) &&
di_key_match(&n->v.dbgi_key, &hovered_line_dbgi_key) &&
n->v.voff_range.min <= hovered_line_voff && hovered_line_voff < n->v.voff_range.max)
{
if(n->v.remap_line == line_num &&
di_key_match(&n->v.dbgi_key, &hovered_line_dbgi_key) &&
n->v.voff_range.min <= hovered_line_voff && hovered_line_voff < n->v.voff_range.max)
{
matches = 1;
line_info_line_num = line_num;
break;
}
}
}
// rjf: check dasm2src
if(dasm2src_list->first != 0)
{
for(DF_TextLineDasm2SrcInfoNode *n = dasm2src_list->first; n != 0; n = n->next)
{
if(n->v.voff_range.min <= hovered_line_voff &&
hovered_line_voff < n->v.voff_range.max)
{
line_info_line_num = n->v.pt.line;
matches = 1;
break;
}
matches = 1;
line_info_line_num = n->v.pt.line;
break;
}
}
@@ -12108,13 +12153,13 @@ df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_
}
internal DF_CodeSliceSignal
df_code_slicef(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...)
df_code_slicef(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeCtx *code_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...)
{
Temp scratch = scratch_begin(0, 0);
va_list args;
va_start(args, fmt);
String8 string = push_str8fv(scratch.arena, fmt, args);
DF_CodeSliceSignal sig = df_code_slice(ws, ctrl_ctx, parse_ctx, params, cursor, mark, preferred_column, string);
DF_CodeSliceSignal sig = df_code_slice(ws, ctrl_ctx, parse_ctx, code_ctx, params, cursor, mark, preferred_column, string);
va_end(args);
scratch_end(scratch);
return sig;
@@ -13414,6 +13459,7 @@ df_gfx_begin_frame(Arena *arena, DF_CmdList *cmds)
r_window_unequip(ws->os, ws->r);
os_window_close(ws->os);
arena_release(ws->query_cmd_arena);
arena_release(ws->code_ctx_menu_arena);
arena_release(ws->hover_eval_arena);
arena_release(ws->autocomp_lister_params_arena);
arena_release(ws->arena);
+18 -5
View File
@@ -432,6 +432,14 @@ enum
DF_CodeSliceFlag_LineNums = (1<<3),
};
typedef struct DF_CodeCtx DF_CodeCtx;
struct DF_CodeCtx
{
DF_Entity *file; // the source file, if any, from which the code was derived
U128 text_key; // the text info cache key for the backing textual data
TXT_LangKind lang_kind; // the language for which the text is parsed/analyzed
};
typedef struct DF_CodeSliceParams DF_CodeSliceParams;
struct DF_CodeSliceParams
{
@@ -444,8 +452,8 @@ struct DF_CodeSliceParams
DF_EntityList *line_bps;
DF_EntityList *line_ips;
DF_EntityList *line_pins;
DF_TextLineDasm2SrcInfoList *line_dasm2src;
DF_TextLineSrc2DasmInfoList *line_src2dasm;
U64 *line_vaddrs;
DF_LineList *line_infos;
DI_KeyList relevant_dbgi_keys;
// rjf: visual parameters
@@ -570,10 +578,14 @@ struct DF_Window
B32 menu_bar_focus_press_started;
// rjf: code context menu state
Arena *code_ctx_menu_arena;
UI_Key code_ctx_menu_key;
DF_Handle code_ctx_menu_entity;
DF_Handle code_ctx_menu_file;
U128 code_ctx_menu_text_key;
TXT_LangKind code_ctx_menu_lang_kind;
TxtRng code_ctx_menu_range;
U64 code_ctx_menu_vaddr;
DF_LineList code_ctx_menu_lines;
// rjf: entity context menu state
UI_Key entity_ctx_menu_key;
@@ -620,6 +632,7 @@ struct DF_Window
Vec2F32 hover_eval_spawn_pos;
String8 hover_eval_string;
// rjf: hover eval timer
U64 hover_eval_first_frame_idx;
U64 hover_eval_last_frame_idx;
@@ -1071,8 +1084,8 @@ internal void df_entity_src_loc_button(DF_Window *ws, DF_Entity *entity, TxtPt p
internal UI_BOX_CUSTOM_DRAW(df_thread_box_draw_extensions);
internal UI_BOX_CUSTOM_DRAW(df_bp_box_draw_extensions);
internal DF_CodeSliceSignal df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string);
internal DF_CodeSliceSignal df_code_slicef(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...);
internal DF_CodeSliceSignal df_code_slice(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeCtx *code_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, String8 string);
internal DF_CodeSliceSignal df_code_slicef(DF_Window *ws, DF_CtrlCtx *ctrl_ctx, EVAL_ParseCtx *parse_ctx, DF_CodeCtx *code_ctx, DF_CodeSliceParams *params, TxtPt *cursor, TxtPt *mark, S64 *preferred_column, char *fmt, ...);
internal B32 df_do_txt_controls(TXT_TextInfo *info, String8 data, U64 line_count_per_page, TxtPt *cursor, TxtPt *mark, S64 *preferred_column);
internal B32 df_do_txti_controls(TXTI_Handle handle, U64 line_count_per_page, TxtPt *cursor, TxtPt *mark, S64 *preferred_column);
+12 -8
View File
@@ -537,9 +537,10 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
String8 data = {0};
TXT_TextInfo info = {0};
TXT_LineTokensSlice line_tokens_slice = {0};
U128 text_key = {0};
{
U128 text_hash = {0};
U128 text_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 1);
text_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 1);
info = txt_text_info_from_key_lang(txt_scope, text_key, top.lang, &text_hash);
data = hs_data_from_hash(hs_scope, text_hash);
line_tokens_slice = txt_line_tokens_slice_from_info_data_line_range(scratch.arena, &info, data, r1s64(1, info.lines_count));
@@ -558,8 +559,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, info.lines_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, info.lines_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, info.lines_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, info.lines_count);
code_slice_params.line_infos = push_array(scratch.arena, DF_LineList, info.lines_count);
for(U64 line_idx = 0; line_idx < info.lines_count; line_idx += 1)
{
code_slice_params.line_text[line_idx] = str8_substr(data, info.lines_ranges[line_idx]);
@@ -591,7 +592,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(text)
//- rjf: build code slice
UI_WidthFill UI_HeightFill UI_Parent(container)
{
DF_CodeSliceSignal slice_sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###slice"));
DF_CodeCtx code_ctx = {&df_g_nil_entity, text_key, top.lang};
DF_CodeSliceSignal slice_sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###slice"));
}
}
@@ -697,11 +699,12 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
DASM_Info dasm_info = dasm_info_from_key_params(dasm_scope, dasm_key, &dasm_params, &data_hash);
String8 dasm_text_data = {0};
TXT_TextInfo dasm_text_info = {0};
TXT_LangKind lang_kind = TXT_LangKind_DisasmX64Intel;
for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1)
{
U128 dasm_text_hash = hs_hash_from_key(dasm_info.text_key, rewind_idx);
dasm_text_data = hs_data_from_hash(hs_scope, dasm_text_hash);
dasm_text_info = txt_text_info_from_hash_lang(txt_scope, dasm_text_hash, TXT_LangKind_DisasmX64Intel);
dasm_text_info = txt_text_info_from_hash_lang(txt_scope, dasm_text_hash, lang_kind);
if(dasm_text_info.lines_count != 0)
{
break;
@@ -720,8 +723,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, dasm_text_info.lines_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, dasm_text_info.lines_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, dasm_text_info.lines_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, dasm_text_info.lines_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, dasm_text_info.lines_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, dasm_text_info.lines_count);
code_slice_params.line_infos = push_array(scratch.arena, DF_LineList, dasm_text_info.lines_count);
for(U64 line_idx = 0; line_idx < dasm_text_info.lines_count; line_idx += 1)
{
code_slice_params.line_text[line_idx] = str8_substr(dasm_text_data, dasm_info.insts.v[line_idx].text_range);
@@ -742,7 +745,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(disasm)
if(dasm_info.insts.count != 0 && dasm_text_info.lines_count != 0)
UI_Padding(ui_pct(1, 0)) UI_PrefWidth(ui_px(dasm_text_info.lines_max_size*ui_top_font_size()*1.2f, 1.f)) UI_Column UI_Padding(ui_pct(1, 0))
{
DF_CodeSliceSignal sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###code_slice"));
DF_CodeCtx code_ctx = {&df_g_nil_entity, dasm_info.text_key, lang_kind};
DF_CodeSliceSignal sig = df_code_slice(ws, ctrl_ctx, parse_ctx, &code_ctx, &code_slice_params, &state->cursor, &state->mark, &state->preferred_column, str8_lit("###code_slice"));
}
}
dasm_scope_close(dasm_scope);
+238 -58
View File
@@ -387,7 +387,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 data, TXT_TextInfo *info)
df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, String8 data, TXT_TextInfo *info, DF_CodeCtx *code_ctx)
{
for(DF_CmdNode *n = cmds->first; n != 0; n = n->next)
{
@@ -499,7 +499,7 @@ df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewStat
}
internal void
df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, Rng2F32 rect, String8 data, TXT_TextInfo *info)
df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, Rng2F32 rect, String8 data, TXT_TextInfo *info, DF_CodeCtx *code_ctx)
{
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
@@ -603,8 +603,8 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, visible_line_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count);
code_slice_params.line_infos = push_array(scratch.arena, DF_LineList, visible_line_count);
code_slice_params.font = code_font;
code_slice_params.font_size = code_font_size;
code_slice_params.tab_size = code_tab_size;
@@ -627,6 +627,73 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
code_slice_params.line_tokens[visible_line_idx] = slice.line_tokens[visible_line_idx];
}
}
// rjf: find visible breakpoints
ProfScope("find visible breakpoints")
{
for(DF_Entity *bp = code_ctx->file->first; !df_entity_is_nil(bp); bp = bp->next)
{
if(bp->deleted || bp->kind != DF_EntityKind_Breakpoint) { continue; }
if(visible_line_num_range.min <= bp->text_point.line && bp->text_point.line <= visible_line_num_range.max)
{
U64 slice_line_idx = (bp->text_point.line-visible_line_num_range.min);
df_entity_list_push(scratch.arena, &code_slice_params.line_bps[slice_line_idx], bp);
}
}
}
// rjf: find live threads mapping to this file
ProfScope("find live threads mapping to this file")
{
DF_Entity *selected_thread = df_entity_from_handle(ctrl_ctx.thread);
DF_EntityList threads = df_query_cached_entity_list_with_kind(DF_EntityKind_Thread);
for(DF_EntityNode *thread_n = threads.first; thread_n != 0; thread_n = thread_n->next)
{
DF_Entity *thread = thread_n->entity;
DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process);
U64 base_unwind_count = (thread == selected_thread) ? ctrl_ctx.unwind_count : 0;
U64 inline_unwind_count = (thread == selected_thread) ? ctrl_ctx.inline_unwind_count : 0;
U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count);
U64 last_inst_on_unwound_rip_vaddr = rip_vaddr - !!unwind_count;
DF_Entity *module = df_module_from_process_vaddr(process, last_inst_on_unwound_rip_vaddr);
U64 rip_voff = df_voff_from_vaddr(module, last_inst_on_unwound_rip_vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
for(DF_LineNode *n = lines.first; n != 0; n = n->next)
{
if(df_entity_from_handle(n->v.file) == code_ctx->file && visible_line_num_range.min <= n->v.pt.line && n->v.pt.line <= visible_line_num_range.max)
{
U64 slice_line_idx = lines.first->v.pt.line-visible_line_num_range.min;
df_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread);
}
}
}
}
// rjf: find visible watch pins
ProfScope("find visible watch pins")
{
for(DF_Entity *wp = code_ctx->file->first; !df_entity_is_nil(wp); wp = wp->next)
{
if(wp->deleted || wp->kind != DF_EntityKind_WatchPin) { continue; }
if(visible_line_num_range.min <= wp->text_point.line && wp->text_point.line <= visible_line_num_range.max)
{
U64 slice_line_idx = (wp->text_point.line-visible_line_num_range.min);
df_entity_list_push(scratch.arena, &code_slice_params.line_pins[slice_line_idx], wp);
}
}
}
// rjf: find all src -> dasm info
ProfScope("find all src -> dasm info")
{
DF_LineListArray lines_array = df_lines_array_from_file_line_range(scratch.arena, code_ctx->file, visible_line_num_range);
if(lines_array.count != 0)
{
MemoryCopy(code_slice_params.line_infos, lines_array.v, sizeof(DF_LineList)*lines_array.count);
}
code_slice_params.relevant_dbgi_keys = lines_array.dbgi_keys;
}
}
//////////////////////////////
@@ -819,7 +886,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
DF_CodeSliceSignal sig = {0};
UI_Focus(UI_FocusKind_On)
{
sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, &code_slice_params, &cv->cursor, &cv->mark, &cv->preferred_column, "txt_view_%p", view);
sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, code_ctx, &code_slice_params, &cv->cursor, &cv->mark, &cv->preferred_column, "txt_view_%p", view);
}
//- rjf: press code slice? -> focus panel
@@ -852,13 +919,6 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_GoToName));
}
//- rjf: copy text
if(!txt_pt_match(sig.copy_range.min, sig.copy_range.max))
{
String8 text = txt_string_from_info_data_txt_rng(info, data, sig.copy_range);
os_set_clipboard_text(text);
}
//- rjf: selected text on single line, no query? -> set search text
if(!txt_pt_match(cv->cursor, cv->mark) && cv->cursor.line == cv->mark.line && search_query.size == 0)
{
@@ -866,22 +926,9 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
df_set_search_string(text);
}
//- rjf: toggle cursor watch
if(sig.toggle_cursor_watch)
{
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_ToggleWatchExpressionAtCursor));
}
//- rjf: set next statement
if(sig.set_next_statement_line_num != 0 && contains_1s64(visible_line_num_range, sig.set_next_statement_line_num))
{
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
params.text_point = txt_pt(sig.set_next_statement_line_num, 1);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_SetNextStatement));
}
//- rjf: go to disasm
// TODO(rjf): @src_collapse
#if 0
if(sig.goto_disasm_line_num != 0 && contains_1s64(visible_line_num_range, sig.goto_disasm_line_num))
{
U64 line_idx = (sig.goto_disasm_line_num-visible_line_num_range.min);
@@ -911,6 +958,7 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
}
}
}
#endif
}
//////////////////////////////
@@ -1038,6 +1086,29 @@ df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewSta
}
ui_scroll_pt_clamp_idx(&view->scroll_pos.x, scroll_idx_rng[Axis2_X]);
ui_scroll_pt_clamp_idx(&view->scroll_pos.y, scroll_idx_rng[Axis2_Y]);
if(ui_mouse_over(sig))
{
UI_EventList *events = ui_events();
for(UI_EventNode *n = events->first, *next = 0; n != 0; n = next)
{
next = n->next;
UI_Event *event = &n->v;
if(event->kind == UI_EventKind_Scroll && event->modifiers & OS_EventFlag_Ctrl)
{
ui_eat_event(events, n);
if(event->delta_2f32.y < 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_IncCodeFontScale));
}
else if(event->delta_2f32.y > 0)
{
DF_CmdParams params = df_cmd_params_from_window(ws);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_DecCodeFontScale));
}
}
}
}
}
txt_scope_close(txt_scope);
@@ -4076,15 +4147,15 @@ DF_VIEW_UI_FUNCTION_DEF(SymbolLister)
}
if(ui_hovering(sig)) UI_Tooltip
{
U64 binary_voff = df_voff_from_dbgi_key_symbol_name(&dbgi_key, name);
DF_TextLineDasm2SrcInfo dasm2src_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, binary_voff, 0);
String8 file_path = df_full_path_from_entity(scratch.arena, dasm2src_info.file);
S64 line_num = dasm2src_info.pt.line;
df_code_label(1.f, 0, df_rgba_from_theme_color(DF_ThemeColor_CodeSymbol), name);
UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak)
ui_labelf("Procedure #%I64u", item->idx);
if(!df_entity_is_nil(dasm2src_info.file))
U64 binary_voff = df_voff_from_dbgi_key_symbol_name(&dbgi_key, name);
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, binary_voff);
if(lines.first != 0)
{
String8 file_path = df_full_path_from_entity(scratch.arena, df_entity_from_handle(lines.first->v.file));
S64 line_num = lines.first->v.pt.line;
UI_Font(df_font_from_slot(DF_FontSlot_Main)) UI_FlagsAdd(UI_BoxFlag_DrawTextWeak)
ui_labelf("%S:%I64d", file_path, line_num);
}
@@ -5460,10 +5531,14 @@ DF_VIEW_UI_FUNCTION_DEF(Scheduler)
DF_Entity *module = df_module_from_process_vaddr(process, rip_vaddr);
U64 rip_voff = df_voff_from_vaddr(module, rip_vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
DF_TextLineDasm2SrcInfo line_info = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, rip_voff, 0);
if(!df_entity_is_nil(line_info.file))
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, rip_voff);
if(lines.first != 0)
{
UI_PrefWidth(ui_children_sum(0)) df_entity_src_loc_button(ws, line_info.file, line_info.pt);
DF_Entity *file = df_entity_from_handle(lines.first->v.file);
if(!df_entity_is_nil(file))
{
UI_PrefWidth(ui_children_sum(0)) df_entity_src_loc_button(ws, file, lines.first->v.pt);
}
}
}
}break;
@@ -6191,7 +6266,7 @@ DF_VIEW_UI_FUNCTION_DEF(PendingEntity)
////////////////////////////////
//~ rjf: Code @view_hook_impl
#if 0
#if 1
DF_VIEW_SETUP_FUNCTION_DEF(Code)
{
// rjf: set up state
@@ -6229,13 +6304,15 @@ DF_VIEW_CMD_FUNCTION_DEF(Code)
Temp scratch = scratch_begin(0, 0);
HS_Scope *hs_scope = hs_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
String8 path = df_full_path_from_entity(scratch.arena, df_entity_from_handle(view->entity));
DF_Entity *entity = df_entity_from_handle(view->entity);
String8 path = df_full_path_from_entity(scratch.arena, entity);
TXT_LangKind lang_kind = txt_lang_kind_from_extension(str8_skip_last_dot(path));
U128 key = fs_key_from_path(path);
U128 hash = {0};
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
String8 data = hs_data_from_hash(hs_scope, hash);
df_code_view_cmds(ws, panel, view, cv, cmds, data, &info);
DF_CodeCtx code_ctx = {entity, key, lang_kind};
df_code_view_cmds(ws, panel, view, cv, cmds, data, &info, &code_ctx);
txt_scope_close(txt_scope);
hs_scope_close(hs_scope);
scratch_end(scratch);
@@ -6321,7 +6398,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
//
if(!entity_is_missing && key_has_data)
{
df_code_view_build(ws, panel, view, cv, code_area_rect, data, &info);
DF_CodeCtx code_ctx = {entity, key, lang_kind};
df_code_view_build(ws, panel, view, cv, code_area_rect, data, &info, &code_ctx);
}
//////////////////////////////
@@ -6377,9 +6455,9 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
}
#endif
//~ TODO(rjf): OLD vvvvvvvv
//~ TODO(rjf): OLD vvvvvvvv @src_collapse
#if 1
#if 0
DF_VIEW_SETUP_FUNCTION_DEF(Code)
{
// rjf: set up state
@@ -6744,6 +6822,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code)
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, visible_line_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count);
code_slice_params.font = code_font;
@@ -7761,8 +7840,9 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
dasm_params.dbgi_key = dasm_dbgi_key;
}
DASM_Info dasm_info = dasm_info_from_key_params(dasm_scope, dasm_key, &dasm_params, &dasm_data_hash);
TXT_LangKind lang_kind = txt_lang_kind_from_architecture(arch);
U128 dasm_text_hash = {0};
TXT_TextInfo dasm_text_info = txt_text_info_from_key_lang(txt_scope, dasm_info.text_key, txt_lang_kind_from_architecture(arch), &dasm_text_hash);
TXT_TextInfo dasm_text_info = txt_text_info_from_key_lang(txt_scope, dasm_info.text_key, 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 is_loading = (!has_disasm && !df_entity_is_nil(process) && dim_1u64(dasm_vaddr_range) != 0);
@@ -7846,8 +7926,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, visible_line_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, visible_line_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, visible_line_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count);
code_slice_params.line_infos = push_array(scratch.arena, DF_LineList, visible_line_count);
code_slice_params.font = code_font;
code_slice_params.font_size = code_font_size;
code_slice_params.tab_size = code_tab_size;
@@ -7858,7 +7938,6 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
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.margin_float_off_px = view->scroll_pos.x.idx + view->scroll_pos.x.off;
di_key_list_push(scratch.arena, &code_slice_params.relevant_dbgi_keys, &dbgi_key);
// rjf: fill text info
@@ -7947,10 +8026,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
U64 vaddr = dasm_vaddr_range.min + dasm_inst_array_code_off_from_idx(&dasm_info.insts, line_num-1);
U64 voff = df_voff_from_vaddr(module, vaddr);
U64 slice_idx = line_num-visible_line_num_range.min;
DF_TextLineDasm2SrcInfoNode *dasm2src_n = push_array(scratch.arena, DF_TextLineDasm2SrcInfoNode, 1);
SLLQueuePush(code_slice_params.line_dasm2src[slice_idx].first, code_slice_params.line_dasm2src[slice_idx].last, dasm2src_n);
code_slice_params.line_dasm2src[slice_idx].count += 1;
dasm2src_n->v = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, voff, 0);
code_slice_params.line_vaddrs[slice_idx] = vaddr;
code_slice_params.line_infos[slice_idx] = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
}
}
}
@@ -8010,7 +8087,8 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
DF_CodeSliceSignal sig = {0};
UI_Focus(UI_FocusKind_On)
{
sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, &code_slice_params, &dv->cursor, &dv->mark, &dv->preferred_column, "dasm_slice_%p", view);
DF_CodeCtx code_ctx = {&df_g_nil_entity, dasm_info.text_key, lang_kind};
sig = df_code_slicef(ws, &ctrl_ctx, &parse_ctx, &code_ctx, &code_slice_params, &dv->cursor, &dv->mark, &dv->preferred_column, "dasm_slice_%p", view);
}
//- rjf: hover eval
@@ -8129,14 +8207,17 @@ DF_VIEW_UI_FUNCTION_DEF(Disassembly)
DF_Entity *module = df_module_from_process_vaddr(process, vaddr);
DI_Key dbgi_key = df_dbgi_key_from_module(module);
U64 voff = df_voff_from_vaddr(module, vaddr);
DF_TextLineDasm2SrcInfo dasm2src = df_text_line_dasm2src_info_from_dbgi_key_voff(&dbgi_key, voff, 0);
String8 file_path = df_full_path_from_entity(scratch.arena, dasm2src.file);
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
params.text_point = dasm2src.pt;
params.file_path = file_path;
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_TextPoint);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_FilePath);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
DF_LineList lines = df_lines_from_dbgi_key_voff(scratch.arena, &dbgi_key, voff);
if(lines.first != 0)
{
String8 file_path = df_full_path_from_entity(scratch.arena, df_entity_from_handle(lines.first->v.file));
DF_CmdParams params = df_cmd_params_from_view(ws, panel, view);
params.text_point = lines.first->v.pt;
params.file_path = file_path;
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_TextPoint);
df_cmd_params_mark_slot(&params, DF_CmdParamSlot_FilePath);
df_push_cmd__root(&params, df_cmd_spec_from_core_cmd_kind(DF_CoreCmdKind_FindCodeLocation));
}
}
}
@@ -8485,6 +8566,103 @@ DF_VIEW_UI_FUNCTION_DEF(Procedures)
////////////////////////////////
//~ rjf: Output @view_hook_impl
#if 1
DF_VIEW_SETUP_FUNCTION_DEF(Output)
{
DF_CodeViewState *cv = df_view_user_state(view, DF_CodeViewState);
df_code_view_init(cv, view);
}
DF_VIEW_STRING_FROM_STATE_FUNCTION_DEF(Output)
{
return str8_zero();
}
DF_VIEW_CMD_FUNCTION_DEF(Output)
{
DF_CodeViewState *cv = df_view_user_state(view, DF_CodeViewState);
Temp scratch = scratch_begin(0, 0);
HS_Scope *hs_scope = hs_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
U128 key = df_state->output_log_key;
TXT_LangKind lang_kind = TXT_LangKind_Null;
U128 hash = {0};
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
String8 data = hs_data_from_hash(hs_scope, hash);
DF_CodeCtx code_ctx = {&df_g_nil_entity, key, lang_kind};
df_code_view_cmds(ws, panel, view, cv, cmds, data, &info, &code_ctx);
txt_scope_close(txt_scope);
hs_scope_close(hs_scope);
scratch_end(scratch);
}
DF_VIEW_UI_FUNCTION_DEF(Output)
{
DF_CodeViewState *cv = df_view_user_state(view, DF_CodeViewState);
Temp scratch = scratch_begin(0, 0);
HS_Scope *hs_scope = hs_scope_open();
TXT_Scope *txt_scope = txt_scope_open();
//////////////////////////////
//- rjf: set up invariants
//
F32 bottom_bar_height = ui_top_font_size()*2.f;
Rng2F32 code_area_rect = r2f32p(rect.x0, rect.y0, rect.x1, rect.y1 - bottom_bar_height);
Rng2F32 bottom_bar_rect = r2f32p(rect.x0, rect.y1 - bottom_bar_height, rect.x1, rect.y1);
//////////////////////////////
//- rjf: unpack text info
//
U128 key = df_state->output_log_key;
TXT_LangKind lang_kind = TXT_LangKind_Null;
U128 hash = {0};
TXT_TextInfo info = txt_text_info_from_key_lang(txt_scope, key, lang_kind, &hash);
String8 data = hs_data_from_hash(hs_scope, hash);
Rng1U64 empty_range = {0};
if(info.lines_count == 0)
{
info.lines_count = 1;
info.lines_ranges = &empty_range;
}
//////////////////////////////
//- rjf: build code contents
//
{
DF_CodeCtx code_ctx = {&df_g_nil_entity, key, lang_kind};
df_code_view_build(ws, panel, view, cv, code_area_rect, data, &info, &code_ctx);
}
//////////////////////////////
//- rjf: build bottom bar
//
{
ui_set_next_rect(shift_2f32(bottom_bar_rect, scale_2f32(rect.p0, -1.f)));
ui_set_next_flags(UI_BoxFlag_DrawBackground);
UI_Row
UI_TextAlignment(UI_TextAlign_Center)
UI_PrefWidth(ui_text_dim(10, 1))
UI_FlagsAdd(UI_BoxFlag_DrawTextWeak)
{
UI_Font(df_font_from_slot(DF_FontSlot_Code))
{
ui_labelf("(Debug String Output)");
ui_spacer(ui_em(1.5f, 1));
ui_labelf("Line: %I64d, Column: %I64d", cv->cursor.line, cv->cursor.column);
ui_spacer(ui_pct(1, 0));
ui_labelf("(read only)");
}
}
}
txt_scope_close(txt_scope);
hs_scope_close(hs_scope);
scratch_end(scratch);
}
#endif
//~ TODO(rjf): OLD vvvvvvvvvvvvvvvvvvvv @src_collapse
#if 0
DF_VIEW_SETUP_FUNCTION_DEF(Output)
{
// rjf: set up state
@@ -8692,6 +8870,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
code_slice_params.line_bps = push_array(scratch.arena, DF_EntityList, slice.line_count);
code_slice_params.line_ips = push_array(scratch.arena, DF_EntityList, slice.line_count);
code_slice_params.line_pins = push_array(scratch.arena, DF_EntityList, slice.line_count);
code_slice_params.line_vaddrs = push_array(scratch.arena, U64, visible_line_count);
code_slice_params.line_dasm2src = push_array(scratch.arena, DF_TextLineDasm2SrcInfoList, slice.line_count);
code_slice_params.line_src2dasm = push_array(scratch.arena, DF_TextLineSrc2DasmInfoList, slice.line_count);
code_slice_params.font = code_font;
@@ -9097,6 +9276,7 @@ DF_VIEW_UI_FUNCTION_DEF(Output)
scratch_end(scratch);
ProfEnd();
}
#endif
////////////////////////////////
//~ rjf: Memory @view_hook_impl
+3 -3
View File
@@ -359,7 +359,7 @@ struct DF_WatchViewState
};
////////////////////////////////
//~ rjf: Code @view_types
//~ rjf: Code, Output @view_types
typedef struct DF_CodeViewState DF_CodeViewState;
struct DF_CodeViewState
@@ -471,8 +471,8 @@ internal void df_entity_lister_item_array_sort_by_strength__in_place(DF_EntityLi
//~ rjf: Code Views
internal void 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 data, TXT_TextInfo *info);
internal void df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, Rng2F32 rect, String8 data, TXT_TextInfo *info);
internal void df_code_view_cmds(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, DF_CmdList *cmds, String8 data, TXT_TextInfo *info, DF_CodeCtx *code_ctx);
internal void df_code_view_build(DF_Window *ws, DF_Panel *panel, DF_View *view, DF_CodeViewState *cv, Rng2F32 rect, String8 data, TXT_TextInfo *info, DF_CodeCtx *code_ctx);
////////////////////////////////
//~ rjf: Watch Views
@@ -198,7 +198,7 @@ fp_init(void)
gamma,
enhanced_contrast,
enhanced_contrast,
1.f,
0.f,
DWRITE_PIXEL_GEOMETRY_FLAT,
DWRITE_RENDERING_MODE_GDI_NATURAL,
DWRITE_GRID_FIT_MODE_ENABLED,
@@ -209,7 +209,7 @@ fp_init(void)
error = IDWriteFactory_CreateCustomRenderingParams(fp_dwrite_state->factory,
gamma,
enhanced_contrast,
1.f,
0.f,
DWRITE_PIXEL_GEOMETRY_FLAT,
DWRITE_RENDERING_MODE_GDI_NATURAL,
&fp_dwrite_state->rendering_params[FP_RasterMode_Sharp]);
@@ -226,7 +226,7 @@ fp_init(void)
gamma,
enhanced_contrast,
enhanced_contrast,
1.f,
0.f,
DWRITE_PIXEL_GEOMETRY_FLAT,
DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC,
DWRITE_GRID_FIT_MODE_DISABLED,