diff --git a/project.4coder b/project.4coder index 14cc2147..127e1515 100644 --- a/project.4coder +++ b/project.4coder @@ -55,7 +55,8 @@ commands = // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [scratch] - .f2 = { .win = "pushd build && for /l %i in (1, 1, 3) do (radbin --capture --rdi mule_main.pdb --async_thread_count=1 --thread_count=8)", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + // .f2 = { .win = "pushd build && for /l %i in (1, 1, 3) do (radbin --rdi raddbg.exe --out:raddbg_%i.rdi && radbin --dump raddbg_%i.rdi --out:raddbg_%i.dump)", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f2 = { .win = "pushd build && radbin --rdi raddbg.exe --thread_count=1 --out:1.rdi && radbin --rdi raddbg.exe --thread_count=8 --out:8.rdi && radbin --dump 1.rdi --out:1.dump && radbin --dump 8.rdi --out:8.dump)", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [textperf] // .f1 = { .win = "raddbg_stable --ipc kill_all && build no_meta telemetry textperf && raddbg_stable --ipc bring_to_front && raddbg_stable --ipc run", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/project.raddbg b/project.raddbg index d0bef4ce..6f67590f 100644 --- a/project.raddbg +++ b/project.raddbg @@ -2,47 +2,22 @@ name: "The RAD Debugger" target: -{ - executable: "build/raddbg.exe" - working_directory: build - arguments: "--user:raddbg_test.user --project:raddbg_test.project" - debug_subprocesses: 0 -} -target: { executable: "build/raddbg.exe" working_directory: "../raddebugger" - arguments: "project.raddbg" + arguments: "--user:C:/devel/raddebugger/build/raddbg_test.user --project:C:/devel/raddebugger/build/raddbg_test.project" + debug_subprocesses: 0 + enabled: 1 } target: { executable: "build/mule_main.exe" working_directory: build - enabled: 1 -} -target: -{ - executable: "build/radbin.exe" - working_directory: build - arguments: "--rdi simple --thread_count=1" -} -target: -{ - executable: "build/radbin.exe" - working_directory: build - arguments: "--rdi chrome.dll.pdb --capture" -} -target: -{ - executable: "build/radbin.exe" - working_directory: build - arguments: "--rdi raddbg.pdb" } target: { executable: "build/torture.exe" working_directory: build - arguments: "rdi_from_pdb/* --gui" } target: { @@ -55,3 +30,20 @@ target: working_directory: build arguments: "--rdi raddbg" } +target: +{ + executable: "build/debugstringperf.exe" + working_directory: build +} +target: +{ + executable: "build/radbin.exe" + working_directory: build + arguments: "--rdi raddbg.exe --thread_count=1" +} +target: +{ + executable: "build/raddbg.exe" + working_directory: build + arguments: "--bin --quiet --rdi --out:C:/devel/raddebugger_stable/build/radbin.rdi --thread_count:1 C:/devel/raddebugger_stable/build/radbin.exe" +} diff --git a/src/dbg_engine/dbg_engine_user.c b/src/dbg_engine/dbg_engine_user.c index 7c2ec311..91e55c68 100644 --- a/src/dbg_engine/dbg_engine_user.c +++ b/src/dbg_engine/dbg_engine_user.c @@ -66,7 +66,7 @@ d_breakpoint_array_copy(Arena *arena, D_BreakpointArray *src) //~ rjf: Path Map Application internal String8List -d_possible_path_overrides_from_maps_path(Arena *arena, D_PathMapArray *path_maps, String8 file_path) +d_possible_path_overrides_from_maps_path(Arena *arena, D_Entity *primary_module, D_PathMapArray *path_maps, String8 file_path) { // NOTE(rjf): This path, given some target file path, scans all file path map // overrides, and collects the set of file paths which could've redirected @@ -85,6 +85,22 @@ d_possible_path_overrides_from_maps_path(Arena *arena, D_PathMapArray *path_maps Temp scratch = scratch_begin(&arena, 1); PathStyle pth_style = PathStyle_Relative; String8List pth_parts = path_normalized_list_from_string(scratch.arena, file_path, &pth_style); + + //- rjf: push possible overrides by relativizing according to module / debug info + { + String8 module_folder = str8_chop_last_slash(primary_module->string); + String8 path_relative_to_module = path_relative_dst_from_absolute_dst_src(arena, file_path, module_folder); + String8 debug_info_path = d_entity_child_from_kind(primary_module, D_EntityKind_DebugInfoPath)->string; + String8 debug_info_folder = str8_chop_last_slash(debug_info_path); + str8_list_push(arena, &result, path_relative_to_module); + if(!path_match_normalized(debug_info_folder, module_folder)) + { + String8 path_relative_to_debug_info = path_relative_dst_from_absolute_dst_src(arena, file_path, debug_info_folder); + str8_list_push(arena, &result, path_relative_to_debug_info); + } + } + + //- rjf: push possible overrides based on path map rules { for(U64 idx = 0; idx < path_maps->count; idx += 1) { @@ -1033,6 +1049,14 @@ d_lines_from_dbgi_key_voff(Arena *arena, DI_Key dbgi_key, U64 voff) 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); + RDI_SectionKind checksum_section_kind = rdi_section_kind_from_checksum_kind(file->checksum_kind); + U64 checksum_size = rdi_section_element_size_table[checksum_section_kind]; + U8 *checksum_data = (U8 *)rdi_section_raw_element_from_kind_idx(rdi, checksum_section_kind, file->checksum_idx); + String8 checksum_value = {0}; + if(file->checksum_idx != 0) + { + checksum_value = str8(checksum_data, checksum_size); + } String8List path_parts = {0}; for(RDI_FilePathNode *fpn = rdi_element_from_name_idx(rdi, FilePathNodes, file->file_path_node_idx); fpn != rdi_element_from_name_idx(rdi, FilePathNodes, 0); @@ -1054,6 +1078,8 @@ d_lines_from_dbgi_key_voff(Arena *arena, DI_Key dbgi_key, U64 voff) } 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.checksum_kind = file->checksum_kind; + n->v.checksum_value = str8_copy(arena, checksum_value); n->v.dbgi_key = dbgi_key; if(line_table_n == top_line_table) { @@ -2258,6 +2284,12 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P d_user_state->ctrl_last_run_param_state_hash = ctrl_param_state_hash; } + // rjf: unpack target thread/module + D_Entity *thread = d_entity_from_handle(params->thread); + D_Entity *process = d_process_from_entity(thread); + U64 thread_ip_vaddr = d_cached_ip_from_thread(thread->handle); + D_Entity *module = d_module_from_process_vaddr(process, thread_ip_vaddr); + // rjf: push & fill run message D_Msg *msg = d_msg_list_push(scratch.arena, &ctrl_msgs); { @@ -2284,7 +2316,7 @@ d_tick(Arena *arena, D_TargetArray *targets, D_BreakpointArray *breakpoints, D_P // rjf: textual location -> add breakpoints for all possible override locations if(bp->file_path.size != 0 && bp->pt.line != 0) { - String8List overrides = d_possible_path_overrides_from_maps_path(scratch.arena, path_maps, bp->file_path); + String8List overrides = d_possible_path_overrides_from_maps_path(scratch.arena, module, path_maps, bp->file_path); for(String8Node *n = overrides.first; n != 0; n = n->next) { D_Breakpoint dst_bp = {0}; diff --git a/src/dbg_engine/dbg_engine_user.h b/src/dbg_engine/dbg_engine_user.h index 8b57b40a..ae9a95d7 100644 --- a/src/dbg_engine/dbg_engine_user.h +++ b/src/dbg_engine/dbg_engine_user.h @@ -13,6 +13,8 @@ struct D_Line String8 file_path; TxtPt pt; Rng1U64 voff_range; + RDI_ChecksumKind checksum_kind; + String8 checksum_value; DI_Key dbgi_key; }; @@ -402,7 +404,7 @@ internal D_BreakpointArray d_breakpoint_array_copy(Arena *arena, D_BreakpointArr //////////////////////////////// //~ rjf: Path Map Application -internal String8List d_possible_path_overrides_from_maps_path(Arena *arena, D_PathMapArray *path_maps, String8 file_path); +internal String8List d_possible_path_overrides_from_maps_path(Arena *arena, D_Entity *primary_module, D_PathMapArray *path_maps, String8 file_path); //////////////////////////////// //~ rjf: Debug Info Extraction Type Pure Functions diff --git a/src/eval/eval_interpret.c b/src/eval/eval_interpret.c index 5e64b380..84b5f8a0 100644 --- a/src/eval/eval_interpret.c +++ b/src/eval/eval_interpret.c @@ -77,6 +77,7 @@ e_space_read(E_Space space, void *out, E_SpaceRangeInfo *out_range_info, Rng1U64 //- rjf: file reads case E_SpaceKind_File: { + Temp scratch = scratch_begin(0, 0); Access *access = access_open(); // rjf: unpack space/path @@ -155,6 +156,7 @@ e_space_read(E_Space space, void *out, E_SpaceRangeInfo *out_range_info, Rng1U64 } access_close(access); + scratch_end(scratch); }break; //- rjf: debug info constant data diff --git a/src/eval/eval_types.c b/src/eval/eval_types.c index 682bef82..2d7e56f7 100644 --- a/src/eval/eval_types.c +++ b/src/eval/eval_types.c @@ -1666,6 +1666,8 @@ e_type_lhs_string_from_key(Arena *arena, E_TypeKey key, String8List *out, U32 pr str8_list_pushf(arena, out, "%S ", type->name); }break; + case E_TypeKind_Null:{}break; + case E_TypeKind_Bitfield: { E_Type *type = e_type_from_key(key); diff --git a/src/raddbg/raddbg_core.c b/src/raddbg/raddbg_core.c index 80f4495a..d8a54442 100644 --- a/src/raddbg/raddbg_core.c +++ b/src/raddbg/raddbg_core.c @@ -560,6 +560,21 @@ rd_possible_overrides_from_file_path(Arena *arena, String8 file_path) Temp scratch = scratch_begin(&arena, 1); PathStyle pth_style = PathStyle_Relative; String8List pth_parts = path_normalized_list_from_string(scratch.arena, file_path, &pth_style); + + //- rjf: push possible overrides for relativized-according-to-debug-info-and-module path + { + String8 module_folder = str8_chop_last_slash(e_base_ctx->primary_module->name); + String8 path_relative_to_module = path_relative_dst_from_absolute_dst_src(arena, file_path, module_folder); + String8 debug_info_folder = str8_chop_last_slash(e_base_ctx->primary_dbg_info->name); + str8_list_push(arena, &result, path_relative_to_module); + if(!path_match_normalized(debug_info_folder, module_folder)) + { + String8 path_relative_to_debug_info = path_relative_dst_from_absolute_dst_src(arena, file_path, debug_info_folder); + str8_list_push(arena, &result, path_relative_to_debug_info); + } + } + + //- rjf: push possible overrides from file path map rules { CFG_NodePtrList links = cfg_node_top_level_list_from_string(scratch.arena, str8_lit("file_path_map")); for(CFG_NodePtrNode *n = links.first; n != 0; n = n->next) @@ -1405,11 +1420,11 @@ rd_file_path_from_eval(Arena *arena, E_Eval eval) default:{}break; case E_SpaceKind_File: { - result = push_str8_copy(arena, e_string_from_id(eval.space.u64_0)); + result = str8_copy(arena, e_string_from_id(eval.space.u64_0)); }break; case E_SpaceKind_FileSystem: { - result = push_str8_copy(arena, e_string_from_id(eval.value.u64)); + result = str8_copy(arena, e_string_from_id(eval.value.u64)); }break; } return result; @@ -4385,30 +4400,46 @@ rd_view_ui(Rng2F32 rect) next_row_expanded = !row_expanded; } - // rjf: can't edit, but has address info? -> go to address - else if(cell->eval.space.kind == D_EvalSpaceKind_Entity) + // rjf: can't edit, but evaluates w/ a type in debug info? -> go to voff + else if(e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_All).kind == E_TypeKeyKind_Ext || + cell->eval.space.kind == D_EvalSpaceKind_Entity) { - D_Entity *entity = rd_ctrl_entity_from_eval_space(cell->eval.space); - D_Entity *process = d_process_from_entity(entity); - if(process != &d_entity_nil) + // rjf: try to unpack debug info from type + E_TypeKey type_key = e_type_key_unwrap(cell->eval.irtree.type_key, E_TypeUnwrapFlag_All); + DI_Key dbgi_key = {0}; + String8 base_folder = {0}; { - U64 vaddr = cell->eval.value.u64; - D_Entity *module = d_module_from_process_vaddr(process, vaddr); - DI_Key dbgi_key = d_dbgi_key_from_module(module); - U64 voff = d_voff_from_vaddr(module, vaddr); - D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, voff); - String8 file_path = {0}; - TxtPt pt = {0}; - if(lines.first != 0) - { - file_path = lines.first->v.file_path; - pt = lines.first->v.pt; - rd_cmd(RD_CmdKind_FindCodeLocation, - .process = process->handle, - .vaddr = vaddr, - .file_path = file_path, - .cursor = pt); - } + E_DbgInfo *dbg_info = e_dbg_info_from_type_key(type_key); + dbgi_key = dbg_info->dbgi_key; + base_folder = str8_chop_last_slash(dbg_info->name); + } + + // rjf: if this is a vaddr evaluation, then unpack voff/vaddr & switch to module's debug info + U64 vaddr = 0; + U64 voff = cell->eval.value.u64; + D_Entity *process = rd_ctrl_entity_from_eval_space(cell->eval.space); + D_Entity *module = &d_entity_nil; + if(process->kind == D_EntityKind_Process) + { + vaddr = cell->eval.value.u64; + module = d_module_from_process_vaddr(process, vaddr); + voff = d_voff_from_vaddr(module, vaddr); + dbgi_key = d_dbgi_key_from_module(module); + base_folder = str8_chop_last_slash(module->string); + } + + // rjf: voff * debug info -> lines + D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, voff); + + // rjf: snap to line + if(lines.first != 0) + { + String8 file_path = lines.first->v.file_path; + TxtPt pt = lines.first->v.pt; + rd_cmd(RD_CmdKind_FindCodeLocation, .file_path = file_path, .cursor = pt, .vaddr = vaddr, + .process = process->handle, + .module = module->handle, + .dbgi_key = dbgi_key); } } @@ -9805,6 +9836,122 @@ rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, D_Event *event) return fstrs; } +//////////////////////////////// +//~ rjf: Source File Checksum Calculations + +internal AC_Artifact +rd_md5_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out) +{ + AC_Artifact result = {0}; + { + Access *access = access_open(); + U128 hash = {0}; + str8_deserial_read_struct(key, 0, &hash); + String8 data = c_data_from_hash(access, hash); + MD5 md5 = md5_from_data(data); + StaticAssert(sizeof(result) >= sizeof(md5), artifact_size_check); + MemoryCopy(&result, &md5, Min(sizeof(result), sizeof(md5))); + access_close(access); + } + return result; +} + +internal AC_Artifact +rd_sha1_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out) +{ + AC_Artifact result = {0}; + { + Access *access = access_open(); + U128 hash = {0}; + str8_deserial_read_struct(key, 0, &hash); + String8 data = c_data_from_hash(access, hash); + SHA1 sha1 = sha1_from_data(data); + StaticAssert(sizeof(result) >= sizeof(sha1), artifact_size_check); + MemoryCopy(&result, &sha1, Min(sizeof(result), sizeof(sha1))); + access_close(access); + } + return result; +} + +internal AC_Artifact +rd_sha256_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out) +{ + AC_Artifact result = {0}; + { + Access *access = access_open(); + U128 hash = {0}; + str8_deserial_read_struct(key, 0, &hash); + String8 data = c_data_from_hash(access, hash); + SHA256 sha256 = sha256_from_data(data); + StaticAssert(sizeof(result) >= sizeof(sha256), artifact_size_check); + MemoryCopy(&result, &sha256, Min(sizeof(result), sizeof(sha256))); + access_close(access); + } + return result; +} + +internal MD5 +rd_md5_from_hash(U128 hash) +{ + Access *access = access_open(); + AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&hash), rd_md5_artifact_create, 0, 0); + MD5 md5 = {0}; + MemoryCopy(&md5, &artifact, Min(sizeof(md5), sizeof(artifact))); + access_close(access); + return md5; +} + +internal SHA1 +rd_sha1_from_hash(U128 hash) +{ + Access *access = access_open(); + AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&hash), rd_sha1_artifact_create, 0, 0); + SHA1 sha1 = {0}; + MemoryCopy(&sha1, &artifact, Min(sizeof(sha1), sizeof(artifact))); + access_close(access); + return sha1; +} + +internal SHA256 +rd_sha256_from_hash(U128 hash) +{ + Access *access = access_open(); + AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&hash), rd_sha256_artifact_create, 0, 0); + SHA256 sha256 = {0}; + MemoryCopy(&sha256, &artifact, Min(sizeof(sha256), sizeof(artifact))); + access_close(access); + return sha256; +} + +internal String8 +rd_checksum_value_from_hash_kind(Arena *arena, U128 hash, RDI_ChecksumKind k) +{ + String8 result = {0}; + switch(k) + { + default:{}break; + case RDI_ChecksumKind_MD5: + { + MD5 md5 = rd_md5_from_hash(hash); + String8 md5_string = str8_struct(&md5); + result = str8_copy(arena, md5_string); + }break; + case RDI_ChecksumKind_SHA1: + { + SHA1 sha1 = rd_sha1_from_hash(hash); + String8 sha1_string = str8_struct(&sha1); + result = str8_copy(arena, sha1_string); + }break; + case RDI_ChecksumKind_SHA256: + { + SHA256 sha256 = rd_sha256_from_hash(hash); + String8 sha256_string = str8_struct(&sha256); + result = str8_copy(arena, sha256_string); + }break; + } + return result; +} + //////////////////////////////// //~ rjf: Vocab Info Lookups @@ -12334,16 +12481,16 @@ rd_frame(void) E_InterpretCtx *interpret_ctx = push_array(scratch.arena, E_InterpretCtx, 1); { E_InterpretCtx *ctx = interpret_ctx; - ctx->primary_space = primary_space; - ctx->reg_arch = arch; - ctx->reg_space = rd_eval_space_from_ctrl_entity(thread, D_EvalSpaceKind_Entity); - ctx->reg_unwind_count = unwind_count; - ctx->module_base = push_array(scratch.arena, U64, 1); - ctx->module_base[0] = module->vaddr_range.min; - ctx->frame_base = push_array(scratch.arena, U64, 1); - ctx->tls_base = push_array(scratch.arena, U64, 1); - ctx->tls_base[0] = d_cached_tls_vaddr_from_thread_module(thread->handle, module->handle, rd_state->frame_eval_memread_endt_us, 0); - ctx->cfa = d_query_cached_cfa_from_thread_unwind(thread, unwind_count); + ctx->primary_space = primary_space; + ctx->reg_arch = arch; + ctx->reg_space = rd_eval_space_from_ctrl_entity(thread, D_EvalSpaceKind_Entity); + ctx->reg_unwind_count = unwind_count; + ctx->module_base = push_array(scratch.arena, U64, 1); + ctx->module_base[0] = module->vaddr_range.min; + ctx->frame_base = push_array(scratch.arena, U64, 1); + ctx->tls_base = push_array(scratch.arena, U64, 1); + ctx->tls_base[0] = d_cached_tls_vaddr_from_thread_module(thread->handle, module->handle, rd_state->frame_eval_memread_endt_us, 0); + ctx->cfa = d_query_cached_cfa_from_thread_unwind(thread, unwind_count); } e_select_interpret_ctx(interpret_ctx, eval_dbg_infos_primary->rdi, rip_voff); @@ -14707,6 +14854,14 @@ rd_frame(void) } } + //- rjf: absolutify file path + { + String8 base_folder = {0}; + if(base_folder.size == 0) { base_folder = str8_chop_last_slash(e_base_ctx->primary_dbg_info->name); } + if(base_folder.size == 0) { base_folder = str8_chop_last_slash(e_base_ctx->primary_module->name); } + file_path = path_absolute_dst_from_relative_dst_src(scratch.arena, file_path, base_folder); + } + //- rjf: if transient tabs are turned off, always prefer new tab if(!rd_setting_b32_from_name(str8_lit("transient_tabs"))) { diff --git a/src/raddbg/raddbg_core.h b/src/raddbg/raddbg_core.h index 60ef35e1..028170eb 100644 --- a/src/raddbg/raddbg_core.h +++ b/src/raddbg/raddbg_core.h @@ -784,6 +784,17 @@ internal FNT_RasterFlags rd_raster_flags_from_slot(RD_FontSlot slot); internal String8 rd_string_from_exception_code(U32 code); internal DR_FStrList rd_stop_explanation_fstrs_from_ctrl_event(Arena *arena, D_Event *event); +//////////////////////////////// +//~ rjf: Source File Checksum Calculations + +internal AC_Artifact rd_md5_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out); +internal AC_Artifact rd_sha1_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out); +internal AC_Artifact rd_sha256_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out); +internal MD5 rd_md5_from_hash(U128 hash); +internal SHA1 rd_sha1_from_hash(U128 hash); +internal SHA256 rd_sha256_from_hash(U128 hash); +internal String8 rd_checksum_value_from_hash_kind(Arena *arena, U128 hash, RDI_ChecksumKind k); + //////////////////////////////// //~ rjf: Vocab Info Lookups diff --git a/src/raddbg/raddbg_views.c b/src/raddbg/raddbg_views.c index db0b38af..05c39aaf 100644 --- a/src/raddbg/raddbg_views.c +++ b/src/raddbg/raddbg_views.c @@ -19,8 +19,8 @@ rd_code_view_init(RD_CodeViewState *cv) ProfEnd(); } -internal RD_CodeViewBuildResult -rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key) +internal void +rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, U128 text_hash, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key) { ProfBeginFunction(); Temp scratch = scratch_begin(&arena, 1); @@ -292,21 +292,37 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla U64 rip_voff = d_voff_from_vaddr(module, last_inst_on_unwound_rip_vaddr); DI_Key dbgi_key = d_dbgi_key_from_module(module); D_LineList lines = d_lines_from_dbgi_key_voff(scratch.arena, dbgi_key, rip_voff); + String8 file_checksums[RDI_ChecksumKind_COUNT] = {0}; for(D_LineNode *n = lines.first; n != 0; n = n->next) { if(visible_line_num_range.min <= n->v.pt.line && n->v.pt.line <= visible_line_num_range.max) { - for(String8Node *override_n = file_path_possible_overrides.first; - override_n != 0; - override_n = override_n->next) + B32 matches_file = 0; + if(!matches_file) + { + if(file_checksums[n->v.checksum_kind].size == 0) + { + file_checksums[n->v.checksum_kind] = rd_checksum_value_from_hash_kind(scratch.arena, text_hash, n->v.checksum_kind); + } + String8 file_checksum = file_checksums[n->v.checksum_kind]; + String8 file_checksum_expected = n->v.checksum_value; + matches_file = str8_match(file_checksum, file_checksum_expected, 0); + } + if(!matches_file) for(String8Node *override_n = file_path_possible_overrides.first; + override_n != 0; + override_n = override_n->next) { if(path_match_normalized(n->v.file_path, override_n->string)) { - U64 slice_line_idx = n->v.pt.line-visible_line_num_range.min; - d_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread); + matches_file = 1; break; } } + if(matches_file) + { + U64 slice_line_idx = n->v.pt.line-visible_line_num_range.min; + d_entity_list_push(scratch.arena, &code_slice_params.line_ips[slice_line_idx], thread); + } } } } @@ -810,17 +826,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla } } - ////////////////////////////// - //- rjf: build result - // - RD_CodeViewBuildResult result = {0}; - { - for(DI_KeyNode *n = code_slice_params.relevant_dbgi_keys.first; n != 0; n = n->next) - { - di_key_list_push(arena, &result.dbgi_keys, n->v); - } - } - ////////////////////////////// //- rjf: store state // @@ -829,7 +834,6 @@ rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags fla scratch_end(scratch); ProfEnd(); - return result; } //////////////////////////////// @@ -1998,90 +2002,6 @@ RD_VIEW_UI_FUNCTION_DEF(null) {} //////////////////////////////// //~ rjf: text @view_hook_impl -internal AC_Artifact -rd_md5_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out) -{ - AC_Artifact result = {0}; - { - Access *access = access_open(); - U128 hash = {0}; - str8_deserial_read_struct(key, 0, &hash); - String8 data = c_data_from_hash(access, hash); - MD5 md5 = md5_from_data(data); - StaticAssert(sizeof(result) >= sizeof(md5), artifact_size_check); - MemoryCopy(&result, &md5, Min(sizeof(result), sizeof(md5))); - access_close(access); - } - return result; -} - -internal AC_Artifact -rd_sha1_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out) -{ - AC_Artifact result = {0}; - { - Access *access = access_open(); - U128 hash = {0}; - str8_deserial_read_struct(key, 0, &hash); - String8 data = c_data_from_hash(access, hash); - SHA1 sha1 = sha1_from_data(data); - StaticAssert(sizeof(result) >= sizeof(sha1), artifact_size_check); - MemoryCopy(&result, &sha1, Min(sizeof(result), sizeof(sha1))); - access_close(access); - } - return result; -} - -internal AC_Artifact -rd_sha256_artifact_create(String8 key, B32 *cancel_out, B32 *retry_out, U64 *gen_out) -{ - AC_Artifact result = {0}; - { - Access *access = access_open(); - U128 hash = {0}; - str8_deserial_read_struct(key, 0, &hash); - String8 data = c_data_from_hash(access, hash); - SHA256 sha256 = sha256_from_data(data); - StaticAssert(sizeof(result) >= sizeof(sha256), artifact_size_check); - MemoryCopy(&result, &sha256, Min(sizeof(result), sizeof(sha256))); - access_close(access); - } - return result; -} - -internal MD5 -rd_md5_from_hash(U128 hash) -{ - Access *access = access_open(); - AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&hash), rd_md5_artifact_create, 0, 0); - MD5 md5 = {0}; - MemoryCopy(&md5, &artifact, Min(sizeof(md5), sizeof(artifact))); - access_close(access); - return md5; -} - -internal SHA1 -rd_sha1_from_hash(U128 hash) -{ - Access *access = access_open(); - AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&hash), rd_sha1_artifact_create, 0, 0); - SHA1 sha1 = {0}; - MemoryCopy(&sha1, &artifact, Min(sizeof(sha1), sizeof(artifact))); - access_close(access); - return sha1; -} - -internal SHA256 -rd_sha256_from_hash(U128 hash) -{ - Access *access = access_open(); - AC_Artifact artifact = ac_artifact_from_key(access, str8_struct(&hash), rd_sha256_artifact_create, 0, 0); - SHA256 sha256 = {0}; - MemoryCopy(&sha256, &artifact, Min(sizeof(sha256), sizeof(artifact))); - access_close(access); - return sha256; -} - EV_EXPAND_RULE_INFO_FUNCTION_DEF(text) { EV_ExpandInfo info = {0}; @@ -2269,7 +2189,6 @@ RD_VIEW_UI_FUNCTION_DEF(text) ////////////////////////////// //- rjf: build code contents // - DI_KeyList dbgi_keys = {0}; if(!file_is_missing) { RD_CodeViewBuildFlags flags = RD_CodeViewBuildFlag_All; @@ -2277,8 +2196,7 @@ RD_VIEW_UI_FUNCTION_DEF(text) { flags &= ~RD_CodeViewBuildFlag_Margins; } - RD_CodeViewBuildResult result = rd_code_view_build(scratch.arena, cv, flags, code_area_rect, data, &info, 0, r1u64(0, 0), di_key_zero()); - dbgi_keys = result.dbgi_keys; + rd_code_view_build(scratch.arena, cv, flags, code_area_rect, hash, data, &info, 0, r1u64(0, 0), di_key_zero()); } ////////////////////////////// @@ -2298,16 +2216,16 @@ RD_VIEW_UI_FUNCTION_DEF(text) { Temp scratch = scratch_begin(0, 0); - // rjf: determine checksum in relevant debug infos + // rjf: determine checksum in selected debug info + E_DbgInfo *dbg_info = e_base_ctx->primary_dbg_info; + DI_Key dbgi_key = dbg_info->dbgi_key; RDI_ChecksumKind checksum_kind = RDI_ChecksumKind_NULL; String8 checksum_expected = {0}; - for(DI_KeyNode *n = dbgi_keys.first; n != 0 && checksum_kind == RDI_ChecksumKind_NULL; n = n->next) { Access *access = access_open(); // rjf: unpack RDI - DI_Key key = n->v; - RDI_Parsed *rdi = di_rdi_from_key(access, key, 0, 0); + RDI_Parsed *rdi = di_rdi_from_key(access, dbgi_key, 0, 0); // rjf: file_path_normalized * rdi -> src_id for EachNode(override_n, String8Node, overrides.first) @@ -2347,24 +2265,10 @@ RD_VIEW_UI_FUNCTION_DEF(text) // rjf: if we got a checksum, compute it locally - check if they match. switch(checksum_kind) { - default:{}break; - case RDI_ChecksumKind_MD5: + default: { - MD5 md5 = rd_md5_from_hash(hash); - String8 md5_string = str8_struct(&md5); - file_is_out_of_date = !MemoryIsZeroStruct(&md5) && !str8_match(md5_string, checksum_expected, 0); - }break; - case RDI_ChecksumKind_SHA1: - { - SHA1 sha1 = rd_sha1_from_hash(hash); - String8 sha1_string = str8_struct(&sha1); - file_is_out_of_date = !MemoryIsZeroStruct(&sha1) && !str8_match(sha1_string, checksum_expected, 0); - }break; - case RDI_ChecksumKind_SHA256: - { - SHA256 sha256 = rd_sha256_from_hash(hash); - String8 sha256_string = str8_struct(&sha256); - file_is_out_of_date = !MemoryIsZeroStruct(&sha256) && !str8_match(sha256_string, checksum_expected, 0); + String8 checksum_value = rd_checksum_value_from_hash_kind(scratch.arena, hash, checksum_kind); + file_is_out_of_date = !memory_is_zero(checksum_value.str, checksum_value.size) && !str8_match(checksum_value, checksum_expected, 0); }break; case RDI_ChecksumKind_Timestamp: { @@ -2635,7 +2539,7 @@ RD_VIEW_UI_FUNCTION_DEF(disasm) // if(!is_loading && has_disasm) { - rd_code_view_build(scratch.arena, cv, RD_CodeViewBuildFlag_All, code_area_rect, dasm_text_data, &dasm_text_info, &dasm_info.lines, range, dbgi_key); + rd_code_view_build(scratch.arena, cv, RD_CodeViewBuildFlag_All, code_area_rect, dasm_text_hash, dasm_text_data, &dasm_text_info, &dasm_info.lines, range, dbgi_key); } ////////////////////////////// diff --git a/src/raddbg/raddbg_views.h b/src/raddbg/raddbg_views.h index 478bd154..b5671c92 100644 --- a/src/raddbg/raddbg_views.h +++ b/src/raddbg/raddbg_views.h @@ -64,12 +64,6 @@ struct RD_CodeViewState U64 wrap_total_vline_count; }; -typedef struct RD_CodeViewBuildResult RD_CodeViewBuildResult; -struct RD_CodeViewBuildResult -{ - DI_KeyList dbgi_keys; -}; - //////////////////////////////// //~ rjf: Watch View Types @@ -200,7 +194,7 @@ struct RD_WatchViewState //~ rjf: Code View Functions internal void rd_code_view_init(RD_CodeViewState *cv); -internal RD_CodeViewBuildResult rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key); +internal void rd_code_view_build(Arena *arena, RD_CodeViewState *cv, RD_CodeViewBuildFlags flags, Rng2F32 rect, U128 text_hash, String8 text_data, TXT_TextInfo *text_info, DASM_LineArray *dasm_lines, Rng1U64 dasm_vaddr_range, DI_Key dasm_dbgi_key); //////////////////////////////// //~ rjf: Watch View Functions