| 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 | 445 | }, |
| 446 | 446 | .plan9 => |dbg_out| { |
| 447 | 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 | 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 | 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 | 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 | |
| 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| | |
| 459 | 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 | 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 | 461 | } 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; | |
| 467 | 465 | // only do this if the pc changed |
| 468 | 466 | self.prev_di_line = line; |
| 469 | 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 | 362 | }, |
| 363 | 363 | .plan9 => |dbg_out| { |
| 364 | 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 | 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 | 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 | 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 | |
| 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| | |
| 376 | 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 | 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 | 378 | } 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; | |
| 384 | 382 | // only do this if the pc changed |
| 385 | 383 | self.prev_di_line = line; |
| 386 | 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 | 96 | }, |
| 97 | 97 | .plan9 => |dbg_out| { |
| 98 | 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 | 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 | 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 | 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 | |
| 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| | |
| 110 | 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 | 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 | 112 | } 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; | |
| 118 | 116 | // only do this if the pc changed |
| 119 | 117 | self.prev_di_line = line; |
| 120 | 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 | 242 | }, |
| 243 | 243 | .plan9 => |dbg_out| { |
| 244 | 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 | 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 | 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 | 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 | |
| 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; | |
| 255 | 253 | while (diff > 0) { |
| 256 | 254 | if (diff < 64) { |
| 257 | 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 | 259 | diff -= 64; |
| 262 | 260 | } |
| 263 | 261 | } |
| 264 | if (dbg_out.pcop_change_index.*) |pci| | |
| 262 | if (dbg_out.pcop_change_index) |pci| | |
| 265 | 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 | 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 | 267 | } 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; | |
| 273 | 271 | // only do this if the pc changed |
| 274 | 272 | emit.prev_di_line = line; |
| 275 | 273 | emit.prev_di_column = column; |
src/codegen.zig+1-22| ... | ... | @@ -40,28 +40,7 @@ pub const CodeGenError = error{ |
| 40 | 40 | |
| 41 | 41 | pub const DebugInfoOutput = union(enum) { |
| 42 | 42 | 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, | |
| 65 | 44 | none, |
| 66 | 45 | }; |
| 67 | 46 |
src/link/Plan9.zig+38-16| ... | ... | @@ -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 | 239 | const DeclMetadata = struct { |
| 215 | 240 | index: Atom.Index, |
| 216 | 241 | exports: std.ArrayListUnmanaged(usize) = .{}, |
| ... | ... | @@ -376,11 +401,15 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 376 | 401 | |
| 377 | 402 | var code_buffer = std.ArrayList(u8).init(self.base.allocator); |
| 378 | 403 | 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(); | |
| 384 | 413 | |
| 385 | 414 | const res = try codegen.generateFunction( |
| 386 | 415 | &self.base, |
| ... | ... | @@ -389,14 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 389 | 418 | air, |
| 390 | 419 | liveness, |
| 391 | 420 | &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 }, | |
| 400 | 422 | ); |
| 401 | 423 | const code = switch (res) { |
| 402 | 424 | .ok => try code_buffer.toOwnedSlice(), |
| ... | ... | @@ -412,9 +434,9 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air: |
| 412 | 434 | }; |
| 413 | 435 | const out: FnDeclOutput = .{ |
| 414 | 436 | .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, | |
| 418 | 440 | }; |
| 419 | 441 | try self.putFn(decl_index, out); |
| 420 | 442 | return self.updateFinish(decl_index); |