authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-03-30 18:29:44+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-04-04 21:46:53+02:00
log364e53f3bf6b5aa4e5e7eba5d790c5b957007067
tree2c6ce39c91c9f1c070c51a0b3beadb45ee29766d
parent795f075790d641499dee283507fc40a2e609e9ce

dwarf: emit debug info for local variables on x86_64

Add support for emitting debug info for local variables within a subprogram. This required moving bits responsible for populating the debug info back to `CodeGen` from `Emit` as we require the operand to be resolved at callsite plus we need to know its type. Without enforcing this, we could end up with a `dead` mcv.

7 files changed, 216 insertions(+), 188 deletions(-)

src/arch/arm/Emit.zig+2-2
...@@ -417,7 +417,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {...@@ -417,7 +417,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
417 .dwarf => |dw| {417 .dwarf => |dw| {
418 const dbg_info = &dw.dbg_info;418 const dbg_info = &dw.dbg_info;
419 try dbg_info.ensureUnusedCapacity(3);419 try dbg_info.ensureUnusedCapacity(3);
420 dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_parameter);420 dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter));
421 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc421 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
422 1, // ULEB128 dwarf expression length422 1, // ULEB128 dwarf expression length
423 reg.dwarfLocOp(),423 reg.dwarfLocOp(),
...@@ -449,7 +449,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {...@@ -449,7 +449,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
449 };449 };
450450
451 const dbg_info = &dw.dbg_info;451 const dbg_info = &dw.dbg_info;
452 try dbg_info.append(link.File.Dwarf.abbrev_parameter);452 try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.parameter));
453453
454 // Get length of the LEB128 stack offset454 // Get length of the LEB128 stack offset
455 var counting_writer = std.io.countingWriter(std.io.null_writer);455 var counting_writer = std.io.countingWriter(std.io.null_writer);
src/arch/riscv64/CodeGen.zig+1-1
...@@ -1574,7 +1574,7 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32...@@ -1574,7 +1574,7 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32
1574 .dwarf => |dw| {1574 .dwarf => |dw| {
1575 const dbg_info = &dw.dbg_info;1575 const dbg_info = &dw.dbg_info;
1576 try dbg_info.ensureUnusedCapacity(3);1576 try dbg_info.ensureUnusedCapacity(3);
1577 dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_parameter);1577 dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter));
1578 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc1578 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
1579 1, // ULEB128 dwarf expression length1579 1, // ULEB128 dwarf expression length
1580 reg.dwarfLocOp(),1580 reg.dwarfLocOp(),
src/arch/x86_64/CodeGen.zig+132-16
...@@ -48,6 +48,7 @@ gpa: Allocator,...@@ -48,6 +48,7 @@ gpa: Allocator,
48air: Air,48air: Air,
49liveness: Liveness,49liveness: Liveness,
50bin_file: *link.File,50bin_file: *link.File,
51debug_output: DebugInfoOutput,
51target: *const std.Target,52target: *const std.Target,
52mod_fn: *const Module.Fn,53mod_fn: *const Module.Fn,
53err_msg: ?*ErrorMsg,54err_msg: ?*ErrorMsg,
...@@ -337,6 +338,7 @@ pub fn generate(...@@ -337,6 +338,7 @@ pub fn generate(
337 .liveness = liveness,338 .liveness = liveness,
338 .target = &bin_file.options.target,339 .target = &bin_file.options.target,
339 .bin_file = bin_file,340 .bin_file = bin_file,
341 .debug_output = debug_output,
340 .mod_fn = module_fn,342 .mod_fn = module_fn,
341 .err_msg = null,343 .err_msg = null,
342 .args = undefined, // populated after `resolveCallingConventionValues`344 .args = undefined, // populated after `resolveCallingConventionValues`
...@@ -382,7 +384,6 @@ pub fn generate(...@@ -382,7 +384,6 @@ pub fn generate(
382 };384 };
383385
384 var mir = Mir{386 var mir = Mir{
385 .function = &function,
386 .instructions = function.mir_instructions.toOwnedSlice(),387 .instructions = function.mir_instructions.toOwnedSlice(),
387 .extra = function.mir_extra.toOwnedSlice(bin_file.allocator),388 .extra = function.mir_extra.toOwnedSlice(bin_file.allocator),
388 };389 };
...@@ -391,7 +392,6 @@ pub fn generate(...@@ -391,7 +392,6 @@ pub fn generate(
391 var emit = Emit{392 var emit = Emit{
392 .mir = mir,393 .mir = mir,
393 .bin_file = bin_file,394 .bin_file = bin_file,
394 .function = &function,
395 .debug_output = debug_output,395 .debug_output = debug_output,
396 .target = &bin_file.options.target,396 .target = &bin_file.options.target,
397 .src_loc = src_loc,397 .src_loc = src_loc,
...@@ -3425,17 +3425,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -3425,17 +3425,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
3425 const arg_index = self.arg_index;3425 const arg_index = self.arg_index;
3426 self.arg_index += 1;3426 self.arg_index += 1;
34273427
3428 const ty = self.air.typeOfIndex(inst);
3428 const mcv = self.args[arg_index];3429 const mcv = self.args[arg_index];
3429 const payload = try self.addExtra(Mir.ArgDbgInfo{3430 const name = self.mod_fn.getParamName(arg_index);
3430 .air_inst = inst,3431 const name_with_null = name.ptr[0 .. name.len + 1];
3431 .arg_index = arg_index,3432
3432 .max_stack = self.max_end_stack,
3433 });
3434 _ = try self.addInst(.{
3435 .tag = .arg_dbg_info,
3436 .ops = undefined,
3437 .data = .{ .payload = payload },
3438 });
3439 if (self.liveness.isUnused(inst))3433 if (self.liveness.isUnused(inst))
3440 return self.finishAirBookkeeping();3434 return self.finishAirBookkeeping();
34413435
...@@ -3443,10 +3437,46 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -3443,10 +3437,46 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
3443 switch (mcv) {3437 switch (mcv) {
3444 .register => |reg| {3438 .register => |reg| {
3445 self.register_manager.getRegAssumeFree(reg.to64(), inst);3439 self.register_manager.getRegAssumeFree(reg.to64(), inst);
3440 switch (self.debug_output) {
3441 .dwarf => |dw| {
3442 const dbg_info = &dw.dbg_info;
3443 try dbg_info.ensureUnusedCapacity(3);
3444 dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter));
3445 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
3446 1, // ULEB128 dwarf expression length
3447 reg.dwarfLocOp(),
3448 });
3449 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
3450 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
3451 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
3452 },
3453 .plan9 => {},
3454 .none => {},
3455 }
3446 break :blk mcv;3456 break :blk mcv;
3447 },3457 },
3448 .stack_offset => |off| {3458 .stack_offset => |off| {
3449 const offset = @intCast(i32, self.max_end_stack) - off + 16;3459 const offset = @intCast(i32, self.max_end_stack) - off + 16;
3460 switch (self.debug_output) {
3461 .dwarf => |dw| {
3462 const dbg_info = &dw.dbg_info;
3463 try dbg_info.ensureUnusedCapacity(8);
3464 dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.parameter));
3465 const fixup = dbg_info.items.len;
3466 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
3467 1, // we will backpatch it after we encode the displacement in LEB128
3468 DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer
3469 });
3470 leb128.writeILEB128(dbg_info.writer(), offset) catch unreachable;
3471 dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
3472 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
3473 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
3474 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
3475
3476 },
3477 .plan9 => {},
3478 .none => {},
3479 }
3450 break :blk MCValue{ .stack_offset = -offset };3480 break :blk MCValue{ .stack_offset = -offset };
3451 },3481 },
3452 else => return self.fail("TODO implement arg for {}", .{mcv}),3482 else => return self.fail("TODO implement arg for {}", .{mcv}),
...@@ -3885,13 +3915,99 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {...@@ -3885,13 +3915,99 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
38853915
3886fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {3916fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
3887 const pl_op = self.air.instructions.items(.data)[inst].pl_op;3917 const pl_op = self.air.instructions.items(.data)[inst].pl_op;
3888 const name = self.air.nullTerminatedString(pl_op.payload);
3889 const operand = pl_op.operand;3918 const operand = pl_op.operand;
3890 // TODO emit debug info for this variable3919 const ty = self.air.typeOf(operand);
3891 _ = name;3920
3921 if (!self.liveness.operandDies(inst, 0)) {
3922 const mcv = try self.resolveInst(operand);
3923 const name = self.air.nullTerminatedString(pl_op.payload);
3924
3925 const tag = self.air.instructions.items(.tag)[inst];
3926 switch (tag) {
3927 .dbg_var_ptr => try self.genVarDbgInfo(ty.childType(), mcv, name),
3928 .dbg_var_val => try self.genVarDbgInfo(ty, mcv, name),
3929 else => unreachable,
3930 }
3931 }
3932
3892 return self.finishAir(inst, .dead, .{ operand, .none, .none });3933 return self.finishAir(inst, .dead, .{ operand, .none, .none });
3893}3934}
38943935
3936fn genVarDbgInfo(
3937 self: *Self,
3938 ty: Type,
3939 mcv: MCValue,
3940 name: [:0]const u8,
3941) !void {
3942 const name_with_null = name.ptr[0 .. name.len + 1];
3943 switch (mcv) {
3944 .register => |reg| {
3945 switch (self.debug_output) {
3946 .dwarf => |dw| {
3947 const dbg_info = &dw.dbg_info;
3948 try dbg_info.ensureUnusedCapacity(3);
3949 dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
3950 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
3951 1, // ULEB128 dwarf expression length
3952 reg.dwarfLocOp(),
3953 });
3954 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
3955 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
3956 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
3957 },
3958 .plan9 => {},
3959 .none => {},
3960 }
3961 },
3962 .ptr_stack_offset, .stack_offset => |off| {
3963 switch (self.debug_output) {
3964 .dwarf => |dw| {
3965 const dbg_info = &dw.dbg_info;
3966 try dbg_info.ensureUnusedCapacity(8);
3967 dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
3968 const fixup = dbg_info.items.len;
3969 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
3970 1, // we will backpatch it after we encode the displacement in LEB128
3971 DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer
3972 });
3973 leb128.writeILEB128(dbg_info.writer(), -off) catch unreachable;
3974 dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
3975 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
3976 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
3977 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
3978
3979 },
3980 .plan9 => {},
3981 .none => {},
3982 }
3983 },
3984 else => {
3985 log.debug("TODO generate debug info for {}", .{mcv});
3986 },
3987 }
3988}
3989
3990/// Adds a Type to the .debug_info at the current position. The bytes will be populated later,
3991/// after codegen for this symbol is done.
3992fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
3993 switch (self.debug_output) {
3994 .dwarf => |dw| {
3995 assert(ty.hasRuntimeBits());
3996 const dbg_info = &dw.dbg_info;
3997 const index = dbg_info.items.len;
3998 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
3999 const atom = switch (self.bin_file.tag) {
4000 .elf => &self.mod_fn.owner_decl.link.elf.dbg_info_atom,
4001 .macho => &self.mod_fn.owner_decl.link.macho.dbg_info_atom,
4002 else => unreachable,
4003 };
4004 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
4005 },
4006 .plan9 => {},
4007 .none => {},
4008 }
4009}
4010
3895fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {4011fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {
3896 const abi_size = ty.abiSize(self.target.*);4012 const abi_size = ty.abiSize(self.target.*);
3897 switch (mcv) {4013 switch (mcv) {
...@@ -5919,7 +6035,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {...@@ -5919,7 +6035,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
5919 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, pl_op.operand });6035 return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, pl_op.operand });
5920}6036}
59216037
5922fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {6038pub fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
5923 // First section of indexes correspond to a set number of constant values.6039 // First section of indexes correspond to a set number of constant values.
5924 const ref_int = @enumToInt(inst);6040 const ref_int = @enumToInt(inst);
5925 if (ref_int < Air.Inst.Ref.typed_value_map.len) {6041 if (ref_int < Air.Inst.Ref.typed_value_map.len) {
src/arch/x86_64/Emit.zig-88
...@@ -30,7 +30,6 @@ const Type = @import("../../type.zig").Type;...@@ -30,7 +30,6 @@ const Type = @import("../../type.zig").Type;
3030
31mir: Mir,31mir: Mir,
32bin_file: *link.File,32bin_file: *link.File,
33function: *const CodeGen,
34debug_output: DebugInfoOutput,33debug_output: DebugInfoOutput,
35target: *const std.Target,34target: *const std.Target,
36err_msg: ?*ErrorMsg = null,35err_msg: ?*ErrorMsg = null,
...@@ -187,7 +186,6 @@ pub fn lowerMir(emit: *Emit) InnerError!void {...@@ -187,7 +186,6 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
187 .dbg_line => try emit.mirDbgLine(inst),186 .dbg_line => try emit.mirDbgLine(inst),
188 .dbg_prologue_end => try emit.mirDbgPrologueEnd(inst),187 .dbg_prologue_end => try emit.mirDbgPrologueEnd(inst),
189 .dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst),188 .dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst),
190 .arg_dbg_info => try emit.mirArgDbgInfo(inst),
191189
192 .push_regs_from_callee_preserved_regs => try emit.mirPushPopRegsFromCalleePreservedRegs(.push, inst),190 .push_regs_from_callee_preserved_regs => try emit.mirPushPopRegsFromCalleePreservedRegs(.push, inst),
193 .pop_regs_from_callee_preserved_regs => try emit.mirPushPopRegsFromCalleePreservedRegs(.pop, inst),191 .pop_regs_from_callee_preserved_regs => try emit.mirPushPopRegsFromCalleePreservedRegs(.pop, inst),
...@@ -1057,92 +1055,6 @@ fn mirDbgEpilogueBegin(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {...@@ -1057,92 +1055,6 @@ fn mirDbgEpilogueBegin(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1057 }1055 }
1058}1056}
10591057
1060fn mirArgDbgInfo(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
1061 const tag = emit.mir.instructions.items(.tag)[inst];
1062 assert(tag == .arg_dbg_info);
1063 const payload = emit.mir.instructions.items(.data)[inst].payload;
1064 const arg_dbg_info = emit.mir.extraData(Mir.ArgDbgInfo, payload).data;
1065 const mcv = emit.mir.function.args[arg_dbg_info.arg_index];
1066 try emit.genArgDbgInfo(arg_dbg_info.air_inst, mcv, arg_dbg_info.max_stack, arg_dbg_info.arg_index);
1067}
1068
1069fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32, arg_index: u32) !void {
1070 const ty = emit.mir.function.air.instructions.items(.data)[inst].ty;
1071 const name = emit.mir.function.mod_fn.getParamName(arg_index);
1072 const name_with_null = name.ptr[0 .. name.len + 1];
1073
1074 switch (mcv) {
1075 .register => |reg| {
1076 switch (emit.debug_output) {
1077 .dwarf => |dw| {
1078 const dbg_info = &dw.dbg_info;
1079 try dbg_info.ensureUnusedCapacity(3);
1080 dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_parameter);
1081 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
1082 1, // ULEB128 dwarf expression length
1083 reg.dwarfLocOp(),
1084 });
1085 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
1086 try emit.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
1087 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
1088 },
1089 .plan9 => {},
1090 .none => {},
1091 }
1092 },
1093 .stack_offset => |off| {
1094 switch (emit.debug_output) {
1095 .dwarf => |dw| {
1096 // we add here +16 like we do in airArg in CodeGen since we refer directly to
1097 // rbp as the start of function frame minus 8 bytes for caller's rbp preserved in the
1098 // prologue, and 8 bytes for return address.
1099 // TODO we need to make this more generic if we don't use rbp as the frame pointer
1100 // for example when -fomit-frame-pointer is set.
1101 const disp = @intCast(i32, max_stack) - off + 16;
1102 const dbg_info = &dw.dbg_info;
1103 try dbg_info.ensureUnusedCapacity(8);
1104 dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_parameter);
1105 const fixup = dbg_info.items.len;
1106 dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
1107 1, // we will backpatch it after we encode the displacement in LEB128
1108 DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer
1109 });
1110 leb128.writeILEB128(dbg_info.writer(), disp) catch unreachable;
1111 dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
1112 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
1113 try emit.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
1114 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
1115
1116 },
1117 .plan9 => {},
1118 .none => {},
1119 }
1120 },
1121 else => {},
1122 }
1123}
1124
1125/// Adds a Type to the .debug_info at the current position. The bytes will be populated later,
1126/// after codegen for this symbol is done.
1127fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {
1128 switch (emit.debug_output) {
1129 .dwarf => |dw| {
1130 assert(ty.hasRuntimeBits());
1131 const dbg_info = &dw.dbg_info;
1132 const index = dbg_info.items.len;
1133 try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
1134 const atom = switch (emit.bin_file.tag) {
1135 .elf => &emit.function.mod_fn.owner_decl.link.elf.dbg_info_atom,
1136 .macho => &emit.function.mod_fn.owner_decl.link.macho.dbg_info_atom,
1137 else => unreachable,
1138 };
1139 try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
1140 },
1141 .plan9 => {},
1142 .none => {},
1143 }
1144}
1145
1146const Tag = enum {1058const Tag = enum {
1147 adc,1059 adc,
1148 add,1060 add,
src/arch/x86_64/Mir.zig+6-16
...@@ -16,7 +16,6 @@ const Air = @import("../../Air.zig");...@@ -16,7 +16,6 @@ const Air = @import("../../Air.zig");
16const CodeGen = @import("CodeGen.zig");16const CodeGen = @import("CodeGen.zig");
17const Register = bits.Register;17const Register = bits.Register;
1818
19function: *const CodeGen,
20instructions: std.MultiArrayList(Inst).Slice,19instructions: std.MultiArrayList(Inst).Slice,
21/// The meaning of this data is determined by `Inst.Tag` value.20/// The meaning of this data is determined by `Inst.Tag` value.
22extra: []const u32,21extra: []const u32,
...@@ -364,9 +363,6 @@ pub const Inst = struct {...@@ -364,9 +363,6 @@ pub const Inst = struct {
364 /// update debug line363 /// update debug line
365 dbg_line,364 dbg_line,
366365
367 /// arg debug info
368 arg_dbg_info,
369
370 /// push registers from the callee_preserved_regs366 /// push registers from the callee_preserved_regs
371 /// data is the bitfield of which regs to push 367 /// data is the bitfield of which regs to push
372 /// for example on x86_64, the callee_preserved_regs are [_]Register{ .rcx, .rsi, .rdi, .r8, .r9, .r10, .r11 }; };368 /// for example on x86_64, the callee_preserved_regs are [_]Register{ .rcx, .rsi, .rdi, .r8, .r9, .r10, .r11 }; };
...@@ -453,18 +449,6 @@ pub const DbgLineColumn = struct {...@@ -453,18 +449,6 @@ pub const DbgLineColumn = struct {
453 column: u32,449 column: u32,
454};450};
455451
456pub const ArgDbgInfo = struct {
457 air_inst: Air.Inst.Index,
458 arg_index: u32,
459 max_stack: u32,
460};
461
462pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
463 mir.instructions.deinit(gpa);
464 gpa.free(mir.extra);
465 mir.* = undefined;
466}
467
468pub const Ops = struct {452pub const Ops = struct {
469 reg1: Register = .none,453 reg1: Register = .none,
470 reg2: Register = .none,454 reg2: Register = .none,
...@@ -490,6 +474,12 @@ pub const Ops = struct {...@@ -490,6 +474,12 @@ pub const Ops = struct {
490 }474 }
491};475};
492476
477pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
478 mir.instructions.deinit(gpa);
479 gpa.free(mir.extra);
480 mir.* = undefined;
481}
482
493pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {483pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
494 const fields = std.meta.fields(T);484 const fields = std.meta.fields(T);
495 var i: usize = index;485 var i: usize = index;
src/arch/x86_64/PrintMir.zig+1-1
...@@ -147,7 +147,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap...@@ -147,7 +147,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
147147
148 .call_extern => try print.mirCallExtern(inst, w),148 .call_extern => try print.mirCallExtern(inst, w),
149149
150 .dbg_line, .dbg_prologue_end, .dbg_epilogue_begin, .arg_dbg_info => try w.print("{s}\n", .{@tagName(tag)}),150 .dbg_line, .dbg_prologue_end, .dbg_epilogue_begin => try w.print("{s}\n", .{@tagName(tag)}),
151151
152 .push_regs_from_callee_preserved_regs => try print.mirPushPopRegsFromCalleePreservedRegs(.push, inst, w),152 .push_regs_from_callee_preserved_regs => try print.mirPushPopRegsFromCalleePreservedRegs(.push, inst, w),
153 .pop_regs_from_callee_preserved_regs => try print.mirPushPopRegsFromCalleePreservedRegs(.pop, inst, w),153 .pop_regs_from_callee_preserved_regs => try print.mirPushPopRegsFromCalleePreservedRegs(.pop, inst, w),
src/link/Dwarf.zig+74-64
...@@ -148,11 +148,11 @@ pub const DeclState = struct {...@@ -148,11 +148,11 @@ pub const DeclState = struct {
148 switch (ty.zigTypeTag()) {148 switch (ty.zigTypeTag()) {
149 .NoReturn => unreachable,149 .NoReturn => unreachable,
150 .Void => {150 .Void => {
151 try dbg_info_buffer.append(abbrev_pad1);151 try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));
152 },152 },
153 .Bool => {153 .Bool => {
154 try dbg_info_buffer.appendSlice(&[_]u8{154 try dbg_info_buffer.appendSlice(&[_]u8{
155 abbrev_base_type,155 @enumToInt(AbbrevKind.base_type),
156 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1156 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
157 1, // DW.AT.byte_size, DW.FORM.data1157 1, // DW.AT.byte_size, DW.FORM.data1
158 'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string158 'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string
...@@ -161,7 +161,7 @@ pub const DeclState = struct {...@@ -161,7 +161,7 @@ pub const DeclState = struct {
161 .Int => {161 .Int => {
162 const info = ty.intInfo(target);162 const info = ty.intInfo(target);
163 try dbg_info_buffer.ensureUnusedCapacity(12);163 try dbg_info_buffer.ensureUnusedCapacity(12);
164 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);164 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
165 // DW.AT.encoding, DW.FORM.data1165 // DW.AT.encoding, DW.FORM.data1
166 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {166 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {
167 .signed => DW.ATE.signed,167 .signed => DW.ATE.signed,
...@@ -175,7 +175,7 @@ pub const DeclState = struct {...@@ -175,7 +175,7 @@ pub const DeclState = struct {
175 .Optional => {175 .Optional => {
176 if (ty.isPtrLikeOptional()) {176 if (ty.isPtrLikeOptional()) {
177 try dbg_info_buffer.ensureUnusedCapacity(12);177 try dbg_info_buffer.ensureUnusedCapacity(12);
178 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);178 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
179 // DW.AT.encoding, DW.FORM.data1179 // DW.AT.encoding, DW.FORM.data1
180 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);180 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
181 // DW.AT.byte_size, DW.FORM.data1181 // DW.AT.byte_size, DW.FORM.data1
...@@ -187,7 +187,7 @@ pub const DeclState = struct {...@@ -187,7 +187,7 @@ pub const DeclState = struct {
187 var buf = try arena.create(Type.Payload.ElemType);187 var buf = try arena.create(Type.Payload.ElemType);
188 const payload_ty = ty.optionalChild(buf);188 const payload_ty = ty.optionalChild(buf);
189 // DW.AT.structure_type189 // DW.AT.structure_type
190 try dbg_info_buffer.append(abbrev_struct_type);190 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
191 // DW.AT.byte_size, DW.FORM.sdata191 // DW.AT.byte_size, DW.FORM.sdata
192 const abi_size = ty.abiSize(target);192 const abi_size = ty.abiSize(target);
193 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);193 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
...@@ -195,7 +195,7 @@ pub const DeclState = struct {...@@ -195,7 +195,7 @@ pub const DeclState = struct {
195 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});195 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
196 // DW.AT.member196 // DW.AT.member
197 try dbg_info_buffer.ensureUnusedCapacity(7);197 try dbg_info_buffer.ensureUnusedCapacity(7);
198 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);198 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
199 // DW.AT.name, DW.FORM.string199 // DW.AT.name, DW.FORM.string
200 dbg_info_buffer.appendSliceAssumeCapacity("maybe");200 dbg_info_buffer.appendSliceAssumeCapacity("maybe");
201 dbg_info_buffer.appendAssumeCapacity(0);201 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -207,7 +207,7 @@ pub const DeclState = struct {...@@ -207,7 +207,7 @@ pub const DeclState = struct {
207 try dbg_info_buffer.ensureUnusedCapacity(6);207 try dbg_info_buffer.ensureUnusedCapacity(6);
208 dbg_info_buffer.appendAssumeCapacity(0);208 dbg_info_buffer.appendAssumeCapacity(0);
209 // DW.AT.member209 // DW.AT.member
210 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);210 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
211 // DW.AT.name, DW.FORM.string211 // DW.AT.name, DW.FORM.string
212 dbg_info_buffer.appendSliceAssumeCapacity("val");212 dbg_info_buffer.appendSliceAssumeCapacity("val");
213 dbg_info_buffer.appendAssumeCapacity(0);213 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -227,14 +227,14 @@ pub const DeclState = struct {...@@ -227,14 +227,14 @@ pub const DeclState = struct {
227 // Slices are structs: struct { .ptr = *, .len = N }227 // Slices are structs: struct { .ptr = *, .len = N }
228 // DW.AT.structure_type228 // DW.AT.structure_type
229 try dbg_info_buffer.ensureUnusedCapacity(2);229 try dbg_info_buffer.ensureUnusedCapacity(2);
230 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_type);230 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type));
231 // DW.AT.byte_size, DW.FORM.sdata231 // DW.AT.byte_size, DW.FORM.sdata
232 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);232 dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
233 // DW.AT.name, DW.FORM.string233 // DW.AT.name, DW.FORM.string
234 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});234 try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
235 // DW.AT.member235 // DW.AT.member
236 try dbg_info_buffer.ensureUnusedCapacity(5);236 try dbg_info_buffer.ensureUnusedCapacity(5);
237 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);237 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
238 // DW.AT.name, DW.FORM.string238 // DW.AT.name, DW.FORM.string
239 dbg_info_buffer.appendSliceAssumeCapacity("ptr");239 dbg_info_buffer.appendSliceAssumeCapacity("ptr");
240 dbg_info_buffer.appendAssumeCapacity(0);240 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -248,7 +248,7 @@ pub const DeclState = struct {...@@ -248,7 +248,7 @@ pub const DeclState = struct {
248 try dbg_info_buffer.ensureUnusedCapacity(6);248 try dbg_info_buffer.ensureUnusedCapacity(6);
249 dbg_info_buffer.appendAssumeCapacity(0);249 dbg_info_buffer.appendAssumeCapacity(0);
250 // DW.AT.member250 // DW.AT.member
251 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);251 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
252 // DW.AT.name, DW.FORM.string252 // DW.AT.name, DW.FORM.string
253 dbg_info_buffer.appendSliceAssumeCapacity("len");253 dbg_info_buffer.appendSliceAssumeCapacity("len");
254 dbg_info_buffer.appendAssumeCapacity(0);254 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -263,7 +263,7 @@ pub const DeclState = struct {...@@ -263,7 +263,7 @@ pub const DeclState = struct {
263 dbg_info_buffer.appendAssumeCapacity(0);263 dbg_info_buffer.appendAssumeCapacity(0);
264 } else {264 } else {
265 try dbg_info_buffer.ensureUnusedCapacity(5);265 try dbg_info_buffer.ensureUnusedCapacity(5);
266 dbg_info_buffer.appendAssumeCapacity(abbrev_ptr_type);266 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.ptr_type));
267 // DW.AT.type, DW.FORM.ref4267 // DW.AT.type, DW.FORM.ref4
268 const index = dbg_info_buffer.items.len;268 const index = dbg_info_buffer.items.len;
269 try dbg_info_buffer.resize(index + 4);269 try dbg_info_buffer.resize(index + 4);
...@@ -272,7 +272,7 @@ pub const DeclState = struct {...@@ -272,7 +272,7 @@ pub const DeclState = struct {
272 },272 },
273 .Struct => blk: {273 .Struct => blk: {
274 // DW.AT.structure_type274 // DW.AT.structure_type
275 try dbg_info_buffer.append(abbrev_struct_type);275 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
276 // DW.AT.byte_size, DW.FORM.sdata276 // DW.AT.byte_size, DW.FORM.sdata
277 const abi_size = ty.abiSize(target);277 const abi_size = ty.abiSize(target);
278 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);278 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
...@@ -285,7 +285,7 @@ pub const DeclState = struct {...@@ -285,7 +285,7 @@ pub const DeclState = struct {
285 const fields = ty.tupleFields();285 const fields = ty.tupleFields();
286 for (fields.types) |field, field_index| {286 for (fields.types) |field, field_index| {
287 // DW.AT.member287 // DW.AT.member
288 try dbg_info_buffer.append(abbrev_struct_member);288 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
289 // DW.AT.name, DW.FORM.string289 // DW.AT.name, DW.FORM.string
290 try dbg_info_buffer.writer().print("{d}\x00", .{field_index});290 try dbg_info_buffer.writer().print("{d}\x00", .{field_index});
291 // DW.AT.type, DW.FORM.ref4291 // DW.AT.type, DW.FORM.ref4
...@@ -315,7 +315,7 @@ pub const DeclState = struct {...@@ -315,7 +315,7 @@ pub const DeclState = struct {
315 const field = fields.get(field_name).?;315 const field = fields.get(field_name).?;
316 // DW.AT.member316 // DW.AT.member
317 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);317 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
318 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);318 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
319 // DW.AT.name, DW.FORM.string319 // DW.AT.name, DW.FORM.string
320 dbg_info_buffer.appendSliceAssumeCapacity(field_name);320 dbg_info_buffer.appendSliceAssumeCapacity(field_name);
321 dbg_info_buffer.appendAssumeCapacity(0);321 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -335,7 +335,7 @@ pub const DeclState = struct {...@@ -335,7 +335,7 @@ pub const DeclState = struct {
335 },335 },
336 .Enum => {336 .Enum => {
337 // DW.AT.enumeration_type337 // DW.AT.enumeration_type
338 try dbg_info_buffer.append(abbrev_enum_type);338 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
339 // DW.AT.byte_size, DW.FORM.sdata339 // DW.AT.byte_size, DW.FORM.sdata
340 const abi_size = ty.abiSize(target);340 const abi_size = ty.abiSize(target);
341 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);341 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
...@@ -355,7 +355,7 @@ pub const DeclState = struct {...@@ -355,7 +355,7 @@ pub const DeclState = struct {
355 for (fields.keys()) |field_name, field_i| {355 for (fields.keys()) |field_name, field_i| {
356 // DW.AT.enumerator356 // DW.AT.enumerator
357 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2 + @sizeOf(u64));357 try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2 + @sizeOf(u64));
358 dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);358 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
359 // DW.AT.name, DW.FORM.string359 // DW.AT.name, DW.FORM.string
360 dbg_info_buffer.appendSliceAssumeCapacity(field_name);360 dbg_info_buffer.appendSliceAssumeCapacity(field_name);
361 dbg_info_buffer.appendAssumeCapacity(0);361 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -385,7 +385,7 @@ pub const DeclState = struct {...@@ -385,7 +385,7 @@ pub const DeclState = struct {
385 // for untagged unions.385 // for untagged unions.
386 if (is_tagged) {386 if (is_tagged) {
387 // DW.AT.structure_type387 // DW.AT.structure_type
388 try dbg_info_buffer.append(abbrev_struct_type);388 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
389 // DW.AT.byte_size, DW.FORM.sdata389 // DW.AT.byte_size, DW.FORM.sdata
390 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);390 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);
391 // DW.AT.name, DW.FORM.string391 // DW.AT.name, DW.FORM.string
...@@ -395,7 +395,7 @@ pub const DeclState = struct {...@@ -395,7 +395,7 @@ pub const DeclState = struct {
395395
396 // DW.AT.member396 // DW.AT.member
397 try dbg_info_buffer.ensureUnusedCapacity(9);397 try dbg_info_buffer.ensureUnusedCapacity(9);
398 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);398 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
399 // DW.AT.name, DW.FORM.string399 // DW.AT.name, DW.FORM.string
400 dbg_info_buffer.appendSliceAssumeCapacity("payload");400 dbg_info_buffer.appendSliceAssumeCapacity("payload");
401 dbg_info_buffer.appendAssumeCapacity(0);401 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -408,7 +408,7 @@ pub const DeclState = struct {...@@ -408,7 +408,7 @@ pub const DeclState = struct {
408 }408 }
409409
410 // DW.AT.union_type410 // DW.AT.union_type
411 try dbg_info_buffer.append(abbrev_union_type);411 try dbg_info_buffer.append(@enumToInt(AbbrevKind.union_type));
412 // DW.AT.byte_size, DW.FORM.sdata,412 // DW.AT.byte_size, DW.FORM.sdata,
413 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.payload_size);413 try leb128.writeULEB128(dbg_info_buffer.writer(), layout.payload_size);
414 // DW.AT.name, DW.FORM.string414 // DW.AT.name, DW.FORM.string
...@@ -423,7 +423,7 @@ pub const DeclState = struct {...@@ -423,7 +423,7 @@ pub const DeclState = struct {
423 const field = fields.get(field_name).?;423 const field = fields.get(field_name).?;
424 if (!field.ty.hasRuntimeBits()) continue;424 if (!field.ty.hasRuntimeBits()) continue;
425 // DW.AT.member425 // DW.AT.member
426 try dbg_info_buffer.append(abbrev_struct_member);426 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
427 // DW.AT.name, DW.FORM.string427 // DW.AT.name, DW.FORM.string
428 try dbg_info_buffer.writer().print("{s}\x00", .{field_name});428 try dbg_info_buffer.writer().print("{s}\x00", .{field_name});
429 // DW.AT.type, DW.FORM.ref4429 // DW.AT.type, DW.FORM.ref4
...@@ -439,7 +439,7 @@ pub const DeclState = struct {...@@ -439,7 +439,7 @@ pub const DeclState = struct {
439 if (is_tagged) {439 if (is_tagged) {
440 // DW.AT.member440 // DW.AT.member
441 try dbg_info_buffer.ensureUnusedCapacity(5);441 try dbg_info_buffer.ensureUnusedCapacity(5);
442 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);442 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
443 // DW.AT.name, DW.FORM.string443 // DW.AT.name, DW.FORM.string
444 dbg_info_buffer.appendSliceAssumeCapacity("tag");444 dbg_info_buffer.appendSliceAssumeCapacity("tag");
445 dbg_info_buffer.appendAssumeCapacity(0);445 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -471,7 +471,7 @@ pub const DeclState = struct {...@@ -471,7 +471,7 @@ pub const DeclState = struct {
471 const payload_off = mem.alignForwardGeneric(u64, error_ty.abiSize(target), abi_align);471 const payload_off = mem.alignForwardGeneric(u64, error_ty.abiSize(target), abi_align);
472472
473 // DW.AT.structure_type473 // DW.AT.structure_type
474 try dbg_info_buffer.append(abbrev_struct_type);474 try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
475 // DW.AT.byte_size, DW.FORM.sdata475 // DW.AT.byte_size, DW.FORM.sdata
476 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);476 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
477 // DW.AT.name, DW.FORM.string477 // DW.AT.name, DW.FORM.string
...@@ -480,7 +480,7 @@ pub const DeclState = struct {...@@ -480,7 +480,7 @@ pub const DeclState = struct {
480480
481 // DW.AT.member481 // DW.AT.member
482 try dbg_info_buffer.ensureUnusedCapacity(7);482 try dbg_info_buffer.ensureUnusedCapacity(7);
483 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);483 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
484 // DW.AT.name, DW.FORM.string484 // DW.AT.name, DW.FORM.string
485 dbg_info_buffer.appendSliceAssumeCapacity("value");485 dbg_info_buffer.appendSliceAssumeCapacity("value");
486 dbg_info_buffer.appendAssumeCapacity(0);486 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -493,7 +493,7 @@ pub const DeclState = struct {...@@ -493,7 +493,7 @@ pub const DeclState = struct {
493493
494 // DW.AT.member494 // DW.AT.member
495 try dbg_info_buffer.ensureUnusedCapacity(5);495 try dbg_info_buffer.ensureUnusedCapacity(5);
496 dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);496 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
497 // DW.AT.name, DW.FORM.string497 // DW.AT.name, DW.FORM.string
498 dbg_info_buffer.appendSliceAssumeCapacity("err");498 dbg_info_buffer.appendSliceAssumeCapacity("err");
499 dbg_info_buffer.appendAssumeCapacity(0);499 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -509,7 +509,7 @@ pub const DeclState = struct {...@@ -509,7 +509,7 @@ pub const DeclState = struct {
509 },509 },
510 else => {510 else => {
511 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});511 log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
512 try dbg_info_buffer.append(abbrev_pad1);512 try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));
513 },513 },
514 }514 }
515 }515 }
...@@ -550,18 +550,21 @@ pub const SrcFn = struct {...@@ -550,18 +550,21 @@ pub const SrcFn = struct {
550550
551pub const PtrWidth = enum { p32, p64 };551pub const PtrWidth = enum { p32, p64 };
552552
553pub const abbrev_compile_unit = 1;553pub const AbbrevKind = enum(u8) {
554pub const abbrev_subprogram = 2;554 compile_unit = 1,
555pub const abbrev_subprogram_retvoid = 3;555 subprogram,
556pub const abbrev_base_type = 4;556 subprogram_retvoid,
557pub const abbrev_ptr_type = 5;557 base_type,
558pub const abbrev_struct_type = 6;558 ptr_type,
559pub const abbrev_struct_member = 7;559 struct_type,
560pub const abbrev_enum_type = 8;560 struct_member,
561pub const abbrev_enum_variant = 9;561 enum_type,
562pub const abbrev_union_type = 10;562 enum_variant,
563pub const abbrev_pad1 = 11;563 union_type,
564pub const abbrev_parameter = 12;564 pad1,
565 parameter,
566 variable,
567};
565568
566/// The reloc offset for the virtual address of a function in its Line Number Program.569/// The reloc offset for the virtual address of a function in its Line Number Program.
567/// Size is a virtual address integer.570/// Size is a virtual address integer.
...@@ -670,9 +673,9 @@ pub fn initDeclState(self: *Dwarf, decl: *Module.Decl) !DeclState {...@@ -670,9 +673,9 @@ pub fn initDeclState(self: *Dwarf, decl: *Module.Decl) !DeclState {
670 const fn_ret_type = decl.ty.fnReturnType();673 const fn_ret_type = decl.ty.fnReturnType();
671 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits();674 const fn_ret_has_bits = fn_ret_type.hasRuntimeBits();
672 if (fn_ret_has_bits) {675 if (fn_ret_has_bits) {
673 dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram);676 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram));
674 } else {677 } else {
675 dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram_retvoid);678 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram_retvoid));
676 }679 }
677 // These get overwritten after generating the machine code. These values are680 // These get overwritten after generating the machine code. These values are
678 // "relocations" and have to be in this fixed place so that functions can be681 // "relocations" and have to be in this fixed place so that functions can be
...@@ -926,7 +929,7 @@ pub fn commitDeclState(...@@ -926,7 +929,7 @@ pub fn commitDeclState(
926 else => unreachable,929 else => unreachable,
927 };930 };
928931
929 {932 if (decl_state.abbrev_table.items.len > 0) {
930 // Now we emit the .debug_info types of the Decl. These will count towards the size of933 // Now we emit the .debug_info types of the Decl. These will count towards the size of
931 // the buffer, so we have to do it before computing the offset, and we can't perform the actual934 // the buffer, so we have to do it before computing the offset, and we can't perform the actual
932 // relocations yet.935 // relocations yet.
...@@ -1244,14 +1247,14 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1244,14 +1247,14 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1244 // These are LEB encoded but since the values are all less than 1271247 // These are LEB encoded but since the values are all less than 127
1245 // we can simply append these bytes.1248 // we can simply append these bytes.
1246 const abbrev_buf = [_]u8{1249 const abbrev_buf = [_]u8{
1247 abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header1250 @enumToInt(AbbrevKind.compile_unit), DW.TAG.compile_unit, DW.CHILDREN.yes, // header
1248 DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc,1251 DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc,
1249 DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr,1252 DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr,
1250 DW.AT.name, DW.FORM.strp, DW.AT.comp_dir,1253 DW.AT.name, DW.FORM.strp, DW.AT.comp_dir,
1251 DW.FORM.strp, DW.AT.producer, DW.FORM.strp,1254 DW.FORM.strp, DW.AT.producer, DW.FORM.strp,
1252 DW.AT.language, DW.FORM.data2, 0,1255 DW.AT.language, DW.FORM.data2, 0,
1253 0, // table sentinel1256 0, // table sentinel
1254 abbrev_subprogram,1257 @enumToInt(AbbrevKind.subprogram),
1255 DW.TAG.subprogram,1258 DW.TAG.subprogram,
1256 DW.CHILDREN.yes, // header1259 DW.CHILDREN.yes, // header
1257 DW.AT.low_pc,1260 DW.AT.low_pc,
...@@ -1262,15 +1265,15 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1262,15 +1265,15 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1262 DW.FORM.ref4,1265 DW.FORM.ref4,
1263 DW.AT.name,1266 DW.AT.name,
1264 DW.FORM.string,1267 DW.FORM.string,
1265 0, 0, // table sentinel1268 0, 0, // table sentinel
1266 abbrev_subprogram_retvoid,1269 @enumToInt(AbbrevKind.subprogram_retvoid),
1267 DW.TAG.subprogram, DW.CHILDREN.yes, // header1270 DW.TAG.subprogram, DW.CHILDREN.yes, // header
1268 DW.AT.low_pc, DW.FORM.addr,1271 DW.AT.low_pc, DW.FORM.addr,
1269 DW.AT.high_pc, DW.FORM.data4,1272 DW.AT.high_pc, DW.FORM.data4,
1270 DW.AT.name, DW.FORM.string,1273 DW.AT.name, DW.FORM.string,
1271 0,1274 0,
1272 0, // table sentinel1275 0, // table sentinel
1273 abbrev_base_type,1276 @enumToInt(AbbrevKind.base_type),
1274 DW.TAG.base_type,1277 DW.TAG.base_type,
1275 DW.CHILDREN.no, // header1278 DW.CHILDREN.no, // header
1276 DW.AT.encoding,1279 DW.AT.encoding,
...@@ -1281,14 +1284,14 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1281,14 +1284,14 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1281 DW.FORM.string,1284 DW.FORM.string,
1282 0,1285 0,
1283 0, // table sentinel1286 0, // table sentinel
1284 abbrev_ptr_type,1287 @enumToInt(AbbrevKind.ptr_type),
1285 DW.TAG.pointer_type,1288 DW.TAG.pointer_type,
1286 DW.CHILDREN.no, // header1289 DW.CHILDREN.no, // header
1287 DW.AT.type,1290 DW.AT.type,
1288 DW.FORM.ref4,1291 DW.FORM.ref4,
1289 0,1292 0,
1290 0, // table sentinel1293 0, // table sentinel
1291 abbrev_struct_type,1294 @enumToInt(AbbrevKind.struct_type),
1292 DW.TAG.structure_type,1295 DW.TAG.structure_type,
1293 DW.CHILDREN.yes, // header1296 DW.CHILDREN.yes, // header
1294 DW.AT.byte_size,1297 DW.AT.byte_size,
...@@ -1297,7 +1300,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1297,7 +1300,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1297 DW.FORM.string,1300 DW.FORM.string,
1298 0,1301 0,
1299 0, // table sentinel1302 0, // table sentinel
1300 abbrev_struct_member,1303 @enumToInt(AbbrevKind.struct_member),
1301 DW.TAG.member,1304 DW.TAG.member,
1302 DW.CHILDREN.no, // header1305 DW.CHILDREN.no, // header
1303 DW.AT.name,1306 DW.AT.name,
...@@ -1308,7 +1311,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1308,7 +1311,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1308 DW.FORM.sdata,1311 DW.FORM.sdata,
1309 0,1312 0,
1310 0, // table sentinel1313 0, // table sentinel
1311 abbrev_enum_type,1314 @enumToInt(AbbrevKind.enum_type),
1312 DW.TAG.enumeration_type,1315 DW.TAG.enumeration_type,
1313 DW.CHILDREN.yes, // header1316 DW.CHILDREN.yes, // header
1314 DW.AT.byte_size,1317 DW.AT.byte_size,
...@@ -1317,7 +1320,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1317,7 +1320,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1317 DW.FORM.string,1320 DW.FORM.string,
1318 0,1321 0,
1319 0, // table sentinel1322 0, // table sentinel
1320 abbrev_enum_variant,1323 @enumToInt(AbbrevKind.enum_variant),
1321 DW.TAG.enumerator,1324 DW.TAG.enumerator,
1322 DW.CHILDREN.no, // header1325 DW.CHILDREN.no, // header
1323 DW.AT.name,1326 DW.AT.name,
...@@ -1326,7 +1329,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1326,7 +1329,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1326 DW.FORM.data8,1329 DW.FORM.data8,
1327 0,1330 0,
1328 0, // table sentinel1331 0, // table sentinel
1329 abbrev_union_type,1332 @enumToInt(AbbrevKind.union_type),
1330 DW.TAG.union_type,1333 DW.TAG.union_type,
1331 DW.CHILDREN.yes, // header1334 DW.CHILDREN.yes, // header
1332 DW.AT.byte_size,1335 DW.AT.byte_size,
...@@ -1335,18 +1338,25 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {...@@ -1335,18 +1338,25 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
1335 DW.FORM.string,1338 DW.FORM.string,
1336 0,1339 0,
1337 0, // table sentinel1340 0, // table sentinel
1338 abbrev_pad1,1341 @enumToInt(AbbrevKind.pad1),
1339 DW.TAG.unspecified_type,1342 DW.TAG.unspecified_type,
1340 DW.CHILDREN.no, // header1343 DW.CHILDREN.no, // header
1341 0,1344 0,
1342 0, // table sentinel1345 0, // table sentinel
1343 abbrev_parameter,1346 @enumToInt(AbbrevKind.parameter),
1344 DW.TAG.formal_parameter, DW.CHILDREN.no, // header1347 DW.TAG.formal_parameter, DW.CHILDREN.no, // header
1345 DW.AT.location, DW.FORM.exprloc,1348 DW.AT.location, DW.FORM.exprloc,
1346 DW.AT.type, DW.FORM.ref4,1349 DW.AT.type, DW.FORM.ref4,
1347 DW.AT.name, DW.FORM.string,1350 DW.AT.name, DW.FORM.string,
1348 0,1351 0,
1349 0, // table sentinel1352 0, // table sentinel
1353 @enumToInt(AbbrevKind.variable),
1354 DW.TAG.variable, DW.CHILDREN.no, // header
1355 DW.AT.location, DW.FORM.exprloc,
1356 DW.AT.type, DW.FORM.ref4,
1357 DW.AT.name, DW.FORM.string,
1358 0,
1359 0, // table sentinel
1350 0,1360 0,
1351 0,1361 0,
1352 0, // section sentinel1362 0, // section sentinel
...@@ -1459,7 +1469,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6...@@ -1459,7 +1469,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
1459 const comp_dir_strp = try self.makeString(module.root_pkg.root_src_directory.path orelse ".");1469 const comp_dir_strp = try self.makeString(module.root_pkg.root_src_directory.path orelse ".");
1460 const producer_strp = try self.makeString(link.producer_string);1470 const producer_strp = try self.makeString(link.producer_string);
14611471
1462 di_buf.appendAssumeCapacity(abbrev_compile_unit);1472 di_buf.appendAssumeCapacity(@enumToInt(AbbrevKind.compile_unit));
1463 if (self.tag == .macho) {1473 if (self.tag == .macho) {
1464 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset1474 mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset
1465 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);1475 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);
...@@ -1606,7 +1616,7 @@ fn pwriteDbgInfoNops(...@@ -1606,7 +1616,7 @@ fn pwriteDbgInfoNops(
1606 const tracy = trace(@src());1616 const tracy = trace(@src());
1607 defer tracy.end();1617 defer tracy.end();
16081618
1609 const page_of_nops = [1]u8{abbrev_pad1} ** 4096;1619 const page_of_nops = [1]u8{@enumToInt(AbbrevKind.pad1)} ** 4096;
1610 var vecs: [32]std.os.iovec_const = undefined;1620 var vecs: [32]std.os.iovec_const = undefined;
1611 var vec_index: usize = 0;1621 var vec_index: usize = 0;
1612 {1622 {
...@@ -1673,7 +1683,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {...@@ -1673,7 +1683,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
1673 .p32 => @as(usize, 4),1683 .p32 => @as(usize, 4),
1674 .p64 => 12,1684 .p64 => 12,
1675 };1685 };
1676 const ptr_width_bytes: u8 = self.ptrWidthBytes();1686 const ptr_width_bytes = self.ptrWidthBytes();
16771687
1678 // Enough for all the data without resizing. When support for more compilation units1688 // Enough for all the data without resizing. When support for more compilation units
1679 // is added, the size of this section will become more variable.1689 // is added, the size of this section will become more variable.
...@@ -2040,7 +2050,7 @@ fn addDbgInfoErrorSet(...@@ -2040,7 +2050,7 @@ fn addDbgInfoErrorSet(
2040 const target_endian = target.cpu.arch.endian();2050 const target_endian = target.cpu.arch.endian();
20412051
2042 // DW.AT.enumeration_type2052 // DW.AT.enumeration_type
2043 try dbg_info_buffer.append(abbrev_enum_type);2053 try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
2044 // DW.AT.byte_size, DW.FORM.sdata2054 // DW.AT.byte_size, DW.FORM.sdata
2045 const abi_size = ty.abiSize(target);2055 const abi_size = ty.abiSize(target);
2046 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);2056 try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
...@@ -2051,7 +2061,7 @@ fn addDbgInfoErrorSet(...@@ -2051,7 +2061,7 @@ fn addDbgInfoErrorSet(
2051 // DW.AT.enumerator2061 // DW.AT.enumerator
2052 const no_error = "(no error)";2062 const no_error = "(no error)";
2053 try dbg_info_buffer.ensureUnusedCapacity(no_error.len + 2 + @sizeOf(u64));2063 try dbg_info_buffer.ensureUnusedCapacity(no_error.len + 2 + @sizeOf(u64));
2054 dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);2064 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
2055 // DW.AT.name, DW.FORM.string2065 // DW.AT.name, DW.FORM.string
2056 dbg_info_buffer.appendSliceAssumeCapacity(no_error);2066 dbg_info_buffer.appendSliceAssumeCapacity(no_error);
2057 dbg_info_buffer.appendAssumeCapacity(0);2067 dbg_info_buffer.appendAssumeCapacity(0);
...@@ -2063,7 +2073,7 @@ fn addDbgInfoErrorSet(...@@ -2063,7 +2073,7 @@ fn addDbgInfoErrorSet(
2063 const kv = module.getErrorValue(error_name) catch unreachable;2073 const kv = module.getErrorValue(error_name) catch unreachable;
2064 // DW.AT.enumerator2074 // DW.AT.enumerator
2065 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));2075 try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
2066 dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);2076 dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
2067 // DW.AT.name, DW.FORM.string2077 // DW.AT.name, DW.FORM.string
2068 dbg_info_buffer.appendSliceAssumeCapacity(error_name);2078 dbg_info_buffer.appendSliceAssumeCapacity(error_name);
2069 dbg_info_buffer.appendAssumeCapacity(0);2079 dbg_info_buffer.appendAssumeCapacity(0);