authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-04-30 20:52:13+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-05-09 18:51:46+02:00
log33b2f4f382234c95e8e10cf1b17d1621bb402bf1
tree41ef97c1fc238ccf1f70373e17b6cd97ee430d95
parent8e1c220be257236565fb28d84dc56045f15be697

wasm: Implement debug info for parameters


3 files changed, 56 insertions(+), 2 deletions(-)

lib/std/dwarf/OP.zig+6
......@@ -205,3 +205,9 @@ pub const HP_unmod_range = 0xe5;
205205pub const HP_tls = 0xe6;
206206// PGI (STMicroelectronics) extensions.
207207pub const PGI_omp_thread_num = 0xf8;
208// Wasm extensions.
209pub const WASM_location = 0xed;
210pub const WASM_local = 0x00;
211pub const WASM_global = 0x01;
212pub const WASM_global_u32 = 0x03;
213pub const WASM_operand_stack = 0x02;
src/arch/wasm/CodeGen.zig+49-1
......@@ -546,6 +546,8 @@ block_depth: u32 = 0,
546546air: Air,
547547liveness: Liveness,
548548gpa: mem.Allocator,
549debug_output: codegen.DebugInfoOutput,
550mod_fn: *const Module.Fn,
549551/// Table to save `WValue`'s generated by an `Air.Inst`
550552values: ValueTable,
551553/// Mapping from Air.Inst.Index to block ids
......@@ -856,6 +858,8 @@ pub fn generate(
856858 .locals = .{},
857859 .target = bin_file.options.target,
858860 .bin_file = bin_file.cast(link.File.Wasm).?,
861 .debug_output = debug_output,
862 .mod_fn = func,
859863 };
860864 defer code_gen.deinit();
861865
......@@ -1022,6 +1026,23 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool
10221026 }
10231027}
10241028
1029/// For a given `Type`, add debug information to .debug_info at the current position.
1030/// The actual bytes will be written to the position after relocation.
1031fn addDbgInfoTypeReloc(self: *Self, ty: Type) !void {
1032 switch (self.debug_output) {
1033 .dwarf => |dwarf| {
1034 assert(ty.hasRuntimeBitsIgnoreComptime());
1035 const dbg_info = &dwarf.dbg_info;
1036 const index = dbg_info.items.len;
1037 try dbg_info.resize(index + 4);
1038 const atom = &self.decl.link.wasm.dbg_info_atom;
1039 try dwarf.addTypeReloc(atom, ty, @intCast(u32, index), null);
1040 },
1041 .plan9 => unreachable,
1042 .none => {},
1043 }
1044}
1045
10251046/// Lowers a Zig type and its value based on a given calling convention to ensure
10261047/// it matches the ABI.
10271048fn 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 {
18731894}
18741895
18751896fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
1876 const arg = self.args[self.arg_index];
1897 const arg_index = self.arg_index;
1898 const arg = self.args[arg_index];
18771899 const cc = self.decl.ty.fnInfo().cc;
18781900 if (cc == .C) {
18791901 const ty = self.air.typeOfIndex(inst);
......@@ -1886,6 +1908,32 @@ fn airArg(self: *Self, inst: Air.Inst.Index) InnerError!WValue {
18861908 } else {
18871909 self.arg_index += 1;
18881910 }
1911
1912 switch (self.debug_output) {
1913 .dwarf => |dwarf| {
1914 // TODO: Get the original arg index rather than wasm arg index
1915 const name = self.mod_fn.getParamName(arg_index);
1916 const leb_size = link.File.Wasm.getULEB128Size(arg.local);
1917 const dbg_info = &dwarf.dbg_info;
1918 try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1);
1919 // wasm locations are encoded as follow:
1920 // DW_OP_WASM_location wasm-op
1921 // where wasm-op is defined as
1922 // wasm-op := wasm-local | wasm-global | wasm-operand_stack
1923 // where each argument is encoded as
1924 // <opcode> i:uleb128
1925 dbg_info.appendSliceAssumeCapacity(&.{
1926 @enumToInt(link.File.Dwarf.AbbrevKind.parameter),
1927 std.dwarf.OP.WASM_location,
1928 std.dwarf.OP.WASM_local,
1929 });
1930 leb.writeULEB128(dbg_info.writer(), arg.local) catch unreachable;
1931 try self.addDbgInfoTypeReloc(self.air.typeOfIndex(inst));
1932 dbg_info.appendSliceAssumeCapacity(name);
1933 dbg_info.appendAssumeCapacity(0);
1934 },
1935 else => {},
1936 }
18891937 return arg;
18901938}
18911939
src/link/Wasm.zig+1-1
......@@ -2668,7 +2668,7 @@ fn emitSegmentInfo(self: *Wasm, file: fs.File, arena: Allocator) !void {
26682668 try file.writevAll(&iovecs);
26692669}
26702670
2671fn getULEB128Size(uint_value: anytype) u32 {
2671pub fn getULEB128Size(uint_value: anytype) u32 {
26722672 const T = @TypeOf(uint_value);
26732673 const U = if (@typeInfo(T).Int.bits < 8) u8 else T;
26742674 var value = @intCast(U, uint_value);