authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-04 19:22:52-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-10-05 00:19:25-04:00
logb4427bc300cd768721891e6747e59102c8cb06fc
tree6224f3695774579ca783e92f0c49b8f4b54f334d
parent5a35734a48fddec7fa58a10be01b045c49099145

plan9: refactor debug info

The main goal is to stop depending on `emit.lower.target`.

6 files changed, 79 insertions(+), 86 deletions(-)

src/arch/aarch64/Emit.zig+10-12
...@@ -445,25 +445,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {...@@ -445,25 +445,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
445 },445 },
446 .plan9 => |dbg_out| {446 .plan9 => |dbg_out| {
447 if (delta_pc <= 0) return; // only do this when the pc changes447 if (delta_pc <= 0) return; // only do this when the pc changes
448 // we have already checked the target in the linker to make sure it is compatable
449 const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
450448
451 // increasing the line number449 // increasing the line number
452 try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);450 try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
453 // increasing the pc451 // increasing the pc
454 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;452 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
455 if (d_pc_p9 > 0) {453 if (d_pc_p9 > 0) {
456 // minus one because if its the last one, we want to leave space to change the line which is one quanta454 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
457 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);455 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
458 if (dbg_out.pcop_change_index.*) |pci|456 if (dbg_out.pcop_change_index) |pci|
459 dbg_out.dbg_line.items[pci] += 1;457 dbg_out.dbg_line.items[pci] += 1;
460 dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));458 dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
461 } else if (d_pc_p9 == 0) {459 } else if (d_pc_p9 == 0) {
462 // we don't need to do anything, because adding the quant does it for us460 // we don't need to do anything, because adding the pc quanta does it for us
463 } else unreachable;461 } else unreachable;
464 if (dbg_out.start_line.* == null)462 if (dbg_out.start_line == null)
465 dbg_out.start_line.* = self.prev_di_line;463 dbg_out.start_line = self.prev_di_line;
466 dbg_out.end_line.* = line;464 dbg_out.end_line = line;
467 // only do this if the pc changed465 // only do this if the pc changed
468 self.prev_di_line = line;466 self.prev_di_line = line;
469 self.prev_di_column = column;467 self.prev_di_column = column;
src/arch/arm/Emit.zig+10-12
...@@ -362,25 +362,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {...@@ -362,25 +362,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
362 },362 },
363 .plan9 => |dbg_out| {363 .plan9 => |dbg_out| {
364 if (delta_pc <= 0) return; // only do this when the pc changes364 if (delta_pc <= 0) return; // only do this when the pc changes
365 // we have already checked the target in the linker to make sure it is compatable
366 const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
367365
368 // increasing the line number366 // increasing the line number
369 try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);367 try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
370 // increasing the pc368 // increasing the pc
371 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;369 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
372 if (d_pc_p9 > 0) {370 if (d_pc_p9 > 0) {
373 // minus one because if its the last one, we want to leave space to change the line which is one quanta371 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
374 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);372 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
375 if (dbg_out.pcop_change_index.*) |pci|373 if (dbg_out.pcop_change_index) |pci|
376 dbg_out.dbg_line.items[pci] += 1;374 dbg_out.dbg_line.items[pci] += 1;
377 dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));375 dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
378 } else if (d_pc_p9 == 0) {376 } else if (d_pc_p9 == 0) {
379 // we don't need to do anything, because adding the quant does it for us377 // we don't need to do anything, because adding the pc quanta does it for us
380 } else unreachable;378 } else unreachable;
381 if (dbg_out.start_line.* == null)379 if (dbg_out.start_line == null)
382 dbg_out.start_line.* = self.prev_di_line;380 dbg_out.start_line = self.prev_di_line;
383 dbg_out.end_line.* = line;381 dbg_out.end_line = line;
384 // only do this if the pc changed382 // only do this if the pc changed
385 self.prev_di_line = line;383 self.prev_di_line = line;
386 self.prev_di_column = column;384 self.prev_di_column = column;
src/arch/riscv64/Emit.zig+10-12
...@@ -96,25 +96,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {...@@ -96,25 +96,23 @@ fn dbgAdvancePCAndLine(self: *Emit, line: u32, column: u32) !void {
96 },96 },
97 .plan9 => |dbg_out| {97 .plan9 => |dbg_out| {
98 if (delta_pc <= 0) return; // only do this when the pc changes98 if (delta_pc <= 0) return; // only do this when the pc changes
99 // we have already checked the target in the linker to make sure it is compatable
100 const quant = @import("../../link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
10199
102 // increasing the line number100 // increasing the line number
103 try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);101 try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
104 // increasing the pc102 // increasing the pc
105 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;103 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
106 if (d_pc_p9 > 0) {104 if (d_pc_p9 > 0) {
107 // minus one because if its the last one, we want to leave space to change the line which is one quanta105 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
108 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);106 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
109 if (dbg_out.pcop_change_index.*) |pci|107 if (dbg_out.pcop_change_index) |pci|
110 dbg_out.dbg_line.items[pci] += 1;108 dbg_out.dbg_line.items[pci] += 1;
111 dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));109 dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
112 } else if (d_pc_p9 == 0) {110 } else if (d_pc_p9 == 0) {
113 // we don't need to do anything, because adding the quant does it for us111 // we don't need to do anything, because adding the pc quanta does it for us
114 } else unreachable;112 } else unreachable;
115 if (dbg_out.start_line.* == null)113 if (dbg_out.start_line == null)
116 dbg_out.start_line.* = self.prev_di_line;114 dbg_out.start_line = self.prev_di_line;
117 dbg_out.end_line.* = line;115 dbg_out.end_line = line;
118 // only do this if the pc changed116 // only do this if the pc changed
119 self.prev_di_line = line;117 self.prev_di_line = line;
120 self.prev_di_column = column;118 self.prev_di_column = column;
src/arch/x86_64/Emit.zig+10-12
...@@ -242,16 +242,14 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {...@@ -242,16 +242,14 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
242 },242 },
243 .plan9 => |dbg_out| {243 .plan9 => |dbg_out| {
244 if (delta_pc <= 0) return; // only do this when the pc changes244 if (delta_pc <= 0) return; // only do this when the pc changes
245 // we have already checked the target in the linker to make sure it is compatable
246 const quant = @import("../../link/Plan9/aout.zig").getPCQuant(emit.lower.target.cpu.arch) catch unreachable;
247245
248 // increasing the line number246 // increasing the line number
249 try @import("../../link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);247 try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
250 // increasing the pc248 // increasing the pc
251 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - quant;249 const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
252 if (d_pc_p9 > 0) {250 if (d_pc_p9 > 0) {
253 // minus one because if its the last one, we want to leave space to change the line which is one quanta251 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
254 var diff = @divExact(d_pc_p9, quant) - quant;252 var diff = @divExact(d_pc_p9, dbg_out.pc_quanta) - dbg_out.pc_quanta;
255 while (diff > 0) {253 while (diff > 0) {
256 if (diff < 64) {254 if (diff < 64) {
257 try dbg_out.dbg_line.append(@as(u8, @intCast(diff + 128)));255 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 {...@@ -261,15 +259,15 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
261 diff -= 64;259 diff -= 64;
262 }260 }
263 }261 }
264 if (dbg_out.pcop_change_index.*) |pci|262 if (dbg_out.pcop_change_index) |pci|
265 dbg_out.dbg_line.items[pci] += 1;263 dbg_out.dbg_line.items[pci] += 1;
266 dbg_out.pcop_change_index.* = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));264 dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
267 } else if (d_pc_p9 == 0) {265 } else if (d_pc_p9 == 0) {
268 // we don't need to do anything, because adding the quant does it for us266 // we don't need to do anything, because adding the pc quanta does it for us
269 } else unreachable;267 } else unreachable;
270 if (dbg_out.start_line.* == null)268 if (dbg_out.start_line == null)
271 dbg_out.start_line.* = emit.prev_di_line;269 dbg_out.start_line = emit.prev_di_line;
272 dbg_out.end_line.* = line;270 dbg_out.end_line = line;
273 // only do this if the pc changed271 // only do this if the pc changed
274 emit.prev_di_line = line;272 emit.prev_di_line = line;
275 emit.prev_di_column = column;273 emit.prev_di_column = column;
src/codegen.zig+1-22
...@@ -40,28 +40,7 @@ pub const CodeGenError = error{...@@ -40,28 +40,7 @@ pub const CodeGenError = error{
4040
41pub const DebugInfoOutput = union(enum) {41pub const DebugInfoOutput = union(enum) {
42 dwarf: *link.File.Dwarf.DeclState,42 dwarf: *link.File.Dwarf.DeclState,
43 /// the plan9 debuginfo output is a bytecode with 4 opcodes43 plan9: *link.File.Plan9.DebugInfoOutput,
44 /// assume all numbers/variables are bytes
45 /// 0 w x y z -> interpret w x y z as a big-endian i32, and add it to the line offset
46 /// x when x < 65 -> add x to line offset
47 /// x when x < 129 -> subtract 64 from x and subtract it from the line offset
48 /// x -> subtract 129 from x, multiply it by the quanta of the instruction size
49 /// (1 on x86_64), and add it to the pc
50 /// after every opcode, add the quanta of the instruction size to the pc
51 plan9: struct {
52 /// the actual opcodes
53 dbg_line: *std.ArrayList(u8),
54 /// what line the debuginfo starts on
55 /// 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
56 start_line: *?u32,
57 /// what the line count ends on after codegen
58 /// 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
59 end_line: *u32,
60 /// the last pc change op
61 /// This is very useful for adding quanta
62 /// to it if its not actually the last one.
63 pcop_change_index: *?u32,
64 },
65 none,44 none,
66};45};
6746
src/link/Plan9.zig+38-16
...@@ -211,6 +211,31 @@ pub const Atom = struct {...@@ -211,6 +211,31 @@ pub const Atom = struct {
211 }211 }
212};212};
213213
214/// the plan9 debuginfo output is a bytecode with 4 opcodes
215/// assume all numbers/variables are bytes
216/// 0 w x y z -> interpret w x y z as a big-endian i32, and add it to the line offset
217/// x when x < 65 -> add x to line offset
218/// x when x < 129 -> subtract 64 from x and subtract it from the line offset
219/// x -> subtract 129 from x, multiply it by the quanta of the instruction size
220/// (1 on x86_64), and add it to the pc
221/// after every opcode, add the quanta of the instruction size to the pc
222pub const DebugInfoOutput = struct {
223 /// the actual opcodes
224 dbg_line: std.ArrayList(u8),
225 /// what line the debuginfo starts on
226 /// 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
227 start_line: ?u32,
228 /// what the line count ends on after codegen
229 /// 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
230 end_line: u32,
231 /// the last pc change op
232 /// This is very useful for adding quanta
233 /// to it if its not actually the last one.
234 pcop_change_index: ?u32,
235 /// cached pc quanta
236 pc_quanta: u8,
237};
238
214const DeclMetadata = struct {239const DeclMetadata = struct {
215 index: Atom.Index,240 index: Atom.Index,
216 exports: std.ArrayListUnmanaged(usize) = .{},241 exports: std.ArrayListUnmanaged(usize) = .{},
...@@ -376,11 +401,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -376,11 +401,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
376401
377 var code_buffer = std.ArrayList(u8).init(self.base.allocator);402 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
378 defer code_buffer.deinit();403 defer code_buffer.deinit();
379 var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator);404 var dbg_info_output: DebugInfoOutput = .{
380 defer dbg_line_buffer.deinit();405 .dbg_line = std.ArrayList(u8).init(self.base.allocator),
381 var start_line: ?u32 = null;406 .start_line = null,
382 var end_line: u32 = undefined;407 .end_line = undefined,
383 var pcop_change_index: ?u32 = null;408 .pcop_change_index = null,
409 // we have already checked the target in the linker to make sure it is compatable
410 .pc_quanta = aout.getPCQuant(self.base.options.target.cpu.arch) catch unreachable,
411 };
412 defer dbg_info_output.dbg_line.deinit();
384413
385 const res = try codegen.generateFunction(414 const res = try codegen.generateFunction(
386 &self.base,415 &self.base,
...@@ -389,14 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -389,14 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
389 air,418 air,
390 liveness,419 liveness,
391 &code_buffer,420 &code_buffer,
392 .{421 .{ .plan9 = &dbg_info_output },
393 .plan9 = .{
394 .dbg_line = &dbg_line_buffer,
395 .end_line = &end_line,
396 .start_line = &start_line,
397 .pcop_change_index = &pcop_change_index,
398 },
399 },
400 );422 );
401 const code = switch (res) {423 const code = switch (res) {
402 .ok => try code_buffer.toOwnedSlice(),424 .ok => try code_buffer.toOwnedSlice(),
...@@ -412,9 +434,9 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:...@@ -412,9 +434,9 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
412 };434 };
413 const out: FnDeclOutput = .{435 const out: FnDeclOutput = .{
414 .code = code,436 .code = code,
415 .lineinfo = try dbg_line_buffer.toOwnedSlice(),437 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),
416 .start_line = start_line.?,438 .start_line = dbg_info_output.start_line.?,
417 .end_line = end_line,439 .end_line = dbg_info_output.end_line,
418 };440 };
419 try self.putFn(decl_index, out);441 try self.putFn(decl_index, out);
420 return self.updateFinish(decl_index);442 return self.updateFinish(decl_index);