mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
wasm: Implement debug info for parameters
This commit is contained in:
parent
8e1c220be2
commit
33b2f4f382
3 changed files with 56 additions and 2 deletions
|
|
@ -205,3 +205,9 @@ pub const HP_unmod_range = 0xe5;
|
|||
pub const HP_tls = 0xe6;
|
||||
// PGI (STMicroelectronics) extensions.
|
||||
pub const PGI_omp_thread_num = 0xf8;
|
||||
// Wasm extensions.
|
||||
pub const WASM_location = 0xed;
|
||||
pub const WASM_local = 0x00;
|
||||
pub const WASM_global = 0x01;
|
||||
pub const WASM_global_u32 = 0x03;
|
||||
pub const WASM_operand_stack = 0x02;
|
||||
|
|
|
|||
|
|
@ -546,6 +546,8 @@ block_depth: u32 = 0,
|
|||
air: Air,
|
||||
liveness: Liveness,
|
||||
gpa: mem.Allocator,
|
||||
debug_output: codegen.DebugInfoOutput,
|
||||
mod_fn: *const Module.Fn,
|
||||
/// Table to save `WValue`'s generated by an `Air.Inst`
|
||||
values: ValueTable,
|
||||
/// Mapping from Air.Inst.Index to block ids
|
||||
|
|
@ -856,6 +858,8 @@ pub fn generate(
|
|||
.locals = .{},
|
||||
.target = bin_file.options.target,
|
||||
.bin_file = bin_file.cast(link.File.Wasm).?,
|
||||
.debug_output = debug_output,
|
||||
.mod_fn = func,
|
||||
};
|
||||
defer code_gen.deinit();
|
||||
|
||||
|
|
@ -1022,6 +1026,23 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool
|
|||
}
|
||||
}
|
||||
|
||||
/// 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(self: *Self, ty: Type) !void {
|
||||
switch (self.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 = &self.decl.link.wasm.dbg_info_atom;
|
||||
try dwarf.addTypeReloc(atom, ty, @intCast(u32, index), null);
|
||||
},
|
||||
.plan9 => unreachable,
|
||||
.none => {},
|
||||
}
|
||||
}
|
||||
|
||||
/// Lowers a Zig type and its value based on a given calling convention to ensure
|
||||
/// it matches the ABI.
|
||||
fn lowerArg(self: *Self, cc: std.builtin.CallingConvention, ty: Type, value: WValue) !void {
|
||||
|
|
@ -1873,7 +1894,8 @@ fn load(self: *Self, operand: WValue, ty: Type, offset: u32) InnerError!WValue {
|
|||
}
|
||||
|
||||
fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
||||
const arg = self.args[self.arg_index];
|
||||
const arg_index = self.arg_index;
|
||||
const arg = self.args[arg_index];
|
||||
const cc = self.decl.ty.fnInfo().cc;
|
||||
if (cc == .C) {
|
||||
const ty = self.air.typeOfIndex(inst);
|
||||
|
|
@ -1886,6 +1908,32 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
|
|||
} else {
|
||||
self.arg_index += 1;
|
||||
}
|
||||
|
||||
switch (self.debug_output) {
|
||||
.dwarf => |dwarf| {
|
||||
// TODO: Get the original arg index rather than wasm arg index
|
||||
const name = self.mod_fn.getParamName(arg_index);
|
||||
const leb_size = link.File.Wasm.getULEB128Size(arg.local);
|
||||
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,
|
||||
});
|
||||
leb.writeULEB128(dbg_info.writer(), arg.local) catch unreachable;
|
||||
try self.addDbgInfoTypeReloc(self.air.typeOfIndex(inst));
|
||||
dbg_info.appendSliceAssumeCapacity(name);
|
||||
dbg_info.appendAssumeCapacity(0);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2668,7 +2668,7 @@ fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {
|
|||
try file.writevAll(&iovecs);
|
||||
}
|
||||
|
||||
fn getULEB128Size(uint_value: anytype) u32 {
|
||||
pub fn getULEB128Size(uint_value: anytype) u32 {
|
||||
const T = @TypeOf(uint_value);
|
||||
const U = if (@typeInfo(T).Int.bits < 8) u8 else T;
|
||||
var value = @intCast(U, uint_value);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue