authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-08-11 01:43:20-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2026-09-03 11:00:55-04:00
log0bf3e08c705ec460c71d3b2261acb0b87aacd066
tree1c5b6358e923fa25d99ffa88563ab1d507411baf
parentabbec23e9cfb6549a2260fd447086dfd2935a350

x86_64: change how epilogue line info is emitted

This more closely matches the output of other compilers.

9 files changed, 161 insertions(+), 92 deletions(-)

src/codegen/riscv64/Emit.zig+1-2
......@@ -192,8 +192,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
192192 switch (emit.debug_output) {
193193 inline .dwarf, .dwarf2 => |dw| {
194194 if (column != emit.prev_di_column) try dw.setColumn(column);
195 if (delta_line == 0) return; // TODO: fix these edge cases.
196 try dw.advancePcAndLine(delta_line, delta_pc);
195 try dw.advanceLineAndPc(delta_line, delta_pc, false);
197196 emit.prev_di_line = line;
198197 emit.prev_di_column = column;
199198 emit.prev_di_pc = emit.w.end;
src/codegen/sparc64/Emit.zig+1-1
......@@ -497,7 +497,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
497497 const delta_pc: usize = emit.w.end - emit.prev_di_pc;
498498 switch (emit.debug_output) {
499499 inline .dwarf, .dwarf2 => |dbg_out| {
500 try dbg_out.advancePcAndLine(delta_line, delta_pc);
500 try dbg_out.advanceLineAndPc(delta_line, delta_pc, false);
501501 emit.prev_di_line = line;
502502 emit.prev_di_column = column;
503503 emit.prev_di_pc = emit.w.end;
src/codegen/x86_64/CodeGen.zig+18-23
......@@ -1072,20 +1072,12 @@ pub fn generate(
10721072 );
10731073 }
10741074
1075 function.gen(&file.zir.?, func_zir.inst, func.comptime_args, call_info.air_arg_count) catch |err| switch (err) {
1075 function.gen(&file.zir.?, func_zir.inst, &func, call_info.air_arg_count) catch |err| switch (err) {
10761076 error.OutOfRegisters => return function.fail("ran out of registers (Zig compiler bug)", .{}),
10771077 else => |e| return e,
10781078 };
10791079
1080 // Drop them off at the rbrace.
1081 if (!mod.strip) _ = try function.addInst(.{
1082 .tag = .pseudo,
1083 .ops = .pseudo_dbg_line_line_column,
1084 .data = .{ .line_column = .{
1085 .line = func.rbrace_line,
1086 .column = func.rbrace_column,
1087 } },
1088 });
1080 if (!mod.strip) _ = try function.asmPseudo(.pseudo_dbg_end_none);
10891081
10901082 try function.mir_extra.shrinkToLen(gpa);
10911083 try function.mir_string_bytes.shrinkToLen(gpa);
......@@ -1228,18 +1220,18 @@ fn formatWipMir(data: FormatWipMirData, w: *Writer) Writer.Error!void {
12281220 switch (mir_inst.ops) {
12291221 else => unreachable,
12301222 .pseudo_dbg_prologue_end_none,
1231 .pseudo_dbg_epilogue_begin_none,
12321223 .pseudo_dbg_enter_block_none,
12331224 .pseudo_dbg_leave_block_none,
1225 .pseudo_dbg_end_none,
12341226 .pseudo_dbg_arg_none,
12351227 .pseudo_dbg_var_args_none,
12361228 .pseudo_dbg_var_none,
12371229 .pseudo_dead_none,
12381230 => {},
1239 .pseudo_dbg_line_stmt_line_column, .pseudo_dbg_line_line_column => try w.print(
1240 " {[line]d}, {[column]d}",
1241 mir_inst.data.line_column,
1242 ),
1231 .pseudo_dbg_line_stmt_line_column,
1232 .pseudo_dbg_line_line_column,
1233 .pseudo_dbg_epilogue_begin_line_column,
1234 => try w.print(" {[line]d}, {[column]d}", mir_inst.data.line_column),
12431235 .pseudo_dbg_enter_inline_func, .pseudo_dbg_leave_inline_func => try w.print(" {f}", .{
12441236 ip.getNav(ip.indexToKey(mir_inst.data.ip_index).func.owner_nav).name.fmt(ip),
12451237 }),
......@@ -2069,7 +2061,7 @@ fn gen(
20692061 self: *CodeGen,
20702062 zir: *const std.zig.Zir,
20712063 func_zir_inst: std.zig.Zir.Inst.Index,
2072 comptime_args: InternPool.Index.Slice,
2064 func: *const InternPool.Key.Func,
20732065 air_arg_count: u32,
20742066) InnerError!void {
20752067 const pt = self.pt;
......@@ -2150,7 +2142,7 @@ fn gen(
21502142
21512143 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
21522144
2153 try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
2145 try self.genMainBody(zir, func_zir_inst, func.comptime_args, air_arg_count);
21542146
21552147 const epilogue = if (self.epilogue_relocs.items.len > 0) epilogue: {
21562148 var last_inst: Mir.Inst.Index = @intCast(self.mir_instructions.len - 1);
......@@ -2165,7 +2157,14 @@ fn gen(
21652157 }
21662158 for (self.epilogue_relocs.items) |epilogue_reloc| self.performReloc(epilogue_reloc);
21672159
2168 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2160 if (!self.mod.strip) _ = try self.addInst(.{
2161 .tag = .pseudo,
2162 .ops = .pseudo_dbg_epilogue_begin_line_column,
2163 .data = .{ .line_column = .{
2164 .line = func.rbrace_line,
2165 .column = func.rbrace_column,
2166 } },
2167 });
21692168 const backpatch_stack_dealloc = try self.asmPlaceholder();
21702169 const backpatch_pop_callee_preserved_regs = try self.asmPlaceholder();
21712170 try self.asmRegister(.{ ._, .pop }, .rbp);
......@@ -2283,11 +2282,7 @@ fn gen(
22832282 .data = .{ .reg_list = frame_layout.save_reg_list },
22842283 });
22852284 }
2286 } else {
2287 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_prologue_end_none);
2288 try self.genMainBody(zir, func_zir_inst, comptime_args, air_arg_count);
2289 if (!self.mod.strip) try self.asmPseudo(.pseudo_dbg_epilogue_begin_none);
2290 }
2285 } else try self.genMainBody(zir, func_zir_inst, func.comptime_args, air_arg_count);
22912286}
22922287
22932288fn genMainBody(
src/codegen/x86_64/Emit.zig+23-9
......@@ -462,20 +462,25 @@ pub fn emitMir(emit: *Emit) Error!void {
462462 switch (mir_inst.ops) {
463463 else => unreachable,
464464 .pseudo_dbg_prologue_end_none => switch (emit.debug_output) {
465 inline .dwarf, .dwarf2 => |dwarf| try dwarf.setPrologueEnd(),
465 inline .dwarf, .dwarf2 => |dwarf| {
466 try dwarf.setPrologueEnd();
467 log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
468 emit.prev_di_loc.line, emit.prev_di_loc.column,
469 });
470 },
466471 .eh_frame, .none => {},
467472 },
468 .pseudo_dbg_line_stmt_line_column => try emit.dbgAdvancePcAndLine(.{
473 .pseudo_dbg_line_stmt_line_column => try emit.dbgAdvanceLineAndPc(.{
469474 .line = mir_inst.data.line_column.line,
470475 .column = mir_inst.data.line_column.column,
471476 .is_stmt = true,
472477 }),
473 .pseudo_dbg_line_line_column => try emit.dbgAdvancePcAndLine(.{
478 .pseudo_dbg_line_line_column => try emit.dbgAdvanceLineAndPc(.{
474479 .line = mir_inst.data.line_column.line,
475480 .column = mir_inst.data.line_column.column,
476481 .is_stmt = false,
477482 }),
478 .pseudo_dbg_epilogue_begin_none => {
483 .pseudo_dbg_epilogue_begin_line_column => {
479484 switch (emit.debug_output) {
480485 inline .dwarf, .dwarf2 => |dwarf| {
481486 try dwarf.setEpilogueBegin();
......@@ -485,7 +490,10 @@ pub fn emitMir(emit: *Emit) Error!void {
485490 },
486491 .eh_frame, .none => {},
487492 }
488 try emit.dbgAdvancePcAndLine(emit.prev_di_loc);
493 try emit.dbgAdvanceLineAndPc(.{
494 .line = mir_inst.data.line_column.line,
495 .column = mir_inst.data.line_column.column,
496 });
489497 },
490498 .pseudo_dbg_enter_block_none => switch (emit.debug_output) {
491499 inline .dwarf, .dwarf2 => |dwarf| {
......@@ -523,6 +531,11 @@ pub fn emitMir(emit: *Emit) Error!void {
523531 },
524532 .eh_frame, .none => {},
525533 },
534 .pseudo_dbg_end_none => try emit.dbgAdvanceLineAndPc(.{
535 .line = emit.prev_di_loc.line,
536 .column = emit.prev_di_loc.column,
537 .end = true,
538 }),
526539 .pseudo_dbg_arg_none,
527540 .pseudo_dbg_arg_i_s,
528541 .pseudo_dbg_arg_i_u,
......@@ -974,18 +987,19 @@ const TableReloc = struct {
974987const Loc = struct {
975988 line: u32,
976989 column: u32,
977 is_stmt: bool,
990 is_stmt: ?bool = null,
991 end: bool = false,
978992};
979993
980fn dbgAdvancePcAndLine(emit: *Emit, loc: Loc) Error!void {
994fn dbgAdvanceLineAndPc(emit: *Emit, loc: Loc) Error!void {
981995 switch (emit.debug_output) {
982996 inline .dwarf, .dwarf2 => |dwarf| {
983997 const delta_line = @as(i33, loc.line) - @as(i33, emit.prev_di_loc.line);
984998 const delta_pc: usize = emit.w.end - emit.prev_di_pc;
985999 log.debug(" (advance pc={d} and line={d})", .{ delta_pc, delta_line });
986 if (loc.is_stmt != emit.prev_di_loc.is_stmt) try dwarf.negateStmt();
1000 if (loc.is_stmt) |is_stmt| if (is_stmt != emit.prev_di_loc.is_stmt) try dwarf.negateStmt();
9871001 if (loc.column != emit.prev_di_loc.column) try dwarf.setColumn(loc.column);
988 try dwarf.advancePcAndLine(delta_line, delta_pc);
1002 try dwarf.advanceLineAndPc(delta_line, delta_pc, loc.end);
9891003 emit.prev_di_loc = loc;
9901004 emit.prev_di_pc = emit.w.end;
9911005 },
src/codegen/x86_64/Lower.zig+2-1
......@@ -314,11 +314,12 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
314314 .pseudo_dbg_prologue_end_none,
315315 .pseudo_dbg_line_stmt_line_column,
316316 .pseudo_dbg_line_line_column,
317 .pseudo_dbg_epilogue_begin_none,
317 .pseudo_dbg_epilogue_begin_line_column,
318318 .pseudo_dbg_enter_block_none,
319319 .pseudo_dbg_leave_block_none,
320320 .pseudo_dbg_enter_inline_func,
321321 .pseudo_dbg_leave_inline_func,
322 .pseudo_dbg_end_none,
322323 .pseudo_dbg_arg_none,
323324 .pseudo_dbg_arg_i_s,
324325 .pseudo_dbg_arg_i_u,
src/codegen/x86_64/Mir.zig+13-10
......@@ -1519,30 +1519,33 @@ pub const Inst = struct {
15191519 /// Uses `bytes` payload.
15201520 pseudo_cfi_escape_bytes,
15211521
1522 /// End of prologue
1522 /// End of prologue.
15231523 /// Uses `none` payload.
15241524 pseudo_dbg_prologue_end_none,
1525 /// Update debug line with is_stmt register set
1525 /// Update debug line with is_stmt register set.
15261526 /// Uses `line_column` payload.
15271527 pseudo_dbg_line_stmt_line_column,
1528 /// Update debug line with is_stmt register clear
1528 /// Update debug line with is_stmt register clear.
15291529 /// Uses `line_column` payload.
15301530 pseudo_dbg_line_line_column,
1531 /// Start of epilogue
1532 /// Uses `none` payload.
1533 pseudo_dbg_epilogue_begin_none,
1534 /// Start of lexical block
1531 /// Start of epilogue.
1532 /// Uses `line_column` payload.
1533 pseudo_dbg_epilogue_begin_line_column,
1534 /// Start of lexical block.
15351535 /// Uses `none` payload.
15361536 pseudo_dbg_enter_block_none,
1537 /// End of lexical block
1537 /// End of lexical block.
15381538 /// Uses `none` payload.
15391539 pseudo_dbg_leave_block_none,
1540 /// Start of inline function
1540 /// Start of inline function.
15411541 /// Uses `ip_index` payload.
15421542 pseudo_dbg_enter_inline_func,
1543 /// End of inline function
1543 /// End of inline function.
15441544 /// Uses `ip_index` payload.
15451545 pseudo_dbg_leave_inline_func,
1546 /// End of function.
1547 /// Uses `none` payload.
1548 pseudo_dbg_end_none,
15461549 /// Local argument.
15471550 /// Uses `none` payload.
15481551 pseudo_dbg_arg_none,
src/link/Dwarf.zig+32-18
......@@ -1626,15 +1626,25 @@ pub const WipNav = struct {
16261626 wip_nav.any_children = true;
16271627 }
16281628
1629 pub fn advancePcAndLine(wip_nav: *WipNav, delta_line: i33, delta_pc: u64) Allocator.Error!void {
1630 return wip_nav.advancePcAndLineWriterError(delta_line, delta_pc) catch |err| switch (err) {
1629 pub fn advanceLineAndPc(
1630 wip_nav: *WipNav,
1631 delta_line: i33,
1632 delta_pc: u64,
1633 end: bool,
1634 ) Allocator.Error!void {
1635 return wip_nav.advanceLineAndPcWriterError(
1636 delta_line,
1637 delta_pc,
1638 end,
1639 ) catch |err| switch (err) {
16311640 error.WriteFailed => error.OutOfMemory,
16321641 };
16331642 }
1634 fn advancePcAndLineWriterError(
1643 fn advanceLineAndPcWriterError(
16351644 wip_nav: *WipNav,
16361645 delta_line: i33,
16371646 delta_pc: u64,
1647 end: bool,
16381648 ) Writer.Error!void {
16391649 const dlw = &wip_nav.debug_line.writer;
16401650
......@@ -1654,20 +1664,30 @@ pub const WipNav = struct {
16541664 const op_advance = @divExact(delta_pc, header.minimum_instruction_length) *
16551665 header.maximum_operations_per_instruction + delta_op;
16561666 const max_op_advance: u9 = (std.math.maxInt(u8) - header.opcode_base) / header.line_range;
1657 const remaining_op_advance: u8 = @intCast(if (op_advance >= 2 * max_op_advance) remaining: {
1658 try dlw.writeByte(DW.LNS.advance_pc);
1659 try dlw.writeUleb128(op_advance);
1667 const remaining_op_advance: u8 = @intCast(if (end or
1668 op_advance >= 2 * max_op_advance)
1669 remaining: {
1670 if (op_advance == max_op_advance) {
1671 try dlw.writeByte(DW.LNS.const_add_pc);
1672 } else if (op_advance != 0) {
1673 try dlw.writeByte(DW.LNS.advance_pc);
1674 try dlw.writeUleb128(op_advance);
1675 } else assert(end);
16601676 break :remaining 0;
16611677 } else if (op_advance >= max_op_advance) remaining: {
16621678 try dlw.writeByte(DW.LNS.const_add_pc);
16631679 break :remaining op_advance - max_op_advance;
16641680 } else op_advance);
16651681
1666 if (remaining_delta_line == 0 and remaining_op_advance == 0)
1667 try dlw.writeByte(DW.LNS.copy)
1668 else
1682 if (remaining_delta_line != 0 or remaining_op_advance != 0) {
1683 assert(!end);
16691684 try dlw.writeByte(@intCast((remaining_delta_line - header.line_base) +
16701685 (header.line_range * remaining_op_advance) + header.opcode_base));
1686 } else if (end) {
1687 try dlw.writeByte(DW.LNS.extended_op);
1688 try dlw.writeUleb128(1);
1689 try dlw.writeByte(DW.LNE.end_sequence);
1690 } else try dlw.writeByte(DW.LNS.copy);
16711691 }
16721692
16731693 pub fn setColumn(wip_nav: *WipNav, column: u32) Allocator.Error!void {
......@@ -2773,7 +2793,7 @@ fn initWipNavInner(
27732793 try dlw.writeByte(DW.LNS.set_column);
27742794 try dlw.writeUleb128(func.lbrace_column + 1);
27752795
2776 try wip_nav.advancePcAndLine(func.lbrace_line, 0);
2796 try wip_nav.advanceLineAndPc(func.lbrace_line, 0, false);
27772797 } else {
27782798 try dlw.writeUleb128(1 + @backingInt(dwarf.address_size));
27792799 try dlw.writeByte(DW.LNE.set_address);
......@@ -2790,7 +2810,7 @@ fn initWipNavInner(
27902810 try dlw.writeByte(DW.LNS.set_column);
27912811 try dlw.writeUleb128(func.lbrace_column + 1);
27922812
2793 try wip_nav.advancePcAndLine(@intCast(decl.src_line + func.lbrace_line), 0);
2813 try wip_nav.advanceLineAndPc(decl.src_line + func.lbrace_line, 0, false);
27942814 }
27952815 },
27962816 else => {
......@@ -2982,13 +3002,7 @@ fn finishWipNavWriterError(
29823002 log.debug("finishWipNav({f})", .{nav.fqn.fmt(ip)});
29833003
29843004 try dwarf.debug_info.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_info.written());
2985 const dlw = &wip_nav.debug_line.writer;
2986 if (dlw.end > 0) {
2987 try dlw.writeByte(DW.LNS.extended_op);
2988 try dlw.writeUleb128(1);
2989 try dlw.writeByte(DW.LNE.end_sequence);
2990 try dwarf.debug_line.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_line.written());
2991 }
3005 try dwarf.debug_line.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_line.written());
29923006 try dwarf.debug_loclists.section.replaceEntry(wip_nav.unit, wip_nav.entry, dwarf, wip_nav.debug_loclists.written());
29933007
29943008 try dwarf.const_pool.flushPending(pt, .{ .dwarf = dwarf });
src/link/Dwarf2.zig+70-27
......@@ -24,14 +24,15 @@ debug_str_offsets: StrOffsets,
2424pub const AddressSize = enum(u8) { @"32" = 4, @"64" = 8, _ };
2525
2626pub const Unit = struct {
27 dirs: std.array_hash_map.Auto(Unit.Index, void),
2728 files: std.array_hash_map.Auto(Zcu.File.Index, void),
28 files_changed: bool,
2929 frame_ni: MappedFile.Node.Index.Optional,
3030 cie_ni: MappedFile.Node.Index.Optional,
3131 debug_info_ni: MappedFile.Node.Index.Optional,
3232 debug_info_header_ni: MappedFile.Node.Index.Optional,
3333 debug_line_ni: MappedFile.Node.Index.Optional,
3434 debug_line_header_ni: MappedFile.Node.Index.Optional,
35 debug_line_header_changed: bool,
3536 debug_rnglists_ni: MappedFile.Node.Index.Optional,
3637 debug_rnglists_offset: usize,
3738
......@@ -47,6 +48,15 @@ pub const Unit = struct {
4748 }
4849 };
4950
51 pub const DirIndex = enum(u32) {
52 root = 0,
53 _,
54
55 fn get(di: DirIndex, unit: *Unit) Unit.Index {
56 return unit.dirs.keys()[@backingInt(di)];
57 }
58 };
59
5060 pub const FileIndex = enum(u32) {
5161 root = 0,
5262 _,
......@@ -56,19 +66,29 @@ pub const Unit = struct {
5666 }
5767 };
5868
69 fn deinit(unit: *Unit, gpa: std.mem.Allocator) void {
70 unit.dirs.deinit(gpa);
71 unit.files.deinit(gpa);
72 unit.* = undefined;
73 }
74
5975 fn getFile(
6076 unit: *Unit,
6177 gpa: std.mem.Allocator,
78 ui: Unit.Index,
6279 zfi: Zcu.File.Index,
63 ) std.mem.Allocator.Error!FileIndex {
64 const file_gop = try unit.files.getOrPut(gpa, zfi);
65 if (!file_gop.found_existing) unit.files_changed = true;
66 return @fromBackingInt(@intCast(file_gop.index));
80 ) std.mem.Allocator.Error!struct { DirIndex, FileIndex } {
81 try unit.dirs.ensureUnusedCapacity(gpa, 1);
82 try unit.files.ensureUnusedCapacity(gpa, 1);
83 const dir_gop = unit.dirs.getOrPutAssumeCapacity(ui);
84 const file_gop = unit.files.getOrPutAssumeCapacity(zfi);
85 if (!dir_gop.found_existing or !file_gop.found_existing) unit.debug_line_header_changed = true;
86 return .{ @fromBackingInt(@intCast(dir_gop.index)), @fromBackingInt(@intCast(file_gop.index)) };
6787 }
6888
69 pub fn cleanFilesChanged(unit: *Unit) bool {
70 defer unit.files_changed = false;
71 return unit.files_changed;
89 pub fn cleanDebugLineHeaderChanged(unit: *Unit) bool {
90 defer unit.debug_line_header_changed = false;
91 return unit.debug_line_header_changed;
7292 }
7393};
7494
......@@ -623,7 +643,6 @@ pub const WipNav = struct {
623643 const zf = zcu.fileByIndex(zfi);
624644 const inst_info = ip.getNav(nav).srcInst(ip).resolveFull(ip).?;
625645 const decl = zf.zir.?.getDeclaration(inst_info.inst);
626 const mod = zf.mod.?;
627646 const dlw = &debug.line_writer.interface;
628647 try dlw.writeByte(DW.LNS.extended_op);
629648 if (zcu.comp.config.incremental) {
......@@ -637,20 +656,21 @@ pub const WipNav = struct {
637656 try dlw.writeByte(DW.LNS.set_column);
638657 try dlw.writeUleb128(func.lbrace_column + 1);
639658
640 try debug.advancePcAndLine(func.lbrace_line, 0);
659 try debug.advanceLineAndPc(func.lbrace_line, 0, false);
641660 } else {
642661 try dlw.writeUleb128(1 + @backingInt(dwarf.address_size));
643662 try dlw.writeByte(DW.LNE.set_address);
644663 try dwarf.symbolAddress(&debug.line_writer, debug.wip_nav.func_si, 0);
645664
646 const fi = try dwarf.getUnit(mod).get(dwarf).getFile(zcu.gpa, zfi);
665 const unit = dwarf.getUnit(zf.mod.?);
666 _, const fi = try unit.get(dwarf).getFile(zcu.gpa, unit, zfi);
647667 try dlw.writeByte(DW.LNS.set_file);
648668 try dlw.writeUleb128(@backingInt(fi));
649669
650670 try dlw.writeByte(DW.LNS.set_column);
651671 try dlw.writeUleb128(func.lbrace_column + 1);
652672
653 try debug.advancePcAndLine(@intCast(decl.src_line + func.lbrace_line), 0);
673 try debug.advanceLineAndPc(decl.src_line + func.lbrace_line, 0, false);
654674 }
655675 }
656676
......@@ -678,9 +698,6 @@ pub const WipNav = struct {
678698 }
679699 fn finishDebugLine(debug: *Debug) link.EmitError!void {
680700 const dlw = &debug.line_writer.interface;
681 try dlw.writeByte(DW.LNS.extended_op);
682 try dlw.writeUleb128(1);
683 try dlw.writeByte(DW.LNE.end_sequence);
684701 try genDebugLinePadding(dlw, dlw.unusedCapacityLen());
685702 }
686703
......@@ -773,12 +790,22 @@ pub const WipNav = struct {
773790 debug.any_children = true;
774791 }
775792
776 pub fn advancePcAndLine(debug: *Debug, delta_line: i33, delta_pc: u64) link.Error!void {
777 return debug.advancePcAndLineInner(delta_line, delta_pc) catch |err| switch (err) {
793 pub fn advanceLineAndPc(
794 debug: *Debug,
795 delta_line: i33,
796 delta_pc: u64,
797 end: bool,
798 ) link.Error!void {
799 return debug.advanceLineAndPcInner(delta_line, delta_pc, end) catch |err| switch (err) {
778800 error.WriteFailed => return debug.wip_nav.reportWriteError(&debug.line_writer),
779801 };
780802 }
781 fn advancePcAndLineInner(debug: *Debug, delta_line: i33, delta_pc: u64) Writer.Error!void {
803 fn advanceLineAndPcInner(
804 debug: *Debug,
805 delta_line: i33,
806 delta_pc: u64,
807 end: bool,
808 ) Writer.Error!void {
782809 const dlw = &debug.line_writer.interface;
783810
784811 const header = debug.wip_nav.dwarf.debug_line.header;
......@@ -797,20 +824,30 @@ pub const WipNav = struct {
797824 const op_advance = @divExact(delta_pc, header.minimum_instruction_length) *
798825 header.maximum_operations_per_instruction + delta_op;
799826 const max_op_advance: u9 = (std.math.maxInt(u8) - header.opcode_base) / header.line_range;
800 const remaining_op_advance: u8 = @intCast(if (op_advance >= 2 * max_op_advance) remaining: {
801 try dlw.writeByte(DW.LNS.advance_pc);
802 try dlw.writeUleb128(op_advance);
827 const remaining_op_advance: u8 = @intCast(if (end or
828 op_advance >= 2 * max_op_advance)
829 remaining: {
830 if (op_advance == max_op_advance) {
831 try dlw.writeByte(DW.LNS.const_add_pc);
832 } else if (op_advance != 0) {
833 try dlw.writeByte(DW.LNS.advance_pc);
834 try dlw.writeUleb128(op_advance);
835 } else assert(end);
803836 break :remaining 0;
804837 } else if (op_advance >= max_op_advance) remaining: {
805838 try dlw.writeByte(DW.LNS.const_add_pc);
806839 break :remaining op_advance - max_op_advance;
807840 } else op_advance);
808841
809 if (remaining_delta_line == 0 and remaining_op_advance == 0)
810 try dlw.writeByte(DW.LNS.copy)
811 else
842 if (remaining_delta_line != 0 or remaining_op_advance != 0) {
843 assert(!end);
812844 try dlw.writeByte(@intCast((remaining_delta_line - header.line_base) +
813845 (header.line_range * remaining_op_advance) + header.opcode_base));
846 } else if (end) {
847 try dlw.writeByte(DW.LNS.extended_op);
848 try dlw.writeUleb128(1);
849 try dlw.writeByte(DW.LNE.end_sequence);
850 } else try dlw.writeByte(DW.LNS.copy);
814851 }
815852
816853 pub fn setColumn(debug: *Debug, column: u32) link.Error!void {
......@@ -1398,7 +1435,7 @@ pub fn init(lf: *link.File, format: DW.Format) Dwarf {
13981435pub fn deinit(dwarf: *Dwarf) void {
13991436 const gpa = dwarf.lf.comp.gpa;
14001437 dwarf.const_pool.deinit(gpa);
1401 for (dwarf.units.values()) |*unit| unit.files.deinit(gpa);
1438 for (dwarf.units.values()) |*unit| unit.deinit(gpa);
14021439 dwarf.units.deinit(gpa);
14031440 dwarf.values.deinit(gpa);
14041441 dwarf.globals.deinit(gpa);
......@@ -1414,18 +1451,24 @@ pub fn initUnits(dwarf: *Dwarf, zcu: *Zcu) std.mem.Allocator.Error!void {
14141451 const unit_gop = dwarf.units.getOrPutAssumeCapacity(mod);
14151452 assert(!unit_gop.found_existing);
14161453 unit_gop.value_ptr.* = .{
1454 .dirs = .empty,
14171455 .files = .empty,
1418 .files_changed = true,
14191456 .frame_ni = .none,
14201457 .cie_ni = .none,
14211458 .debug_info_ni = .none,
14221459 .debug_info_header_ni = .none,
14231460 .debug_line_ni = .none,
14241461 .debug_line_header_ni = .none,
1462 .debug_line_header_changed = true,
14251463 .debug_rnglists_ni = .none,
14261464 .debug_rnglists_offset = undefined,
14271465 };
1428 assert(try unit_gop.value_ptr.getFile(zcu.gpa, root_zfi) == .root);
1466 const root_di, const root_fi = try unit_gop.value_ptr.getFile(
1467 zcu.gpa,
1468 @fromBackingInt(@intCast(unit_gop.index)),
1469 root_zfi,
1470 );
1471 assert(root_di == .root and root_fi == .root);
14291472 };
14301473}
14311474
src/link/Elf2.zig+1-1
......@@ -7205,7 +7205,7 @@ fn zcuFilesReadyInner(elf: *Elf, zcu: *Zcu) Error!void {
72057205fn flushFiles(elf: *Elf) Error!void {
72067206 const gpa = elf.base.comp.gpa;
72077207 if (elf.shndx.debug_line != .UNDEF) for (elf.dwarf.units.keys(), elf.dwarf.units.values()) |mod, *unit| {
7208 if (!unit.cleanFilesChanged()) continue;
7208 if (!unit.cleanDebugLineHeaderChanged()) continue;
72097209 const debug_line_header_ni = unit.debug_line_header_ni.unwrap().?;
72107210 try debug_line_header_ni.moved(gpa, &elf.mf);
72117211 try debug_line_header_ni.nextMoved(gpa, &elf.mf);