From 3ec0520bac74cf750482abae0c8ce09344299613 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Fri, 2 Dec 2022 12:22:17 +0100 Subject: [PATCH] dwarf: use common DI union object for arg and var gen --- src/arch/aarch64/CodeGen.zig | 42 ++++++------- src/arch/arm/CodeGen.zig | 36 +++++------ src/arch/riscv64/CodeGen.zig | 22 ++++--- src/arch/wasm/CodeGen.zig | 2 +- src/arch/x86_64/CodeGen.zig | 29 +++++---- src/link/Dwarf.zig | 119 +++++++++++++++++------------------ 6 files changed, 123 insertions(+), 127 deletions(-) diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index ae24178a5abfb828d2dbd7759ad792ddd11bae8a..7bf0f99a844d960c590a680f783de1122dc4a5a2 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -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, diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 066a82e5a2cc391237840648767f93e4cc78d158..0a19214e48ad6d0ab6fcb52b150974b91bdadf80 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -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 => {}, diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 368c0ba71f3d191343e5543d4d8f913fbf103460..b2c7ac293f5453491a15f60034363a93db69cb22 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -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; diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index ddb1803998f05ae6d8655fbf69d1a83b0ea3b671..6584ad204110bc30797ba99f0c25e472a613c52a 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -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}); diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index 5d9e3ccb5eed25320a83ef5b5d3e1f3b95b469eb..b526743b2a93592cd02ba7358f7030e9bac56cd2 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -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 = .{ diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index feb285732253b64526199452165366817dc937ad..8540b8a542a4d260f1733a5f636709451b994af2 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -562,66 +562,7 @@ 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 }, - wasm_local: u32, - }, - ) 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, - }); - }, - .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); - }, - .wasm_local => |value| { - const leb_size = link.File.Wasm.getULEB128Size(value); - try dbg_info.ensureUnusedCapacity(3 + leb_size); - // wasm locations are encoded as follow: - // DW_OP_WASM_location wasm-op - // where wasm-op is defined as - // wasm-op := wasm-local | wasm-global | wasm-operand_stack - // where each argument is encoded as - // i:uleb128 - dbg_info.appendSliceAssumeCapacity(&.{ - @enumToInt(AbbrevKind.parameter), - DW.OP.WASM_location, - DW.OP.WASM_local, - }); - leb128.writeULEB128(dbg_info.writer(), value) catch unreachable; - }, - } - - try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); - const index = dbg_info.items.len; - try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 - 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 - } - - pub const VarArgDbgInfoLoc = union(enum) { + pub const DbgInfoLoc = union(enum) { register: u8, stack: struct { fp_register: u8, @@ -636,13 +577,69 @@ pub const DeclState = struct { nop, }; + pub fn genArgDbgInfo( + self: *DeclState, + name: [:0]const u8, + ty: Type, + atom: *Atom, + loc: DbgInfoLoc, + ) 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, + }); + }, + .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); + }, + .wasm_local => |value| { + const leb_size = link.File.Wasm.getULEB128Size(value); + try dbg_info.ensureUnusedCapacity(3 + leb_size); + // wasm locations are encoded as follow: + // DW_OP_WASM_location wasm-op + // where wasm-op is defined as + // wasm-op := wasm-local | wasm-global | wasm-operand_stack + // where each argument is encoded as + // i:uleb128 + dbg_info.appendSliceAssumeCapacity(&.{ + @enumToInt(AbbrevKind.parameter), + DW.OP.WASM_location, + DW.OP.WASM_local, + }); + leb128.writeULEB128(dbg_info.writer(), value) catch unreachable; + }, + else => unreachable, + } + + try dbg_info.ensureUnusedCapacity(5 + name_with_null.len); + const index = dbg_info.items.len; + try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4 + 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 + } + 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]; -- 2.54.0