Commit a07f288eb1

Jakub Konka <kubkon@jakubkonka.com>
2023-10-23 14:27:00
dwarf: add missing struct_type sentinel - make DWARF data valid again!
1 parent 4bf27da
Changed files (1)
src
src/link/Dwarf.zig
@@ -282,44 +282,19 @@ pub const DeclState = struct {
                 // DW.AT.array_type delimit children
                 try dbg_info_buffer.append(0);
             },
-            .Struct => blk: {
+            .Struct => {
                 // DW.AT.structure_type
                 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_type));
                 // DW.AT.byte_size, DW.FORM.udata
                 try leb128.writeULEB128(dbg_info_buffer.writer(), ty.abiSize(mod));
 
-                switch (ip.indexToKey(ty.ip_index)) {
-                    .anon_struct_type => |fields| {
-                        // DW.AT.name, DW.FORM.string
-                        try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
-
-                        for (fields.types.get(ip), 0..) |field_ty, field_index| {
-                            // DW.AT.member
-                            try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
+                blk: {
+                    switch (ip.indexToKey(ty.ip_index)) {
+                        .anon_struct_type => |fields| {
                             // DW.AT.name, DW.FORM.string
-                            try dbg_info_buffer.writer().print("{d}\x00", .{field_index});
-                            // DW.AT.type, DW.FORM.ref4
-                            var index = dbg_info_buffer.items.len;
-                            try dbg_info_buffer.resize(index + 4);
-                            try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index)));
-                            // DW.AT.data_member_location, DW.FORM.udata
-                            const field_off = ty.structFieldOffset(field_index, mod);
-                            try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
-                        }
-                    },
-                    .struct_type => |struct_type| {
-                        // DW.AT.name, DW.FORM.string
-                        try ty.print(dbg_info_buffer.writer(), mod);
-                        try dbg_info_buffer.append(0);
-
-                        if (struct_type.layout == .Packed) {
-                            log.debug("TODO implement .debug_info for packed structs", .{});
-                            break :blk;
-                        }
+                            try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)});
 
-                        if (struct_type.isTuple(ip)) {
-                            for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {
-                                if (!field_ty.toType().hasRuntimeBits(mod)) continue;
+                            for (fields.types.get(ip), 0..) |field_ty, field_index| {
                                 // DW.AT.member
                                 try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
                                 // DW.AT.name, DW.FORM.string
@@ -329,32 +304,59 @@ pub const DeclState = struct {
                                 try dbg_info_buffer.resize(index + 4);
                                 try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index)));
                                 // DW.AT.data_member_location, DW.FORM.udata
+                                const field_off = ty.structFieldOffset(field_index, mod);
                                 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
                             }
-                        } else {
-                            for (
-                                struct_type.field_names.get(ip),
-                                struct_type.field_types.get(ip),
-                                struct_type.offsets.get(ip),
-                            ) |field_name_ip, field_ty, field_off| {
-                                if (!field_ty.toType().hasRuntimeBits(mod)) continue;
-                                const field_name = ip.stringToSlice(field_name_ip);
-                                // DW.AT.member
-                                try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
-                                dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));
-                                // DW.AT.name, DW.FORM.string
-                                dbg_info_buffer.appendSliceAssumeCapacity(field_name);
-                                dbg_info_buffer.appendAssumeCapacity(0);
-                                // DW.AT.type, DW.FORM.ref4
-                                var index = dbg_info_buffer.items.len;
-                                try dbg_info_buffer.resize(index + 4);
-                                try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));
-                                // DW.AT.data_member_location, DW.FORM.udata
-                                try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
+                        },
+                        .struct_type => |struct_type| {
+                            // DW.AT.name, DW.FORM.string
+                            try ty.print(dbg_info_buffer.writer(), mod);
+                            try dbg_info_buffer.append(0);
+
+                            if (struct_type.layout == .Packed) {
+                                log.debug("TODO implement .debug_info for packed structs", .{});
+                                break :blk;
                             }
-                        }
-                    },
-                    else => unreachable,
+
+                            if (struct_type.isTuple(ip)) {
+                                for (struct_type.field_types.get(ip), struct_type.offsets.get(ip), 0..) |field_ty, field_off, field_index| {
+                                    if (!field_ty.toType().hasRuntimeBits(mod)) continue;
+                                    // DW.AT.member
+                                    try dbg_info_buffer.append(@intFromEnum(AbbrevKind.struct_member));
+                                    // DW.AT.name, DW.FORM.string
+                                    try dbg_info_buffer.writer().print("{d}\x00", .{field_index});
+                                    // DW.AT.type, DW.FORM.ref4
+                                    var index = dbg_info_buffer.items.len;
+                                    try dbg_info_buffer.resize(index + 4);
+                                    try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @as(u32, @intCast(index)));
+                                    // DW.AT.data_member_location, DW.FORM.udata
+                                    try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
+                                }
+                            } else {
+                                for (
+                                    struct_type.field_names.get(ip),
+                                    struct_type.field_types.get(ip),
+                                    struct_type.offsets.get(ip),
+                                ) |field_name_ip, field_ty, field_off| {
+                                    if (!field_ty.toType().hasRuntimeBits(mod)) continue;
+                                    const field_name = ip.stringToSlice(field_name_ip);
+                                    // DW.AT.member
+                                    try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
+                                    dbg_info_buffer.appendAssumeCapacity(@intFromEnum(AbbrevKind.struct_member));
+                                    // DW.AT.name, DW.FORM.string
+                                    dbg_info_buffer.appendSliceAssumeCapacity(field_name);
+                                    dbg_info_buffer.appendAssumeCapacity(0);
+                                    // DW.AT.type, DW.FORM.ref4
+                                    var index = dbg_info_buffer.items.len;
+                                    try dbg_info_buffer.resize(index + 4);
+                                    try self.addTypeRelocGlobal(atom_index, field_ty.toType(), @intCast(index));
+                                    // DW.AT.data_member_location, DW.FORM.udata
+                                    try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
+                                }
+                            }
+                        },
+                        else => unreachable,
+                    }
                 }
 
                 // DW.AT.structure_type delimit children