| ... | ... | @@ -123,9 +123,10 @@ object_init_funcs: std.ArrayListUnmanaged(InitFunc) = .empty, |
| 123 | 123 | /// logically to an object file's .data section, or .rodata section. In |
| 124 | 124 | /// the case of `-fdata-sections` there will be one segment per data symbol. |
| 125 | 125 | object_data_segments: std.ArrayListUnmanaged(ObjectDataSegment) = .empty, |
| 126 | | /// Each segment has many data symbols. These correspond logically to global |
| 126 | /// Each segment has many data symbols, which correspond logically to global |
| 127 | 127 | /// constants. |
| 128 | 128 | object_datas: std.ArrayListUnmanaged(ObjectData) = .empty, |
| 129 | object_data_imports: std.AutoArrayHashMapUnmanaged(String, ObjectDataImport) = .empty, |
| 129 | 130 | /// Non-synthetic section that can essentially be mem-cpy'd into place after performing relocations. |
| 130 | 131 | object_custom_segments: std.AutoArrayHashMapUnmanaged(ObjectSectionIndex, CustomSegment) = .empty, |
| 131 | 132 | |
| ... | ... | @@ -227,6 +228,22 @@ functions_end_prelink: u32 = 0, |
| 227 | 228 | /// symbol errors, or import section entries depending on the output mode. |
| 228 | 229 | function_imports: std.AutoArrayHashMapUnmanaged(String, FunctionImportId) = .empty, |
| 229 | 230 | |
| 231 | /// At the end of prelink, this is populated with data symbols needed by |
| 232 | /// objects. |
| 233 | /// |
| 234 | /// During the Zcu phase, entries are not deleted from this table |
| 235 | /// because doing so would be irreversible when a `deleteExport` call is |
| 236 | /// handled. However, entries are added during the Zcu phase when extern |
| 237 | /// functions are passed to `updateNav`. |
| 238 | /// |
| 239 | /// `flush` gets a copy of this table, and then Zcu exports are applied to |
| 240 | /// remove elements from the table, and the remainder are either undefined |
| 241 | /// symbol errors, or symbol table entries depending on the output mode. |
| 242 | data_imports: std.AutoArrayHashMapUnmanaged(String, DataImportId) = .empty, |
| 243 | /// Set of data symbols that will appear in the final binary. Used to populate |
| 244 | /// `Flush.data_segments` before sorting. |
| 245 | data_segments: std.AutoArrayHashMapUnmanaged(DataId, void) = .empty, |
| 246 | |
| 230 | 247 | /// Ordered list of non-import globals that will appear in the final binary. |
| 231 | 248 | /// Empty until prelink. |
| 232 | 249 | globals: std.AutoArrayHashMapUnmanaged(GlobalImport.Resolution, void) = .empty, |
| ... | ... | @@ -251,6 +268,7 @@ error_name_table_ref_count: u32 = 0, |
| 251 | 268 | /// value must be this OR'd with the same logic for zig functions |
| 252 | 269 | /// (set to true if any threadlocal global is used). |
| 253 | 270 | any_tls_relocs: bool = false, |
| 271 | any_passive_inits: bool = false, |
| 254 | 272 | |
| 255 | 273 | /// All MIR instructions for all Zcu functions. |
| 256 | 274 | mir_instructions: std.MultiArrayList(Mir.Inst) = .{}, |
| ... | ... | @@ -1499,6 +1517,50 @@ pub const ObjectData = extern struct { |
| 1499 | 1517 | }; |
| 1500 | 1518 | }; |
| 1501 | 1519 | |
| 1520 | pub const ObjectDataImport = extern struct { |
| 1521 | resolution: Resolution, |
| 1522 | flags: SymbolFlags, |
| 1523 | source_location: SourceLocation, |
| 1524 | |
| 1525 | pub const Resolution = enum(u32) { |
| 1526 | __zig_error_names, |
| 1527 | __zig_error_name_table, |
| 1528 | __heap_base, |
| 1529 | __heap_end, |
| 1530 | unresolved = std.math.maxInt(u32), |
| 1531 | _, |
| 1532 | |
| 1533 | comptime { |
| 1534 | assert(@intFromEnum(Resolution.__zig_error_names) == @intFromEnum(DataId.__zig_error_names)); |
| 1535 | assert(@intFromEnum(Resolution.__zig_error_name_table) == @intFromEnum(DataId.__zig_error_name_table)); |
| 1536 | assert(@intFromEnum(Resolution.__heap_base) == @intFromEnum(DataId.__heap_base)); |
| 1537 | assert(@intFromEnum(Resolution.__heap_end) == @intFromEnum(DataId.__heap_end)); |
| 1538 | } |
| 1539 | |
| 1540 | pub fn toDataId(r: Resolution) ?DataId { |
| 1541 | if (r == .unresolved) return null; |
| 1542 | return @enumFromInt(@intFromEnum(r)); |
| 1543 | } |
| 1544 | |
| 1545 | pub fn fromObjectDataIndex(wasm: *const Wasm, object_data_index: ObjectData.Index) Resolution { |
| 1546 | return @enumFromInt(@intFromEnum(DataId.pack(wasm, .{ .object = object_data_index.ptr(wasm).segment }))); |
| 1547 | } |
| 1548 | }; |
| 1549 | |
| 1550 | /// Points into `Wasm.object_data_imports`. |
| 1551 | pub const Index = enum(u32) { |
| 1552 | _, |
| 1553 | |
| 1554 | pub fn value(i: @This(), wasm: *const Wasm) *ObjectDataImport { |
| 1555 | return &wasm.object_data_imports.values()[@intFromEnum(i)]; |
| 1556 | } |
| 1557 | |
| 1558 | pub fn fromSymbolName(wasm: *const Wasm, name: String) ?Index { |
| 1559 | return @enumFromInt(wasm.object_data_imports.getIndex(name) orelse return null); |
| 1560 | } |
| 1561 | }; |
| 1562 | }; |
| 1563 | |
| 1502 | 1564 | pub const DataPayload = extern struct { |
| 1503 | 1565 | off: Off, |
| 1504 | 1566 | /// The size in bytes of the data representing the segment within the section. |
| ... | ... | @@ -1524,12 +1586,17 @@ pub const DataPayload = extern struct { |
| 1524 | 1586 | pub const DataId = enum(u32) { |
| 1525 | 1587 | __zig_error_names, |
| 1526 | 1588 | __zig_error_name_table, |
| 1589 | /// This and `__heap_end` are better retrieved via a global, but there is |
| 1590 | /// some suboptimal code out there (wasi libc) that additionally needs them |
| 1591 | /// as data symbols. |
| 1592 | __heap_base, |
| 1593 | __heap_end, |
| 1527 | 1594 | /// First, an `ObjectDataSegment.Index`. |
| 1528 | 1595 | /// Next, index into `uavs_obj` or `uavs_exe` depending on whether emitting an object. |
| 1529 | 1596 | /// Next, index into `navs_obj` or `navs_exe` depending on whether emitting an object. |
| 1530 | 1597 | _, |
| 1531 | 1598 | |
| 1532 | | const first_object = @intFromEnum(DataId.__zig_error_name_table) + 1; |
| 1599 | const first_object = @intFromEnum(DataId.__heap_end) + 1; |
| 1533 | 1600 | |
| 1534 | 1601 | pub const Category = enum { |
| 1535 | 1602 | /// Thread-local variables. |
| ... | ... | @@ -1544,6 +1611,8 @@ pub const DataId = enum(u32) { |
| 1544 | 1611 | pub const Unpacked = union(enum) { |
| 1545 | 1612 | __zig_error_names, |
| 1546 | 1613 | __zig_error_name_table, |
| 1614 | __heap_base, |
| 1615 | __heap_end, |
| 1547 | 1616 | object: ObjectDataSegment.Index, |
| 1548 | 1617 | uav_exe: UavsExeIndex, |
| 1549 | 1618 | uav_obj: UavsObjIndex, |
| ... | ... | @@ -1555,6 +1624,8 @@ pub const DataId = enum(u32) { |
| 1555 | 1624 | return switch (unpacked) { |
| 1556 | 1625 | .__zig_error_names => .__zig_error_names, |
| 1557 | 1626 | .__zig_error_name_table => .__zig_error_name_table, |
| 1627 | .__heap_base => .__heap_base, |
| 1628 | .__heap_end => .__heap_end, |
| 1558 | 1629 | .object => |i| @enumFromInt(first_object + @intFromEnum(i)), |
| 1559 | 1630 | inline .uav_exe, .uav_obj => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + @intFromEnum(i)), |
| 1560 | 1631 | .nav_exe => |i| @enumFromInt(first_object + wasm.object_data_segments.items.len + wasm.uavs_exe.entries.len + @intFromEnum(i)), |
| ... | ... | @@ -1566,6 +1637,8 @@ pub const DataId = enum(u32) { |
| 1566 | 1637 | return switch (id) { |
| 1567 | 1638 | .__zig_error_names => .__zig_error_names, |
| 1568 | 1639 | .__zig_error_name_table => .__zig_error_name_table, |
| 1640 | .__heap_base => .__heap_base, |
| 1641 | .__heap_end => .__heap_end, |
| 1569 | 1642 | _ => { |
| 1570 | 1643 | const object_index = @intFromEnum(id) - first_object; |
| 1571 | 1644 | |
| ... | ... | @@ -1601,7 +1674,7 @@ pub const DataId = enum(u32) { |
| 1601 | 1674 | |
| 1602 | 1675 | pub fn category(id: DataId, wasm: *const Wasm) Category { |
| 1603 | 1676 | return switch (unpack(id, wasm)) { |
| 1604 | | .__zig_error_names, .__zig_error_name_table => .data, |
| 1677 | .__zig_error_names, .__zig_error_name_table, .__heap_base, .__heap_end => .data, |
| 1605 | 1678 | .object => |i| { |
| 1606 | 1679 | const ptr = i.ptr(wasm); |
| 1607 | 1680 | if (ptr.flags.tls) return .tls; |
| ... | ... | @@ -1622,7 +1695,7 @@ pub const DataId = enum(u32) { |
| 1622 | 1695 | |
| 1623 | 1696 | pub fn isTls(id: DataId, wasm: *const Wasm) bool { |
| 1624 | 1697 | return switch (unpack(id, wasm)) { |
| 1625 | | .__zig_error_names, .__zig_error_name_table => false, |
| 1698 | .__zig_error_names, .__zig_error_name_table, .__heap_base, .__heap_end => false, |
| 1626 | 1699 | .object => |i| i.ptr(wasm).flags.tls, |
| 1627 | 1700 | .uav_exe, .uav_obj => false, |
| 1628 | 1701 | inline .nav_exe, .nav_obj => |i| { |
| ... | ... | @@ -1640,7 +1713,7 @@ pub const DataId = enum(u32) { |
| 1640 | 1713 | |
| 1641 | 1714 | pub fn name(id: DataId, wasm: *const Wasm) []const u8 { |
| 1642 | 1715 | return switch (unpack(id, wasm)) { |
| 1643 | | .__zig_error_names, .__zig_error_name_table, .uav_exe, .uav_obj => ".data", |
| 1716 | .__zig_error_names, .__zig_error_name_table, .uav_exe, .uav_obj, .__heap_base, .__heap_end => ".data", |
| 1644 | 1717 | .object => |i| i.ptr(wasm).name.unwrap().?.slice(wasm), |
| 1645 | 1718 | inline .nav_exe, .nav_obj => |i| { |
| 1646 | 1719 | const zcu = wasm.base.comp.zcu.?; |
| ... | ... | @@ -1654,7 +1727,7 @@ pub const DataId = enum(u32) { |
| 1654 | 1727 | pub fn alignment(id: DataId, wasm: *const Wasm) Alignment { |
| 1655 | 1728 | return switch (unpack(id, wasm)) { |
| 1656 | 1729 | .__zig_error_names => .@"1", |
| 1657 | | .__zig_error_name_table => wasm.pointerAlignment(), |
| 1730 | .__zig_error_name_table, .__heap_base, .__heap_end => wasm.pointerAlignment(), |
| 1658 | 1731 | .object => |i| i.ptr(wasm).flags.alignment, |
| 1659 | 1732 | inline .uav_exe, .uav_obj => |i| { |
| 1660 | 1733 | const zcu = wasm.base.comp.zcu.?; |
| ... | ... | @@ -1683,7 +1756,7 @@ pub const DataId = enum(u32) { |
| 1683 | 1756 | return switch (unpack(id, wasm)) { |
| 1684 | 1757 | .__zig_error_names => @intCast(wasm.error_name_offs.items.len), |
| 1685 | 1758 | .__zig_error_name_table => wasm.error_name_table_ref_count, |
| 1686 | | .object, .uav_obj, .nav_obj => 0, |
| 1759 | .object, .uav_obj, .nav_obj, .__heap_base, .__heap_end => 0, |
| 1687 | 1760 | inline .uav_exe, .nav_exe => |i| i.value(wasm).count, |
| 1688 | 1761 | }; |
| 1689 | 1762 | } |
| ... | ... | @@ -1692,7 +1765,7 @@ pub const DataId = enum(u32) { |
| 1692 | 1765 | const comp = wasm.base.comp; |
| 1693 | 1766 | if (comp.config.import_memory and !id.isBss(wasm)) return true; |
| 1694 | 1767 | return switch (unpack(id, wasm)) { |
| 1695 | | .__zig_error_names, .__zig_error_name_table => false, |
| 1768 | .__zig_error_names, .__zig_error_name_table, .__heap_base, .__heap_end => false, |
| 1696 | 1769 | .object => |i| i.ptr(wasm).flags.is_passive, |
| 1697 | 1770 | .uav_exe, .uav_obj, .nav_exe, .nav_obj => false, |
| 1698 | 1771 | }; |
| ... | ... | @@ -1700,7 +1773,7 @@ pub const DataId = enum(u32) { |
| 1700 | 1773 | |
| 1701 | 1774 | pub fn isEmpty(id: DataId, wasm: *const Wasm) bool { |
| 1702 | 1775 | return switch (unpack(id, wasm)) { |
| 1703 | | .__zig_error_names, .__zig_error_name_table => false, |
| 1776 | .__zig_error_names, .__zig_error_name_table, .__heap_base, .__heap_end => false, |
| 1704 | 1777 | .object => |i| i.ptr(wasm).payload.off == .none, |
| 1705 | 1778 | inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.off == .none, |
| 1706 | 1779 | }; |
| ... | ... | @@ -1716,6 +1789,7 @@ pub const DataId = enum(u32) { |
| 1716 | 1789 | const elem_size = ZcuType.slice_const_u8_sentinel_0.abiSize(zcu); |
| 1717 | 1790 | return @intCast(errors_len * elem_size); |
| 1718 | 1791 | }, |
| 1792 | .__heap_base, .__heap_end => wasm.pointerSize(), |
| 1719 | 1793 | .object => |i| i.ptr(wasm).payload.len, |
| 1720 | 1794 | inline .uav_exe, .uav_obj, .nav_exe, .nav_obj => |i| i.value(wasm).code.len, |
| 1721 | 1795 | }; |
| ... | ... | @@ -2110,6 +2184,55 @@ pub const GlobalImportId = enum(u32) { |
| 2110 | 2184 | } |
| 2111 | 2185 | }; |
| 2112 | 2186 | |
| 2187 | /// 0. Index into `Wasm.object_data_imports`. |
| 2188 | /// 1. Index into `Wasm.imports`. |
| 2189 | pub const DataImportId = enum(u32) { |
| 2190 | _, |
| 2191 | |
| 2192 | pub const Unpacked = union(enum) { |
| 2193 | object_data_import: ObjectDataImport.Index, |
| 2194 | zcu_import: ZcuImportIndex, |
| 2195 | }; |
| 2196 | |
| 2197 | pub fn pack(unpacked: Unpacked, wasm: *const Wasm) DataImportId { |
| 2198 | return switch (unpacked) { |
| 2199 | .object_data_import => |i| @enumFromInt(@intFromEnum(i)), |
| 2200 | .zcu_import => |i| @enumFromInt(@intFromEnum(i) - wasm.object_data_imports.entries.len), |
| 2201 | }; |
| 2202 | } |
| 2203 | |
| 2204 | pub fn unpack(id: DataImportId, wasm: *const Wasm) Unpacked { |
| 2205 | const i = @intFromEnum(id); |
| 2206 | if (i < wasm.object_data_imports.entries.len) return .{ .object_data_import = @enumFromInt(i) }; |
| 2207 | const zcu_import_i = i - wasm.object_data_imports.entries.len; |
| 2208 | return .{ .zcu_import = @enumFromInt(zcu_import_i) }; |
| 2209 | } |
| 2210 | |
| 2211 | pub fn fromZcuImport(zcu_import: ZcuImportIndex, wasm: *const Wasm) DataImportId { |
| 2212 | return pack(.{ .zcu_import = zcu_import }, wasm); |
| 2213 | } |
| 2214 | |
| 2215 | pub fn fromObject(object_data_import: ObjectDataImport.Index, wasm: *const Wasm) DataImportId { |
| 2216 | return pack(.{ .object_data_import = object_data_import }, wasm); |
| 2217 | } |
| 2218 | |
| 2219 | pub fn sourceLocation(id: DataImportId, wasm: *const Wasm) SourceLocation { |
| 2220 | switch (id.unpack(wasm)) { |
| 2221 | .object_data_import => |obj_data_index| { |
| 2222 | // TODO binary search |
| 2223 | for (wasm.objects.items, 0..) |o, i| { |
| 2224 | if (o.data_imports.off <= @intFromEnum(obj_data_index) and |
| 2225 | o.data_imports.off + o.data_imports.len > @intFromEnum(obj_data_index)) |
| 2226 | { |
| 2227 | return .pack(.{ .object_index = @enumFromInt(i) }, wasm); |
| 2228 | } |
| 2229 | } else unreachable; |
| 2230 | }, |
| 2231 | .zcu_import => return .zig_object_nofile, // TODO give a better source location |
| 2232 | } |
| 2233 | } |
| 2234 | }; |
| 2235 | |
| 2113 | 2236 | /// Index into `Wasm.symbol_table`. |
| 2114 | 2237 | pub const SymbolTableIndex = enum(u32) { |
| 2115 | 2238 | _, |
| ... | ... | @@ -2716,6 +2839,7 @@ pub fn deinit(wasm: *Wasm) void { |
| 2716 | 2839 | wasm.object_memory_imports.deinit(gpa); |
| 2717 | 2840 | wasm.object_memories.deinit(gpa); |
| 2718 | 2841 | wasm.object_relocations.deinit(gpa); |
| 2842 | wasm.object_data_imports.deinit(gpa); |
| 2719 | 2843 | wasm.object_data_segments.deinit(gpa); |
| 2720 | 2844 | wasm.object_datas.deinit(gpa); |
| 2721 | 2845 | wasm.object_custom_segments.deinit(gpa); |
| ... | ... | @@ -2734,6 +2858,8 @@ pub fn deinit(wasm: *Wasm) void { |
| 2734 | 2858 | wasm.global_imports.deinit(gpa); |
| 2735 | 2859 | wasm.table_imports.deinit(gpa); |
| 2736 | 2860 | wasm.tables.deinit(gpa); |
| 2861 | wasm.data_imports.deinit(gpa); |
| 2862 | wasm.data_segments.deinit(gpa); |
| 2737 | 2863 | wasm.symbol_table.deinit(gpa); |
| 2738 | 2864 | wasm.out_relocs.deinit(gpa); |
| 2739 | 2865 | wasm.uav_fixups.deinit(gpa); |
| ... | ... | @@ -2805,15 +2931,16 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 2805 | 2931 | const name = try wasm.internString(ext.name.toSlice(ip)); |
| 2806 | 2932 | if (ext.lib_name.toSlice(ip)) |ext_name| _ = try wasm.internString(ext_name); |
| 2807 | 2933 | try wasm.imports.ensureUnusedCapacity(gpa, 1); |
| 2934 | try wasm.function_imports.ensureUnusedCapacity(gpa, 1); |
| 2935 | try wasm.data_imports.ensureUnusedCapacity(gpa, 1); |
| 2936 | const zcu_import = wasm.addZcuImportReserved(ext.owner_nav); |
| 2808 | 2937 | if (ip.isFunctionType(nav.typeOf(ip))) { |
| 2809 | | try wasm.function_imports.ensureUnusedCapacity(gpa, 1); |
| 2810 | | const zcu_import = wasm.addZcuImportReserved(ext.owner_nav); |
| 2811 | 2938 | wasm.function_imports.putAssumeCapacity(name, .fromZcuImport(zcu_import, wasm)); |
| 2812 | 2939 | // Ensure there is a corresponding function type table entry. |
| 2813 | 2940 | const fn_info = zcu.typeToFunc(.fromInterned(ext.ty)).?; |
| 2814 | 2941 | _ = try internFunctionType(wasm, fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), target); |
| 2815 | 2942 | } else { |
| 2816 | | @panic("TODO extern data"); |
| 2943 | wasm.data_imports.putAssumeCapacity(name, .fromZcuImport(zcu_import, wasm)); |
| 2817 | 2944 | } |
| 2818 | 2945 | return; |
| 2819 | 2946 | }, |
| ... | ... | @@ -3023,6 +3150,12 @@ pub fn prelink(wasm: *Wasm, prog_node: std.Progress.Node) link.File.FlushError!v |
| 3023 | 3150 | try markTableImport(wasm, name, import, @enumFromInt(i)); |
| 3024 | 3151 | } |
| 3025 | 3152 | } |
| 3153 | |
| 3154 | for (wasm.object_data_imports.keys(), wasm.object_data_imports.values(), 0..) |name, *import, i| { |
| 3155 | if (import.flags.isIncluded(rdynamic)) { |
| 3156 | try markDataImport(wasm, name, import, @enumFromInt(i)); |
| 3157 | } |
| 3158 | } |
| 3026 | 3159 | } |
| 3027 | 3160 | |
| 3028 | 3161 | fn markFunctionImport( |
| ... | ... | @@ -3163,13 +3296,45 @@ fn markTableImport( |
| 3163 | 3296 | } |
| 3164 | 3297 | |
| 3165 | 3298 | fn markDataSegment(wasm: *Wasm, segment_index: ObjectDataSegment.Index) link.File.FlushError!void { |
| 3299 | const comp = wasm.base.comp; |
| 3166 | 3300 | const segment = segment_index.ptr(wasm); |
| 3167 | 3301 | if (segment.flags.alive) return; |
| 3168 | 3302 | segment.flags.alive = true; |
| 3169 | 3303 | |
| 3304 | wasm.any_passive_inits = wasm.any_passive_inits or segment.flags.is_passive or |
| 3305 | (comp.config.import_memory and !wasm.isBss(segment.name)); |
| 3306 | |
| 3307 | try wasm.data_segments.put(comp.gpa, .pack(wasm, .{ .object = segment_index }), {}); |
| 3170 | 3308 | try wasm.markRelocations(segment.relocations(wasm)); |
| 3171 | 3309 | } |
| 3172 | 3310 | |
| 3311 | fn markDataImport( |
| 3312 | wasm: *Wasm, |
| 3313 | name: String, |
| 3314 | import: *ObjectDataImport, |
| 3315 | data_index: ObjectDataImport.Index, |
| 3316 | ) link.File.FlushError!void { |
| 3317 | if (import.flags.alive) return; |
| 3318 | import.flags.alive = true; |
| 3319 | |
| 3320 | const comp = wasm.base.comp; |
| 3321 | const gpa = comp.gpa; |
| 3322 | |
| 3323 | if (import.resolution == .unresolved) { |
| 3324 | if (name == wasm.preloaded_strings.__heap_base) { |
| 3325 | import.resolution = .__heap_base; |
| 3326 | wasm.data_segments.putAssumeCapacity(.__heap_base, {}); |
| 3327 | } else if (name == wasm.preloaded_strings.__heap_end) { |
| 3328 | import.resolution = .__heap_end; |
| 3329 | wasm.data_segments.putAssumeCapacity(.__heap_end, {}); |
| 3330 | } else { |
| 3331 | try wasm.data_imports.put(gpa, name, .fromObject(data_index, wasm)); |
| 3332 | } |
| 3333 | } else { |
| 3334 | try markDataSegment(wasm, import.resolution.toDataId().?.unpack(wasm).object); |
| 3335 | } |
| 3336 | } |
| 3337 | |
| 3173 | 3338 | fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.File.FlushError!void { |
| 3174 | 3339 | for (relocs.slice.tags(wasm), relocs.slice.pointees(wasm), relocs.slice.offsets(wasm)) |tag, pointee, offset| { |
| 3175 | 3340 | if (offset >= relocs.end) break; |
| ... | ... | @@ -3199,6 +3364,22 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Fil |
| 3199 | 3364 | const i: TableImport.Index = @enumFromInt(wasm.object_table_imports.getIndex(name).?); |
| 3200 | 3365 | try markTableImport(wasm, name, i.value(wasm), i); |
| 3201 | 3366 | }, |
| 3367 | .memory_addr_import_leb, |
| 3368 | .memory_addr_import_sleb, |
| 3369 | .memory_addr_import_i32, |
| 3370 | .memory_addr_import_rel_sleb, |
| 3371 | .memory_addr_import_leb64, |
| 3372 | .memory_addr_import_sleb64, |
| 3373 | .memory_addr_import_i64, |
| 3374 | .memory_addr_import_rel_sleb64, |
| 3375 | .memory_addr_import_tls_sleb, |
| 3376 | .memory_addr_import_locrel_i32, |
| 3377 | .memory_addr_import_tls_sleb64, |
| 3378 | => { |
| 3379 | const name = pointee.symbol_name; |
| 3380 | const i = ObjectDataImport.Index.fromSymbolName(wasm, name).?; |
| 3381 | try markDataImport(wasm, name, i.value(wasm), i); |
| 3382 | }, |
| 3202 | 3383 | |
| 3203 | 3384 | .function_index_leb, |
| 3204 | 3385 | .function_index_i32, |
| ... | ... | @@ -3220,26 +3401,6 @@ fn markRelocations(wasm: *Wasm, relocs: ObjectRelocation.IterableSlice) link.Fil |
| 3220 | 3401 | .section_offset_i32 => { |
| 3221 | 3402 | log.warn("TODO: ensure section {d} is included in output", .{pointee.section}); |
| 3222 | 3403 | }, |
| 3223 | | .memory_addr_import_leb, |
| 3224 | | .memory_addr_import_sleb, |
| 3225 | | .memory_addr_import_i32, |
| 3226 | | .memory_addr_import_rel_sleb, |
| 3227 | | .memory_addr_import_leb64, |
| 3228 | | .memory_addr_import_sleb64, |
| 3229 | | .memory_addr_import_i64, |
| 3230 | | .memory_addr_import_rel_sleb64, |
| 3231 | | .memory_addr_import_tls_sleb, |
| 3232 | | .memory_addr_import_locrel_i32, |
| 3233 | | .memory_addr_import_tls_sleb64, |
| 3234 | | => { |
| 3235 | | const name = pointee.symbol_name; |
| 3236 | | if (name == wasm.preloaded_strings.__heap_end or |
| 3237 | | name == wasm.preloaded_strings.__heap_base) |
| 3238 | | { |
| 3239 | | continue; |
| 3240 | | } |
| 3241 | | log.warn("TODO: ensure data symbol {s} is included in output", .{name.slice(wasm)}); |
| 3242 | | }, |
| 3243 | 3404 | |
| 3244 | 3405 | .memory_addr_leb, |
| 3245 | 3406 | .memory_addr_sleb, |
| ... | ... | @@ -3309,6 +3470,7 @@ pub fn flushModule( |
| 3309 | 3470 | try wasm.flush_buffer.missing_exports.reinit(gpa, wasm.missing_exports.keys(), &.{}); |
| 3310 | 3471 | try wasm.flush_buffer.function_imports.reinit(gpa, wasm.function_imports.keys(), wasm.function_imports.values()); |
| 3311 | 3472 | try wasm.flush_buffer.global_imports.reinit(gpa, wasm.global_imports.keys(), wasm.global_imports.values()); |
| 3473 | try wasm.flush_buffer.data_imports.reinit(gpa, wasm.data_imports.keys(), wasm.data_imports.values()); |
| 3312 | 3474 | |
| 3313 | 3475 | return wasm.flush_buffer.finish(wasm) catch |err| switch (err) { |
| 3314 | 3476 | error.OutOfMemory => return error.OutOfMemory, |
| ... | ... | @@ -4117,6 +4279,15 @@ fn pointerAlignment(wasm: *const Wasm) Alignment { |
| 4117 | 4279 | }; |
| 4118 | 4280 | } |
| 4119 | 4281 | |
| 4282 | fn pointerSize(wasm: *const Wasm) u32 { |
| 4283 | const target = &wasm.base.comp.root_mod.resolved_target.result; |
| 4284 | return switch (target.cpu.arch) { |
| 4285 | .wasm32 => 4, |
| 4286 | .wasm64 => 8, |
| 4287 | else => unreachable, |
| 4288 | }; |
| 4289 | } |
| 4290 | |
| 4120 | 4291 | fn addZcuImportReserved(wasm: *Wasm, nav_index: InternPool.Nav.Index) ZcuImportIndex { |
| 4121 | 4292 | const gop = wasm.imports.getOrPutAssumeCapacity(nav_index); |
| 4122 | 4293 | gop.value_ptr.* = {}; |