Skip to content

Commit a2dd0c3

Browse files
authored
Merge pull request #9652 from g-w1/p9d
plan9: emit debug info
2 parents d722f0c + f697e0a commit a2dd0c3

File tree

4 files changed

+414
-70
lines changed

4 files changed

+414
-70
lines changed

src/Module.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3707,7 +3707,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
37073707
mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
37083708
},
37093709
.plan9 => {
3710-
// TODO implement for plan9
3710+
// TODO Look into detecting when this would be unnecessary by storing enough state
3711+
// in `Decl` to notice that the line number did not change.
3712+
mod.comp.work_queue.writeItemAssumeCapacity(.{ .update_line_number = decl });
37113713
},
37123714
.c, .wasm, .spirv => {},
37133715
}

src/codegen.zig

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,28 @@ pub const DebugInfoOutput = union(enum) {
4848
dbg_info: *std.ArrayList(u8),
4949
dbg_info_type_relocs: *link.File.DbgInfoTypeRelocsTable,
5050
},
51+
/// the plan9 debuginfo output is a bytecode with 4 opcodes
52+
/// assume all numbers/variables are bytes
53+
/// 0 w x y z -> interpret w x y z as a big-endian i32, and add it to the line offset
54+
/// x when x < 65 -> add x to line offset
55+
/// x when x < 129 -> subtract 64 from x and subtract it from the line offset
56+
/// x -> subtract 129 from x, multiply it by the quanta of the instruction size
57+
/// (1 on x86_64), and add it to the pc
58+
/// after every opcode, add the quanta of the instruction size to the pc
59+
plan9: struct {
60+
/// the actual opcodes
61+
dbg_line: *std.ArrayList(u8),
62+
/// what line the debuginfo starts on
63+
/// 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
64+
start_line: *?u32,
65+
/// what the line count ends on after codegen
66+
/// 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
67+
end_line: *u32,
68+
/// the last pc change op
69+
/// This is very useful for adding quanta
70+
/// to it if its not actually the last one.
71+
pcop_change_index: *?u32,
72+
},
5173
none,
5274
};
5375

@@ -915,6 +937,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
915937
try dbg_out.dbg_line.append(DW.LNS.set_prologue_end);
916938
try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
917939
},
940+
.plan9 => {},
918941
.none => {},
919942
}
920943
}
@@ -925,15 +948,16 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
925948
try dbg_out.dbg_line.append(DW.LNS.set_epilogue_begin);
926949
try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
927950
},
951+
.plan9 => {},
928952
.none => {},
929953
}
930954
}
931955

932956
fn dbgAdvancePCAndLine(self: *Self, line: u32, column: u32) InnerError!void {
957+
const delta_line = @intCast(i32, line) - @intCast(i32, self.prev_di_line);
958+
const delta_pc: usize = self.code.items.len - self.prev_di_pc;
933959
switch (self.debug_output) {
934960
.dwarf => |dbg_out| {
935-
const delta_line = @intCast(i32, line) - @intCast(i32, self.prev_di_line);
936-
const delta_pc = self.code.items.len - self.prev_di_pc;
937961
// TODO Look into using the DWARF special opcodes to compress this data.
938962
// It lets you emit single-byte opcodes that add different numbers to
939963
// both the PC and the line number at the same time.
@@ -945,12 +969,39 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
945969
leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable;
946970
}
947971
dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.copy);
972+
self.prev_di_pc = self.code.items.len;
973+
self.prev_di_line = line;
974+
self.prev_di_column = column;
975+
self.prev_di_pc = self.code.items.len;
976+
},
977+
.plan9 => |dbg_out| {
978+
if (delta_pc <= 0) return; // only do this when the pc changes
979+
// we have already checked the target in the linker to make sure it is compatable
980+
const quant = @import("link/Plan9/aout.zig").getPCQuant(self.target.cpu.arch) catch unreachable;
981+
982+
// increasing the line number
983+
try @import("link/Plan9.zig").changeLine(dbg_out.dbg_line, delta_line);
984+
// increasing the pc
985+
const d_pc_p9 = @intCast(i64, delta_pc) - quant;
986+
if (d_pc_p9 > 0) {
987+
// minus one becaue if its the last one, we want to leave space to change the line which is one quanta
988+
try dbg_out.dbg_line.append(@intCast(u8, @divExact(d_pc_p9, quant) + 128) - quant);
989+
if (dbg_out.pcop_change_index.*) |pci|
990+
dbg_out.dbg_line.items[pci] += 1;
991+
dbg_out.pcop_change_index.* = @intCast(u32, dbg_out.dbg_line.items.len - 1);
992+
} else if (d_pc_p9 == 0) {
993+
// we don't need to do anything, because adding the quant does it for us
994+
} else unreachable;
995+
if (dbg_out.start_line.* == null)
996+
dbg_out.start_line.* = self.prev_di_line;
997+
dbg_out.end_line.* = line;
998+
// only do this if the pc changed
999+
self.prev_di_line = line;
1000+
self.prev_di_column = column;
1001+
self.prev_di_pc = self.code.items.len;
9481002
},
9491003
.none => {},
9501004
}
951-
self.prev_di_line = line;
952-
self.prev_di_column = column;
953-
self.prev_di_pc = self.code.items.len;
9541005
}
9551006

9561007
/// Asserts there is already capacity to insert into top branch inst_table.
@@ -1034,6 +1085,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
10341085
}
10351086
try gop.value_ptr.relocs.append(self.gpa, @intCast(u32, index));
10361087
},
1088+
.plan9 => {},
10371089
.none => {},
10381090
}
10391091
}
@@ -2459,6 +2511,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24592511
try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
24602512
dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
24612513
},
2514+
.plan9 => {},
24622515
.none => {},
24632516
}
24642517
},
@@ -2493,6 +2546,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24932546
else => {},
24942547
}
24952548
},
2549+
.plan9 => {},
24962550
.none => {},
24972551
}
24982552
},
@@ -2929,6 +2983,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
29292983
}
29302984
if (self.air.value(callee)) |func_value| {
29312985
if (func_value.castTag(.function)) |func_payload| {
2986+
try p9.seeDecl(func_payload.data.owner_decl);
29322987
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
29332988
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
29342989
const got_addr = p9.bases.data;
@@ -2976,6 +3031,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
29763031
}
29773032
if (self.air.value(callee)) |func_value| {
29783033
if (func_value.castTag(.function)) |func_payload| {
3034+
try p9.seeDecl(func_payload.data.owner_decl);
29793035
const ptr_bits = self.target.cpu.arch.ptrBitWidth();
29803036
const ptr_bytes: u64 = @divExact(ptr_bits, 8);
29813037
const got_addr = p9.bases.data;
@@ -4923,6 +4979,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
49234979
const got_addr = coff_file.offset_table_virtual_address + decl.link.coff.offset_table_index * ptr_bytes;
49244980
return MCValue{ .memory = got_addr };
49254981
} else if (self.bin_file.cast(link.File.Plan9)) |p9| {
4982+
try p9.seeDecl(decl);
49264983
const got_addr = p9.bases.data + decl.link.plan9.got_index.? * ptr_bytes;
49274984
return MCValue{ .memory = got_addr };
49284985
} else {

0 commit comments

Comments
 (0)