| ... | ... | @@ -468,6 +468,7 @@ fn createSyntheticSymbol(wasm: *Wasm, name: []const u8, tag: Symbol.Tag) !Symbol |
| 468 | 468 | .flags = 0, |
| 469 | 469 | .tag = tag, |
| 470 | 470 | .index = undefined, |
| 471 | .virtual_address = undefined, |
| 471 | 472 | }); |
| 472 | 473 | try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, loc, {}); |
| 473 | 474 | try wasm.globals.put(wasm.base.allocator, name_offset, loc); |
| ... | ... | @@ -1011,6 +1012,7 @@ pub fn allocateSymbol(wasm: *Wasm) !u32 { |
| 1011 | 1012 | .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL), |
| 1012 | 1013 | .tag = undefined, // will be set after updateDecl |
| 1013 | 1014 | .index = undefined, // will be set after updateDecl |
| 1015 | .virtual_address = undefined, // will be set during atom allocation |
| 1014 | 1016 | }; |
| 1015 | 1017 | if (wasm.symbols_free_list.popOrNull()) |index| { |
| 1016 | 1018 | wasm.symbols.items[index] = symbol; |
| ... | ... | @@ -1246,6 +1248,7 @@ pub fn lowerUnnamedConst(wasm: *Wasm, tv: TypedValue, decl_index: Module.Decl.In |
| 1246 | 1248 | .flags = @enumToInt(Symbol.Flag.WASM_SYM_BINDING_LOCAL), |
| 1247 | 1249 | .tag = .data, |
| 1248 | 1250 | .index = undefined, |
| 1251 | .virtual_address = undefined, |
| 1249 | 1252 | }; |
| 1250 | 1253 | try wasm.resolved_symbols.putNoClobber(wasm.base.allocator, atom.symbolLoc(), {}); |
| 1251 | 1254 | |
| ... | ... | @@ -1292,6 +1295,7 @@ pub fn getGlobalSymbol(wasm: *Wasm, name: []const u8) !u32 { |
| 1292 | 1295 | .flags = 0, |
| 1293 | 1296 | .index = undefined, // index to type will be set after merging function symbols |
| 1294 | 1297 | .tag = .function, |
| 1298 | .virtual_address = undefined, |
| 1295 | 1299 | }; |
| 1296 | 1300 | symbol.setGlobal(true); |
| 1297 | 1301 | symbol.setUndefined(true); |
| ... | ... | @@ -1788,6 +1792,30 @@ fn allocateAtoms(wasm: *Wasm) !void { |
| 1788 | 1792 | } |
| 1789 | 1793 | } |
| 1790 | 1794 | |
| 1795 | /// For each data symbol, sets the virtual address. |
| 1796 | fn allocateVirtualAddresses(wasm: *Wasm) void { |
| 1797 | for (wasm.resolved_symbols.keys()) |loc| { |
| 1798 | const symbol = loc.getSymbol(wasm); |
| 1799 | if (symbol.tag != .data) { |
| 1800 | continue; // only data symbols have virtual addresses |
| 1801 | } |
| 1802 | const atom_index = wasm.symbol_atom.get(loc) orelse { |
| 1803 | // synthetic symbol that does not contain an atom |
| 1804 | continue; |
| 1805 | }; |
| 1806 | |
| 1807 | const atom = wasm.getAtom(atom_index); |
| 1808 | const merge_segment = wasm.base.options.output_mode != .Obj; |
| 1809 | const segment_info = if (atom.file) |object_index| blk: { |
| 1810 | break :blk wasm.objects.items[object_index].segment_info; |
| 1811 | } else wasm.segment_info.values(); |
| 1812 | const segment_name = segment_info[symbol.index].outputName(merge_segment); |
| 1813 | const segment_index = wasm.data_segments.get(segment_name).?; |
| 1814 | const segment = wasm.segments.items[segment_index]; |
| 1815 | symbol.virtual_address = atom.offset + segment.offset; |
| 1816 | } |
| 1817 | } |
| 1818 | |
| 1791 | 1819 | fn sortDataSegments(wasm: *Wasm) !void { |
| 1792 | 1820 | var new_mapping: std.StringArrayHashMapUnmanaged(u32) = .{}; |
| 1793 | 1821 | try new_mapping.ensureUnusedCapacity(wasm.base.allocator, wasm.data_segments.count()); |
| ... | ... | @@ -2137,13 +2165,10 @@ fn setupExports(wasm: *Wasm) !void { |
| 2137 | 2165 | break :blk try wasm.string_table.put(wasm.base.allocator, sym_name); |
| 2138 | 2166 | }; |
| 2139 | 2167 | const exp: types.Export = if (symbol.tag == .data) exp: { |
| 2140 | | const atom_index = wasm.symbol_atom.get(sym_loc).?; |
| 2141 | | const atom = wasm.getAtom(atom_index); |
| 2142 | | const va = atom.getVA(wasm, symbol); |
| 2143 | 2168 | const global_index = @intCast(u32, wasm.imported_globals_count + wasm.wasm_globals.items.len); |
| 2144 | 2169 | try wasm.wasm_globals.append(wasm.base.allocator, .{ |
| 2145 | 2170 | .global_type = .{ .valtype = .i32, .mutable = false }, |
| 2146 | | .init = .{ .i32_const = @intCast(i32, va) }, |
| 2171 | .init = .{ .i32_const = @intCast(i32, symbol.virtual_address) }, |
| 2147 | 2172 | }); |
| 2148 | 2173 | break :exp .{ |
| 2149 | 2174 | .name = export_name, |
| ... | ... | @@ -2240,12 +2265,8 @@ fn setupMemory(wasm: *Wasm) !void { |
| 2240 | 2265 | // One of the linked object files has a reference to the __heap_base symbol. |
| 2241 | 2266 | // We must set its virtual address so it can be used in relocations. |
| 2242 | 2267 | if (wasm.findGlobalSymbol("__heap_base")) |loc| { |
| 2243 | | const segment_index = wasm.data_segments.get(".synthetic").?; |
| 2244 | | const segment = &wasm.segments.items[segment_index]; |
| 2245 | | segment.offset = 0; // for simplicity we store the entire VA into atom's offset. |
| 2246 | | const atom_index = wasm.symbol_atom.get(loc).?; |
| 2247 | | const atom = wasm.getAtomPtr(atom_index); |
| 2248 | | atom.offset = @intCast(u32, mem.alignForwardGeneric(u64, memory_ptr, heap_alignment)); |
| 2268 | const symbol = loc.getSymbol(wasm); |
| 2269 | symbol.virtual_address = @intCast(u32, mem.alignForwardGeneric(u64, memory_ptr, heap_alignment)); |
| 2249 | 2270 | } |
| 2250 | 2271 | |
| 2251 | 2272 | // Setup the max amount of pages |
| ... | ... | @@ -2274,12 +2295,8 @@ fn setupMemory(wasm: *Wasm) !void { |
| 2274 | 2295 | log.debug("Total memory pages: {d}", .{wasm.memories.limits.min}); |
| 2275 | 2296 | |
| 2276 | 2297 | if (wasm.findGlobalSymbol("__heap_end")) |loc| { |
| 2277 | | const segment_index = wasm.data_segments.get(".synthetic").?; |
| 2278 | | const segment = &wasm.segments.items[segment_index]; |
| 2279 | | segment.offset = 0; |
| 2280 | | const atom_index = wasm.symbol_atom.get(loc).?; |
| 2281 | | const atom = wasm.getAtomPtr(atom_index); |
| 2282 | | atom.offset = @intCast(u32, memory_ptr); |
| 2298 | const symbol = loc.getSymbol(wasm); |
| 2299 | symbol.virtual_address = @intCast(u32, memory_ptr); |
| 2283 | 2300 | } |
| 2284 | 2301 | |
| 2285 | 2302 | if (wasm.base.options.max_memory) |max_memory| { |
| ... | ... | @@ -2417,6 +2434,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { |
| 2417 | 2434 | .tag = .data, |
| 2418 | 2435 | .flags = 0, |
| 2419 | 2436 | .index = 0, |
| 2437 | .virtual_address = undefined, |
| 2420 | 2438 | }; |
| 2421 | 2439 | symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 2422 | 2440 | |
| ... | ... | @@ -2449,6 +2467,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 2449 | 2467 | .tag = .data, |
| 2450 | 2468 | .flags = 0, |
| 2451 | 2469 | .index = 0, |
| 2470 | .virtual_address = undefined, |
| 2452 | 2471 | }; |
| 2453 | 2472 | names_symbol.setFlag(.WASM_SYM_VISIBILITY_HIDDEN); |
| 2454 | 2473 | |
| ... | ... | @@ -2748,6 +2767,7 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l |
| 2748 | 2767 | |
| 2749 | 2768 | try wasm.allocateAtoms(); |
| 2750 | 2769 | try wasm.setupMemory(); |
| 2770 | wasm.allocateVirtualAddresses(); |
| 2751 | 2771 | wasm.mapFunctionTable(); |
| 2752 | 2772 | try wasm.mergeSections(); |
| 2753 | 2773 | try wasm.mergeTypes(); |
| ... | ... | @@ -2866,6 +2886,7 @@ pub fn flushModule(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Nod |
| 2866 | 2886 | |
| 2867 | 2887 | try wasm.allocateAtoms(); |
| 2868 | 2888 | try wasm.setupMemory(); |
| 2889 | wasm.allocateVirtualAddresses(); |
| 2869 | 2890 | wasm.mapFunctionTable(); |
| 2870 | 2891 | try wasm.mergeSections(); |
| 2871 | 2892 | try wasm.mergeTypes(); |