From 7157e813a0a88817f208009f0170fdb174f3931b Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Sun, 3 May 2026 17:55:53 -0700 Subject: [PATCH] d2r2: fix line table build - correct program data size, correct special opcode application --- project.4coder | 2 +- src/dwarf/dwarf_parse_2.c | 6 +++++- src/dwarf/dwarf_parse_2.h | 2 ++ src/radbin/radbin.c | 2 +- src/rdi_from_dwarf/rdi_from_dwarf_2.c | 11 ++++------- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/project.4coder b/project.4coder index 91e82725..223f2125 100644 --- a/project.4coder +++ b/project.4coder @@ -49,7 +49,7 @@ commands = // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg meta telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build raddbg debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, // .f1 = { .win = "raddbg_stable --ipc kill_all && build radbin", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, - .f1 = { .win = "build radbin release telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, + .f1 = { .win = "build radbin debug telemetry", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, //- rjf: [raddbg wsl] // .f1 = { .win = "wsl ./build.sh raddbg", .linux = "", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false, }, diff --git a/src/dwarf/dwarf_parse_2.c b/src/dwarf/dwarf_parse_2.c index 1cf8b735..5c7d5099 100644 --- a/src/dwarf/dwarf_parse_2.c +++ b/src/dwarf/dwarf_parse_2.c @@ -597,7 +597,7 @@ internal U64 dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 off, DW2_LineTableHeader *out) { Temp scratch = scratch_begin(&arena, 1); - U64 start_off = 0; + U64 start_off = off; ////////////////////////////// //- rjf: read unit length @@ -637,6 +637,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of ////////////////////////////// //- rjf: read all remaining flat header properties // + U64 opl_header_length_off = 0; U64 header_length = 0; U8 min_inst_length = 0; U8 max_ops_per_inst = 1; @@ -646,6 +647,7 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of U8 opcode_base = 0; { off += dw2_read_fmt_u64(data, off, format, &header_length); + opl_header_length_off = off; off += str8_deserial_read_struct(data, off, &min_inst_length); off += str8_deserial_read_struct(data, off, &max_ops_per_inst); off += str8_deserial_read_struct(data, off, &default_is_stmt); @@ -876,6 +878,8 @@ dw2_read_line_table_header(Arena *arena, DW2_ParseCtx *ctx, String8 data, U64 of out->opcode_lengths = opcode_lengths; out->dirs = dirs; out->files = files; + out->line_program_off = opl_header_length_off + header_length; + out->total_unit_data_size = (off_opl - start_off); } U64 bytes_read = (off - start_off); diff --git a/src/dwarf/dwarf_parse_2.h b/src/dwarf/dwarf_parse_2.h index c583fbca..d90addc9 100644 --- a/src/dwarf/dwarf_parse_2.h +++ b/src/dwarf/dwarf_parse_2.h @@ -180,6 +180,8 @@ struct DW2_LineTableHeader U8 *opcode_lengths; DW2_LineTableFileArray dirs; DW2_LineTableFileArray files; + U64 line_program_off; + U64 total_unit_data_size; // NOTE(rjf): would be implied by `unit_length`, but DWARF makes that the size *past* the variable-width unit-length field itself }; typedef struct DW2_LineVMRegs DW2_LineVMRegs; diff --git a/src/radbin/radbin.c b/src/radbin/radbin.c index 92d142f2..4dc3f53d 100644 --- a/src/radbin/radbin.c +++ b/src/radbin/radbin.c @@ -788,7 +788,7 @@ rb_thread_entry_point(void *p) convert_params.deterministic = cmd_line_has_flag(cmdline, str8_lit("deterministic")); convert_params.is_parse_relaxed = 1; // TODO: switch } - // ProfScope("convert") dwarf_bake_params = d2r_convert(arena, &convert_params); + ProfScope("convert") dwarf_bake_params = d2r_convert(arena, &convert_params); // rjf: convert [2] D2R2_ConvertParams convert_params_2 = {0}; diff --git a/src/rdi_from_dwarf/rdi_from_dwarf_2.c b/src/rdi_from_dwarf/rdi_from_dwarf_2.c index 9df25afa..538df252 100644 --- a/src/rdi_from_dwarf/rdi_from_dwarf_2.c +++ b/src/rdi_from_dwarf/rdi_from_dwarf_2.c @@ -701,16 +701,13 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params) //- rjf: parse each unit's line table header // DW2_LineTableHeader *unit_line_table_headers = 0; - U64 *unit_line_table_header_sizes = 0; ProfScope("parse each unit's line table header") { if(lane_idx() == 0) { unit_line_table_headers = push_array(scratch.arena, DW2_LineTableHeader, unit_count); - unit_line_table_header_sizes = push_array(scratch.arena, U64, unit_count); } lane_sync_u64(&unit_line_table_headers, 0); - lane_sync_u64(&unit_line_table_header_sizes, 0); U64 unit_take_idx = 0; U64 *unit_take_idx_ptr = &unit_take_idx; lane_sync_u64(&unit_take_idx_ptr, 0); @@ -726,7 +723,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params) DW2_Attrib *stmt_list = dw2_attrib_from_kind(unit_root_tag, DW_AttribKind_StmtList); U64 line_info_off = stmt_list->val.u128.u64[0]; String8 line_info_data = raw->sec[DW_Section_Line].data; - unit_line_table_header_sizes[unit_idx] = dw2_read_line_table_header(scratch.arena, ctx, line_info_data, line_info_off, &unit_line_table_headers[unit_idx]); + dw2_read_line_table_header(scratch.arena, ctx, line_info_data, line_info_off, &unit_line_table_headers[unit_idx]); } lane_sync(); } @@ -880,7 +877,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params) DW2_Attrib *stmt_list = dw2_attrib_from_kind(unit_root_tag, DW_AttribKind_StmtList); U64 line_info_off = stmt_list->val.u128.u64[0]; String8 all_line_info_data = raw->sec[DW_Section_Line].data; - String8 unit_line_table_data = str8_substr(all_line_info_data, r1u64(line_info_off + unit_line_table_header_sizes[unit_idx], line_info_off + line_table_header->unit_length)); + String8 unit_line_table_data = str8_substr(all_line_info_data, r1u64(line_info_off + line_table_header->line_program_off, line_info_off + line_table_header->total_unit_data_size)); //- rjf: build unit's line table RDIM_LineTable *dst_line_table = rdim_line_table_chunk_list_push(arena, dst_line_tables, 1); @@ -920,7 +917,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params) U32 adjusted_opcode = (U32)(opcode - line_table_header->opcode_base); U32 op_advance = adjusted_opcode / line_table_header->line_range; S64 line_advance = (S64)line_table_header->line_base + (S64)adjusted_opcode%(S64)line_table_header->line_range; - U64 addr_advance = line_table_header->min_inst_length + (vm_regs.vliw_op_index + op_advance) / line_table_header->max_ops_per_inst; + U64 addr_advance = line_table_header->min_inst_length * (vm_regs.vliw_op_index + op_advance) / line_table_header->max_ops_per_inst; vm_regs.address += addr_advance; vm_regs.vliw_op_index = (vm_regs.vliw_op_index + op_advance) % line_table_header->max_ops_per_inst; vm_regs.line += line_advance; @@ -1168,7 +1165,7 @@ d2r2_convert(Arena *arena, D2R2_ConvertParams *params) } //- rjf: emit lines - if(emit_line) + if(emit_line && vm_regs.address != 0 && vm_regs.line != 0) { emit_line = 0; LineSeqChunk *chunk = last_line_seq_chunk;