authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-01 20:55:55+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-12-01 20:55:55+01:00
log8fea84f77ebc6805fe4558ae73064955dbfdcb64
tree1d5e16eb93373eaff9a7c802991b1d00ce828fff
parent17ab40f755a038bd9c06c7817354f9ce2eb4353f

dwarf: move Wasm specific dwarf gen out of codegen


2 files changed, 61 insertions(+), 74 deletions(-)

src/arch/wasm/CodeGen.zig+18-59
......@@ -1291,23 +1291,6 @@ fn firstParamSRet(cc: std.builtin.CallingConvention, return_type: Type, target:
12911291 }
12921292}
12931293
1294/// For a given `Type`, add debug information to .debug_info at the current position.
1295/// The actual bytes will be written to the position after relocation.
1296fn addDbgInfoTypeReloc(func: *CodeGen, ty: Type) !void {
1297 switch (func.debug_output) {
1298 .dwarf => |dwarf| {
1299 assert(ty.hasRuntimeBitsIgnoreComptime());
1300 const dbg_info = &dwarf.dbg_info;
1301 const index = dbg_info.items.len;
1302 try dbg_info.resize(index + 4);
1303 const atom = &func.decl.link.wasm.dbg_info_atom;
1304 try dwarf.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
1305 },
1306 .plan9 => unreachable,
1307 .none => {},
1308 }
1309}
1310
13111294/// Lowers a Zig type and its value based on a given calling convention to ensure
13121295/// it matches the ABI.
13131296fn 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 {
23582341 .dwarf => |dwarf| {
23592342 // TODO: Get the original arg index rather than wasm arg index
23602343 const name = func.mod_fn.getParamName(func.bin_file.base.options.module.?, arg_index);
2361 const leb_size = link.File.Wasm.getULEB128Size(arg.local.value);
2362 const dbg_info = &dwarf.dbg_info;
2363 try dbg_info.ensureUnusedCapacity(3 + leb_size + 5 + name.len + 1);
2364 // wasm locations are encoded as follow:
2365 // DW_OP_WASM_location wasm-op
2366 // where wasm-op is defined as
2367 // wasm-op := wasm-local | wasm-global | wasm-operand_stack
2368 // where each argument is encoded as
2369 // <opcode> i:uleb128
2370 dbg_info.appendSliceAssumeCapacity(&.{
2371 @enumToInt(link.File.Dwarf.AbbrevKind.parameter),
2372 std.dwarf.OP.WASM_location,
2373 std.dwarf.OP.WASM_local,
2344 const atom = func.getDbgInfoAtom();
2345 try dwarf.genArgDbgInfo(name, arg_ty, atom, .{
2346 .wasm_local = arg.local.value,
23742347 });
2375 leb.writeULEB128(dbg_info.writer(), arg.local.value) catch unreachable;
2376 try func.addDbgInfoTypeReloc(arg_ty);
2377 dbg_info.appendSliceAssumeCapacity(name);
2378 dbg_info.appendAssumeCapacity(0);
23792348 },
23802349 else => {},
23812350 }
......@@ -2383,6 +2352,12 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
23832352 func.finishAir(inst, arg, &.{});
23842353}
23852354
2355fn getDbgInfoAtom(func: CodeGen) *link.File.Dwarf.Atom {
2356 const mod = func.bin_file.base.options.module.?;
2357 const fn_owner_decl = mod.declPtr(func.mod_fn.owner_decl);
2358 return &fn_owner_decl.link.wasm.dbg_info_atom;
2359}
2360
23862361fn airBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void {
23872362 const bin_op = func.air.instructions.items(.data)[inst].bin_op;
23882363 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 {
53455320 const pl_op = func.air.instructions.items(.data)[inst].pl_op;
53465321 const ty = func.air.typeOf(pl_op.operand);
53475322 const operand = try func.resolveInst(pl_op.operand);
5348 const op_ty = if (is_ptr) ty.childType() else ty;
53495323
5350 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, op_ty.fmtDebug(), operand });
5324 log.debug("airDbgVar: %{d}: {}, {}", .{ inst, ty.fmtDebug(), operand });
53515325
53525326 const name = func.air.nullTerminatedString(pl_op.payload);
53535327 log.debug(" var name = ({s})", .{name});
53545328
5355 const dbg_info = &func.debug_output.dwarf.dbg_info;
5356 try dbg_info.append(@enumToInt(link.File.Dwarf.AbbrevKind.variable));
5357 switch (operand) {
5358 .local => |local| {
5359 const leb_size = link.File.Wasm.getULEB128Size(local.value);
5360 try dbg_info.ensureUnusedCapacity(2 + leb_size);
5361 // wasm locals are encoded as follow:
5362 // DW_OP_WASM_location wasm-op
5363 // where wasm-op is defined as
5364 // wasm-op := wasm-local | wasm-global | wasm-operand_stack
5365 // where wasm-local is encoded as
5366 // wasm-local := 0x00 i:uleb128
5367 dbg_info.appendSliceAssumeCapacity(&.{
5368 std.dwarf.OP.WASM_location,
5369 std.dwarf.OP.WASM_local,
5370 });
5371 leb.writeULEB128(dbg_info.writer(), local.value) catch unreachable;
5329 const atom = func.getDbgInfoAtom();
5330 const loc: link.File.Dwarf.DeclState.VarArgDbgInfoLoc = switch (operand) {
5331 .local => |local| .{ .wasm_local = local.value },
5332 else => blk: {
5333 log.debug("TODO generate debug info for {}", .{operand});
5334 break :blk .nop;
53725335 },
5373 else => {}, // TODO
5374 }
5336 };
5337 try func.debug_output.dwarf.genVarDbgInfo(name, ty, atom, is_ptr, loc);
53755338
5376 try dbg_info.ensureUnusedCapacity(5 + name.len + 1);
5377 try func.addDbgInfoTypeReloc(op_ty);
5378 dbg_info.appendSliceAssumeCapacity(name);
5379 dbg_info.appendAssumeCapacity(0);
53805339 func.finishAir(inst, .none, &.{});
53815340}
53825341
src/link/Dwarf.zig+43-15
......@@ -102,7 +102,7 @@ pub const DeclState = struct {
102102 self.exprloc_relocs.deinit(self.gpa);
103103 }
104104
105 pub fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void {
105 fn addExprlocReloc(self: *DeclState, target: u32, offset: u32, is_ptr: bool) !void {
106106 log.debug("{x}: target sym %{d}, via GOT {}", .{ offset, target, is_ptr });
107107 try self.exprloc_relocs.append(self.gpa, .{
108108 .type = if (is_ptr) .got_load else .direct_load,
......@@ -113,7 +113,7 @@ pub const DeclState = struct {
113113
114114 /// Adds local type relocation of the form: @offset => @this + addend
115115 /// @this signifies the offset within the .debug_abbrev section of the containing atom.
116 pub fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
116 fn addTypeRelocLocal(self: *DeclState, atom: *const Atom, offset: u32, addend: u32) !void {
117117 log.debug("{x}: @this + {x}", .{ offset, addend });
118118 try self.abbrev_relocs.append(self.gpa, .{
119119 .target = null,
......@@ -126,7 +126,7 @@ pub const DeclState = struct {
126126 /// Adds global type relocation of the form: @offset => @symbol + 0
127127 /// @symbol signifies a type abbreviation posititioned somewhere in the .debug_abbrev section
128128 /// which we use as our target of the relocation.
129 pub fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
129 fn addTypeRelocGlobal(self: *DeclState, atom: *const Atom, ty: Type, offset: u32) !void {
130130 const resolv = self.abbrev_resolver.getContext(ty, .{
131131 .mod = self.mod,
132132 }) orelse blk: {
......@@ -570,6 +570,7 @@ pub const DeclState = struct {
570570 loc: union(enum) {
571571 register: u8,
572572 stack: struct { fp_register: u8, offset: i32 },
573 wasm_local: u32,
573574 },
574575 ) error{OutOfMemory}!void {
575576 const dbg_info = &self.dbg_info;
......@@ -583,12 +584,6 @@ pub const DeclState = struct {
583584 1, // ULEB128 dwarf expression length
584585 reg,
585586 });
586 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
587 const index = dbg_info.items.len;
588 try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
589 try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4
590 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
591
592587 },
593588 .stack => |info| {
594589 try dbg_info.ensureUnusedCapacity(8);
......@@ -600,14 +595,30 @@ pub const DeclState = struct {
600595 });
601596 leb128.writeILEB128(dbg_info.writer(), info.offset) catch unreachable;
602597 dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
603 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
604 const index = dbg_info.items.len;
605 try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
606 try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index));
607 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
608
598 },
599 .wasm_local => |value| {
600 const leb_size = link.File.Wasm.getULEB128Size(value);
601 try dbg_info.ensureUnusedCapacity(3 + leb_size);
602 // wasm locations are encoded as follow:
603 // DW_OP_WASM_location wasm-op
604 // where wasm-op is defined as
605 // wasm-op := wasm-local | wasm-global | wasm-operand_stack
606 // where each argument is encoded as
607 // <opcode> i:uleb128
608 dbg_info.appendSliceAssumeCapacity(&.{
609 @enumToInt(AbbrevKind.parameter),
610 DW.OP.WASM_location,
611 DW.OP.WASM_local,
612 });
613 leb128.writeULEB128(dbg_info.writer(), value) catch unreachable;
609614 },
610615 }
616
617 try dbg_info.ensureUnusedCapacity(5 + name_with_null.len);
618 const index = dbg_info.items.len;
619 try dbg_info.resize(index + 4); // dw.at.type, dw.form.ref4
620 try self.addTypeRelocGlobal(atom, ty, @intCast(u32, index)); // DW.AT.type, DW.FORM.ref4
621 dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string
611622 }
612623
613624 pub const VarArgDbgInfoLoc = union(enum) {
......@@ -616,6 +627,7 @@ pub const DeclState = struct {
616627 fp_register: u8,
617628 offset: i32,
618629 },
630 wasm_local: u32,
619631 memory: u64,
620632 linker_load: LinkerLoad,
621633 immediate: u64,
......@@ -659,6 +671,22 @@ pub const DeclState = struct {
659671 dbg_info.items[fixup] += @intCast(u8, dbg_info.items.len - fixup - 2);
660672 },
661673
674 .wasm_local => |value| {
675 const leb_size = link.File.Wasm.getULEB128Size(value);
676 try dbg_info.ensureUnusedCapacity(2 + leb_size);
677 // wasm locals are encoded as follow:
678 // DW_OP_WASM_location wasm-op
679 // where wasm-op is defined as
680 // wasm-op := wasm-local | wasm-global | wasm-operand_stack
681 // where wasm-local is encoded as
682 // wasm-local := 0x00 i:uleb128
683 dbg_info.appendSliceAssumeCapacity(&.{
684 DW.OP.WASM_location,
685 DW.OP.WASM_local,
686 });
687 leb128.writeULEB128(dbg_info.writer(), value) catch unreachable;
688 },
689
662690 .memory,
663691 .linker_load,
664692 => {