| ... | @@ -11,6 +11,7 @@ const log = std.log.scoped(.link); | ... | @@ -11,6 +11,7 @@ const log = std.log.scoped(.link); |
| 11 | const wasm = std.wasm; | 11 | const wasm = std.wasm; |
| 12 | | 12 | |
| 13 | const Atom = @import("Wasm/Atom.zig"); | 13 | const Atom = @import("Wasm/Atom.zig"); |
| | 14 | const Dwarf = @import("Dwarf.zig"); |
| 14 | const Module = @import("../Module.zig"); | 15 | const Module = @import("../Module.zig"); |
| 15 | const Compilation = @import("../Compilation.zig"); | 16 | const Compilation = @import("../Compilation.zig"); |
| 16 | const CodeGen = @import("../arch/wasm/CodeGen.zig"); | 17 | const CodeGen = @import("../arch/wasm/CodeGen.zig"); |
| ... | @@ -82,6 +83,8 @@ data_segments: std.StringArrayHashMapUnmanaged(u32) = .{}, | ... | @@ -82,6 +83,8 @@ data_segments: std.StringArrayHashMapUnmanaged(u32) = .{}, |
| 82 | segment_info: std.ArrayListUnmanaged(types.Segment) = .{}, | 83 | segment_info: std.ArrayListUnmanaged(types.Segment) = .{}, |
| 83 | /// Deduplicated string table for strings used by symbols, imports and exports. | 84 | /// Deduplicated string table for strings used by symbols, imports and exports. |
| 84 | string_table: StringTable = .{}, | 85 | string_table: StringTable = .{}, |
| | 86 | /// Debug information for wasm |
| | 87 | dwarf: ?Dwarf = null, |
| 85 | | 88 | |
| 86 | // Output sections | 89 | // Output sections |
| 87 | /// Output type section | 90 | /// Output type section |
| ... | @@ -137,10 +140,15 @@ pub const Segment = struct { | ... | @@ -137,10 +140,15 @@ pub const Segment = struct { |
| 137 | }; | 140 | }; |
| 138 | | 141 | |
| 139 | pub const FnData = struct { | 142 | pub const FnData = struct { |
| | 143 | /// Reference to the wasm type that represents this function. |
| 140 | type_index: u32, | 144 | 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, |
| 141 | | 148 | |
| 142 | pub const empty: FnData = .{ | 149 | pub const empty: FnData = .{ |
| 143 | .type_index = undefined, | 150 | .type_index = undefined, |
| | 151 | .src_fn = Dwarf.SrcFn.empty, |
| 144 | }; | 152 | }; |
| 145 | }; | 153 | }; |
| 146 | | 154 | |
| ... | @@ -318,6 +326,11 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm { | ... | @@ -318,6 +326,11 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Wasm { |
| 318 | }, | 326 | }, |
| 319 | .name = undefined, | 327 | .name = undefined, |
| 320 | }; | 328 | }; |
| | 329 | |
| | 330 | if (!options.strip and options.module != null) { |
| | 331 | self.dwarf = Dwarf.init(gpa, .wasm, options.target); |
| | 332 | } |
| | 333 | |
| 321 | const use_llvm = build_options.have_llvm and options.use_llvm; | 334 | const use_llvm = build_options.have_llvm and options.use_llvm; |
| 322 | const use_stage1 = build_options.is_stage1 and options.use_stage1; | 335 | const use_stage1 = build_options.is_stage1 and options.use_stage1; |
| 323 | if (use_llvm and !use_stage1) { | 336 | if (use_llvm and !use_stage1) { |
| ... | @@ -479,6 +492,10 @@ pub fn deinit(self: *Wasm) void { | ... | @@ -479,6 +492,10 @@ pub fn deinit(self: *Wasm) void { |
| 479 | self.exports.deinit(gpa); | 492 | self.exports.deinit(gpa); |
| 480 | | 493 | |
| 481 | self.string_table.deinit(gpa); | 494 | self.string_table.deinit(gpa); |
| | 495 | |
| | 496 | if (self.dwarf) |*dwarf| { |
| | 497 | dwarf.deinit(); |
| | 498 | } |
| 482 | } | 499 | } |
| 483 | | 500 | |
| 484 | pub fn allocateDeclIndexes(self: *Wasm, decl_index: Module.Decl.Index) !void { | 501 | 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 | ... | @@ -515,12 +532,19 @@ pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes |
| 515 | if (build_options.have_llvm) { | 532 | if (build_options.have_llvm) { |
| 516 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness); | 533 | if (self.llvm_object) |llvm_object| return llvm_object.updateFunc(mod, func, air, liveness); |
| 517 | } | 534 | } |
| | 535 | |
| | 536 | const tracy = trace(@src()); |
| | 537 | defer tracy.end(); |
| | 538 | |
| 518 | const decl_index = func.owner_decl; | 539 | const decl_index = func.owner_decl; |
| 519 | const decl = mod.declPtr(decl_index); | 540 | const decl = mod.declPtr(decl_index); |
| 520 | assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() | 541 | assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() |
| 521 | | 542 | |
| 522 | decl.link.wasm.clear(); | 543 | decl.link.wasm.clear(); |
| 523 | | 544 | |
| | 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 | |
| 524 | var code_writer = std.ArrayList(u8).init(self.base.allocator); | 548 | var code_writer = std.ArrayList(u8).init(self.base.allocator); |
| 525 | defer code_writer.deinit(); | 549 | defer code_writer.deinit(); |
| 526 | const result = try codegen.generateFunction( | 550 | const result = try codegen.generateFunction( |
| ... | @@ -530,7 +554,7 @@ pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes | ... | @@ -530,7 +554,7 @@ pub fn updateFunc(self: *Wasm, mod: *Module, func: *Module.Fn, air: Air, livenes |
| 530 | air, | 554 | air, |
| 531 | liveness, | 555 | liveness, |
| 532 | &code_writer, | 556 | &code_writer, |
| 533 | .none, | 557 | if (decl_state) |*ds| .{ .dwarf = ds } else .none, |
| 534 | ); | 558 | ); |
| 535 | | 559 | |
| 536 | const code = switch (result) { | 560 | const code = switch (result) { |
| ... | @@ -555,6 +579,9 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi | ... | @@ -555,6 +579,9 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi |
| 555 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); | 579 | if (self.llvm_object) |llvm_object| return llvm_object.updateDecl(mod, decl_index); |
| 556 | } | 580 | } |
| 557 | | 581 | |
| | 582 | const tracy = trace(@src()); |
| | 583 | defer tracy.end(); |
| | 584 | |
| 558 | const decl = mod.declPtr(decl_index); | 585 | const decl = mod.declPtr(decl_index); |
| 559 | assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() | 586 | assert(decl.link.wasm.sym_index != 0); // Must call allocateDeclIndexes() |
| 560 | | 587 | |
| ... | @@ -596,6 +623,20 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi | ... | @@ -596,6 +623,20 @@ pub fn updateDecl(self: *Wasm, mod: *Module, decl_index: Module.Decl.Index) !voi |
| 596 | return self.finishUpdateDecl(decl, code); | 623 | return self.finishUpdateDecl(decl, code); |
| 597 | } | 624 | } |
| 598 | | 625 | |
| | 626 | pub 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 | |
| 599 | fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void { | 640 | fn finishUpdateDecl(self: *Wasm, decl: *Module.Decl, code: []const u8) !void { |
| 600 | if (code.len == 0) return; | 641 | if (code.len == 0) return; |
| 601 | const mod = self.base.options.module.?; | 642 | const mod = self.base.options.module.?; |
| ... | @@ -852,6 +893,12 @@ pub fn freeDecl(self: *Wasm, decl_index: Module.Decl.Index) void { | ... | @@ -852,6 +893,12 @@ pub fn freeDecl(self: *Wasm, decl_index: Module.Decl.Index) void { |
| 852 | } | 893 | } |
| 853 | _ = self.resolved_symbols.swapRemove(atom.symbolLoc()); | 894 | _ = self.resolved_symbols.swapRemove(atom.symbolLoc()); |
| 854 | _ = self.symbol_atom.remove(atom.symbolLoc()); | 895 | _ = 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 | |
| 855 | atom.deinit(self.base.allocator); | 902 | atom.deinit(self.base.allocator); |
| 856 | } | 903 | } |
| 857 | | 904 | |