authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-04-30 15:42:21+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-05-09 18:51:46+02:00
log8e1c220be257236565fb28d84dc56045f15be697
tree6715e0f845829c9e2a0ab3b25d0a75a866537417
parent941b6830b1831c4df5ba369088ff473a012a3b54

wasm: Add basic debug info references


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

src/link.zig+2-1
......@@ -485,8 +485,9 @@ pub const File = struct {
485485 .elf => return @fieldParentPtr(Elf, "base", base).updateDeclLineNumber(module, decl),
486486 .macho => return @fieldParentPtr(MachO, "base", base).updateDeclLineNumber(module, decl),
487487 .c => return @fieldParentPtr(C, "base", base).updateDeclLineNumber(module, decl),
488 .wasm => return @fieldParentPtr(Wasm, "base", base).updateDeclLineNumber(module, decl),
488489 .plan9 => @panic("TODO: implement updateDeclLineNumber for plan9"),
489 .wasm, .spirv, .nvptx => {},
490 .spirv, .nvptx => {},
490491 }
491492 }
492493
src/link/Dwarf.zig+6
......@@ -735,6 +735,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState
735735 const atom = switch (self.tag) {
736736 .elf => &decl.link.elf.dbg_info_atom,
737737 .macho => &decl.link.macho.dbg_info_atom,
738 .wasm => &decl.link.wasm.dbg_info_atom,
738739 else => unreachable,
739740 };
740741 try decl_state.addTypeReloc(
......@@ -1250,6 +1251,10 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl)
12501251 const file_pos = sect.offset + decl.fn_link.macho.off + self.getRelocDbgLineOff();
12511252 try d_sym.file.pwriteAll(&data, file_pos);
12521253 },
1254 .wasm => {
1255 const wasm_file = file.cast(File.Wasm).?;
1256 _ = wasm_file; // TODO, update .debug_line
1257 },
12531258 else => unreachable,
12541259 }
12551260}
......@@ -1285,6 +1290,7 @@ pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void {
12851290 const fn_link = switch (self.tag) {
12861291 .elf => &decl.fn_link.elf,
12871292 .macho => &decl.fn_link.macho,
1293 .wasm => &decl.fn_link.wasm.src_fn,
12881294 else => unreachable,
12891295 };
12901296 _ = self.dbg_line_fn_free_list.remove(fn_link);
src/link/Wasm.zig+48-1
......@@ -11,6 +11,7 @@ const log = std.log.scoped(.link);
1111const wasm = std.wasm;
1212
1313const Atom = @import("Wasm/Atom.zig");
14const Dwarf = @import("Dwarf.zig");
1415const Module = @import("../Module.zig");
1516const Compilation = @import("../Compilation.zig");
1617const CodeGen = @import("../arch/wasm/CodeGen.zig");
......@@ -82,6 +83,8 @@ data_segments: std.StringArrayHashMapUnmanaged(u32) = .{},
8283segment_info: std.ArrayListUnmanaged(types.Segment) = .{},
8384/// Deduplicated string table for strings used by symbols, imports and exports.
8485string_table: StringTable = .{},
86/// Debug information for wasm
87dwarf: ?Dwarf = null,
8588
8689// Output sections
8790/// Output type section
......@@ -137,10 +140,15 @@ pub const Segment = struct {
137140};
138141
139142pub const FnData = struct {
143 /// Reference to the wasm type that represents this function.
140144 type_index: u32,
145 /// Contains debug information related to this function.
146 /// For Wasm, the offset is relative to the code-section.
147 src_fn: Dwarf.SrcFn,
141148
142149 pub const empty: FnData = .{
143150 .type_index = undefined,
151 .src_fn = Dwarf.SrcFn.empty,
144152 };
145153};
146154
......@@ -318,6 +326,11 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm {
318326 },
319327 .name = undefined,
320328 };
329
330 if (!options.strip and options.module != null) {
331 self.dwarf = Dwarf.init(gpa, .wasm, options.target);
332 }
333
321334 const use_llvm = build_options.have_llvm and options.use_llvm;
322335 const use_stage1 = build_options.is_stage1 and options.use_stage1;
323336 if (use_llvm and !use_stage1) {
......@@ -479,6 +492,10 @@ pub fn deinit(self: *Wasm) void {
479492 self.exports.deinit(gpa);
480493
481494 self.string_table.deinit(gpa);
495
496 if (self.dwarf) |*dwarf| {
497 dwarf.deinit();
498 }
482499}
483500
484501pub fn allocateDeclIndexes(self: *Wasm, decl_index: Module.Decl.Index) !void {
......@@ -515,12 +532,19 @@ pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes
515532 if (build_options.have_llvm) {
516533 if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness);
517534 }
535
536 const tracy = trace(@src());
537 defer tracy.end();
538
518539 const decl_index = func.owner_decl;
519540 const decl = mod.declPtr(decl_index);
520541 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()
521542
522543 decl.link.wasm.clear();
523544
545 var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl) else null;
546 defer if (decl_state) |*ds| ds.deinit();
547
524548 var code_writer = std.ArrayList(u8).init(self.base.allocator);
525549 defer code_writer.deinit();
526550 const result = try codegen.generateFunction(
......@@ -530,7 +554,7 @@ pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes
530554 air,
531555 liveness,
532556 &code_writer,
533 .none,
557 if (decl_state) |*ds| .{ .dwarf = ds } else .none,
534558 );
535559
536560 const code = switch (result) {
......@@ -555,6 +579,9 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
555579 if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index);
556580 }
557581
582 const tracy = trace(@src());
583 defer tracy.end();
584
558585 const decl = mod.declPtr(decl_index);
559586 assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes()
560587
......@@ -596,6 +623,20 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi
596623 return self.finishUpdateDecl(decl, code);
597624}
598625
626pub fn updateDeclLineNumber(self: *Wasm, mod: *Module, decl: *const Module.Decl) !void {
627 if (self.llvm_object) |_| return;
628 if (self.dwarf) |*dw| {
629 const tracy = trace(@src());
630 defer tracy.end();
631
632 const decl_name = try decl.getFullyQualifiedName(mod);
633 defer self.base.allocator.free(decl_name);
634
635 log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl });
636 try dw.updateDeclLineNumber(&self.base, decl);
637 }
638}
639
599640fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void {
600641 if (code.len == 0) return;
601642 const mod = self.base.options.module.?;
......@@ -852,6 +893,12 @@ pub fn freeDecl(self: *Wasm, decl_index: Module.Decl.Index) void {
852893 }
853894 _ = self.resolved_symbols.swapRemove(atom.symbolLoc());
854895 _ = self.symbol_atom.remove(atom.symbolLoc());
896
897 if (self.dwarf) |*dwarf| {
898 dwarf.freeDecl(decl);
899 dwarf.freeAtom(&atom.dbg_info_atom);
900 }
901
855902 atom.deinit(self.base.allocator);
856903}
857904
src/link/Wasm/Atom.zig+5
......@@ -4,6 +4,7 @@ const std = @import("std");
44const types = @import("types.zig");
55const Wasm = @import("../Wasm.zig");
66const Symbol = @import("Symbol.zig");
7const Dwarf = @import("../Dwarf.zig");
78
89const leb = std.leb;
910const log = std.log.scoped(.link);
......@@ -38,6 +39,9 @@ prev: ?*Atom,
3839/// When the parent atom is being freed, it will also do so for all local atoms.
3940locals: std.ArrayListUnmanaged(Atom) = .{},
4041
42/// Represents the debug Atom that holds all debug information of this Atom.
43dbg_info_atom: Dwarf.Atom,
44
4145/// Represents a default empty wasm `Atom`
4246pub const empty: Atom = .{
4347 .alignment = 0,
......@@ -47,6 +51,7 @@ pub const empty: Atom = .{
4751 .prev = null,
4852 .size = 0,
4953 .sym_index = 0,
54 .dbg_info_atom = undefined,
5055};
5156
5257/// Frees all resources owned by this `Atom`.