Commit 1a3f58f5e5

Luuk de Gram <luuk@degram.dev>
2022-05-26 15:05:31
wasm-linker: Correctly resolve function type
When performing relocations for a type index, we first check if the target symbol is undefined. In which case, we will obtain the type from the `import` rather than look into the `functions` table.
1 parent cb28fc2
Changed files (1)
src
link
src/link/Wasm/Atom.zig
@@ -97,7 +97,7 @@ pub fn symbolLoc(self: Atom) Wasm.SymbolLoc {
 
 /// Resolves the relocations within the atom, writing the new value
 /// at the calculated offset.
-pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {
+pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) void {
     if (self.relocs.items.len == 0) return;
     const symbol_name = self.symbolLoc().getName(wasm_bin);
     log.debug("Resolving relocs in atom '{s}' count({d})", .{
@@ -106,7 +106,7 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {
     });
 
     for (self.relocs.items) |reloc| {
-        const value = try self.relocationValue(reloc, wasm_bin);
+        const value = self.relocationValue(reloc, wasm_bin);
         log.debug("Relocating '{s}' referenced in '{s}' offset=0x{x:0>8} value={d}", .{
             (Wasm.SymbolLoc{ .file = self.file, .index = reloc.index }).getName(wasm_bin),
             symbol_name,
@@ -144,9 +144,10 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {
 /// From a given `relocation` will return the new value to be written.
 /// All values will be represented as a `u64` as all values can fit within it.
 /// The final value must be casted to the correct size.
-fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) !u64 {
+fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
     const target_loc: Wasm.SymbolLoc = .{ .file = self.file, .index = relocation.index };
     const symbol = target_loc.getSymbol(wasm_bin).*;
+
     switch (relocation.relocation_type) {
         .R_WASM_FUNCTION_INDEX_LEB => return symbol.index,
         .R_WASM_TABLE_NUMBER_LEB => return symbol.index,
@@ -155,7 +156,13 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
         .R_WASM_TABLE_INDEX_SLEB,
         .R_WASM_TABLE_INDEX_SLEB64,
         => return wasm_bin.function_table.get(target_loc) orelse 0,
-        .R_WASM_TYPE_INDEX_LEB => return wasm_bin.functions.values()[symbol.index - wasm_bin.imported_functions_count].type_index,
+        .R_WASM_TYPE_INDEX_LEB => return blk: {
+            if (symbol.isUndefined()) {
+                const imp = wasm_bin.imports.get(target_loc).?;
+                break :blk imp.kind.function;
+            }
+            break :blk wasm_bin.functions.values()[symbol.index - wasm_bin.imported_functions_count].type_index;
+        },
         .R_WASM_GLOBAL_INDEX_I32,
         .R_WASM_GLOBAL_INDEX_LEB,
         => return symbol.index,