diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 52f9a544b1..a335a5e5ad 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -186,22 +186,21 @@ const DbgInfoReloc = struct { } fn genArgDbgInfo(reloc: DbgInfoReloc, function: Self) error{OutOfMemory}!void { - const name_with_null = reloc.name.ptr[0 .. reloc.name.len + 1]; + const mod = function.bin_file.options.module.?; + const fn_owner_decl = mod.declPtr(function.mod_fn.owner_decl); + const atom = switch (function.bin_file.tag) { + .elf => &fn_owner_decl.link.elf.dbg_info_atom, + .macho => &fn_owner_decl.link.macho.dbg_info_atom, + else => unreachable, + }; switch (function.debug_output) { .dwarf => |dw| { - const dbg_info = &dw.dbg_info; switch (reloc.mcv) { .register => |reg| { - try dbg_info.ensureUnusedCapacity(3); - dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); - dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc - 1, // ULEB128 dwarf expression length - reg.dwarfLocOp(), + try dw.genArgDbgInfo(reloc.name, reloc.ty, atom, .{ + .register = reg.dwarfLocOp(), }); - try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); - try function.addDbgInfoTypeReloc(reloc.ty); // DW.AT.type, DW.FORM.ref4 - dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string }, .stack_offset, @@ -212,20 +211,12 @@ const DbgInfoReloc = struct { .stack_argument_offset => @intCast(i32, function.saved_regs_stack_space + offset), else => unreachable, }; - - try dbg_info.ensureUnusedCapacity(8); - dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); - const fixup = dbg_info.items.len; - dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc - 1, // we will backpatch it after we encode the displacement in LEB128 - Register.x29.dwarfLocOpDeref(), // frame pointer + try dw.genArgDbgInfo(reloc.name, reloc.ty, atom, .{ + .stack = .{ + .fp_register = Register.x29.dwarfLocOpDeref(), + .offset = adjusted_offset, + }, }); - leb128.writeILEB128(dbg_info.writer(), adjusted_offset) catch unreachable; - dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); - try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); - try function.addDbgInfoTypeReloc(reloc.ty); // DW.AT.type, DW.FORM.ref4 - dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string - }, else => unreachable, // not a possible argument diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 9efd50aec4..fb40e14d7f 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -3818,38 +3818,27 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { } fn genArgDbgInfo(self: Self, ty: Type, name: [:0]const u8, mcv: MCValue) !void { - const name_with_null = name.ptr[0 .. name.len + 1]; + 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, + }; + switch (self.debug_output) { .dwarf => |dw| { - const dbg_info = &dw.dbg_info; switch (mcv) { - .register => |reg| { - try dbg_info.ensureUnusedCapacity(3); - dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); - dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc - 1, // ULEB128 dwarf expression length - reg.dwarfLocOp(), - }); - try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); - try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 - dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string - }, + .register => |reg| try dw.genArgDbgInfo(name, ty, atom, .{ + .register = reg.dwarfLocOp(), + }), - .stack_offset => |off| { - try dbg_info.ensureUnusedCapacity(8); - dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter)); - const fixup = dbg_info.items.len; - dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc - 1, // we will backpatch it after we encode the displacement in LEB128 - Register.rbp.dwarfLocOpDeref(), // TODO handle -fomit-frame-pointer - }); - leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable; - dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); - try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); - try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 - dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string - - }, + .stack_offset => |off| try dw.genArgDbgInfo(name, ty, atom, .{ + .stack = .{ + .fp_register = Register.rbp.dwarfLocOpDeref(), // TODO handle -fomit-frame-pointer + .offset = -off, + }, + }), else => unreachable, // not a valid function parameter } diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 843d14edd7..299bb57d7e 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -560,6 +560,52 @@ pub const DeclState = struct { }, } } + + 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 }, + }, + ) error{OutOfMemory}!void { + const dbg_info = &self.dbg_info; + const name_with_null = name.ptr[0 .. name.len + 1]; + + switch (loc) { + .register => |reg| { + try dbg_info.ensureUnusedCapacity(3); + dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); + dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc + 1, // ULEB128 dwarf expression length + reg, + }); + try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); + const index = dbg_info.items.len; + try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4 + dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string + + }, + .stack => |info| { + try dbg_info.ensureUnusedCapacity(8); + dbg_info.appendAssumeCapacity(@enumToInt(AbbrevKind.parameter)); + const fixup = dbg_info.items.len; + dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc + 1, // we will backpatch it after we encode the displacement in LEB128 + info.fp_register, // frame pointer + }); + leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable; + dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2); + try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); + const index = dbg_info.items.len; + try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); + dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string + + }, + } + } }; pub const AbbrevEntry = struct {