Commit 12e34e7037

Jakub Konka <kubkon@jakubkonka.com>
2022-12-05 17:48:54
dwarf: pull out debug line program internals into DeclState helpers
1 parent 97827d6
Changed files (7)
src
arch
aarch64
arm
riscv64
sparc64
wasm
x86_64
link
src/arch/aarch64/Emit.zig
@@ -10,8 +10,6 @@ const link = @import("../../link.zig");
 const Module = @import("../../Module.zig");
 const ErrorMsg = Module.ErrorMsg;
 const assert = std.debug.assert;
-const DW = std.dwarf;
-const leb128 = std.leb;
 const Instruction = bits.Instruction;
 const Register = bits.Register;
 const log = std.log.scoped(.aarch64_emit);
@@ -440,19 +438,7 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
     const delta_pc: usize = self.code.items.len - self.prev_di_pc;
     switch (self.debug_output) {
         .dwarf => |dw| {
-            // TODO Look into using the DWARF special opcodes to compress this data.
-            // It lets you emit single-byte opcodes that add different numbers to
-            // both the PC and the line number at the same time.
-            const dbg_line = &dw.dbg_line;
-            try dbg_line.ensureUnusedCapacity(11);
-            dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
-            leb128.writeULEB128(dbg_line.writer(), delta_pc) catch unreachable;
-            if (delta_line != 0) {
-                dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
-                leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable;
-            }
-            dbg_line.appendAssumeCapacity(DW.LNS.copy);
-            self.prev_di_pc = self.code.items.len;
+            try dw.advancePCAndLine(delta_line, delta_pc);
             self.prev_di_line = line;
             self.prev_di_column = column;
             self.prev_di_pc = self.code.items.len;
@@ -652,7 +638,7 @@ fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) !void {
 fn mirDebugPrologueEnd(self: *Emit) !void {
     switch (self.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_prologue_end);
+            try dw.setPrologueEnd();
             try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
         },
         .plan9 => {},
@@ -663,7 +649,7 @@ fn mirDebugPrologueEnd(self: *Emit) !void {
 fn mirDebugEpilogueBegin(self: *Emit) !void {
     switch (self.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_epilogue_begin);
+            try dw.setEpilogueBegin();
             try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
         },
         .plan9 => {},
src/arch/arm/Emit.zig
@@ -13,8 +13,6 @@ const Type = @import("../../type.zig").Type;
 const ErrorMsg = Module.ErrorMsg;
 const Target = std.Target;
 const assert = std.debug.assert;
-const DW = std.dwarf;
-const leb128 = std.leb;
 const Instruction = bits.Instruction;
 const Register = bits.Register;
 const log = std.log.scoped(.aarch64_emit);
@@ -356,19 +354,7 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
     const delta_pc: usize = self.code.items.len - self.prev_di_pc;
     switch (self.debug_output) {
         .dwarf => |dw| {
-            // TODO Look into using the DWARF special opcodes to compress this data.
-            // It lets you emit single-byte opcodes that add different numbers to
-            // both the PC and the line number at the same time.
-            const dbg_line = &dw.dbg_line;
-            try dbg_line.ensureUnusedCapacity(11);
-            dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
-            leb128.writeULEB128(dbg_line.writer(), delta_pc) catch unreachable;
-            if (delta_line != 0) {
-                dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
-                leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable;
-            }
-            dbg_line.appendAssumeCapacity(DW.LNS.copy);
-            self.prev_di_pc = self.code.items.len;
+            try dw.advancePCAndLine(delta_line, delta_pc);
             self.prev_di_line = line;
             self.prev_di_column = column;
             self.prev_di_pc = self.code.items.len;
@@ -543,7 +529,7 @@ fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) !void {
 fn mirDebugPrologueEnd(emit: *Emit) !void {
     switch (emit.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_prologue_end);
+            try dw.setPrologueEnd();
             try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
         },
         .plan9 => {},
@@ -554,7 +540,7 @@ fn mirDebugPrologueEnd(emit: *Emit) !void {
 fn mirDebugEpilogueBegin(emit: *Emit) !void {
     switch (emit.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_epilogue_begin);
+            try dw.setEpilogueBegin();
             try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
         },
         .plan9 => {},
src/arch/riscv64/Emit.zig
@@ -10,8 +10,6 @@ const link = @import("../../link.zig");
 const Module = @import("../../Module.zig");
 const ErrorMsg = Module.ErrorMsg;
 const assert = std.debug.assert;
-const DW = std.dwarf;
-const leb128 = std.leb;
 const Instruction = bits.Instruction;
 const Register = bits.Register;
 const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
@@ -90,19 +88,7 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
     const delta_pc: usize = self.code.items.len - self.prev_di_pc;
     switch (self.debug_output) {
         .dwarf => |dw| {
-            // TODO Look into using the DWARF special opcodes to compress this data.
-            // It lets you emit single-byte opcodes that add different numbers to
-            // both the PC and the line number at the same time.
-            const dbg_line = &dw.dbg_line;
-            try dbg_line.ensureUnusedCapacity(11);
-            dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
-            leb128.writeULEB128(dbg_line.writer(), delta_pc) catch unreachable;
-            if (delta_line != 0) {
-                dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
-                leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable;
-            }
-            dbg_line.appendAssumeCapacity(DW.LNS.copy);
-            self.prev_di_pc = self.code.items.len;
+            try dw.advancePCAndLine(delta_line, delta_pc);
             self.prev_di_line = line;
             self.prev_di_column = column;
             self.prev_di_pc = self.code.items.len;
@@ -184,7 +170,7 @@ fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) !void {
 fn mirDebugPrologueEnd(self: *Emit) !void {
     switch (self.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_prologue_end);
+            try dw.setPrologueEnd();
             try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
         },
         .plan9 => {},
@@ -195,7 +181,7 @@ fn mirDebugPrologueEnd(self: *Emit) !void {
 fn mirDebugEpilogueBegin(self: *Emit) !void {
     switch (self.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_epilogue_begin);
+            try dw.setEpilogueBegin();
             try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
         },
         .plan9 => {},
src/arch/sparc64/Emit.zig
@@ -10,8 +10,6 @@ const ErrorMsg = Module.ErrorMsg;
 const Liveness = @import("../../Liveness.zig");
 const log = std.log.scoped(.sparcv9_emit);
 const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
-const DW = std.dwarf;
-const leb128 = std.leb;
 
 const Emit = @This();
 const Mir = @import("Mir.zig");
@@ -168,7 +166,7 @@ fn mirDbgLine(emit: *Emit, inst: Mir.Inst.Index) !void {
 fn mirDebugPrologueEnd(emit: *Emit) !void {
     switch (emit.debug_output) {
         .dwarf => |dbg_out| {
-            try dbg_out.dbg_line.append(DW.LNS.set_prologue_end);
+            try dbg_out.setPrologueEnd();
             try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
         },
         .plan9 => {},
@@ -179,7 +177,7 @@ fn mirDebugPrologueEnd(emit: *Emit) !void {
 fn mirDebugEpilogueBegin(emit: *Emit) !void {
     switch (emit.debug_output) {
         .dwarf => |dbg_out| {
-            try dbg_out.dbg_line.append(DW.LNS.set_epilogue_begin);
+            try dbg_out.setEpilogueBegin();
             try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
         },
         .plan9 => {},
@@ -468,18 +466,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
     const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
     switch (emit.debug_output) {
         .dwarf => |dbg_out| {
-            // TODO Look into using the DWARF special opcodes to compress this data.
-            // It lets you emit single-byte opcodes that add different numbers to
-            // both the PC and the line number at the same time.
-            try dbg_out.dbg_line.ensureUnusedCapacity(11);
-            dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
-            leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable;
-            if (delta_line != 0) {
-                dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
-                leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable;
-            }
-            dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.copy);
-            emit.prev_di_pc = emit.code.items.len;
+            try dbg_out.advancePCAndLine(delta_line, delta_pc);
             emit.prev_di_line = line;
             emit.prev_di_column = column;
             emit.prev_di_pc = emit.code.items.len;
src/arch/wasm/Emit.zig
@@ -444,18 +444,12 @@ fn emitDbgLine(emit: *Emit, inst: Mir.Inst.Index) !void {
 fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
     if (emit.dbg_output != .dwarf) return;
 
-    const dbg_line = &emit.dbg_output.dwarf.dbg_line;
-    try dbg_line.ensureUnusedCapacity(11);
-    dbg_line.appendAssumeCapacity(std.dwarf.LNS.advance_pc);
+    const delta_line = @intCast(i32, line) - @intCast(i32, emit.prev_di_line);
+    const delta_pc = emit.offset() - emit.prev_di_offset;
     // TODO: This must emit a relocation to calculate the offset relative
     // to the code section start.
-    leb128.writeULEB128(dbg_line.writer(), emit.offset() - emit.prev_di_offset) catch unreachable;
-    const delta_line = @intCast(i32, line) - @intCast(i32, emit.prev_di_line);
-    if (delta_line != 0) {
-        dbg_line.appendAssumeCapacity(std.dwarf.LNS.advance_line);
-        leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable;
-    }
-    dbg_line.appendAssumeCapacity(std.dwarf.LNS.copy);
+    try emit.dbg_output.dwarf.advancePCAndLine(delta_line, delta_pc);
+
     emit.prev_di_line = line;
     emit.prev_di_column = column;
     emit.prev_di_offset = emit.offset();
@@ -464,13 +458,13 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) !void {
 fn emitDbgPrologueEnd(emit: *Emit) !void {
     if (emit.dbg_output != .dwarf) return;
 
-    try emit.dbg_output.dwarf.dbg_line.append(std.dwarf.LNS.set_prologue_end);
+    try emit.dbg_output.dwarf.setPrologueEnd();
     try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
 }
 
 fn emitDbgEpilogueBegin(emit: *Emit) !void {
     if (emit.dbg_output != .dwarf) return;
 
-    try emit.dbg_output.dwarf.dbg_line.append(std.dwarf.LNS.set_epilogue_begin);
+    try emit.dbg_output.dwarf.setEpilogueBegin();
     try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
 }
src/arch/x86_64/Emit.zig
@@ -7,7 +7,6 @@ const std = @import("std");
 const assert = std.debug.assert;
 const bits = @import("bits.zig");
 const abi = @import("abi.zig");
-const leb128 = std.leb;
 const link = @import("../../link.zig");
 const log = std.log.scoped(.codegen);
 const math = std.math;
@@ -18,7 +17,6 @@ const Air = @import("../../Air.zig");
 const Allocator = mem.Allocator;
 const CodeGen = @import("CodeGen.zig");
 const DebugInfoOutput = @import("../../codegen.zig").DebugInfoOutput;
-const DW = std.dwarf;
 const Encoder = bits.Encoder;
 const ErrorMsg = Module.ErrorMsg;
 const MCValue = @import("CodeGen.zig").MCValue;
@@ -1184,18 +1182,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) InnerError!void {
     log.debug("  (advance pc={d} and line={d})", .{ delta_line, delta_pc });
     switch (emit.debug_output) {
         .dwarf => |dw| {
-            // TODO Look into using the DWARF special opcodes to compress this data.
-            // It lets you emit single-byte opcodes that add different numbers to
-            // both the PC and the line number at the same time.
-            const dbg_line = &dw.dbg_line;
-            try dbg_line.ensureUnusedCapacity(11);
-            dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
-            leb128.writeULEB128(dbg_line.writer(), delta_pc) catch unreachable;
-            if (delta_line != 0) {
-                dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
-                leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable;
-            }
-            dbg_line.appendAssumeCapacity(DW.LNS.copy);
+            try dw.advancePCAndLine(delta_line, delta_pc);
             emit.prev_di_line = line;
             emit.prev_di_column = column;
             emit.prev_di_pc = emit.code.items.len;
@@ -1244,8 +1231,11 @@ fn mirDbgPrologueEnd(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
     assert(tag == .dbg_prologue_end);
     switch (emit.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_prologue_end);
-            log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{ emit.prev_di_line, emit.prev_di_column });
+            try dw.setPrologueEnd();
+            log.debug("mirDbgPrologueEnd (line={d}, col={d})", .{
+                emit.prev_di_line,
+                emit.prev_di_column,
+            });
             try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
         },
         .plan9 => {},
@@ -1258,8 +1248,11 @@ fn mirDbgEpilogueBegin(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
     assert(tag == .dbg_epilogue_begin);
     switch (emit.debug_output) {
         .dwarf => |dw| {
-            try dw.dbg_line.append(DW.LNS.set_epilogue_begin);
-            log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{ emit.prev_di_line, emit.prev_di_column });
+            try dw.setEpilogueBegin();
+            log.debug("mirDbgEpilogueBegin (line={d}, col={d})", .{
+                emit.prev_di_line,
+                emit.prev_di_column,
+            });
             try emit.dbgAdvancePCAndLine(emit.prev_di_line, emit.prev_di_column);
         },
         .plan9 => {},
src/link/Dwarf.zig
@@ -778,6 +778,33 @@ pub const DeclState = struct {
         try self.addTypeRelocGlobal(atom, child_ty, @intCast(u32, index));
         dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
     }
+
+    pub fn advancePCAndLine(
+        self: *DeclState,
+        delta_line: i32,
+        delta_pc: usize,
+    ) error{OutOfMemory}!void {
+        // TODO Look into using the DWARF special opcodes to compress this data.
+        // It lets you emit single-byte opcodes that add different numbers to
+        // both the PC and the line number at the same time.
+        const dbg_line = &self.dbg_line;
+        try dbg_line.ensureUnusedCapacity(11);
+        dbg_line.appendAssumeCapacity(DW.LNS.advance_pc);
+        leb128.writeULEB128(dbg_line.writer(), delta_pc) catch unreachable;
+        if (delta_line != 0) {
+            dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
+            leb128.writeILEB128(dbg_line.writer(), delta_line) catch unreachable;
+        }
+        dbg_line.appendAssumeCapacity(DW.LNS.copy);
+    }
+
+    pub fn setPrologueEnd(self: *DeclState) error{OutOfMemory}!void {
+        try self.dbg_line.append(DW.LNS.set_prologue_end);
+    }
+
+    pub fn setEpilogueBegin(self: *DeclState) error{OutOfMemory}!void {
+        try self.dbg_line.append(DW.LNS.set_epilogue_begin);
+    }
 };
 
 pub const AbbrevEntry = struct {