| ... | ... | @@ -855,10 +855,11 @@ pub const abbrev_subprogram = 2; |
| 855 | 855 | pub const abbrev_subprogram_retvoid = 3; |
| 856 | 856 | pub const abbrev_base_type = 4; |
| 857 | 857 | pub const abbrev_ptr_type = 5; |
| 858 | | pub const abbrev_anon_struct_type = 6; |
| 859 | | pub const abbrev_struct_member = 7; |
| 860 | | pub const abbrev_pad1 = 8; |
| 861 | | pub const abbrev_parameter = 9; |
| 858 | pub const abbrev_struct_type = 6; |
| 859 | pub const abbrev_anon_struct_type = 7; |
| 860 | pub const abbrev_struct_member = 8; |
| 861 | pub const abbrev_pad1 = 9; |
| 862 | pub const abbrev_parameter = 10; |
| 862 | 863 | |
| 863 | 864 | pub fn flush(self: *Elf, comp: *Compilation) !void { |
| 864 | 865 | if (self.base.options.emit == null) { |
| ... | ... | @@ -955,6 +956,15 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 955 | 956 | DW.FORM.ref4, |
| 956 | 957 | 0, |
| 957 | 958 | 0, // table sentinel |
| 959 | abbrev_struct_type, |
| 960 | DW.TAG.structure_type, |
| 961 | DW.CHILDREN.yes, // header |
| 962 | DW.AT.byte_size, |
| 963 | DW.FORM.sdata, |
| 964 | DW.AT.name, |
| 965 | DW.FORM.string, |
| 966 | 0, |
| 967 | 0, // table sentinel |
| 958 | 968 | abbrev_anon_struct_type, |
| 959 | 969 | DW.TAG.structure_type, |
| 960 | 970 | DW.CHILDREN.yes, // header |
| ... | ... | @@ -2968,6 +2978,46 @@ fn addDbgInfoType( |
| 2968 | 2978 | try relocs.append(.{ .ty = ty.childType(), .reloc = @intCast(u32, index) }); |
| 2969 | 2979 | } |
| 2970 | 2980 | }, |
| 2981 | .Struct => blk: { |
| 2982 | // try dbg_info_buffer.ensureUnusedCapacity(23); |
| 2983 | // DW.AT.structure_type |
| 2984 | try dbg_info_buffer.append(abbrev_struct_type); |
| 2985 | // DW.AT.byte_size, DW.FORM.sdata |
| 2986 | const abi_size = ty.abiSize(self.base.options.target); |
| 2987 | try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size); |
| 2988 | // DW.AT.name, DW.FORM.string |
| 2989 | const struct_name = try ty.nameAlloc(arena); |
| 2990 | try dbg_info_buffer.ensureUnusedCapacity(struct_name.len + 1); |
| 2991 | dbg_info_buffer.appendSliceAssumeCapacity(struct_name); |
| 2992 | dbg_info_buffer.appendAssumeCapacity(0); |
| 2993 | |
| 2994 | const struct_obj = ty.castTag(.@"struct").?.data; |
| 2995 | if (struct_obj.layout == .Packed) { |
| 2996 | log.debug("TODO implement .debug_info for packed structs", .{}); |
| 2997 | break :blk; |
| 2998 | } |
| 2999 | |
| 3000 | const fields = ty.structFields(); |
| 3001 | for (fields.keys()) |field_name, field_index| { |
| 3002 | const field = fields.get(field_name).?; |
| 3003 | // DW.AT.member |
| 3004 | try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2); |
| 3005 | dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member); |
| 3006 | // DW.AT.name, DW.FORM.string |
| 3007 | dbg_info_buffer.appendSliceAssumeCapacity(field_name); |
| 3008 | dbg_info_buffer.appendAssumeCapacity(0); |
| 3009 | // DW.AT.type, DW.FORM.ref4 |
| 3010 | var index = dbg_info_buffer.items.len; |
| 3011 | try dbg_info_buffer.resize(index + 4); |
| 3012 | try relocs.append(.{ .ty = field.ty, .reloc = @intCast(u32, index) }); |
| 3013 | // DW.AT.data_member_location, DW.FORM.sdata |
| 3014 | const field_off = ty.structFieldOffset(field_index, self.base.options.target); |
| 3015 | try leb128.writeULEB128(dbg_info_buffer.writer(), field_off); |
| 3016 | } |
| 3017 | |
| 3018 | // DW.AT.structure_type delimit children |
| 3019 | try dbg_info_buffer.append(0); |
| 3020 | }, |
| 2971 | 3021 | else => { |
| 2972 | 3022 | log.debug("TODO implement .debug_info for type '{}'", .{ty}); |
| 2973 | 3023 | try dbg_info_buffer.append(abbrev_pad1); |