authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-05-26 15:05:31+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-06-24 08:12:17+02:00
log1a3f58f5e56ad166eb5441c6960a8fac36b4ff5f
tree978658fea3c20d8ec8c61cf1ac1692a960e892cf
parentcb28fc2e63dea2902fda21b7738aa93eaf4a2ea0

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 files changed, 11 insertions(+), 4 deletions(-)

src/link/Wasm/Atom.zig+11-4
...@@ -97,7 +97,7 @@ pub fn symbolLoc(self: Atom) Wasm.SymbolLoc {...@@ -97,7 +97,7 @@ pub fn symbolLoc(self: Atom) Wasm.SymbolLoc {
9797
98/// Resolves the relocations within the atom, writing the new value98/// Resolves the relocations within the atom, writing the new value
99/// at the calculated offset.99/// at the calculated offset.
100pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {100pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) void {
101 if (self.relocs.items.len == 0) return;101 if (self.relocs.items.len == 0) return;
102 const symbol_name = self.symbolLoc().getName(wasm_bin);102 const symbol_name = self.symbolLoc().getName(wasm_bin);
103 log.debug("Resolving relocs in atom '{s}' count({d})", .{103 log.debug("Resolving relocs in atom '{s}' count({d})", .{
...@@ -106,7 +106,7 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {...@@ -106,7 +106,7 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {
106 });106 });
107107
108 for (self.relocs.items) |reloc| {108 for (self.relocs.items) |reloc| {
109 const value = try self.relocationValue(reloc, wasm_bin);109 const value = self.relocationValue(reloc, wasm_bin);
110 log.debug("Relocating '{s}' referenced in '{s}' offset=0x{x:0>8} value={d}", .{110 log.debug("Relocating '{s}' referenced in '{s}' offset=0x{x:0>8} value={d}", .{
111 (Wasm.SymbolLoc{ .file = self.file, .index = reloc.index }).getName(wasm_bin),111 (Wasm.SymbolLoc{ .file = self.file, .index = reloc.index }).getName(wasm_bin),
112 symbol_name,112 symbol_name,
...@@ -144,9 +144,10 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {...@@ -144,9 +144,10 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) !void {
144/// From a given `relocation` will return the new value to be written.144/// From a given `relocation` will return the new value to be written.
145/// All values will be represented as a `u64` as all values can fit within it.145/// All values will be represented as a `u64` as all values can fit within it.
146/// The final value must be casted to the correct size.146/// The final value must be casted to the correct size.
147fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) !u64 {147fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
148 const target_loc: Wasm.SymbolLoc = .{ .file = self.file, .index = relocation.index };148 const target_loc: Wasm.SymbolLoc = .{ .file = self.file, .index = relocation.index };
149 const symbol = target_loc.getSymbol(wasm_bin).*;149 const symbol = target_loc.getSymbol(wasm_bin).*;
150
150 switch (relocation.relocation_type) {151 switch (relocation.relocation_type) {
151 .R_WASM_FUNCTION_INDEX_LEB => return symbol.index,152 .R_WASM_FUNCTION_INDEX_LEB => return symbol.index,
152 .R_WASM_TABLE_NUMBER_LEB => return symbol.index,153 .R_WASM_TABLE_NUMBER_LEB => return symbol.index,
...@@ -155,7 +156,13 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa...@@ -155,7 +156,13 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
155 .R_WASM_TABLE_INDEX_SLEB,156 .R_WASM_TABLE_INDEX_SLEB,
156 .R_WASM_TABLE_INDEX_SLEB64,157 .R_WASM_TABLE_INDEX_SLEB64,
157 => return wasm_bin.function_table.get(target_loc) orelse 0,158 => return wasm_bin.function_table.get(target_loc) orelse 0,
158 .R_WASM_TYPE_INDEX_LEB => return wasm_bin.functions.values()[symbol.index - wasm_bin.imported_functions_count].type_index,159 .R_WASM_TYPE_INDEX_LEB => return blk: {
160 if (symbol.isUndefined()) {
161 const imp = wasm_bin.imports.get(target_loc).?;
162 break :blk imp.kind.function;
163 }
164 break :blk wasm_bin.functions.values()[symbol.index - wasm_bin.imported_functions_count].type_index;
165 },
159 .R_WASM_GLOBAL_INDEX_I32,166 .R_WASM_GLOBAL_INDEX_I32,
160 .R_WASM_GLOBAL_INDEX_LEB,167 .R_WASM_GLOBAL_INDEX_LEB,
161 => return symbol.index,168 => return symbol.index,