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 {
445445 },
446446 .plan9 => |dbg_out| {
447447 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
451449 // 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);
453451 // 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;
455453 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 quanta
457 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);
458 if (dbg_out.pcop_change_index.*) |pci|
454 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
455 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
456 if (dbg_out.pcop_change_index) |pci|
459457 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));
461459 } else if (d_pc_p9 == 0) {
462 // we don't need to do anything, because adding the quant does it for us
460 // we don't need to do anything, because adding the pc quanta does it for us
463461 } else unreachable;
464 if (dbg_out.start_line.* == null)
465 dbg_out.start_line.* = self.prev_di_line;
466 dbg_out.end_line.* = line;
462 if (dbg_out.start_line == null)
463 dbg_out.start_line = self.prev_di_line;
464 dbg_out.end_line = line;
467465 // only do this if the pc changed
468466 self.prev_di_line = line;
469467 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 {
362362 },
363363 .plan9 => |dbg_out| {
364364 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
368366 // 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);
370368 // 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;
372370 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 quanta
374 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);
375 if (dbg_out.pcop_change_index.*) |pci|
371 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
372 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
373 if (dbg_out.pcop_change_index) |pci|
376374 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));
378376 } else if (d_pc_p9 == 0) {
379 // we don't need to do anything, because adding the quant does it for us
377 // we don't need to do anything, because adding the pc quanta does it for us
380378 } else unreachable;
381 if (dbg_out.start_line.* == null)
382 dbg_out.start_line.* = self.prev_di_line;
383 dbg_out.end_line.* = line;
379 if (dbg_out.start_line == null)
380 dbg_out.start_line = self.prev_di_line;
381 dbg_out.end_line = line;
384382 // only do this if the pc changed
385383 self.prev_di_line = line;
386384 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 {
9696 },
9797 .plan9 => |dbg_out| {
9898 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
102100 // 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);
104102 // 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;
106104 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 quanta
108 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, quant) + 128)) - quant);
109 if (dbg_out.pcop_change_index.*) |pci|
105 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
106 try dbg_out.dbg_line.append(@as(u8, @intCast(@divExact(d_pc_p9, dbg_out.pc_quanta) + 128)) - dbg_out.pc_quanta);
107 if (dbg_out.pcop_change_index) |pci|
110108 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));
112110 } else if (d_pc_p9 == 0) {
113 // we don't need to do anything, because adding the quant does it for us
111 // we don't need to do anything, because adding the pc quanta does it for us
114112 } else unreachable;
115 if (dbg_out.start_line.* == null)
116 dbg_out.start_line.* = self.prev_di_line;
117 dbg_out.end_line.* = line;
113 if (dbg_out.start_line == null)
114 dbg_out.start_line = self.prev_di_line;
115 dbg_out.end_line = line;
118116 // only do this if the pc changed
119117 self.prev_di_line = line;
120118 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 {
242242 },
243243 .plan9 => |dbg_out| {
244244 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
248246 // 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);
250248 // 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;
252250 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 quanta
254 var diff = @divExact(d_pc_p9, quant) - quant;
251 // minus one because if its the last one, we want to leave space to change the line which is one pc quanta
252 var diff = @divExact(d_pc_p9, dbg_out.pc_quanta) - dbg_out.pc_quanta;
255253 while (diff > 0) {
256254 if (diff < 64) {
257255 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 {
261259 diff -= 64;
262260 }
263261 }
264 if (dbg_out.pcop_change_index.*) |pci|
262 if (dbg_out.pcop_change_index) |pci|
265263 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));
267265 } else if (d_pc_p9 == 0) {
268 // we don't need to do anything, because adding the quant does it for us
266 // we don't need to do anything, because adding the pc quanta does it for us
269267 } else unreachable;
270 if (dbg_out.start_line.* == null)
271 dbg_out.start_line.* = emit.prev_di_line;
272 dbg_out.end_line.* = line;
268 if (dbg_out.start_line == null)
269 dbg_out.start_line = emit.prev_di_line;
270 dbg_out.end_line = line;
273271 // only do this if the pc changed
274272 emit.prev_di_line = line;
275273 emit.prev_di_column = column;
src/codegen.zig+1-22
......@@ -40,28 +40,7 @@ pub const CodeGenError = error{
4040
4141pub const DebugInfoOutput = union(enum) {
4242 dwarf: *link.File.Dwarf.DeclState,
43 /// the plan9 debuginfo output is a bytecode with 4 opcodes
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 },
43 plan9: *link.File.Plan9.DebugInfoOutput,
6544 none,
6645};
6746
src/link/Plan9.zig+38-16
......@@ -211,6 +211,31 @@ pub const Atom = struct {
211211 }
212212};
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
214239const DeclMetadata = struct {
215240 index: Atom.Index,
216241 exports: std.ArrayListUnmanaged(usize) = .{},
......@@ -376,11 +401,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
376401
377402 var code_buffer = std.ArrayList(u8).init(self.base.allocator);
378403 defer code_buffer.deinit();
379 var dbg_line_buffer = std.ArrayList(u8).init(self.base.allocator);
380 defer dbg_line_buffer.deinit();
381 var start_line: ?u32 = null;
382 var end_line: u32 = undefined;
383 var pcop_change_index: ?u32 = null;
404 var dbg_info_output: DebugInfoOutput = .{
405 .dbg_line = std.ArrayList(u8).init(self.base.allocator),
406 .start_line = null,
407 .end_line = undefined,
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
385414 const res = try codegen.generateFunction(
386415 &self.base,
......@@ -389,14 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
389418 air,
390419 liveness,
391420 &code_buffer,
392 .{
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 },
421 .{ .plan9 = &dbg_info_output },
400422 );
401423 const code = switch (res) {
402424 .ok => try code_buffer.toOwnedSlice(),
......@@ -412,9 +434,9 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
412434 };
413435 const out: FnDeclOutput = .{
414436 .code = code,
415 .lineinfo = try dbg_line_buffer.toOwnedSlice(),
416 .start_line = start_line.?,
417 .end_line = end_line,
437 .lineinfo = try dbg_info_output.dbg_line.toOwnedSlice(),
438 .start_line = dbg_info_output.start_line.?,
439 .end_line = dbg_info_output.end_line,
418440 };
419441 try self.putFn(decl_index, out);
420442 return self.updateFinish(decl_index);