authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-05 23:07:36+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-05 23:07:36+01:00
log72992b6513b3c6f5d8bd0abffe0d08a2a7d6e7cd
tree566f64e6edf9bfe1b43e6bf397ad9bb0cc7d7795
parent908f41a67cbd377eb15d07a27778dbbca0a4309f
parent1252bdd4d63eda5ee70b7f58979b2471c2f83555
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11062 from ziglang/dwarf-more-types


5 files changed, 158 insertions(+), 68 deletions(-)

src/arch/x86_64/Emit.zig+16-2
...@@ -1019,7 +1019,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32...@@ -1019,7 +1019,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32
1019 switch (emit.debug_output) {1019 switch (emit.debug_output) {
1020 .dwarf => |dbg_out| {1020 .dwarf => |dbg_out| {
1021 try dbg_out.dbg_info.ensureUnusedCapacity(3);1021 try dbg_out.dbg_info.ensureUnusedCapacity(3);
1022 dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter);1022
1023 // TODO this will go away once we pull DWARF into a cross-platform module.
1024 if (emit.bin_file.cast(link.File.MachO)) |_| {
1025 dbg_out.dbg_info.appendAssumeCapacity(link.File.MachO.DebugSymbols.abbrev_parameter);
1026 } else if (emit.bin_file.cast(link.File.Elf)) |_| {
1027 dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter);
1028 } else return emit.fail("TODO DWARF in non-MachO and non-ELF backend", .{});
1029
1023 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc1030 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
1024 1, // ULEB128 dwarf expression length1031 1, // ULEB128 dwarf expression length
1025 reg.dwarfLocOp(),1032 reg.dwarfLocOp(),
...@@ -1042,7 +1049,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32...@@ -1042,7 +1049,14 @@ fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32
1042 // for example when -fomit-frame-pointer is set.1049 // for example when -fomit-frame-pointer is set.
1043 const disp = @intCast(i32, max_stack) - off + 16;1050 const disp = @intCast(i32, max_stack) - off + 16;
1044 try dbg_out.dbg_info.ensureUnusedCapacity(8);1051 try dbg_out.dbg_info.ensureUnusedCapacity(8);
1045 dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter);1052
1053 // TODO this will go away once we pull DWARF into a cross-platform module.
1054 if (emit.bin_file.cast(link.File.MachO)) |_| {
1055 dbg_out.dbg_info.appendAssumeCapacity(link.File.MachO.DebugSymbols.abbrev_parameter);
1056 } else if (emit.bin_file.cast(link.File.Elf)) |_| {
1057 dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter);
1058 } else return emit.fail("TODO DWARF in non-MachO and non-ELF backend", .{});
1059
1046 const fixup = dbg_out.dbg_info.items.len;1060 const fixup = dbg_out.dbg_info.items.len;
1047 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc1061 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
1048 1, // we will backpatch it after we encode the displacement in LEB1281062 1, // we will backpatch it after we encode the displacement in LEB128
src/codegen.zig-1
...@@ -639,7 +639,6 @@ pub fn generateSymbol(...@@ -639,7 +639,6 @@ pub fn generateSymbol(
639 return Result{ .appended = {} };639 return Result{ .appended = {} };
640 },640 },
641 .Optional => {641 .Optional => {
642 // TODO generate debug info for optionals
643 var opt_buf: Type.Payload.ElemType = undefined;642 var opt_buf: Type.Payload.ElemType = undefined;
644 const payload_type = typed_value.ty.optionalChild(&opt_buf);643 const payload_type = typed_value.ty.optionalChild(&opt_buf);
645 const is_pl = !typed_value.val.isNull();644 const is_pl = !typed_value.val.isNull();
src/link/Elf.zig+56-23
...@@ -983,10 +983,9 @@ pub const abbrev_subprogram_retvoid = 3;...@@ -983,10 +983,9 @@ pub const abbrev_subprogram_retvoid = 3;
983pub const abbrev_base_type = 4;983pub const abbrev_base_type = 4;
984pub const abbrev_ptr_type = 5;984pub const abbrev_ptr_type = 5;
985pub const abbrev_struct_type = 6;985pub const abbrev_struct_type = 6;
986pub const abbrev_anon_struct_type = 7;986pub const abbrev_struct_member = 7;
987pub const abbrev_struct_member = 8;987pub const abbrev_pad1 = 8;
988pub const abbrev_pad1 = 9;988pub const abbrev_parameter = 9;
989pub const abbrev_parameter = 10;
990989
991pub fn flush(self: *Elf, comp: *Compilation) !void {990pub fn flush(self: *Elf, comp: *Compilation) !void {
992 if (self.base.options.emit == null) {991 if (self.base.options.emit == null) {
...@@ -1127,13 +1126,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {...@@ -1127,13 +1126,6 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
1127 DW.FORM.string,1126 DW.FORM.string,
1128 0,1127 0,
1129 0, // table sentinel1128 0, // table sentinel
1130 abbrev_anon_struct_type,
1131 DW.TAG.structure_type,
1132 DW.CHILDREN.yes, // header
1133 DW.AT.byte_size,
1134 DW.FORM.sdata,
1135 0,
1136 0, // table sentinel
1137 abbrev_struct_member,1129 abbrev_struct_member,
1138 DW.TAG.member,1130 DW.TAG.member,
1139 DW.CHILDREN.no, // header1131 DW.CHILDREN.no, // header
...@@ -3186,6 +3178,7 @@ fn addDbgInfoType(...@@ -3186,6 +3178,7 @@ fn addDbgInfoType(
3186 dbg_info_buffer: *std.ArrayList(u8),3178 dbg_info_buffer: *std.ArrayList(u8),
3187 dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable,3179 dbg_info_type_relocs: *File.DbgInfoTypeRelocsTable,
3188) error{OutOfMemory}!void {3180) error{OutOfMemory}!void {
3181 const target = self.base.options.target;
3189 var relocs = std.ArrayList(struct { ty: Type, reloc: u32 }).init(arena);3182 var relocs = std.ArrayList(struct { ty: Type, reloc: u32 }).init(arena);
31903183
3191 switch (ty.zigTypeTag()) {3184 switch (ty.zigTypeTag()) {
...@@ -3202,7 +3195,7 @@ fn addDbgInfoType(...@@ -3202,7 +3195,7 @@ fn addDbgInfoType(
3202 });3195 });
3203 },3196 },
3204 .Int => {3197 .Int => {
3205 const info = ty.intInfo(self.base.options.target);3198 const info = ty.intInfo(target);
3206 try dbg_info_buffer.ensureUnusedCapacity(12);3199 try dbg_info_buffer.ensureUnusedCapacity(12);
3207 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);3200 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
3208 // DW.AT.encoding, DW.FORM.data13201 // DW.AT.encoding, DW.FORM.data1
...@@ -3211,7 +3204,7 @@ fn addDbgInfoType(...@@ -3211,7 +3204,7 @@ fn addDbgInfoType(
3211 .unsigned => DW.ATE.unsigned,3204 .unsigned => DW.ATE.unsigned,
3212 });3205 });
3213 // DW.AT.byte_size, DW.FORM.data13206 // DW.AT.byte_size, DW.FORM.data1
3214 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target)));3207 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
3215 // DW.AT.name, DW.FORM.string3208 // DW.AT.name, DW.FORM.string
3216 try dbg_info_buffer.writer().print("{}\x00", .{ty});3209 try dbg_info_buffer.writer().print("{}\x00", .{ty});
3217 },3210 },
...@@ -3222,23 +3215,61 @@ fn addDbgInfoType(...@@ -3222,23 +3215,61 @@ fn addDbgInfoType(
3222 // DW.AT.encoding, DW.FORM.data13215 // DW.AT.encoding, DW.FORM.data1
3223 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);3216 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
3224 // DW.AT.byte_size, DW.FORM.data13217 // DW.AT.byte_size, DW.FORM.data1
3225 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target)));3218 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
3226 // DW.AT.name, DW.FORM.string3219 // DW.AT.name, DW.FORM.string
3227 try dbg_info_buffer.writer().print("{}\x00", .{ty});3220 try dbg_info_buffer.writer().print("{}\x00", .{ty});
3228 } else {3221 } else {
3229 log.debug("TODO implement .debug_info for type '{}'", .{ty});3222 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
3230 try dbg_info_buffer.append(abbrev_pad1);3223 var buf = try arena.create(Type.Payload.ElemType);
3224 const payload_ty = ty.optionalChild(buf);
3225 // DW.AT.structure_type
3226 try dbg_info_buffer.append(abbrev_struct_type);
3227 // DW.AT.byte_size, DW.FORM.sdata
3228 const abi_size = ty.abiSize(target);
3229 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
3230 // DW.AT.name, DW.FORM.string
3231 try dbg_info_buffer.writer().print("{}\x00", .{ty});
3232 // DW.AT.member
3233 try dbg_info_buffer.ensureUnusedCapacity(7);
3234 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
3235 // DW.AT.name, DW.FORM.string
3236 dbg_info_buffer.appendSliceAssumeCapacity("maybe");
3237 dbg_info_buffer.appendAssumeCapacity(0);
3238 // DW.AT.type, DW.FORM.ref4
3239 var index = dbg_info_buffer.items.len;
3240 try dbg_info_buffer.resize(index + 4);
3241 try relocs.append(.{ .ty = Type.bool, .reloc = @intCast(u32, index) });
3242 // DW.AT.data_member_location, DW.FORM.sdata
3243 try dbg_info_buffer.ensureUnusedCapacity(6);
3244 dbg_info_buffer.appendAssumeCapacity(0);
3245 // DW.AT.member
3246 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
3247 // DW.AT.name, DW.FORM.string
3248 dbg_info_buffer.appendSliceAssumeCapacity("val");
3249 dbg_info_buffer.appendAssumeCapacity(0);
3250 // DW.AT.type, DW.FORM.ref4
3251 index = dbg_info_buffer.items.len;
3252 try dbg_info_buffer.resize(index + 4);
3253 try relocs.append(.{ .ty = payload_ty, .reloc = @intCast(u32, index) });
3254 // DW.AT.data_member_location, DW.FORM.sdata
3255 const offset = abi_size - payload_ty.abiSize(target);
3256 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
3257 // DW.AT.structure_type delimit children
3258 try dbg_info_buffer.append(0);
3231 }3259 }
3232 },3260 },
3233 .Pointer => {3261 .Pointer => {
3234 if (ty.isSlice()) {3262 if (ty.isSlice()) {
3235 // Slices are anonymous structs: struct { .ptr = *, .len = N }3263 // Slices are structs: struct { .ptr = *, .len = N }
3236 try dbg_info_buffer.ensureUnusedCapacity(23);
3237 // DW.AT.structure_type3264 // DW.AT.structure_type
3238 dbg_info_buffer.appendAssumeCapacity(abbrev_anon_struct_type);3265 try dbg_info_buffer.ensureUnusedCapacity(2);
3266 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_type);
3239 // DW.AT.byte_size, DW.FORM.sdata3267 // DW.AT.byte_size, DW.FORM.sdata
3240 dbg_info_buffer.appendAssumeCapacity(16);3268 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
3269 // DW.AT.name, DW.FORM.string
3270 try dbg_info_buffer.writer().print("{}\x00", .{ty});
3241 // DW.AT.member3271 // DW.AT.member
3272 try dbg_info_buffer.ensureUnusedCapacity(5);
3242 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);3273 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
3243 // DW.AT.name, DW.FORM.string3274 // DW.AT.name, DW.FORM.string
3244 dbg_info_buffer.appendSliceAssumeCapacity("ptr");3275 dbg_info_buffer.appendSliceAssumeCapacity("ptr");
...@@ -3250,6 +3281,7 @@ fn addDbgInfoType(...@@ -3250,6 +3281,7 @@ fn addDbgInfoType(
3250 const ptr_ty = ty.slicePtrFieldType(buf);3281 const ptr_ty = ty.slicePtrFieldType(buf);
3251 try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) });3282 try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) });
3252 // DW.AT.data_member_location, DW.FORM.sdata3283 // DW.AT.data_member_location, DW.FORM.sdata
3284 try dbg_info_buffer.ensureUnusedCapacity(6);
3253 dbg_info_buffer.appendAssumeCapacity(0);3285 dbg_info_buffer.appendAssumeCapacity(0);
3254 // DW.AT.member3286 // DW.AT.member
3255 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);3287 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
...@@ -3261,7 +3293,8 @@ fn addDbgInfoType(...@@ -3261,7 +3293,8 @@ fn addDbgInfoType(
3261 try dbg_info_buffer.resize(index + 4);3293 try dbg_info_buffer.resize(index + 4);
3262 try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) });3294 try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) });
3263 // DW.AT.data_member_location, DW.FORM.sdata3295 // DW.AT.data_member_location, DW.FORM.sdata
3264 dbg_info_buffer.appendAssumeCapacity(8);3296 try dbg_info_buffer.ensureUnusedCapacity(2);
3297 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize));
3265 // DW.AT.structure_type delimit children3298 // DW.AT.structure_type delimit children
3266 dbg_info_buffer.appendAssumeCapacity(0);3299 dbg_info_buffer.appendAssumeCapacity(0);
3267 } else {3300 } else {
...@@ -3278,7 +3311,7 @@ fn addDbgInfoType(...@@ -3278,7 +3311,7 @@ fn addDbgInfoType(
3278 // DW.AT.structure_type3311 // DW.AT.structure_type
3279 try dbg_info_buffer.append(abbrev_struct_type);3312 try dbg_info_buffer.append(abbrev_struct_type);
3280 // DW.AT.byte_size, DW.FORM.sdata3313 // DW.AT.byte_size, DW.FORM.sdata
3281 const abi_size = ty.abiSize(self.base.options.target);3314 const abi_size = ty.abiSize(target);
3282 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);3315 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
3283 // DW.AT.name, DW.FORM.string3316 // DW.AT.name, DW.FORM.string
3284 const struct_name = try ty.nameAlloc(arena);3317 const struct_name = try ty.nameAlloc(arena);
...@@ -3306,7 +3339,7 @@ fn addDbgInfoType(...@@ -3306,7 +3339,7 @@ fn addDbgInfoType(
3306 try dbg_info_buffer.resize(index + 4);3339 try dbg_info_buffer.resize(index + 4);
3307 try relocs.append(.{ .ty = field.ty, .reloc = @intCast(u32, index) });3340 try relocs.append(.{ .ty = field.ty, .reloc = @intCast(u32, index) });
3308 // DW.AT.data_member_location, DW.FORM.sdata3341 // DW.AT.data_member_location, DW.FORM.sdata
3309 const field_off = ty.structFieldOffset(field_index, self.base.options.target);3342 const field_off = ty.structFieldOffset(field_index, target);
3310 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);3343 try leb128.writeULEB128(dbg_info_buffer.writer(), field_off);
3311 }3344 }
33123345
src/link/MachO.zig+30-6
...@@ -27,7 +27,6 @@ const Atom = @import("MachO/Atom.zig");...@@ -27,7 +27,6 @@ const Atom = @import("MachO/Atom.zig");
27const Cache = @import("../Cache.zig");27const Cache = @import("../Cache.zig");
28const CodeSignature = @import("MachO/CodeSignature.zig");28const CodeSignature = @import("MachO/CodeSignature.zig");
29const Compilation = @import("../Compilation.zig");29const Compilation = @import("../Compilation.zig");
30const DebugSymbols = @import("MachO/DebugSymbols.zig");
31const Dylib = @import("MachO/Dylib.zig");30const Dylib = @import("MachO/Dylib.zig");
32const File = link.File;31const File = link.File;
33const Object = @import("MachO/Object.zig");32const Object = @import("MachO/Object.zig");
...@@ -43,6 +42,7 @@ const TypedValue = @import("../TypedValue.zig");...@@ -43,6 +42,7 @@ const TypedValue = @import("../TypedValue.zig");
43const Value = @import("../value.zig").Value;42const Value = @import("../value.zig").Value;
4443
45pub const TextBlock = Atom;44pub const TextBlock = Atom;
45pub const DebugSymbols = @import("MachO/DebugSymbols.zig");
4646
47pub const base_tag: File.Tag = File.Tag.macho;47pub const base_tag: File.Tag = File.Tag.macho;
4848
...@@ -2178,6 +2178,34 @@ fn writeAllAtoms(self: *MachO) !void {...@@ -2178,6 +2178,34 @@ fn writeAllAtoms(self: *MachO) !void {
2178 }2178 }
2179}2179}
21802180
2181fn writePadding(self: *MachO, match: MatchingSection, size: usize, writer: anytype) !void {
2182 const is_code = match.seg == self.text_segment_cmd_index.? and match.sect == self.text_section_index.?;
2183 const min_alignment: u3 = if (!is_code)
2184 1
2185 else switch (self.base.options.target.cpu.arch) {
2186 .aarch64 => @sizeOf(u32),
2187 .x86_64 => @as(u3, 1),
2188 else => unreachable,
2189 };
2190
2191 const len = @divExact(size, min_alignment);
2192 var i: usize = 0;
2193 while (i < len) : (i += 1) {
2194 if (!is_code) {
2195 try writer.writeByte(0);
2196 } else switch (self.base.options.target.cpu.arch) {
2197 .aarch64 => {
2198 const inst = aarch64.Instruction.nop();
2199 try writer.writeIntLittle(u32, inst.toU32());
2200 },
2201 .x86_64 => {
2202 try writer.writeByte(0x90);
2203 },
2204 else => unreachable,
2205 }
2206 }
2207}
2208
2181fn writeAtoms(self: *MachO) !void {2209fn writeAtoms(self: *MachO) !void {
2182 var buffer = std.ArrayList(u8).init(self.base.allocator);2210 var buffer = std.ArrayList(u8).init(self.base.allocator);
2183 defer buffer.deinit();2211 defer buffer.deinit();
...@@ -2213,11 +2241,7 @@ fn writeAtoms(self: *MachO) !void {...@@ -2213,11 +2241,7 @@ fn writeAtoms(self: *MachO) !void {
2213 try atom.resolveRelocs(self);2241 try atom.resolveRelocs(self);
2214 try buffer.appendSlice(atom.code.items);2242 try buffer.appendSlice(atom.code.items);
2215 try buffer.ensureUnusedCapacity(padding_size);2243 try buffer.ensureUnusedCapacity(padding_size);
22162244 try self.writePadding(match, padding_size, buffer.writer());
2217 var i: usize = 0;
2218 while (i < padding_size) : (i += 1) {
2219 buffer.appendAssumeCapacity(0);
2220 }
22212245
2222 if (file_offset == null) {2246 if (file_offset == null) {
2223 file_offset = sect.offset + atom_sym.n_value - sect.addr;2247 file_offset = sect.offset + atom_sym.n_value - sect.addr;
src/link/MachO/DebugSymbols.zig+56-36
...@@ -78,16 +78,15 @@ debug_aranges_section_dirty: bool = false,...@@ -78,16 +78,15 @@ debug_aranges_section_dirty: bool = false,
78debug_info_header_dirty: bool = false,78debug_info_header_dirty: bool = false,
79debug_line_header_dirty: bool = false,79debug_line_header_dirty: bool = false,
8080
81const abbrev_compile_unit = 1;81pub const abbrev_compile_unit = 1;
82const abbrev_subprogram = 2;82pub const abbrev_subprogram = 2;
83const abbrev_subprogram_retvoid = 3;83pub const abbrev_subprogram_retvoid = 3;
84const abbrev_base_type = 4;84pub const abbrev_base_type = 4;
85const abbrev_ptr_type = 5;85pub const abbrev_ptr_type = 5;
86const abbrev_struct_type = 6;86pub const abbrev_struct_type = 6;
87const abbrev_anon_struct_type = 7;87pub const abbrev_struct_member = 7;
88const abbrev_struct_member = 8;88pub const abbrev_pad1 = 8;
89const abbrev_pad1 = 9;89pub const abbrev_parameter = 9;
90const abbrev_parameter = 10;
9190
92/// The reloc offset for the virtual address of a function in its Line Number Program.91/// The reloc offset for the virtual address of a function in its Line Number Program.
93/// Size is a virtual address integer.92/// Size is a virtual address integer.
...@@ -353,13 +352,6 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti...@@ -353,13 +352,6 @@ pub fn flushModule(self: *DebugSymbols, allocator: Allocator, options: link.Opti
353 DW.FORM.string,352 DW.FORM.string,
354 0,353 0,
355 0, // table sentinel354 0, // table sentinel
356 abbrev_anon_struct_type,
357 DW.TAG.structure_type,
358 DW.CHILDREN.yes, // header
359 DW.AT.byte_size,
360 DW.FORM.sdata,
361 0,
362 0, // table sentinel
363 abbrev_struct_member,355 abbrev_struct_member,
364 DW.TAG.member,356 DW.TAG.member,
365 DW.CHILDREN.no, // header357 DW.CHILDREN.no, // header
...@@ -1134,18 +1126,6 @@ pub fn commitDeclDebugInfo(...@@ -1134,18 +1126,6 @@ pub fn commitDeclDebugInfo(
1134 mem.writeIntLittle(u32, ptr, @intCast(u32, text_block.size));1126 mem.writeIntLittle(u32, ptr, @intCast(u32, text_block.size));
1135 }1127 }
11361128
1137 {
1138 // Advance line and PC.
1139 // TODO encapsulate logic in a helper function.
1140 try dbg_line_buffer.append(DW.LNS.advance_pc);
1141 try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size);
1142
1143 try dbg_line_buffer.append(DW.LNS.advance_line);
1144 const func = decl.val.castTag(.function).?.data;
1145 const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line);
1146 try leb.writeULEB128(dbg_line_buffer.writer(), line_off);
1147 }
1148
1149 try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence });1129 try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence });
11501130
1151 // Now we have the full contents and may allocate a region to store it.1131 // Now we have the full contents and may allocate a region to store it.
...@@ -1332,19 +1312,57 @@ fn addDbgInfoType(...@@ -1332,19 +1312,57 @@ fn addDbgInfoType(
1332 // DW.AT.name, DW.FORM.string1312 // DW.AT.name, DW.FORM.string
1333 try dbg_info_buffer.writer().print("{}\x00", .{ty});1313 try dbg_info_buffer.writer().print("{}\x00", .{ty});
1334 } else {1314 } else {
1335 log.debug("TODO implement .debug_info for type '{}'", .{ty});1315 // Non-pointer optionals are structs: struct { .maybe = *, .val = * }
1336 try dbg_info_buffer.append(abbrev_pad1);1316 var buf = try arena.create(Type.Payload.ElemType);
1317 const payload_ty = ty.optionalChild(buf);
1318 // DW.AT.structure_type
1319 try dbg_info_buffer.append(abbrev_struct_type);
1320 // DW.AT.byte_size, DW.FORM.sdata
1321 const abi_size = ty.abiSize(target);
1322 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
1323 // DW.AT.name, DW.FORM.string
1324 try dbg_info_buffer.writer().print("{}\x00", .{ty});
1325 // DW.AT.member
1326 try dbg_info_buffer.ensureUnusedCapacity(7);
1327 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
1328 // DW.AT.name, DW.FORM.string
1329 dbg_info_buffer.appendSliceAssumeCapacity("maybe");
1330 dbg_info_buffer.appendAssumeCapacity(0);
1331 // DW.AT.type, DW.FORM.ref4
1332 var index = dbg_info_buffer.items.len;
1333 try dbg_info_buffer.resize(index + 4);
1334 try relocs.append(.{ .ty = Type.bool, .reloc = @intCast(u32, index) });
1335 // DW.AT.data_member_location, DW.FORM.sdata
1336 try dbg_info_buffer.ensureUnusedCapacity(6);
1337 dbg_info_buffer.appendAssumeCapacity(0);
1338 // DW.AT.member
1339 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
1340 // DW.AT.name, DW.FORM.string
1341 dbg_info_buffer.appendSliceAssumeCapacity("val");
1342 dbg_info_buffer.appendAssumeCapacity(0);
1343 // DW.AT.type, DW.FORM.ref4
1344 index = dbg_info_buffer.items.len;
1345 try dbg_info_buffer.resize(index + 4);
1346 try relocs.append(.{ .ty = payload_ty, .reloc = @intCast(u32, index) });
1347 // DW.AT.data_member_location, DW.FORM.sdata
1348 const offset = abi_size - payload_ty.abiSize(target);
1349 try leb128.writeULEB128(dbg_info_buffer.writer(), offset);
1350 // DW.AT.structure_type delimit children
1351 try dbg_info_buffer.append(0);
1337 }1352 }
1338 },1353 },
1339 .Pointer => {1354 .Pointer => {
1340 if (ty.isSlice()) {1355 if (ty.isSlice()) {
1341 // Slices are anonymous structs: struct { .ptr = *, .len = N }1356 // Slices are structs: struct { .ptr = *, .len = N }
1342 try dbg_info_buffer.ensureUnusedCapacity(23);
1343 // DW.AT.structure_type1357 // DW.AT.structure_type
1344 dbg_info_buffer.appendAssumeCapacity(abbrev_anon_struct_type);1358 try dbg_info_buffer.ensureUnusedCapacity(2);
1359 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_type);
1345 // DW.AT.byte_size, DW.FORM.sdata1360 // DW.AT.byte_size, DW.FORM.sdata
1346 dbg_info_buffer.appendAssumeCapacity(16);1361 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
1362 // DW.AT.name, DW.FORM.string
1363 try dbg_info_buffer.writer().print("{}\x00", .{ty});
1347 // DW.AT.member1364 // DW.AT.member
1365 try dbg_info_buffer.ensureUnusedCapacity(5);
1348 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);1366 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
1349 // DW.AT.name, DW.FORM.string1367 // DW.AT.name, DW.FORM.string
1350 dbg_info_buffer.appendSliceAssumeCapacity("ptr");1368 dbg_info_buffer.appendSliceAssumeCapacity("ptr");
...@@ -1356,6 +1374,7 @@ fn addDbgInfoType(...@@ -1356,6 +1374,7 @@ fn addDbgInfoType(
1356 const ptr_ty = ty.slicePtrFieldType(buf);1374 const ptr_ty = ty.slicePtrFieldType(buf);
1357 try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) });1375 try relocs.append(.{ .ty = ptr_ty, .reloc = @intCast(u32, index) });
1358 // DW.AT.data_member_location, DW.FORM.sdata1376 // DW.AT.data_member_location, DW.FORM.sdata
1377 try dbg_info_buffer.ensureUnusedCapacity(6);
1359 dbg_info_buffer.appendAssumeCapacity(0);1378 dbg_info_buffer.appendAssumeCapacity(0);
1360 // DW.AT.member1379 // DW.AT.member
1361 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);1380 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
...@@ -1367,7 +1386,8 @@ fn addDbgInfoType(...@@ -1367,7 +1386,8 @@ fn addDbgInfoType(
1367 try dbg_info_buffer.resize(index + 4);1386 try dbg_info_buffer.resize(index + 4);
1368 try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) });1387 try relocs.append(.{ .ty = Type.initTag(.usize), .reloc = @intCast(u32, index) });
1369 // DW.AT.data_member_location, DW.FORM.sdata1388 // DW.AT.data_member_location, DW.FORM.sdata
1370 dbg_info_buffer.appendAssumeCapacity(8);1389 try dbg_info_buffer.ensureUnusedCapacity(2);
1390 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize));
1371 // DW.AT.structure_type delimit children1391 // DW.AT.structure_type delimit children
1372 dbg_info_buffer.appendAssumeCapacity(0);1392 dbg_info_buffer.appendAssumeCapacity(0);
1373 } else {1393 } else {