diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-04-30 15:42:21 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-05-09 18:51:46 +0200 |
| commit | 8e1c220be257236565fb28d84dc56045f15be697 (patch) | |
| tree | 6715e0f845829c9e2a0ab3b25d0a75a866537417 /src/link | |
| parent | 941b6830b1831c4df5ba369088ff473a012a3b54 (diff) | |
| download | zig-8e1c220be257236565fb28d84dc56045f15be697.tar.gz zig-8e1c220be257236565fb28d84dc56045f15be697.zip | |
wasm: Add basic debug info references
Diffstat (limited to 'src/link')
| -rw-r--r-- | src/link/Dwarf.zig | 6 | ||||
| -rw-r--r-- | src/link/Wasm.zig | 49 | ||||
| -rw-r--r-- | src/link/Wasm/Atom.zig | 5 |
3 files changed, 59 insertions, 1 deletions
diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 97fc090b9a..bf02c22f7b 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -735,6 +735,7 @@ pub fn initDeclState(self: *Dwarf, mod: *Module, decl: *Module.Decl) !DeclState const atom = switch (self.tag) { .elf => &decl.link.elf.dbg_info_atom, .macho => &decl.link.macho.dbg_info_atom, + .wasm => &decl.link.wasm.dbg_info_atom, else => unreachable, }; try decl_state.addTypeReloc( @@ -1250,6 +1251,10 @@ pub fn updateDeclLineNumber(self: *Dwarf, file: *File, decl: *const Module.Decl) const file_pos = sect.offset + decl.fn_link.macho.off + self.getRelocDbgLineOff(); try d_sym.file.pwriteAll(&data, file_pos); }, + .wasm => { + const wasm_file = file.cast(File.Wasm).?; + _ = wasm_file; // TODO, update .debug_line + }, else => unreachable, } } @@ -1285,6 +1290,7 @@ pub fn freeDecl(self: *Dwarf, decl: *Module.Decl) void { const fn_link = switch (self.tag) { .elf => &decl.fn_link.elf, .macho => &decl.fn_link.macho, + .wasm => &decl.fn_link.wasm.src_fn, else => unreachable, }; _ = self.dbg_line_fn_free_list.remove(fn_link); diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 4e898cee07..f4bd962016 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -11,6 +11,7 @@ const log = std.log.scoped(.link); const wasm = std.wasm; const Atom = @import("Wasm/Atom.zig"); +const Dwarf = @import("Dwarf.zig"); const Module = @import("../Module.zig"); const Compilation = @import("../Compilation.zig"); const CodeGen = @import("../arch/wasm/CodeGen.zig"); @@ -82,6 +83,8 @@ data_segments: std.StringArrayHashMapUnmanaged(u32) = .{}, segment_info: std.ArrayListUnmanaged(types.Segment) = .{}, /// Deduplicated string table for strings used by symbols, imports and exports. string_table: StringTable = .{}, +/// Debug information for wasm +dwarf: ?Dwarf = null, // Output sections /// Output type section @@ -137,10 +140,15 @@ pub const Segment = struct { }; pub const FnData = struct { + /// Reference to the wasm type that represents this function. type_index: u32, + /// Contains debug information related to this function. + /// For Wasm, the offset is relative to the code-section. + src_fn: Dwarf.SrcFn, pub const empty: FnData = .{ .type_index = undefined, + .src_fn = Dwarf.SrcFn.empty, }; }; @@ -318,6 +326,11 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm { }, .name = undefined, }; + + if (!options.strip and options.module != null) { + self.dwarf = Dwarf.init(gpa, .wasm, options.target); + } + const use_llvm = build_options.have_llvm and options.use_llvm; const use_stage1 = build_options.is_stage1 and options.use_stage1; if (use_llvm and !use_stage1) { @@ -479,6 +492,10 @@ pub fn deinit(self: *Wasm) void { self.exports.deinit(gpa); self.string_table.deinit(gpa); + + if (self.dwarf) |*dwarf| { + dwarf.deinit(); + } } pub 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 if (build_options.have_llvm) { if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness); } + + const tracy = trace(@src()); + defer tracy.end(); + const decl_index = func.owner_decl; const decl = mod.declPtr(decl_index); assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() decl.link.wasm.clear(); + var decl_state: ?Dwarf.DeclState = if (self.dwarf) |*dwarf| try dwarf.initDeclState(mod, decl) else null; + defer if (decl_state) |*ds| ds.deinit(); + var code_writer = std.ArrayList(u8).init(self.base.allocator); defer code_writer.deinit(); const result = try codegen.generateFunction( @@ -530,7 +554,7 @@ pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes air, liveness, &code_writer, - .none, + if (decl_state) |*ds| .{ .dwarf = ds } else .none, ); const code = switch (result) { @@ -555,6 +579,9 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); } + const tracy = trace(@src()); + defer tracy.end(); + const decl = mod.declPtr(decl_index); assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() @@ -596,6 +623,20 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi return self.finishUpdateDecl(decl, code); } +pub fn updateDeclLineNumber(self: *Wasm, mod: *Module, decl: *const Module.Decl) !void { + if (self.llvm_object) |_| return; + if (self.dwarf) |*dw| { + const tracy = trace(@src()); + defer tracy.end(); + + const decl_name = try decl.getFullyQualifiedName(mod); + defer self.base.allocator.free(decl_name); + + log.debug("updateDeclLineNumber {s}{*}", .{ decl_name, decl }); + try dw.updateDeclLineNumber(&self.base, decl); + } +} + fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void { if (code.len == 0) return; const mod = self.base.options.module.?; @@ -852,6 +893,12 @@ pub fn freeDecl(self: *Wasm, decl_index: Module.Decl.Index) void { } _ = self.resolved_symbols.swapRemove(atom.symbolLoc()); _ = self.symbol_atom.remove(atom.symbolLoc()); + + if (self.dwarf) |*dwarf| { + dwarf.freeDecl(decl); + dwarf.freeAtom(&atom.dbg_info_atom); + } + atom.deinit(self.base.allocator); } diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index fc45648d9a..f56a0995bf 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -4,6 +4,7 @@ const std = @import("std"); const types = @import("types.zig"); const Wasm = @import("../Wasm.zig"); const Symbol = @import("Symbol.zig"); +const Dwarf = @import("../Dwarf.zig"); const leb = std.leb; const log = std.log.scoped(.link); @@ -38,6 +39,9 @@ prev: ?*Atom, /// When the parent atom is being freed, it will also do so for all local atoms. locals: std.ArrayListUnmanaged(Atom) = .{}, +/// Represents the debug Atom that holds all debug information of this Atom. +dbg_info_atom: Dwarf.Atom, + /// Represents a default empty wasm `Atom` pub const empty: Atom = .{ .alignment = 0, @@ -47,6 +51,7 @@ pub const empty: Atom = .{ .prev = null, .size = 0, .sym_index = 0, + .dbg_info_atom = undefined, }; /// Frees all resources owned by this `Atom`. |
