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 {...@@ -385,7 +385,19 @@ fn emitCallIndirect(emit: *Emit, inst: Mir.Inst.Index) !void {
385 try emit.code.append(std.wasm.opcode(.call_indirect));385 try emit.code.append(std.wasm.opcode(.call_indirect));
386 // NOTE: If we remove unused function types in the future for incremental386 // NOTE: If we remove unused function types in the future for incremental
387 // linking, we must also emit a relocation for this `type_index`387 // 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 }
389 try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index401 try leb128.writeULEB128(emit.code.writer(), @as(u32, 0)); // TODO: Emit relocation for table index
390}402}
391403
src/link/Wasm.zig+3-1
...@@ -3057,7 +3057,9 @@ fn writeToFile(...@@ -3057,7 +3057,9 @@ fn writeToFile(
3057 try leb.writeULEB128(binary_writer, @as(u32, @intCast(wasm.function_table.count())));3057 try leb.writeULEB128(binary_writer, @as(u32, @intCast(wasm.function_table.count())));
3058 var symbol_it = wasm.function_table.keyIterator();3058 var symbol_it = wasm.function_table.keyIterator();
3059 while (symbol_it.next()) |symbol_loc_ptr| {3059 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);
3061 try leb.writeULEB128(binary_writer, sym.index);3063 try leb.writeULEB128(binary_writer, sym.index);
3062 }3064 }
30633065
src/link/Wasm/ZigObject.zig+8-2
...@@ -1137,14 +1137,20 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)...@@ -1137,14 +1137,20 @@ pub fn parseSymbolIntoAtom(zig_object: *ZigObject, wasm_file: *Wasm, index: u32)
1137 .R_WASM_TABLE_INDEX_SLEB,1137 .R_WASM_TABLE_INDEX_SLEB,
1138 .R_WASM_TABLE_INDEX_SLEB64,1138 .R_WASM_TABLE_INDEX_SLEB64,
1139 => {1139 => {
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);
1141 },1144 },
1142 .R_WASM_GLOBAL_INDEX_I32,1145 .R_WASM_GLOBAL_INDEX_I32,
1143 .R_WASM_GLOBAL_INDEX_LEB,1146 .R_WASM_GLOBAL_INDEX_LEB,
1144 => {1147 => {
1145 const sym = zig_object.symbol(reloc.index);1148 const sym = zig_object.symbol(reloc.index);
1146 if (sym.tag != .global) {1149 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 });
1148 }1154 }
1149 },1155 },
1150 else => {},1156 else => {},