diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 31c15ce0ef..ded960daf1 100644 --- a/src/arch/wasm/Emit.zig +++ b/src/arch/wasm/Emit.zig @@ -385,7 +385,19 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void { try emit.code.append(std.wasm.opcode(.call_indirect)); // NOTE: If we remove unused function types in the future for incremental // linking, we must also emit a relocation for this `type_index` - try leb128.writeULEB128(emit.code.writer(), type_index); + const call_offset = emit.offset(); + var buf: [5]u8 = undefined; + leb128.writeUnsignedFixed(5, &buf, type_index); + try emit.code.appendSlice(&buf); + if (type_index != 0) { + const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom; + const atom = emit.bin_file.getAtomPtr(atom_index); + try atom.relocs.append(emit.bin_file.base.comp.gpa, .{ + .offset = call_offset, + .index = type_index, + .relocation_type = .R_WASM_TYPE_INDEX_LEB, + }); + } try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 26dd8b47b6..5f4277dfdd 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -3057,7 +3057,9 @@ fn writeToFile( try leb.writeULEB128(binary_writer, @as(u32, @intCast(wasm.function_table.count()))); var symbol_it = wasm.function_table.keyIterator(); while (symbol_it.next()) |symbol_loc_ptr| { - const sym = symbol_loc_ptr.*.getSymbol(wasm); + const sym = symbol_loc_ptr.getSymbol(wasm); + std.debug.assert(sym.isAlive()); + std.debug.assert(sym.index < wasm.functions.count() + wasm.imported_functions_count); try leb.writeULEB128(binary_writer, sym.index); } diff --git a/src/link/Wasm/ZigObject.zig b/src/link/Wasm/ZigObject.zig index ae5252cdd4..e73bd466cc 100644 --- a/src/link/Wasm/ZigObject.zig +++ b/src/link/Wasm/ZigObject.zig @@ -1137,14 +1137,20 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32) .R_WASM_TABLE_INDEX_SLEB, .R_WASM_TABLE_INDEX_SLEB64, => { - try wasm_file.function_table.put(gpa, loc, 0); + try wasm_file.function_table.put(gpa, .{ + .file = zig_object.index, + .index = reloc.index, + }, 0); }, .R_WASM_GLOBAL_INDEX_I32, .R_WASM_GLOBAL_INDEX_LEB, => { const sym = zig_object.symbol(reloc.index); if (sym.tag != .global) { - try wasm_file.got_symbols.append(gpa, loc); + try wasm_file.got_symbols.append(gpa, .{ + .file = zig_object.index, + .index = reloc.index, + }); } }, else => {},