Commit b4427bc300

Jacob Young <jacobly0@users.noreply.github.com>
2023-10-05 01:22:52
plan9: refactor debug info
The main goal is to stop depending on `emit.lower.target`.
1 parent 5a35734
Changed files (6)
src
arch
aarch64
arm
riscv64
x86_64
link
src/arch/aarch64/Emit.zig
@@ -445,25 +445,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
         },
         .plan9 => |dbg_out| {
             if (delta_pc <= 0) return; // only do this when the pc changes
-            // we have already checked the target in the linker to make sure it is compatable
-            const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
 
             // increasing the line number
-            try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);
+            try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
             // increasing the pc
-            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;
+            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
             if (d_pc_p9 > 0) {
-                // minus one because if its the last one, we want to leave space to change the line which is one quanta
-                try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);
-                if (dbg_out.pcop_change_index.*) |pci|
+                // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
+                try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
+                if (dbg_out.pcop_change_index) |pci|
                     dbg_out.dbg_line.items[pci] += 1;
-                dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
+                dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
             } else if (d_pc_p9 == 0) {
-                // we don't need to do anything, because adding the quant does it for us
+                // we don't need to do anything, because adding the pc quanta does it for us
             } else unreachable;
-            if (dbg_out.start_line.* == null)
-                dbg_out.start_line.* = self.prev_di_line;
-            dbg_out.end_line.* = line;
+            if (dbg_out.start_line == null)
+                dbg_out.start_line = self.prev_di_line;
+            dbg_out.end_line = line;
             // only do this if the pc changed
             self.prev_di_line = line;
             self.prev_di_column = column;
src/arch/arm/Emit.zig
@@ -362,25 +362,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
         },
         .plan9 => |dbg_out| {
             if (delta_pc <= 0) return; // only do this when the pc changes
-            // we have already checked the target in the linker to make sure it is compatable
-            const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
 
             // increasing the line number
-            try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);
+            try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
             // increasing the pc
-            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;
+            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
             if (d_pc_p9 > 0) {
-                // minus one because if its the last one, we want to leave space to change the line which is one quanta
-                try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);
-                if (dbg_out.pcop_change_index.*) |pci|
+                // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
+                try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
+                if (dbg_out.pcop_change_index) |pci|
                     dbg_out.dbg_line.items[pci] += 1;
-                dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
+                dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
             } else if (d_pc_p9 == 0) {
-                // we don't need to do anything, because adding the quant does it for us
+                // we don't need to do anything, because adding the pc quanta does it for us
             } else unreachable;
-            if (dbg_out.start_line.* == null)
-                dbg_out.start_line.* = self.prev_di_line;
-            dbg_out.end_line.* = line;
+            if (dbg_out.start_line == null)
+                dbg_out.start_line = self.prev_di_line;
+            dbg_out.end_line = line;
             // only do this if the pc changed
             self.prev_di_line = line;
             self.prev_di_column = column;
src/arch/riscv64/Emit.zig
@@ -96,25 +96,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
         },
         .plan9 => |dbg_out| {
             if (delta_pc <= 0) return; // only do this when the pc changes
-            // we have already checked the target in the linker to make sure it is compatable
-            const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
 
             // increasing the line number
-            try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);
+            try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
             // increasing the pc
-            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;
+            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
             if (d_pc_p9 > 0) {
-                // minus one because if its the last one, we want to leave space to change the line which is one quanta
-                try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);
-                if (dbg_out.pcop_change_index.*) |pci|
+                // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
+                try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
+                if (dbg_out.pcop_change_index) |pci|
                     dbg_out.dbg_line.items[pci] += 1;
-                dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
+                dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
             } else if (d_pc_p9 == 0) {
-                // we don't need to do anything, because adding the quant does it for us
+                // we don't need to do anything, because adding the pc quanta does it for us
             } else unreachable;
-            if (dbg_out.start_line.* == null)
-                dbg_out.start_line.* = self.prev_di_line;
-            dbg_out.end_line.* = line;
+            if (dbg_out.start_line == null)
+                dbg_out.start_line = self.prev_di_line;
+            dbg_out.end_line = line;
             // only do this if the pc changed
             self.prev_di_line = line;
             self.prev_di_column = column;
src/arch/x86_64/Emit.zig
@@ -242,16 +242,14 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
         },
         .plan9 => |dbg_out| {
             if (delta_pc <= 0) return; // only do this when the pc changes
-            // we have already checked the target in the linker to make sure it is compatable
-            const quant = @import("../../link/Plan9/aout.zig").getPCQuant(emit.lower.target.cpu.arch) catch unreachable;
 
             // increasing the line number
-            try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);
+            try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
             // increasing the pc
-            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;
+            const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
             if (d_pc_p9 > 0) {
-                // minus one because if its the last one, we want to leave space to change the line which is one quanta
-                var diff = @divExact(d_pc_p9, quant) - quant;
+                // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
+                var diff = @divExact(d_pc_p9, dbg_out.pc_quanta) - dbg_out.pc_quanta;
                 while (diff > 0) {
                     if (diff < 64) {
                         try dbg_out.dbg_line.append(@as(u8, @intCast(diff + 128)));
@@ -261,15 +259,15 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
                         diff -= 64;
                     }
                 }
-                if (dbg_out.pcop_change_index.*) |pci|
+                if (dbg_out.pcop_change_index) |pci|
                     dbg_out.dbg_line.items[pci] += 1;
-                dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
+                dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
             } else if (d_pc_p9 == 0) {
-                // we don't need to do anything, because adding the quant does it for us
+                // we don't need to do anything, because adding the pc quanta does it for us
             } else unreachable;
