From 5aec88fa4102e87295bf60971209d114c6ae6733 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Mon, 5 Feb 2024 17:17:07 +0100 Subject: [PATCH] wasm: correctly generate relocations for type index Previously we could directly write the type index because we used the index that was known in the final binary. However, as we now process the Zig module as its own relocatable object file, we must ensure to generate a relocation for type indexes. This also ensures that we can later link the relocatable object file as a standalone also. This also fixes generating indirect function table entries for ZigObject as it now correctly points to the relocation symbol index rather than the symbol index that owns the relocation. --- src/arch/wasm/Emit.zig | 14 +++++++++++++- src/link/Wasm.zig | 4 +++- src/link/Wasm/ZigObject.zig | 10 ++++++++-- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/arch/wasm/Emit.zig b/src/arch/wasm/Emit.zig index 31c15ce0ef838d0e06e632d4aa0d040324233204..ded960daf198da07ee82bb9e971eed116ef7aa9e 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 26dd8b47b683f0d5c89cf69d2d0bec6bd99730e3..5f4277dfddc32e661ab3bc1e44509d0f23c5491e 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 ae5252cdd4ad9ace0cd3f5cd750094021479803b..e73bd466cc68f34edc60664d2f8131fa87932d84 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 => {}, -- 2.54.0