authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-05 17:17:07+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2024-02-29 15:23:05+01:00
log5aec88fa4102e87295bf60971209d114c6ae6733
treeaa4a533cf831d6bb93f7b647b5d253059e20a29e
parent5a0f2af7e4aa01f861d86bfe9fb457ffde3d335e
signaturelock-open Commit is signed but in an unrecognized format.

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.

3 files changed, 24 insertions(+), 4 deletions(-)

src/arch/wasm/Emit.zig+13-1
......@@ -385,7 +385,19 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
385385 try emit.code.append(std.wasm.opcode(.call_indirect));
386386 // NOTE: If we remove unused function types in the future for incremental
387387 // linking, we must also emit a relocation for this `type_index`
388 try leb128.writeULEB128(emit.code.writer(), type_index);
388 const call_offset = emit.offset();
389 var buf: [5]u8 = undefined;
390 leb128.writeUnsignedFixed(5, &buf, type_index);
391 try emit.code.appendSlice(&buf);
392 if (type_index != 0) {
393 const atom_index = emit.bin_file.zigObjectPtr().?.decls_map.get(emit.decl_index).?.atom;
394 const atom = emit.bin_file.getAtomPtr(atom_index);
395 try atom.relocs.append(emit.bin_file.base.comp.gpa, .{
396 .offset = call_offset,
397 .index = type_index,
398 .relocation_type = .R_WASM_TYPE_INDEX_LEB,
399 });
400 }
389401 try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index
390402}
391403
src/link/Wasm.zig+3-1
......@@ -3057,7 +3057,9 @@ fn writeToFile(
30573057 try leb.writeULEB128(binary_writer, @as(u32, @intCast(wasm.function_table.count())));
30583058 var symbol_it = wasm.function_table.keyIterator();
30593059 while (symbol_it.next()) |symbol_loc_ptr| {
3060 const sym = symbol_loc_ptr.*.getSymbol(wasm);
3060 const sym = symbol_loc_ptr.getSymbol(wasm);
3061 std.debug.assert(sym.isAlive());
3062 std.debug.assert(sym.index < wasm.functions.count() + wasm.imported_functions_count);
30613063 try leb.writeULEB128(binary_writer, sym.index);
30623064 }
30633065
src/link/Wasm/ZigObject.zig+8-2
......@@ -1137,14 +1137,20 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)
11371137 .R_WASM_TABLE_INDEX_SLEB,
11381138 .R_WASM_TABLE_INDEX_SLEB64,
11391139 => {
1140 try wasm_file.function_table.put(gpa, loc, 0);
1140 try wasm_file.function_table.put(gpa, .{
1141 .file = zig_object.index,
1142 .index = reloc.index,
1143 }, 0);
11411144 },
11421145 .R_WASM_GLOBAL_INDEX_I32,
11431146 .R_WASM_GLOBAL_INDEX_LEB,
11441147 => {
11451148 const sym = zig_object.symbol(reloc.index);
11461149 if (sym.tag != .global) {
1147 try wasm_file.got_symbols.append(gpa, loc);
1150 try wasm_file.got_symbols.append(gpa, .{
1151 .file = zig_object.index,
1152 .index = reloc.index,
1153 });
11481154 }
11491155 },
11501156 else => {},