| ... | ... | @@ -67,6 +67,18 @@ code_section_index: ?u32 = null, |
| 67 | 67 | debug_info_index: ?u32 = null, |
| 68 | 68 | /// The index of the segment representing the custom '.debug_line' section. |
| 69 | 69 | debug_line_index: ?u32 = null, |
| 70 | /// The index of the segment representing the custom '.debug_loc' section. |
| 71 | debug_loc_index: ?u32 = null, |
| 72 | /// The index of the segment representing the custom '.debug_ranges' section. |
| 73 | debug_ranges_index: ?u32 = null, |
| 74 | /// The index of the segment representing the custom '.debug_pubnames' section. |
| 75 | debug_pubnames_index: ?u32 = null, |
| 76 | /// The index of the segment representing the custom '.debug_pubtypes' section. |
| 77 | debug_pubtypes_index: ?u32 = null, |
| 78 | /// The index of the segment representing the custom '.debug_pubtypes' section. |
| 79 | debug_str_index: ?u32 = null, |
| 80 | /// The index of the segment representing the custom '.debug_pubtypes' section. |
| 81 | debug_abbrev_index: ?u32 = null, |
| 70 | 82 | /// The count of imported functions. This number will be appended |
| 71 | 83 | /// to the function indexes as their index starts at the lowest non-extern function. |
| 72 | 84 | imported_functions_count: u32 = 0, |
| ... | ... | @@ -1753,7 +1765,7 @@ fn setupMemory(self: *Wasm) !void { |
| 1753 | 1765 | /// From a given object's index and the index of the segment, returns the corresponding |
| 1754 | 1766 | /// index of the segment within the final data section. When the segment does not yet |
| 1755 | 1767 | /// exist, a new one will be initialized and appended. The new index will be returned in that case. |
| 1756 | | pub fn getMatchingSegment(self: *Wasm, object_index: u16, relocatable_index: u32) !u32 { |
| 1768 | pub fn getMatchingSegment(self: *Wasm, object_index: u16, relocatable_index: u32) !?u32 { |
| 1757 | 1769 | const object: Object = self.objects.items[object_index]; |
| 1758 | 1770 | const relocatable_data = object.relocatable_data[relocatable_index]; |
| 1759 | 1771 | const index = @intCast(u32, self.segments.items.len); |
| ... | ... | @@ -1765,27 +1777,83 @@ pub fn getMatchingSegment(self: *Wasm, object_index: u16, relocatable_index: u32 |
| 1765 | 1777 | const result = try self.data_segments.getOrPut(self.base.allocator, segment_info.outputName(merge_segment)); |
| 1766 | 1778 | if (!result.found_existing) { |
| 1767 | 1779 | result.value_ptr.* = index; |
| 1768 | | try self.segments.append(self.base.allocator, .{ |
| 1769 | | .alignment = 1, |
| 1770 | | .size = 0, |
| 1771 | | .offset = 0, |
| 1772 | | }); |
| 1780 | try self.appendDummySegment(); |
| 1773 | 1781 | return index; |
| 1774 | 1782 | } else return result.value_ptr.*; |
| 1775 | 1783 | }, |
| 1776 | 1784 | .code => return self.code_section_index orelse blk: { |
| 1777 | 1785 | self.code_section_index = index; |
| 1778 | | try self.segments.append(self.base.allocator, .{ |
| 1779 | | .alignment = 1, |
| 1780 | | .size = 0, |
| 1781 | | .offset = 0, |
| 1782 | | }); |
| 1786 | try self.appendDummySegment(); |
| 1783 | 1787 | break :blk index; |
| 1784 | 1788 | }, |
| 1785 | | .debug => return error.@"TODO: Custom section relocations for wasm", |
| 1789 | .debug => { |
| 1790 | const debug_name = object.getDebugName(relocatable_data); |
| 1791 | if (mem.eql(u8, debug_name, ".debug_info")) { |
| 1792 | return self.debug_info_index orelse blk: { |
| 1793 | self.debug_info_index = index; |
| 1794 | try self.appendDummySegment(); |
| 1795 | break :blk index; |
| 1796 | }; |
| 1797 | } else if (mem.eql(u8, debug_name, ".debug_line")) { |
| 1798 | return self.debug_line_index orelse blk: { |
| 1799 | self.debug_line_index = index; |
| 1800 | try self.appendDummySegment(); |
| 1801 | break :blk index; |
| 1802 | }; |
| 1803 | } else if (mem.eql(u8, debug_name, ".debug_loc")) { |
| 1804 | return self.debug_loc_index orelse blk: { |
| 1805 | self.debug_loc_index = index; |
| 1806 | try self.appendDummySegment(); |
| 1807 | break :blk index; |
| 1808 | }; |
| 1809 | } else if (mem.eql(u8, debug_name, ".debug_ranges")) { |
| 1810 | return self.debug_line_index orelse blk: { |
| 1811 | self.debug_ranges_index = index; |
| 1812 | try self.appendDummySegment(); |
| 1813 | break :blk index; |
| 1814 | }; |
| 1815 | } else if (mem.eql(u8, debug_name, ".debug_pubnames")) { |
| 1816 | return self.debug_pubnames_index orelse blk: { |
| 1817 | self.debug_pubnames_index = index; |
| 1818 | try self.appendDummySegment(); |
| 1819 | break :blk index; |
| 1820 | }; |
| 1821 | } else if (mem.eql(u8, debug_name, ".debug_pubtypes")) { |
| 1822 | return self.debug_pubtypes_index orelse blk: { |
| 1823 | self.debug_pubtypes_index = index; |
| 1824 | try self.appendDummySegment(); |
| 1825 | break :blk index; |
| 1826 | }; |
| 1827 | } else if (mem.eql(u8, debug_name, ".debug_abbrev")) { |
| 1828 | return self.debug_abbrev_index orelse blk: { |
| 1829 | self.debug_abbrev_index = index; |
| 1830 | try self.appendDummySegment(); |
| 1831 | break :blk index; |
| 1832 | }; |
| 1833 | } else if (mem.eql(u8, debug_name, ".debug_str")) { |
| 1834 | return self.debug_str_index orelse blk: { |
| 1835 | self.debug_str_index = index; |
| 1836 | try self.appendDummySegment(); |
| 1837 | break :blk index; |
| 1838 | }; |
| 1839 | } else { |
| 1840 | log.warn("found unknown debug section '{s}'", .{debug_name}); |
| 1841 | log.warn(" debug section will be skipped", .{}); |
| 1842 | return null; |
| 1843 | } |
| 1844 | }, |
| 1786 | 1845 | } |
| 1787 | 1846 | } |
| 1788 | 1847 | |
| 1848 | /// Appends a new segment with default field values |
| 1849 | fn appendDummySegment(self: *Wasm) !void { |
| 1850 | try self.segments.append(self.base.allocator, .{ |
| 1851 | .alignment = 1, |
| 1852 | .size = 0, |
| 1853 | .offset = 0, |
| 1854 | }); |
| 1855 | } |
| 1856 | |
| 1789 | 1857 | /// Returns the symbol index of the error name table. |
| 1790 | 1858 | /// |
| 1791 | 1859 | /// When the symbol does not yet exist, it will create a new one instead. |
| ... | ... | @@ -1936,17 +2004,18 @@ fn resetState(self: *Wasm) void { |
| 1936 | 2004 | for (self.segment_info.items) |*segment_info| { |
| 1937 | 2005 | self.base.allocator.free(segment_info.name); |
| 1938 | 2006 | } |
| 1939 | | const mod = self.base.options.module.?; |
| 1940 | | var decl_it = self.decls.keyIterator(); |
| 1941 | | while (decl_it.next()) |decl_index_ptr| { |
| 1942 | | const decl = mod.declPtr(decl_index_ptr.*); |
| 1943 | | const atom = &decl.link.wasm; |
| 1944 | | atom.next = null; |
| 1945 | | atom.prev = null; |
| 2007 | if (self.base.options.module) |mod| { |
| 2008 | var decl_it = self.decls.keyIterator(); |
| 2009 | while (decl_it.next()) |decl_index_ptr| { |
| 2010 | const decl = mod.declPtr(decl_index_ptr.*); |
| 2011 | const atom = &decl.link.wasm; |
| 2012 | atom.next = null; |
| 2013 | atom.prev = null; |
| 1946 | 2014 | |
| 1947 | | for (atom.locals.items) |*local_atom| { |
| 1948 | | local_atom.next = null; |
| 1949 | | local_atom.prev = null; |
| 2015 | for (atom.locals.items) |*local_atom| { |
| 2016 | local_atom.next = null; |
| 2017 | local_atom.prev = null; |
| 2018 | } |
| 1950 | 2019 | } |
| 1951 | 2020 | } |
| 1952 | 2021 | self.functions.clearRetainingCapacity(); |
| ... | ... | @@ -2036,29 +2105,34 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2036 | 2105 | defer self.resetState(); |
| 2037 | 2106 | try self.setupStart(); |
| 2038 | 2107 | try self.setupImports(); |
| 2039 | | const mod = self.base.options.module.?; |
| 2040 | | var decl_it = self.decls.keyIterator(); |
| 2041 | | while (decl_it.next()) |decl_index_ptr| { |
| 2042 | | const decl = mod.declPtr(decl_index_ptr.*); |
| 2043 | | if (decl.isExtern()) continue; |
| 2044 | | const atom = &decl.*.link.wasm; |
| 2045 | | if (decl.ty.zigTypeTag() == .Fn) { |
| 2046 | | try self.parseAtom(atom, .{ .function = decl.fn_link.wasm }); |
| 2047 | | } else if (decl.getVariable()) |variable| { |
| 2048 | | if (!variable.is_mutable) { |
| 2049 | | try self.parseAtom(atom, .{ .data = .read_only }); |
| 2050 | | } else if (variable.init.isUndefDeep()) { |
| 2051 | | try self.parseAtom(atom, .{ .data = .uninitialized }); |
| 2108 | if (self.base.options.module) |mod| { |
| 2109 | var decl_it = self.decls.keyIterator(); |
| 2110 | while (decl_it.next()) |decl_index_ptr| { |
| 2111 | const decl = mod.declPtr(decl_index_ptr.*); |
| 2112 | if (decl.isExtern()) continue; |
| 2113 | const atom = &decl.*.link.wasm; |
| 2114 | if (decl.ty.zigTypeTag() == .Fn) { |
| 2115 | try self.parseAtom(atom, .{ .function = decl.fn_link.wasm }); |
| 2116 | } else if (decl.getVariable()) |variable| { |
| 2117 | if (!variable.is_mutable) { |
| 2118 | try self.parseAtom(atom, .{ .data = .read_only }); |
| 2119 | } else if (variable.init.isUndefDeep()) { |
| 2120 | try self.parseAtom(atom, .{ .data = .uninitialized }); |
| 2121 | } else { |
| 2122 | try self.parseAtom(atom, .{ .data = .initialized }); |
| 2123 | } |
| 2052 | 2124 | } else { |
| 2053 | | try self.parseAtom(atom, .{ .data = .initialized }); |
| 2125 | try self.parseAtom(atom, .{ .data = .read_only }); |
| 2126 | } |
| 2127 | |
| 2128 | // also parse atoms for a decl's locals |
| 2129 | for (atom.locals.items) |*local_atom| { |
| 2130 | try self.parseAtom(local_atom, .{ .data = .read_only }); |
| 2054 | 2131 | } |
| 2055 | | } else { |
| 2056 | | try self.parseAtom(atom, .{ .data = .read_only }); |
| 2057 | 2132 | } |
| 2058 | 2133 | |
| 2059 | | // also parse atoms for a decl's locals |
| 2060 | | for (atom.locals.items) |*local_atom| { |
| 2061 | | try self.parseAtom(local_atom, .{ .data = .read_only }); |
| 2134 | if (self.dwarf) |*dwarf| { |
| 2135 | try dwarf.flushModule(&self.base, self.base.options.module.?); |
| 2062 | 2136 | } |
| 2063 | 2137 | } |
| 2064 | 2138 | |
| ... | ... | @@ -2066,9 +2140,6 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2066 | 2140 | try object.parseIntoAtoms(self.base.allocator, @intCast(u16, object_index), self); |
| 2067 | 2141 | } |
| 2068 | 2142 | |
| 2069 | | if (self.dwarf) |*dwarf| { |
| 2070 | | try dwarf.flushModule(&self.base, self.base.options.module.?); |
| 2071 | | } |
| 2072 | 2143 | try self.allocateAtoms(); |
| 2073 | 2144 | try self.setupMemory(); |
| 2074 | 2145 | self.mapFunctionTable(); |
| ... | ... | @@ -2425,12 +2496,14 @@ pub fn flushModule(self: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2425 | 2496 | } else if (!self.base.options.strip) { |
| 2426 | 2497 | if (self.dwarf) |*dwarf| { |
| 2427 | 2498 | if (self.debug_info_index != null) { |
| 2428 | | try dwarf.writeDbgAbbrev(&self.base); |
| 2429 | | // for debug info and ranges, the address is always 0, |
| 2430 | | // as locations are always offsets relative to 'code' section. |
| 2431 | | try dwarf.writeDbgInfoHeader(&self.base, mod, 0, code_section_size); |
| 2432 | | try dwarf.writeDbgAranges(&self.base, 0, code_section_size); |
| 2433 | | try dwarf.writeDbgLineHeader(&self.base, mod); |
| 2499 | if (self.base.options.module) |mod| { |
| 2500 | try dwarf.writeDbgAbbrev(&self.base); |
| 2501 | // for debug info and ranges, the address is always 0, |
| 2502 | // as locations are always offsets relative to 'code' section. |
| 2503 | try dwarf.writeDbgInfoHeader(&self.base, mod, 0, code_section_size); |
| 2504 | try dwarf.writeDbgAranges(&self.base, 0, code_section_size); |
| 2505 | try dwarf.writeDbgLineHeader(&self.base, mod); |
| 2506 | } |
| 2434 | 2507 | |
| 2435 | 2508 | try emitDebugSection(file, self.debug_info.items, ".debug_info"); |
| 2436 | 2509 | try emitDebugSection(file, self.debug_aranges.items, ".debug_ranges"); |