Commit 364e53f3bf
Changed files (7)
src
arch
link
src/arch/arm/Emit.zig
@@ -417,7 +417,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
.dwarf => |dw| {
const dbg_info = &dw.dbg_info;
try dbg_info.ensureUnusedCapacity(3);
- dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_parameter);
+ 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(),
@@ -449,7 +449,7 @@ fn genArgDbgInfo(self: *Emit, inst: Air.Inst.Index, arg_index: u32) !void {
};
const dbg_info = &dw.dbg_info;
- try dbg_info.append(link.File.Dwarf.abbrev_parameter);
+ try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.parameter));
// Get length of the LEB128 stack offset
var counting_writer = std.io.countingWriter(std.io.null_writer);
src/arch/riscv64/CodeGen.zig
@@ -1574,7 +1574,7 @@ fn genArgDbgInfo(self: *Self, inst: Air.Inst.Index, mcv: MCValue, arg_index: u32
.dwarf => |dw| {
const dbg_info = &dw.dbg_info;
try dbg_info.ensureUnusedCapacity(3);
- dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_parameter);
+ 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(),
src/arch/x86_64/CodeGen.zig
@@ -48,6 +48,7 @@ gpa: Allocator,
air: Air,
liveness: Liveness,
bin_file: *link.File,
+debug_output: DebugInfoOutput,
target: *const std.Target,
mod_fn: *const Module.Fn,
err_msg: ?*ErrorMsg,
@@ -337,6 +338,7 @@ pub fn generate(
.liveness = liveness,
.target = &bin_file.options.target,
.bin_file = bin_file,
+ .debug_output = debug_output,
.mod_fn = module_fn,
.err_msg = null,
.args = undefined, // populated after `resolveCallingConventionValues`
@@ -382,7 +384,6 @@ pub fn generate(
};
var mir = Mir{
- .function = &function,
.instructions = function.mir_instructions.toOwnedSlice(),
.extra = function.mir_extra.toOwnedSlice(bin_file.allocator),
};
@@ -391,7 +392,6 @@ pub fn generate(
var emit = Emit{
.mir = mir,
.bin_file = bin_file,
- .function = &function,
.debug_output = debug_output,
.target = &bin_file.options.target,
.src_loc = src_loc,
@@ -3425,17 +3425,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
const arg_index = self.arg_index;
self.arg_index += 1;
+ const ty = self.air.typeOfIndex(inst);
const mcv = self.args[arg_index];
- const payload = try self.addExtra(Mir.ArgDbgInfo{
- .air_inst = inst,
- .arg_index = arg_index,
- .max_stack = self.max_end_stack,
- });
- _ = try self.addInst(.{
- .tag = .arg_dbg_info,
- .ops = undefined,
- .data = .{ .payload = payload },
- });
+ const name = self.mod_fn.getParamName(arg_index);
+ const name_with_null = name.ptr[0 .. name.len + 1];
+
if (self.liveness.isUnused(inst))
return self.finishAirBookkeeping();
@@ -3443,10 +3437,46 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
switch (mcv) {
.register => |reg| {
self.register_manager.getRegAssumeFree(reg.to64(), inst);
+ switch (self.debug_output) {
+ .dwarf => |dw| {
+ const dbg_info = &dw.dbg_info;
+ 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
+ },
+ .plan9 => {},
+ .none => {},
+ }
break :blk mcv;
},
.stack_offset => |off| {
const offset = @intCast(i32, self.max_end_stack) - off + 16;
+ switch (self.debug_output) {
+ .dwarf => |dw| {
+ const dbg_info = &dw.dbg_info;
+ 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
+ DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer
+ });
+ leb128.writeILEB128(dbg_info.writer(), 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 self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
+ dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
+
+ },
+ .plan9 => {},
+ .none => {},
+ }
break :blk MCValue{ .stack_offset = -offset };
},
else => return self.fail("TODO implement arg for {}", .{mcv}),
@@ -3885,13 +3915,99 @@ fn airDbgBlock(self: *Self, inst: Air.Inst.Index) !void {
fn airDbgVar(self: *Self, inst: Air.Inst.Index) !void {
const pl_op = self.air.instructions.items(.data)[inst].pl_op;
- const name = self.air.nullTerminatedString(pl_op.payload);
const operand = pl_op.operand;
- // TODO emit debug info for this variable
- _ = name;
+ const ty = self.air.typeOf(operand);
+
+ if (!self.liveness.operandDies(inst, 0)) {
+ const mcv = try self.resolveInst(operand);
+ const name = self.air.nullTerminatedString(pl_op.payload);
+
+ const tag = self.air.instructions.items(.tag)[inst];
+ switch (tag) {
+ .dbg_var_ptr => try self.genVarDbgInfo(ty.childType(), mcv, name),
+ .dbg_var_val => try self.genVarDbgInfo(ty, mcv, name),
+ else => unreachable,
+ }
+ }
+
return self.finishAir(inst, .dead, .{ operand, .none, .none });
}
+fn genVarDbgInfo(
+ self: *Self,
+ ty: Type,
+ mcv: MCValue,
+ name: [:0]const u8,
+) !void {
+ const name_with_null = name.ptr[0 .. name.len + 1];
+ switch (mcv) {
+ .register => |reg| {
+ switch (self.debug_output) {
+ .dwarf => |dw| {
+ const dbg_info = &dw.dbg_info;
+ try dbg_info.ensureUnusedCapacity(3);
+ dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
+ 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
+ },
+ .plan9 => {},
+ .none => {},
+ }
+ },
+ .ptr_stack_offset, .stack_offset => |off| {
+ switch (self.debug_output) {
+ .dwarf => |dw| {
+ const dbg_info = &dw.dbg_info;
+ try dbg_info.ensureUnusedCapacity(8);
+ dbg_info.appendAssumeCapacity(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
+ 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
+ DW.OP.breg6, // .rbp 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
+
+ },
+ .plan9 => {},
+ .none => {},
+ }
+ },
+ else => {
+ log.debug("TODO generate debug info for {}", .{mcv});
+ },
+ }
+}
+
+/// Adds a Type to the .debug_info at the current position. The bytes will be populated later,
+/// after codegen for this symbol is done.
+fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
+ switch (self.debug_output) {
+ .dwarf => |dw| {
+ assert(ty.hasRuntimeBits());
+ const dbg_info = &dw.dbg_info;
+ const index = dbg_info.items.len;
+ try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
+ const atom = switch (self.bin_file.tag) {
+ .elf => &self.mod_fn.owner_decl.link.elf.dbg_info_atom,
+ .macho => &self.mod_fn.owner_decl.link.macho.dbg_info_atom,
+ else => unreachable,
+ };
+ try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
+ },
+ .plan9 => {},
+ .none => {},
+ }
+}
+
fn genCondBrMir(self: *Self, ty: Type, mcv: MCValue) !u32 {
const abi_size = ty.abiSize(self.target.*);
switch (mcv) {
@@ -5919,7 +6035,7 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void {
return self.finishAir(inst, result, .{ extra.lhs, extra.rhs, pl_op.operand });
}
-fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
+pub fn resolveInst(self: *Self, inst: Air.Inst.Ref) InnerError!MCValue {
// First section of indexes correspond to a set number of constant values.
const ref_int = @enumToInt(inst);
if (ref_int < Air.Inst.Ref.typed_value_map.len) {
src/arch/x86_64/Emit.zig
@@ -30,7 +30,6 @@ const Type = @import("../../type.zig").Type;
mir: Mir,
bin_file: *link.File,
-function: *const CodeGen,
debug_output: DebugInfoOutput,
target: *const std.Target,
err_msg: ?*ErrorMsg = null,
@@ -187,7 +186,6 @@ pub fn lowerMir(emit: *Emit) InnerError!void {
.dbg_line => try emit.mirDbgLine(inst),
.dbg_prologue_end => try emit.mirDbgPrologueEnd(inst),
.dbg_epilogue_begin => try emit.mirDbgEpilogueBegin(inst),
- .arg_dbg_info => try emit.mirArgDbgInfo(inst),
.push_regs_from_callee_preserved_regs => try emit.mirPushPopRegsFromCalleePreservedRegs(.push, inst),
.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 {
}
}
-fn mirArgDbgInfo(emit: *Emit, inst: Mir.Inst.Index) InnerError!void {
- const tag = emit.mir.instructions.items(.tag)[inst];
- assert(tag == .arg_dbg_info);
- const payload = emit.mir.instructions.items(.data)[inst].payload;
- const arg_dbg_info = emit.mir.extraData(Mir.ArgDbgInfo, payload).data;
- const mcv = emit.mir.function.args[arg_dbg_info.arg_index];
- try emit.genArgDbgInfo(arg_dbg_info.air_inst, mcv, arg_dbg_info.max_stack, arg_dbg_info.arg_index);
-}
-
-fn genArgDbgInfo(emit: *Emit, inst: Air.Inst.Index, mcv: MCValue, max_stack: u32, arg_index: u32) !void {
- const ty = emit.mir.function.air.instructions.items(.data)[inst].ty;
- const name = emit.mir.function.mod_fn.getParamName(arg_index);
- const name_with_null = name.ptr[0 .. name.len + 1];
-
- switch (mcv) {
- .register => |reg| {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- const dbg_info = &dw.dbg_info;
- try dbg_info.ensureUnusedCapacity(3);
- dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_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 emit.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
- dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
- },
- .plan9 => {},
- .none => {},
- }
- },
- .stack_offset => |off| {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- // we add here +16 like we do in airArg in CodeGen since we refer directly to
- // rbp as the start of function frame minus 8 bytes for caller's rbp preserved in the
- // prologue, and 8 bytes for return address.
- // TODO we need to make this more generic if we don't use rbp as the frame pointer
- // for example when -fomit-frame-pointer is set.
- const disp = @intCast(i32, max_stack) - off + 16;
- const dbg_info = &dw.dbg_info;
- try dbg_info.ensureUnusedCapacity(8);
- dbg_info.appendAssumeCapacity(link.File.Dwarf.abbrev_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
- DW.OP.breg6, // .rbp TODO handle -fomit-frame-pointer
- });
- leb128.writeILEB128(dbg_info.writer(), disp) catch unreachable;
- dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
- try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
- try emit.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
- dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
-
- },
- .plan9 => {},
- .none => {},
- }
- },
- else => {},
- }
-}
-
-/// Adds a Type to the .debug_info at the current position. The bytes will be populated later,
-/// after codegen for this symbol is done.
-fn addDbgInfoTypeReloc(emit: *Emit, ty: Type) !void {
- switch (emit.debug_output) {
- .dwarf => |dw| {
- assert(ty.hasRuntimeBits());
- const dbg_info = &dw.dbg_info;
- const index = dbg_info.items.len;
- try dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
- const atom = switch (emit.bin_file.tag) {
- .elf => &emit.function.mod_fn.owner_decl.link.elf.dbg_info_atom,
- .macho => &emit.function.mod_fn.owner_decl.link.macho.dbg_info_atom,
- else => unreachable,
- };
- try dw.addTypeReloc(atom, ty, @intCast(u32, index), null);
- },
- .plan9 => {},
- .none => {},
- }
-}
-
const Tag = enum {
adc,
add,
src/arch/x86_64/Mir.zig
@@ -16,7 +16,6 @@ const Air = @import("../../Air.zig");
const CodeGen = @import("CodeGen.zig");
const Register = bits.Register;
-function: *const CodeGen,
instructions: std.MultiArrayList(Inst).Slice,
/// The meaning of this data is determined by `Inst.Tag` value.
extra: []const u32,
@@ -364,9 +363,6 @@ pub const Inst = struct {
/// update debug line
dbg_line,
- /// arg debug info
- arg_dbg_info,
-
/// push registers from the callee_preserved_regs
/// data is the bitfield of which regs to push
/// 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 {
column: u32,
};
-pub const ArgDbgInfo = struct {
- air_inst: Air.Inst.Index,
- arg_index: u32,
- max_stack: u32,
-};
-
-pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
- mir.instructions.deinit(gpa);
- gpa.free(mir.extra);
- mir.* = undefined;
-}
-
pub const Ops = struct {
reg1: Register = .none,
reg2: Register = .none,
@@ -490,6 +474,12 @@ pub const Ops = struct {
}
};
+pub fn deinit(mir: *Mir, gpa: std.mem.Allocator) void {
+ mir.instructions.deinit(gpa);
+ gpa.free(mir.extra);
+ mir.* = undefined;
+}
+
pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } {
const fields = std.meta.fields(T);
var i: usize = index;
src/arch/x86_64/PrintMir.zig
@@ -147,7 +147,7 @@ pub fn printMir(print: *const Print, w: anytype, mir_to_air_map: std.AutoHashMap
.call_extern => try print.mirCallExtern(inst, w),
- .dbg_line, .dbg_prologue_end, .dbg_epilogue_begin, .arg_dbg_info => try w.print("{s}\n", .{@tagName(tag)}),
+ .dbg_line, .dbg_prologue_end, .dbg_epilogue_begin => try w.print("{s}\n", .{@tagName(tag)}),
.push_regs_from_callee_preserved_regs => try print.mirPushPopRegsFromCalleePreservedRegs(.push, inst, w),
.pop_regs_from_callee_preserved_regs => try print.mirPushPopRegsFromCalleePreservedRegs(.pop, inst, w),
src/link/Dwarf.zig
@@ -148,11 +148,11 @@ pub const DeclState = struct {
switch (ty.zigTypeTag()) {
.NoReturn => unreachable,
.Void => {
- try dbg_info_buffer.append(abbrev_pad1);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));
},
.Bool => {
try dbg_info_buffer.appendSlice(&[_]u8{
- abbrev_base_type,
+ @enumToInt(AbbrevKind.base_type),
DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
1, // DW.AT.byte_size, DW.FORM.data1
'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string
@@ -161,7 +161,7 @@ pub const DeclState = struct {
.Int => {
const info = ty.intInfo(target);
try dbg_info_buffer.ensureUnusedCapacity(12);
- dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
// DW.AT.encoding, DW.FORM.data1
dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {
.signed => DW.ATE.signed,
@@ -175,7 +175,7 @@ pub const DeclState = struct {
.Optional => {
if (ty.isPtrLikeOptional()) {
try dbg_info_buffer.ensureUnusedCapacity(12);
- dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.base_type));
// DW.AT.encoding, DW.FORM.data1
dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
// DW.AT.byte_size, DW.FORM.data1
@@ -187,7 +187,7 @@ pub const DeclState = struct {
var buf = try arena.create(Type.Payload.ElemType);
const payload_ty = ty.optionalChild(buf);
// DW.AT.structure_type
- try dbg_info_buffer.append(abbrev_struct_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
// DW.AT.byte_size, DW.FORM.sdata
const abi_size = ty.abiSize(target);
try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
@@ -195,7 +195,7 @@ pub const DeclState = struct {
try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(7);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("maybe");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -207,7 +207,7 @@ pub const DeclState = struct {
try dbg_info_buffer.ensureUnusedCapacity(6);
dbg_info_buffer.appendAssumeCapacity(0);
// DW.AT.member
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("val");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -227,14 +227,14 @@ pub const DeclState = struct {
// Slices are structs: struct { .ptr = *, .len = N }
// DW.AT.structure_type
try dbg_info_buffer.ensureUnusedCapacity(2);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_type);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_type));
// DW.AT.byte_size, DW.FORM.sdata
dbg_info_buffer.appendAssumeCapacity(@sizeOf(usize) * 2);
// DW.AT.name, DW.FORM.string
try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(target)});
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(5);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("ptr");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -248,7 +248,7 @@ pub const DeclState = struct {
try dbg_info_buffer.ensureUnusedCapacity(6);
dbg_info_buffer.appendAssumeCapacity(0);
// DW.AT.member
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("len");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -263,7 +263,7 @@ pub const DeclState = struct {
dbg_info_buffer.appendAssumeCapacity(0);
} else {
try dbg_info_buffer.ensureUnusedCapacity(5);
- dbg_info_buffer.appendAssumeCapacity(abbrev_ptr_type);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.ptr_type));
// DW.AT.type, DW.FORM.ref4
const index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
@@ -272,7 +272,7 @@ pub const DeclState = struct {
},
.Struct => blk: {
// DW.AT.structure_type
- try dbg_info_buffer.append(abbrev_struct_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
// DW.AT.byte_size, DW.FORM.sdata
const abi_size = ty.abiSize(target);
try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
@@ -285,7 +285,7 @@ pub const DeclState = struct {
const fields = ty.tupleFields();
for (fields.types) |field, field_index| {
// DW.AT.member
- try dbg_info_buffer.append(abbrev_struct_member);
+ try dbg_info_buffer.append(@enumToInt(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
@@ -315,7 +315,7 @@ pub const DeclState = struct {
const field = fields.get(field_name).?;
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity(field_name);
dbg_info_buffer.appendAssumeCapacity(0);
@@ -335,7 +335,7 @@ pub const DeclState = struct {
},
.Enum => {
// DW.AT.enumeration_type
- try dbg_info_buffer.append(abbrev_enum_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
// DW.AT.byte_size, DW.FORM.sdata
const abi_size = ty.abiSize(target);
try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
@@ -355,7 +355,7 @@ pub const DeclState = struct {
for (fields.keys()) |field_name, field_i| {
// DW.AT.enumerator
try dbg_info_buffer.ensureUnusedCapacity(field_name.len + 2 + @sizeOf(u64));
- dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity(field_name);
dbg_info_buffer.appendAssumeCapacity(0);
@@ -385,7 +385,7 @@ pub const DeclState = struct {
// for untagged unions.
if (is_tagged) {
// DW.AT.structure_type
- try dbg_info_buffer.append(abbrev_struct_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
// DW.AT.byte_size, DW.FORM.sdata
try leb128.writeULEB128(dbg_info_buffer.writer(), layout.abi_size);
// DW.AT.name, DW.FORM.string
@@ -395,7 +395,7 @@ pub const DeclState = struct {
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(9);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("payload");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -408,7 +408,7 @@ pub const DeclState = struct {
}
// DW.AT.union_type
- try dbg_info_buffer.append(abbrev_union_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.union_type));
// DW.AT.byte_size, DW.FORM.sdata,
try leb128.writeULEB128(dbg_info_buffer.writer(), layout.payload_size);
// DW.AT.name, DW.FORM.string
@@ -423,7 +423,7 @@ pub const DeclState = struct {
const field = fields.get(field_name).?;
if (!field.ty.hasRuntimeBits()) continue;
// DW.AT.member
- try dbg_info_buffer.append(abbrev_struct_member);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
try dbg_info_buffer.writer().print("{s}\x00", .{field_name});
// DW.AT.type, DW.FORM.ref4
@@ -439,7 +439,7 @@ pub const DeclState = struct {
if (is_tagged) {
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(5);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("tag");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -471,7 +471,7 @@ pub const DeclState = struct {
const payload_off = mem.alignForwardGeneric(u64, error_ty.abiSize(target), abi_align);
// DW.AT.structure_type
- try dbg_info_buffer.append(abbrev_struct_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type));
// DW.AT.byte_size, DW.FORM.sdata
try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
// DW.AT.name, DW.FORM.string
@@ -480,7 +480,7 @@ pub const DeclState = struct {
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(7);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("value");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -493,7 +493,7 @@ pub const DeclState = struct {
// DW.AT.member
try dbg_info_buffer.ensureUnusedCapacity(5);
- dbg_info_buffer.appendAssumeCapacity(abbrev_struct_member);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.struct_member));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity("err");
dbg_info_buffer.appendAssumeCapacity(0);
@@ -509,7 +509,7 @@ pub const DeclState = struct {
},
else => {
log.debug("TODO implement .debug_info for type '{}'", .{ty.fmtDebug()});
- try dbg_info_buffer.append(abbrev_pad1);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.pad1));
},
}
}
@@ -550,18 +550,21 @@ pub const SrcFn = struct {
pub const PtrWidth = enum { p32, p64 };
-pub const abbrev_compile_unit = 1;
-pub const abbrev_subprogram = 2;
-pub const abbrev_subprogram_retvoid = 3;
-pub const abbrev_base_type = 4;
-pub const abbrev_ptr_type = 5;
-pub const abbrev_struct_type = 6;
-pub const abbrev_struct_member = 7;
-pub const abbrev_enum_type = 8;
-pub const abbrev_enum_variant = 9;
-pub const abbrev_union_type = 10;
-pub const abbrev_pad1 = 11;
-pub const abbrev_parameter = 12;
+pub const AbbrevKind = enum(u8) {
+ compile_unit = 1,
+ subprogram,
+ subprogram_retvoid,
+ base_type,
+ ptr_type,
+ struct_type,
+ struct_member,
+ enum_type,
+ enum_variant,
+ union_type,
+ pad1,
+ parameter,
+ variable,
+};
/// The reloc offset for the virtual address of a function in its Line Number Program.
/// Size is a virtual address integer.
@@ -670,9 +673,9 @@ pub fn initDeclState(self: *Dwarf, decl: *Module.Decl) !DeclState {
const fn_ret_type = decl.ty.fnReturnType();
const fn_ret_has_bits = fn_ret_type.hasRuntimeBits();
if (fn_ret_has_bits) {
- dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram));
} else {
- dbg_info_buffer.appendAssumeCapacity(abbrev_subprogram_retvoid);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.subprogram_retvoid));
}
// These get overwritten after generating the machine code. These values are
// "relocations" and have to be in this fixed place so that functions can be
@@ -926,7 +929,7 @@ pub fn commitDeclState(
else => unreachable,
};
- {
+ if (decl_state.abbrev_table.items.len > 0) {
// Now we emit the .debug_info types of the Decl. These will count towards the size of
// the buffer, so we have to do it before computing the offset, and we can't perform the actual
// relocations yet.
@@ -1244,14 +1247,14 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
// These are LEB encoded but since the values are all less than 127
// we can simply append these bytes.
const abbrev_buf = [_]u8{
- abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header
- DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc,
- DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr,
- DW.AT.name, DW.FORM.strp, DW.AT.comp_dir,
- DW.FORM.strp, DW.AT.producer, DW.FORM.strp,
- DW.AT.language, DW.FORM.data2, 0,
+ @enumToInt(AbbrevKind.compile_unit), DW.TAG.compile_unit, DW.CHILDREN.yes, // header
+ DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc,
+ DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr,
+ DW.AT.name, DW.FORM.strp, DW.AT.comp_dir,
+ DW.FORM.strp, DW.AT.producer, DW.FORM.strp,
+ DW.AT.language, DW.FORM.data2, 0,
0, // table sentinel
- abbrev_subprogram,
+ @enumToInt(AbbrevKind.subprogram),
DW.TAG.subprogram,
DW.CHILDREN.yes, // header
DW.AT.low_pc,
@@ -1262,15 +1265,15 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.ref4,
DW.AT.name,
DW.FORM.string,
- 0, 0, // table sentinel
- abbrev_subprogram_retvoid,
+ 0, 0, // table sentinel
+ @enumToInt(AbbrevKind.subprogram_retvoid),
DW.TAG.subprogram, DW.CHILDREN.yes, // header
DW.AT.low_pc, DW.FORM.addr,
DW.AT.high_pc, DW.FORM.data4,
DW.AT.name, DW.FORM.string,
0,
0, // table sentinel
- abbrev_base_type,
+ @enumToInt(AbbrevKind.base_type),
DW.TAG.base_type,
DW.CHILDREN.no, // header
DW.AT.encoding,
@@ -1281,14 +1284,14 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.string,
0,
0, // table sentinel
- abbrev_ptr_type,
+ @enumToInt(AbbrevKind.ptr_type),
DW.TAG.pointer_type,
DW.CHILDREN.no, // header
DW.AT.type,
DW.FORM.ref4,
0,
0, // table sentinel
- abbrev_struct_type,
+ @enumToInt(AbbrevKind.struct_type),
DW.TAG.structure_type,
DW.CHILDREN.yes, // header
DW.AT.byte_size,
@@ -1297,7 +1300,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.string,
0,
0, // table sentinel
- abbrev_struct_member,
+ @enumToInt(AbbrevKind.struct_member),
DW.TAG.member,
DW.CHILDREN.no, // header
DW.AT.name,
@@ -1308,7 +1311,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.sdata,
0,
0, // table sentinel
- abbrev_enum_type,
+ @enumToInt(AbbrevKind.enum_type),
DW.TAG.enumeration_type,
DW.CHILDREN.yes, // header
DW.AT.byte_size,
@@ -1317,7 +1320,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.string,
0,
0, // table sentinel
- abbrev_enum_variant,
+ @enumToInt(AbbrevKind.enum_variant),
DW.TAG.enumerator,
DW.CHILDREN.no, // header
DW.AT.name,
@@ -1326,7 +1329,7 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.data8,
0,
0, // table sentinel
- abbrev_union_type,
+ @enumToInt(AbbrevKind.union_type),
DW.TAG.union_type,
DW.CHILDREN.yes, // header
DW.AT.byte_size,
@@ -1335,18 +1338,25 @@ pub fn writeDbgAbbrev(self: *Dwarf, file: *File) !void {
DW.FORM.string,
0,
0, // table sentinel
- abbrev_pad1,
+ @enumToInt(AbbrevKind.pad1),
DW.TAG.unspecified_type,
DW.CHILDREN.no, // header
0,
0, // table sentinel
- abbrev_parameter,
+ @enumToInt(AbbrevKind.parameter),
DW.TAG.formal_parameter, DW.CHILDREN.no, // header
DW.AT.location, DW.FORM.exprloc,
DW.AT.type, DW.FORM.ref4,
DW.AT.name, DW.FORM.string,
0,
0, // table sentinel
+ @enumToInt(AbbrevKind.variable),
+ DW.TAG.variable, DW.CHILDREN.no, // header
+ DW.AT.location, DW.FORM.exprloc,
+ DW.AT.type, DW.FORM.ref4,
+ DW.AT.name, DW.FORM.string,
+ 0,
+ 0, // table sentinel
0,
0,
0, // section sentinel
@@ -1459,7 +1469,7 @@ pub fn writeDbgInfoHeader(self: *Dwarf, file: *File, module: *Module, low_pc: u6
const comp_dir_strp = try self.makeString(module.root_pkg.root_src_directory.path orelse ".");
const producer_strp = try self.makeString(link.producer_string);
- di_buf.appendAssumeCapacity(abbrev_compile_unit);
+ di_buf.appendAssumeCapacity(@enumToInt(AbbrevKind.compile_unit));
if (self.tag == .macho) {
mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset
mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);
@@ -1606,7 +1616,7 @@ fn pwriteDbgInfoNops(
const tracy = trace(@src());
defer tracy.end();
- const page_of_nops = [1]u8{abbrev_pad1} ** 4096;
+ const page_of_nops = [1]u8{@enumToInt(AbbrevKind.pad1)} ** 4096;
var vecs: [32]std.os.iovec_const = undefined;
var vec_index: usize = 0;
{
@@ -1673,7 +1683,7 @@ pub fn writeDbgAranges(self: *Dwarf, file: *File, addr: u64, size: u64) !void {
.p32 => @as(usize, 4),
.p64 => 12,
};
- const ptr_width_bytes: u8 = self.ptrWidthBytes();
+ const ptr_width_bytes = self.ptrWidthBytes();
// Enough for all the data without resizing. When support for more compilation units
// is added, the size of this section will become more variable.
@@ -2040,7 +2050,7 @@ fn addDbgInfoErrorSet(
const target_endian = target.cpu.arch.endian();
// DW.AT.enumeration_type
- try dbg_info_buffer.append(abbrev_enum_type);
+ try dbg_info_buffer.append(@enumToInt(AbbrevKind.enum_type));
// DW.AT.byte_size, DW.FORM.sdata
const abi_size = ty.abiSize(target);
try leb128.writeULEB128(dbg_info_buffer.writer(), abi_size);
@@ -2051,7 +2061,7 @@ fn addDbgInfoErrorSet(
// DW.AT.enumerator
const no_error = "(no error)";
try dbg_info_buffer.ensureUnusedCapacity(no_error.len + 2 + @sizeOf(u64));
- dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity(no_error);
dbg_info_buffer.appendAssumeCapacity(0);
@@ -2063,7 +2073,7 @@ fn addDbgInfoErrorSet(
const kv = module.getErrorValue(error_name) catch unreachable;
// DW.AT.enumerator
try dbg_info_buffer.ensureUnusedCapacity(error_name.len + 2 + @sizeOf(u64));
- dbg_info_buffer.appendAssumeCapacity(abbrev_enum_variant);
+ dbg_info_buffer.appendAssumeCapacity(@enumToInt(AbbrevKind.enum_variant));
// DW.AT.name, DW.FORM.string
dbg_info_buffer.appendSliceAssumeCapacity(error_name);
dbg_info_buffer.appendAssumeCapacity(0);