From b47530b9fef28d32747b0f6978ad4b71e5fc5df9 Mon Sep 17 00:00:00 2001 From: Jacob G-W Date: Sun, 2 Jan 2022 15:52:25 -0500 Subject: [PATCH] plan9: fix .z symbol in debuginfo This allows the `acid` debugger on plan9 to be used to debug a zig source file without patching `acid`! The patch adds a second `z` symbol. This z symbol has a value of 0, which means that it pops the history stack. We put a very large number for the value of the second symbol because it has to be at least as large as the linecount of the file. The debuginfo format is meant to be used with c files, where the stack would look something like this: ``` -> Line: 0x1 (1) Name: 0x1/0x2/0x3/0xe/0x13/0x1b (/sys/src/libc/port/malloc.c) -> Line: 0x2 (2) Name: 0x1/0x6/0x7/0x8 (/amd64/include/u.h) -> Line: 0x4f (79) Name: () -> Line: 0x50 (80) Name: 0x1/0x2/0x7/0x9 (/sys/include/libc.h) -> Line: 0x358 (856) Name: () -> Line: 0x359 (857) Name: 0x1/0x2/0x7/0x1c (/sys/include/pool.h) -> Line: 0x392 (914) Name: () -> Line: 0x393 (915) Name: 0x1/0x2/0x7/0x1d (/sys/include/tos.h) -> Line: 0x3ab (939) Name: () -> Line: 0x4eb (1259) Name: () ``` however in zig, we do not use includes and .h files, so we only need the first and last items in the stack: the source file that the symbols belong to, and the pop symbol with a null name and a value of the total linecount of the preprocessed source. Since there is no preprocessing in zig, we just make the linecount very large. There do not appear to be any downsides to this approach. If this causes a bug in the future, a simple fix would be to make the pop symbol just have the value of how many newlines are in the source file. --- src/link/Plan9.zig | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/link/Plan9.zig b/src/link/Plan9.zig index 362a966c31..4493ae4d5b 100644 --- a/src/link/Plan9.zig +++ b/src/link/Plan9.zig @@ -172,6 +172,7 @@ fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void { // each file gets a symbol fn_map_res.value_ptr.* = .{ .sym_index = blk: { + try self.syms.append(gpa, undefined); try self.syms.append(gpa, undefined); break :blk @intCast(u32, self.syms.items.len - 1); }, @@ -194,11 +195,17 @@ fn putFn(self: *Plan9, decl: *Module.Decl, out: FnDeclOutput) !void { // null terminate try a.append(0); const final = a.toOwnedSlice(); - self.syms.items[fn_map_res.value_ptr.sym_index] = .{ + self.syms.items[fn_map_res.value_ptr.sym_index - 1] = .{ .type = .z, .value = 1, .name = final, }; + self.syms.items[fn_map_res.value_ptr.sym_index] = .{ + .type = .z, + // just put a giant number, no source file will have this many newlines + .value = std.math.maxInt(u32), + .name = &.{ 0, 0 }, + }; } } @@ -705,7 +712,8 @@ pub fn writeSyms(self: *Plan9, buf: *std.ArrayList(u8)) !void { var it_file = self.fn_decl_table.iterator(); while (it_file.next()) |fentry| { var symidx_and_submap = fentry.value_ptr; - // write the z symbol + // write the z symbols + try self.writeSym(writer, self.syms.items[symidx_and_submap.sym_index - 1]); try self.writeSym(writer, self.syms.items[symidx_and_submap.sym_index]); // write all the decls come from the file of the z symbol