aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/arch/wasm/CodeGen.zig77
-rw-r--r--src/link/Dwarf.zig58
2 files changed, 61 insertions, 74 deletions
diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig
index ebfff25b2f..ddb1803998 100644
--- a/src/arch/wasm/CodeGen.zig
+++ b/src/arch/wasm/CodeGen.zig
@@ -1291,23 +1291,6 @@ fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, target:
}
}
-/// For a given `Type`, add debug information to .debug_info at the current position.
-/// The actual bytes will be written to the position after relocation.
-fn addDbgInfoTypeReloc(func: *CodeGen, ty: Type) !void {
- switch (func.debug_output) {
- .dwarf => |dwarf| {
- assert(ty.hasRuntimeBitsIgnoreComptime());
- const dbg_info = &dwarf.dbg_info;
- const index = dbg_info.items.len;
- try dbg_info.resize(index + 4);
- const atom = &func.decl.link.wasm.dbg_info_atom;
- try dwarf.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
- },
- .plan9 => unreachable,
- .none => {},
- }
-}
-
/// Lowers a Zig type and its value based on a given calling convention to ensure
/// it matches the ABI.
fn lowerArg(func: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: WValue) !void {
@@ -2358,24 +2341,10 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
.dwarf => |dwarf| {
// TODO: Get the original arg index rather than wasm arg index
const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, arg_index);
- const leb_size = link.File.Wasm.getULEB128Size(arg.local.value);
- const dbg_info = &dwarf.dbg_info;
- try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1);
- // wasm locations are encoded as follow:
- // DW_OP_WASM_location wasm-op
- // where wasm-op is defined as
- // wasm-op := wasm-local | wasm-global | wasm-operand_stack
- // where each argument is encoded as
- // <opcode> i:uleb128
- dbg_info.appendSliceAssumeCapacity(&.{
- @enumToInt(link.File.Dwarf.AbbrevKind.parameter),
- std.dwarf.OP.WASM_location,
- std.dwarf.OP.WASM_local,
+ const atom = func.getDbgInfoAtom();
+ try dwarf.genArgDbgInfo(name, arg_ty, atom, .{
+ .wasm_local = arg.local.value,
});
- leb.writeULEB128(dbg_info.writer(), arg.local.value) catch unreachable;
- try func.addDbgInfoTypeReloc(arg_ty);
- dbg_info.appendSliceAssumeCapacity(name);
- dbg_info.appendAssumeCapacity(0);
},
else => {},
}
@@ -2383,6 +2352,12 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
func.finishAir(inst, arg, &.{});
}
+fn getDbgInfoAtom(func: CodeGen) *link.File.Dwarf.Atom {
+ const mod = func.bin_file.base.options.module.?;
+ const fn_owner_decl = mod.declPtr(func.mod_fn.owner_decl);
+ return &fn_owner_decl.link.wasm.dbg_info_atom;
+}
+
fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
const bin_op = func.air.instructions.items(.data)[inst].bin_op;
if (func.liveness.isUnused(inst)) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs });
@@ -5345,38 +5320,22 @@ fn airDbgVar(func: *CodeGen, inst: Air.Inst.Index, is_ptr: bool) !void {
const pl_op = func.air.instructions.items(.data)[inst].pl_op;
const ty = func.air.typeOf(pl_op.operand);
const operand = try func.resolveInst(pl_op.operand);
- const op_ty = if (is_ptr) ty.childType() else ty;
- log.debug("airDbgVar: %{d}: {}, {}", .{ inst, op_ty.fmtDebug(), operand });
+ log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });
const name = func.air.nullTerminatedString(pl_op.payload);
log.debug(" var name = ({s})", .{name});
- const dbg_info = &func.debug_output.dwarf.dbg_info;
- try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
- switch (operand) {
- .local => |local| {
- const leb_size = link.File.Wasm.getULEB128Size(local.value);
- try dbg_info.ensureUnusedCapacity(2 + leb_size);
- // wasm locals are encoded as follow:
- // DW_OP_WASM_location wasm-op
- // where wasm-op is defined as
- // wasm-op := wasm-local | wasm-global | wasm-operand_stack
- // where wasm-local is encoded as
- // wasm-local := 0x00 i:uleb128
- dbg_info.appendSliceAssumeCapacity(&.{
- std.dwarf.OP.WASM_location,
- std.dwarf.OP.WASM_local,
- });
- leb.writeULEB128(dbg_info.writer(), local.value) catch unreachable;
+ const atom = func.getDbgInfoAtom();
+ const loc: link.File.Dwarf.DeclState.VarArgDbgInfoLoc = switch (operand) {
+ .local => |local| .{ .wasm_local = local.value },
+ else => blk: {
+ log.debug("TODO generate debug info for {}", .{operand});
+ break :blk .nop;
},
- else => {}, // TODO
- }
+ };
+ try func.debug_output.dwarf.genVarDbgInfo(name, ty, atom, is_ptr, loc);
- try dbg_info.ensureUnusedCapacity(5 + name.len + 1);
- try func.addDbgInfoTypeReloc(op_ty);
- dbg_info.appendSliceAssumeCapacity(name);
- dbg_info.appendAssumeCapacity(0);
func.finishAir(inst, .none, &.{});
}
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig
index 89ef68b6cf..feb2857322 100644
--- a/src/link/Dwarf.zig
+++ b/src/link/Dwarf.zig
@@ -102,7 +102,7 @@ pub const DeclState = struct {
self.exprloc_relocs.deinit(self.gpa);
}
- pub fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void {
+ fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void {
log.debug("{x}: target sym %{d}, via GOT {}", .{ offset, target, is_ptr });
try self.exprloc_relocs.append(self.gpa, .{
.type = if (is_ptr) .got_load else .direct_load,
@@ -113,7 +113,7 @@ pub const DeclState = struct {
/// Adds local type relocation of the form: @offset => @this + addend
/// @this signifies the offset within the .debug_abbrev section of the containing atom.
- pub fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
+ fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
log.debug("{x}: @this + {x}", .{ offset, addend });
try self.abbrev_relocs.append(self.gpa, .{
.target = null,
@@ -126,7 +126,7 @@ pub const DeclState = struct {
/// Adds global type relocation of the form: @offset => @symbol + 0
/// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
/// which we use as our target of the relocation.
- pub fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
+ fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
const resolv = self.abbrev_resolver.getContext(ty, .{
.mod = self.mod,
}) orelse blk: {
@@ -570,6 +570,7 @@ pub const DeclState = struct {
loc: union(enum) {
register: u8,
stack: struct { fp_register: u8, offset: i32 },
+ wasm_local: u32,
},
) error{OutOfMemory}!void {
const dbg_info = &self.dbg_info;
@@ -583,12 +584,6 @@ pub const DeclState = struct {
1, // ULEB128 dwarf expression length
reg,
});
- try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
- const index = dbg_info.items.len;
- try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
- try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4
- dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
-
},
.stack => |info| {
try dbg_info.ensureUnusedCapacity(8);
@@ -600,14 +595,30 @@ pub const DeclState = struct {
});
leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable;
dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
- try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
- const index = dbg_info.items.len;
- try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
- try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
- dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
-
+ },
+ .wasm_local => |value| {
+ const leb_size = link.File.Wasm.getULEB128Size(value);
+ try dbg_info.ensureUnusedCapacity(3 + leb_size);
+ // wasm locations are encoded as follow:
+ // DW_OP_WASM_location wasm-op
+ // where wasm-op is defined as
+ // wasm-op := wasm-local | wasm-global | wasm-operand_stack
+ // where each argument is encoded as
+ // <opcode> i:uleb128
+ dbg_info.appendSliceAssumeCapacity(&.{
+ @enumToInt(AbbrevKind.parameter),
+ DW.OP.WASM_location,
+ DW.OP.WASM_local,
+ });
+ leb128.writeULEB128(dbg_info.writer(), value) catch unreachable;
},
}
+
+ try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
+ const index = dbg_info.items.len;
+ try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
+ try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4
+ dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
}
pub const VarArgDbgInfoLoc = union(enum) {
@@ -616,6 +627,7 @@ pub const DeclState = struct {
fp_register: u8,
offset: i32,
},
+ wasm_local: u32,
memory: u64,
linker_load: LinkerLoad,
immediate: u64,
@@ -659,6 +671,22 @@ pub const DeclState = struct {
dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
},
+ .wasm_local => |value| {
+ const leb_size = link.File.Wasm.getULEB128Size(value);
+ try dbg_info.ensureUnusedCapacity(2 + leb_size);
+ // wasm locals are encoded as follow:
+ // DW_OP_WASM_location wasm-op
+ // where wasm-op is defined as
+ // wasm-op := wasm-local | wasm-global | wasm-operand_stack
+ // where wasm-local is encoded as
+ // wasm-local := 0x00 i:uleb128
+ dbg_info.appendSliceAssumeCapacity(&.{
+ DW.OP.WASM_location,
+ DW.OP.WASM_local,
+ });
+ leb128.writeULEB128(dbg_info.writer(), value) catch unreachable;
+ },
+
.memory,
.linker_load,
=> {