Commit 5ee99f862a

Jakub Konka <kubkon@jakubkonka.com>
2022-12-01 14:06:24
dwarf: extract common logic for generating func arg dbg info
1 parent fc3142a
Changed files (3)
src
arch
aarch64
x86_64
link
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
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
-                },
-
-                .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
+                .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,
+                    },
+                }),
 
                 else => unreachable, // not a valid function parameter
             }
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 {