dwarf: use common DI union object for arg and var gen

This commit is contained in:
Jakub Konka 2022-12-02 12:22:17 +01:00
parent 8fea84f77e
commit 3ec0520bac
6 changed files with 83 additions and 87 deletions

View File

@ -185,28 +185,26 @@ const DbgInfoReloc = struct {
const atom = function.getDbgInfoAtomPtr();
switch (function.debug_output) {
.dwarf => |dw| switch (reloc.mcv) {
.register => |reg| try dw.genArgDbgInfo(reloc.name, reloc.ty, atom, .{
.register = reg.dwarfLocOp(),
}),
.stack_offset,
.stack_argument_offset,
=> |offset| {
const adjusted_offset = switch (reloc.mcv) {
.stack_offset => -@intCast(i32, offset),
.stack_argument_offset => @intCast(i32, function.saved_regs_stack_space + offset),
else => unreachable,
};
try dw.genArgDbgInfo(reloc.name, reloc.ty, atom, .{
.stack = .{
.dwarf => |dw| {
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
.register => |reg| .{ .register = reg.dwarfLocOp() },
.stack_offset,
.stack_argument_offset,
=> |offset| blk: {
const adjusted_offset = switch (reloc.mcv) {
.stack_offset => -@intCast(i32, offset),
.stack_argument_offset => @intCast(i32, function.saved_regs_stack_space + offset),
else => unreachable,
};
break :blk .{ .stack = .{
.fp_register = Register.x29.dwarfLocOpDeref(),
.offset = adjusted_offset,
},
});
},
} };
},
else => unreachable, // not a possible argument
else => unreachable, // not a possible argument
};
try dw.genArgDbgInfo(reloc.name, reloc.ty, atom, loc);
},
.plan9 => {},
.none => {},
@ -223,10 +221,8 @@ const DbgInfoReloc = struct {
switch (function.debug_output) {
.dwarf => |dw| {
const loc: link.File.Dwarf.DeclState.VarArgDbgInfoLoc = switch (reloc.mcv) {
.register => |reg| .{
.register = reg.dwarfLocOp(),
},
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (reloc.mcv) {
.register => |reg| .{ .register = reg.dwarfLocOp() },
.ptr_stack_offset,
.stack_offset,
.stack_argument_offset,

View File

@ -4036,26 +4036,26 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, arg_index: u32) error{OutOfMe
const atom = self.getDbgInfoAtom();
switch (self.debug_output) {
.dwarf => |dw| switch (mcv) {
.register => |reg| try dw.genArgDbgInfo(name, ty, atom, .{
.register = reg.dwarfLocOp(),
}),
.stack_offset,
.stack_argument_offset,
=> {
const adjusted_stack_offset = switch (mcv) {
.stack_offset => |offset| -@intCast(i32, offset),
.stack_argument_offset => |offset| @intCast(i32, self.saved_regs_stack_space + offset),
else => unreachable,
};
try dw.genArgDbgInfo(name, ty, atom, .{
.stack = .{
.dwarf => |dw| {
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
.register => |reg| .{ .register = reg.dwarfLocOp() },
.stack_offset,
.stack_argument_offset,
=> blk: {
const adjusted_stack_offset = switch (mcv) {
.stack_offset => |offset| -@intCast(i32, offset),
.stack_argument_offset => |offset| @intCast(i32, self.saved_regs_stack_space + offset),
else => unreachable,
};
break :blk .{ .stack = .{
.fp_register = DW.OP.breg11,
.offset = adjusted_stack_offset,
},
});
},
else => unreachable, // not a possible argument
} };
},
else => unreachable, // not a possible argument
};
try dw.genArgDbgInfo(name, ty, atom, loc);
},
.plan9 => {},
.none => {},

View File

@ -1602,17 +1602,10 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void {
return self.fail("TODO implement codegen airFieldParentPtr", .{});
}
fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {
fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32) !void {
const ty = self.air.instructions.items(.data)[inst].ty;
const name = self.mod_fn.getParamName(self.bin_file.options.module.?, arg_index);
const mod = self.bin_file.options.module.?;
const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom = switch (self.bin_file.tag) {
.elf => &fn_owner_decl.link.elf.dbg_info_atom,
.macho => &fn_owner_decl.link.macho.dbg_info_atom,
else => unreachable,
};
const atom = self.getDbgIntoAtomPtr();
switch (self.debug_output) {
.dwarf => |dw| switch (mcv) {
@ -1627,6 +1620,17 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32
}
}
fn getDbgIntoAtomPtr(self: Self) *link.File.Dwarf.Atom {
const mod = self.bin_file.options.module.?;
const fn_owner_decl = mod.declPtr(self.mod_fn.owner_decl);
const atom = switch (self.bin_file.tag) {
.elf => &fn_owner_decl.link.elf.dbg_info_atom,
.macho => &fn_owner_decl.link.macho.dbg_info_atom,
else => unreachable,
};
return atom;
}
fn airArg(self: *Self, inst: Air.Inst.Index) !void {
const arg_index = self.arg_index;
self.arg_index += 1;

View File

@ -5327,7 +5327,7 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
log.debug(" var name = ({s})", .{name});
const atom = func.getDbgInfoAtom();
const loc: link.File.Dwarf.DeclState.VarArgDbgInfoLoc = switch (operand) {
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (operand) {
.local => |local| .{ .wasm_local = local.value },
else => blk: {
log.debug("TODO generate debug info for {}", .{operand});

View File

@ -3818,18 +3818,19 @@ fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void {
const atom = self.getDbgInfoAtomPtr();
switch (self.debug_output) {
.dwarf => |dw| switch (mcv) {
.register => |reg| try dw.genArgDbgInfo(name, ty, atom, .{
.register = reg.dwarfLocOp(),
}),
.stack_offset => |off| try dw.genArgDbgInfo(name, ty, atom, .{
.stack = .{
.fp_register = Register.rbp.dwarfLocOpDeref(), // TODO handle -fomit-frame-pointer
.offset = -off,
.dwarf => |dw| {
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
.register => |reg| .{ .register = reg.dwarfLocOp() },
.stack_offset => |off| .{
.stack = .{
// TODO handle -fomit-frame-pointer
.fp_register = Register.rbp.dwarfLocOpDeref(),
.offset = -off,
},
},
}),
else => unreachable, // not a valid function parameter
else => unreachable, // not a valid function parameter
};
try dw.genArgDbgInfo(name, ty, atom, loc);
},
.plan9 => {},
.none => {},
@ -3852,10 +3853,8 @@ fn genVarDbgInfo(
switch (self.debug_output) {
.dwarf => |dw| {
const loc: link.File.Dwarf.DeclState.VarArgDbgInfoLoc = switch (mcv) {
.register => |reg| .{
.register = reg.dwarfLocOp(),
},
const loc: link.File.Dwarf.DeclState.DbgInfoLoc = switch (mcv) {
.register => |reg| .{ .register = reg.dwarfLocOp() },
.ptr_stack_offset,
.stack_offset,
=> |off| .{ .stack = .{

View File

@ -562,16 +562,27 @@ pub const DeclState = struct {
}
}
pub const DbgInfoLoc = union(enum) {
register: u8,
stack: struct {
fp_register: u8,
offset: i32,
},
wasm_local: u32,
memory: u64,
linker_load: LinkerLoad,
immediate: u64,
undef,
none,
nop,
};
pub fn genArgDbgInfo(
self: *DeclState,
name: [:0]const u8,
ty: Type,
atom: *Atom,
loc: union(enum) {
register: u8,
stack: struct { fp_register: u8, offset: i32 },
wasm_local: u32,
},
loc: DbgInfoLoc,
) error{OutOfMemory}!void {
const dbg_info = &self.dbg_info;
const name_with_null = name.ptr[0 .. name.len + 1];
@ -612,6 +623,7 @@ pub const DeclState = struct {
});
leb128.writeULEB128(dbg_info.writer(), value) catch unreachable;
},
else => unreachable,
}
try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
@ -621,28 +633,13 @@ pub const DeclState = struct {
dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
}
pub const VarArgDbgInfoLoc = union(enum) {
register: u8,
stack: struct {
fp_register: u8,
offset: i32,
},
wasm_local: u32,
memory: u64,
linker_load: LinkerLoad,
immediate: u64,
undef,
none,
nop,
};
pub fn genVarDbgInfo(
self: *DeclState,
name: [:0]const u8,
ty: Type,
atom: *Atom,
is_ptr: bool,
loc: VarArgDbgInfoLoc,
loc: DbgInfoLoc,
) error{OutOfMemory}!void {
const dbg_info = &self.dbg_info;
const name_with_null = name.ptr[0 .. name.len + 1];