aboutsummaryrefslogtreecommitdiff
path: root/src/link
diff options
context:
space:
mode:
authorLuuk de Gram <luuk@degram.dev>2022-05-26 15:05:31 +0200
committerLuuk de Gram <luuk@degram.dev>2022-06-24 08:12:17 +0200
commit1a3f58f5e56ad166eb5441c6960a8fac36b4ff5f (patch)
tree978658fea3c20d8ec8c61cf1ac1692a960e892cf /src/link
parentcb28fc2e63dea2902fda21b7738aa93eaf4a2ea0 (diff)
downloadzig-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.
Diffstat (limited to 'src/link')
-rw-r--r--src/link/Wasm/Atom.zig15
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,