-            if (dbg_out.start_line.* == null)
-                dbg_out.start_line.* = emit.prev_di_line;
-            dbg_out.end_line.* = line;
+            if (dbg_out.start_line == null)
+                dbg_out.start_line = emit.prev_di_line;
+            dbg_out.end_line = line;
             // only do this if the pc changed
             emit.prev_di_line = line;
             emit.prev_di_column = column;
src/link/Plan9.zig
@@ -211,6 +211,31 @@ pub const Atom = struct {
     }
 };
 
+/// the plan9 debuginfo output is a bytecode with 4 opcodes
+/// assume all numbers/variables are bytes
+/// 0 w x y z -> interpret w x y z as a big-endian i32, and add it to the line offset
+/// x when x < 65 -> add x to line offset
+/// x when x < 129 -> subtract 64 from x and subtract it from the line offset
+/// x -> subtract 129 from x, multiply it by the quanta of the instruction size
+/// (1 on x86_64), and add it to the pc
+/// after every opcode, add the quanta of the instruction size to the pc
+pub const DebugInfoOutput = struct {
+    /// the actual opcodes
+    dbg_line: std.ArrayList(u8),
+    /// what line the debuginfo starts on
+    /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
+    start_line: ?u32,
+    /// what the line count ends on after codegen
+    /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
+    end_line: u32,
+    /// the last pc change op
+    /// This is very useful for adding quanta
+    /// to it if its not actually the last one.
+    pcop_change_index: ?u32,
+    /// cached pc quanta
+    pc_quanta: u8,
+};
+
 const DeclMetadata = struct {
     index: Atom.Index,
     exports: std.ArrayListUnmanaged(usize) = .{},
@@ -376,11 +401,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
 
     var code_buffer = std.ArrayList(u8).init(self.base.allocator);
     defer code_buffer.deinit();
-    var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator);
-    defer dbg_line_buffer.deinit();
-    var start_line: ?u32 = null;
-    var end_line: u32 = undefined;
-    var pcop_change_index: ?u32 = null;
+    var dbg_info_output: DebugInfoOutput = .{
+        .dbg_line = std.ArrayList(u8).init(self.base.allocator),
+        .start_line = null,
+        .end_line = undefined,
+        .pcop_change_index = null,
+        // we have already checked the target in the linker to make sure it is compatable
+        .pc_quanta = aout.getPCQuant(self.base.options.target.cpu.arch) catch unreachable,
+    };
+    defer dbg_info_output.dbg_line.deinit();
 
     const res = try codegen.generateFunction(
         &self.base,
@@ -389,14 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
         air,
         liveness,
         &code_buffer,
-        .{
-            .plan9 = .{
-                .dbg_line = &dbg_line_buffer,
-                .end_line = &end_line,
-                .start_line = &start_line,
-                .pcop_change_index = &pcop_change_index,
-            },
-        },
+        .{ .plan9 = &dbg_info_output },
     );
     const code = switch (res) {
         .ok => try code_buffer.toOwnedSlice(),
@@ -412,9 +434,9 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
     };
     const out: FnDeclOutput = .{
         .code = code,
-        .lineinfo = try dbg_line_buffer.toOwnedSlice(),
-        .start_line = start_line.?,
-        .end_line = end_line,
+        .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),
+        .start_line = dbg_info_output.start_line.?,
+        .end_line = dbg_info_output.end_line,
     };
     try self.putFn(decl_index, out);
     return self.updateFinish(decl_index);
src/codegen.zig
@@ -40,28 +40,7 @@ pub const CodeGenError = error{
 
 pub const DebugInfoOutput = union(enum) {
     dwarf: *link.File.Dwarf.DeclState,
-    /// the plan9 debuginfo output is a bytecode with 4 opcodes
-    /// assume all numbers/variables are bytes
-    /// 0 w x y z -> interpret w x y z as a big-endian i32, and add it to the line offset
-    /// x when x < 65 -> add x to line offset
-    /// x when x < 129 -> subtract 64 from x and subtract it from the line offset
-    /// x -> subtract 129 from x, multiply it by the quanta of the instruction size
-    /// (1 on x86_64), and add it to the pc
-    /// after every opcode, add the quanta of the instruction size to the pc
-    plan9: struct {
-        /// the actual opcodes
-        dbg_line: *std.ArrayList(u8),
-        /// what line the debuginfo starts on
-        /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
-        start_line: *?u32,
-        /// what the line count ends on after codegen
-        /// this helps because the linker might have to insert some opcodes to make sure that the line count starts at the right amount for the next decl
-        end_line: *u32,
-        /// the last pc change op
-        /// This is very useful for adding quanta
-        /// to it if its not actually the last one.
-        pcop_change_index: *?u32,
-    },
+    plan9: *link.File.Plan9.DebugInfoOutput,
     none,
 };