aboutsummaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorJacob Young <jacobly0@users.noreply.github.com>2023-11-11 16:06:01 -0500
committerAndrew Kelley <andrew@ziglang.org>2023-11-12 03:21:52 -0500
commit2eeb7358227d13ff4d77ef73c54a0e2ae12c1d58 (patch)
tree94660b851f8734a6b9520e6754937bb30511e648 /src/arch
parent3fc6a2f11399e84b9cfa4cfef65ef40aa6de173b (diff)
downloadzig-2eeb7358227d13ff4d77ef73c54a0e2ae12c1d58.tar.gz
zig-2eeb7358227d13ff4d77ef73c54a0e2ae12c1d58.zip
Dwarf: improve x86_64 backend debug info
Closes #17811
Diffstat (limited to 'src/arch')
-rw-r--r--src/arch/x86_64/CodeGen.zig33
-rw-r--r--src/arch/x86_64/Emit.zig33
-rw-r--r--src/arch/x86_64/Lower.zig1
-rw-r--r--src/arch/x86_64/Mir.zig27
4 files changed, 55 insertions, 39 deletions
diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig
index 95eb16c267..49e9b598c1 100644
--- a/src/arch/x86_64/CodeGen.zig
+++ b/src/arch/x86_64/CodeGen.zig
@@ -10576,12 +10576,12 @@ fn genVarDbgInfo(
fn airTrap(self: *Self) !void {
try self.asmOpOnly(.{ ._, .ud2 });
- return self.finishAirBookkeeping();
+ self.finishAirBookkeeping();
}
fn airBreakpoint(self: *Self) !void {
try self.asmOpOnly(.{ ._, .int3 });
- return self.finishAirBookkeeping();
+ self.finishAirBookkeeping();
}
fn airRetAddr(self: *Self, inst: Air.Inst.Index) !void {
@@ -10603,7 +10603,7 @@ fn airFence(self: *Self, inst: Air.Inst.Index) !void {
.Acquire, .Release, .AcqRel => {},
.SeqCst => try self.asmOpOnly(.{ ._, .mfence }),
}
- return self.finishAirBookkeeping();
+ self.finishAirBookkeeping();
}
fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier) !void {
@@ -11419,21 +11419,23 @@ fn airDbgStmt(self: *Self, inst: Air.Inst.Index) !void {
.column = dbg_stmt.column,
} },
});
- return self.finishAirBookkeeping();
+ self.finishAirBookkeeping();
}
fn airDbgInline(self: *Self, inst: Air.Inst.Index) !void {
- const mod = self.bin_file.options.module.?;
const ty_fn = self.air.instructions.items(.data)[inst].ty_fn;
- const func = mod.funcInfo(ty_fn.func);
- // TODO emit debug info for function change
- _ = func;
- return self.finishAir(inst, .unreach, .{ .none, .none, .none });
+ _ = try self.addInst(.{
+ .tag = .pseudo,
+ .ops = .pseudo_dbg_inline_func,
+ .data = .{ .func = ty_fn.func },
+ });
+ self.finishAirBookkeeping();
}
fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
+ _ = inst;
// TODO emit debug info lexical block
- return self.finishAir(inst, .unreach, .{ .none, .none, .none });
+ self.finishAirBookkeeping();
}
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
@@ -11518,9 +11520,8 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void {
.close_scope = true,
});
- // We already took care of pl_op.operand earlier, so we're going
- // to pass .none here
- return self.finishAir(inst, .unreach, .{ .none, .none, .none });
+ // We already took care of pl_op.operand earlier, so there's nothing left to do.
+ self.finishAirBookkeeping();
}
fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MCValue {
@@ -11865,7 +11866,7 @@ fn airLoop(self: *Self, inst: Air.Inst.Index) !void {
});
_ = try self.asmJmpReloc(jmp_target);
- return self.finishAirBookkeeping();
+ self.finishAirBookkeeping();
}
fn airBlock(self: *Self, inst: Air.Inst.Index) !void {
@@ -11977,8 +11978,8 @@ fn airSwitchBr(self: *Self, inst: Air.Inst.Index) !void {
});
}
- // We already took care of pl_op.operand earlier, so we're going to pass .none here
- return self.finishAir(inst, .unreach, .{ .none, .none, .none });
+ // We already took care of pl_op.operand earlier, so there's nothing left to do
+ self.finishAirBookkeeping();
}
fn performReloc(self: *Self, reloc: Mir.Inst.Index) !void {
diff --git a/src/arch/x86_64/Emit.zig b/src/arch/x86_64/Emit.zig
index db951a71a2..aa091a89ad 100644
--- a/src/arch/x86_64/Emit.zig
+++ b/src/arch/x86_64/Emit.zig
@@ -151,7 +151,7 @@ pub fn emitMir(emit: *Emit) Error!void {
else => unreachable,
},
.target = target,
- .offset = @as(u32, @intCast(end_offset - 4)),
+ .offset = @intCast(end_offset - 4),
.addend = 0,
.pcrel = true,
.length = 2,
@@ -173,7 +173,7 @@ pub fn emitMir(emit: *Emit) Error!void {
else => unreachable,
},
.target = target,
- .offset = @as(u32, @intCast(end_offset - 4)),
+ .offset = @intCast(end_offset - 4),
.addend = 0,
.pcrel = true,
.length = 2,
@@ -182,7 +182,7 @@ pub fn emitMir(emit: *Emit) Error!void {
const atom_index = symbol.atom_index;
try p9_file.addReloc(atom_index, .{ // TODO we may need to add a .type field to the relocs if they are .linker_got instead of just .linker_direct
.target = symbol.sym_index, // we set sym_index to just be the atom index
- .offset = @as(u32, @intCast(end_offset - 4)),
+ .offset = @intCast(end_offset - 4),
.addend = 0,
.type = .pcrel,
});
@@ -229,6 +229,18 @@ pub fn emitMir(emit: *Emit) Error!void {
.none => {},
}
},
+ .pseudo_dbg_inline_func => {
+ switch (emit.debug_output) {
+ .dwarf => |dw| {
+ log.debug("mirDbgInline (line={d}, col={d})", .{
+ emit.prev_di_line, emit.prev_di_column,
+ });
+ try dw.setInlineFunc(mir_inst.data.func);
+ },
+ .plan9 => {},
+ .none => {},
+ }
+ },
.pseudo_dead_none => {},
},
}
@@ -269,17 +281,18 @@ fn fixupRelocs(emit: *Emit) Error!void {
for (emit.relocs.items) |reloc| {
const target = emit.code_offset_mapping.get(reloc.target) orelse
return emit.fail("JMP/CALL relocation target not found!", .{});
- const disp = @as(i32, @intCast(@as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length))));
- mem.writeInt(i32, emit.code.items[reloc.offset..][0..4], disp, .little);
+ const disp = @as(i64, @intCast(target)) - @as(i64, @intCast(reloc.source + reloc.length));
+ mem.writeInt(i32, emit.code.items[reloc.offset..][0..4], @intCast(disp), .little);
}
}
fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
- const delta_line = @as(i32, @intCast(line)) - @as(i32, @intCast(emit.prev_di_line));
+ const delta_line = @as(i33, line) - @as(i33, emit.prev_di_line);
const delta_pc: usize = emit.code.items.len - emit.prev_di_pc;
log.debug(" (advance pc={d} and line={d})", .{ delta_line, delta_pc });
switch (emit.debug_output) {
.dwarf => |dw| {
+ if (column != emit.prev_di_column) try dw.setColumn(column);
try dw.advancePCAndLine(delta_line, delta_pc);
emit.prev_di_line = line;
emit.prev_di_column = column;
@@ -289,7 +302,7 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
if (delta_pc <= 0) return; // only do this when the pc changes
// increasing the line number
- try link.File.Plan9.changeLine(&dbg_out.dbg_line, delta_line);
+ try link.File.Plan9.changeLine(&dbg_out.dbg_line, @intCast(delta_line));
// increasing the pc
const d_pc_p9 = @as(i64, @intCast(delta_pc)) - dbg_out.pc_quanta;
if (d_pc_p9 > 0) {
@@ -297,16 +310,16 @@ fn dbgAdvancePCAndLine(emit: *Emit, line: u32, column: u32) Error!void {
var diff = @divExact(d_pc_p9, dbg_out.pc_quanta) - dbg_out.pc_quanta;
while (diff > 0) {
if (diff < 64) {
- try dbg_out.dbg_line.append(@as(u8, @intCast(diff + 128)));
+ try dbg_out.dbg_line.append(@intCast(diff + 128));
diff = 0;
} else {
- try dbg_out.dbg_line.append(@as(u8, @intCast(64 + 128)));
+ try dbg_out.dbg_line.append(@intCast(64 + 128));
diff -= 64;
}
}
if (dbg_out.pcop_change_index) |pci|
dbg_out.dbg_line.items[pci] += 1;
- dbg_out.pcop_change_index = @as(u32, @intCast(dbg_out.dbg_line.items.len - 1));
+ dbg_out.pcop_change_index = @intCast(dbg_out.dbg_line.items.len - 1);
} else if (d_pc_p9 == 0) {
// we don't need to do anything, because adding the pc quanta does it for us
} else unreachable;
diff --git a/src/arch/x86_64/Lower.zig b/src/arch/x86_64/Lower.zig
index 621d61d7f8..935fbe8f46 100644
--- a/src/arch/x86_64/Lower.zig
+++ b/src/arch/x86_64/Lower.zig
@@ -259,6 +259,7 @@ pub fn lowerMir(lower: *Lower, index: Mir.Inst.Index) Error!struct {
.pseudo_dbg_prologue_end_none,
.pseudo_dbg_line_line_column,
.pseudo_dbg_epilogue_begin_none,
+ .pseudo_dbg_inline_func,
.pseudo_dead_none,
=> {},
else => unreachable,
diff --git a/src/arch/x86_64/Mir.zig b/src/arch/x86_64/Mir.zig
index 2e8970eee7..de3db8d224 100644
--- a/src/arch/x86_64/Mir.zig
+++ b/src/arch/x86_64/Mir.zig
@@ -6,19 +6,6 @@
//! The main purpose of MIR is to postpone the assignment of offsets until Isel,
//! so that, for example, the smaller encodings of jump instructions can be used.
-const Mir = @This();
-const std = @import("std");
-const builtin = @import("builtin");
-const assert = std.debug.assert;
-
-const bits = @import("bits.zig");
-const encoder = @import("encoder.zig");
-
-const Air = @import("../../Air.zig");
-const CodeGen = @import("CodeGen.zig");
-const IntegerBitSet = std.bit_set.IntegerBitSet;
-const Register = bits.Register;
-
instructions: std.MultiArrayList(Inst).Slice,
/// The meaning of this data is determined by `Inst.Tag` value.
extra: []const u32,
@@ -884,6 +871,8 @@ pub const Inst = struct {
pseudo_dbg_line_line_column,
/// Start of epilogue
pseudo_dbg_epilogue_begin_none,
+ /// Start or end of inline function
+ pseudo_dbg_inline_func,
/// Tombstone
/// Emitter should skip this instruction.
@@ -987,6 +976,7 @@ pub const Inst = struct {
line: u32,
column: u32,
},
+ func: InternPool.Index,
/// Register list
reg_list: RegisterList,
};
@@ -1198,3 +1188,14 @@ pub fn resolveFrameLoc(mir: Mir, mem: Memory) Memory {
} else mem,
};
}
+
+const assert = std.debug.assert;
+const bits = @import("bits.zig");
+const builtin = @import("builtin");
+const encoder = @import("encoder.zig");
+const std = @import("std");
+
+const IntegerBitSet = std.bit_set.IntegerBitSet;
+const InternPool = @import("../../InternPool.zig");
+const Mir = @This();
+const Register = bits.Register;