diff options
| author | Luuk de Gram <luuk@degram.dev> | 2022-05-26 15:05:31 +0200 |
|---|---|---|
| committer | Luuk de Gram <luuk@degram.dev> | 2022-06-24 08:12:17 +0200 |
| commit | 1a3f58f5e56ad166eb5441c6960a8fac36b4ff5f (patch) | |
| tree | 978658fea3c20d8ec8c61cf1ac1692a960e892cf | |
| parent | cb28fc2e63dea2902fda21b7738aa93eaf4a2ea0 (diff) | |
| download | zig-1a3f58f5e56ad166eb5441c6960a8fac36b4ff5f.tar.gz zig-1a3f58f5e56ad166eb5441c6960a8fac36b4ff5f.zip | |
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.
| -rw-r--r-- | src/link/Wasm/Atom.zig | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index 40b7f64804..edef52004d 100644 --- a/src/link/Wasm/Atom.zig +++ b/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, |
