| author | |
| committer | |
| log | b4427bc300cd768721891e6747e59102c8cb06fc |
| tree | 6224f3695774579ca783e92f0c49b8f4b54f334d |
| parent | 5a35734a48fddec7fa58a10be01b045c49099145 |
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 changes | 447 | 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; | ||
| 450 | 448 | ||
| 451 | // increasing the line number | 449 | // 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 pc | 451 | // 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 quanta | 454 | // 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 us | 460 | // 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 changed | 465 | // 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 changes | 364 | 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; | ||
| 367 | 365 | ||
| 368 | // increasing the line number | 366 | // 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 pc | 368 | // 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 quanta | 371 | // 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 us | 377 | // 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 changed | 382 | // 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 changes | 98 | 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; | ||
| 101 | 99 | ||
| 102 | // increasing the line number | 100 | // 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 pc | 102 | // 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 quanta | 105 | // 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 us | 111 | // 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 changed | 116 | // 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 changes | 244 | 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; | ||
| 247 | 245 | ||
| 248 | // increasing the line number | 246 | // 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 pc | 248 | // 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 quanta | 251 | // 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 us | 266 | // 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 changed | 271 | // 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{ |
| 40 | 40 | ||
| 41 | pub const DebugInfoOutput = union(enum) { | 41 | pub 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 opcodes | 43 | 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 | }; |
| 67 | 46 |
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 | }; |
| 213 | 213 | ||
| 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 | ||
| 222 | pub 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 | |||
| 214 | const DeclMetadata = struct { | 239 | const 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: |
| 376 | 401 | ||
| 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(); | ||
| 384 | 413 | ||
| 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); |