mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 17:35:12 +00:00
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.
This commit is contained in:
parent
795f075790
commit
364e53f3bf
@ -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);
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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),
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user