Skip to content

Commit 7f50848

Browse files
Luukdegramjoachimschmidt557
authored andcommitted
wasm-linker: convert relocation addend to i32
Addends in relocations are signed integers as theoretically it could be a negative number. As Atom's offsets are relative to their parent section, the relocation value should still result in a postive number. For this reason, the final result is stored as an unsigned integer. Also, rather than using `null` for relocations that do not support addends. We set the value to 0 for those that do not support addends, and have to call `addendIsPresent` to determine if an addend exists or not. This means each Relocation costs 4 bytes less than before, saving memory while linking.
1 parent fa9327a commit 7f50848

File tree

5 files changed

+14
-11
lines changed

5 files changed

+14
-11
lines changed

src/arch/wasm/Emit.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
413413
.offset = mem_offset,
414414
.index = mem.pointer,
415415
.relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_LEB else .R_WASM_MEMORY_ADDR_LEB64,
416-
.addend = mem.offset,
416+
.addend = @intCast(i32, mem.offset),
417417
});
418418
}
419419
}

src/link/Wasm.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ pub fn getDeclVAddr(
10801080
.index = target_symbol_index,
10811081
.offset = @intCast(u32, reloc_info.offset),
10821082
.relocation_type = if (is_wasm32) .R_WASM_MEMORY_ADDR_I32 else .R_WASM_MEMORY_ADDR_I64,
1083-
.addend = reloc_info.addend,
1083+
.addend = @intCast(i32, reloc_info.addend),
10841084
});
10851085
}
10861086
// we do not know the final address at this point,
@@ -2001,7 +2001,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void {
20012001
.index = names_symbol_index,
20022002
.relocation_type = .R_WASM_MEMORY_ADDR_I32,
20032003
.offset = offset,
2004-
.addend = addend,
2004+
.addend = @intCast(i32, addend),
20052005
});
20062006
atom.size += @intCast(u32, slice_ty.abiSize(wasm.base.options.target));
20072007
addend += len;
@@ -3433,7 +3433,7 @@ fn emitCodeRelocations(
34333433
try leb.writeULEB128(writer, offset);
34343434
try leb.writeULEB128(writer, symbol_index);
34353435
if (relocation.relocation_type.addendIsPresent()) {
3436-
try leb.writeULEB128(writer, relocation.addend orelse 0);
3436+
try leb.writeILEB128(writer, relocation.addend);
34373437
}
34383438
log.debug("Emit relocation: {}", .{relocation});
34393439
}
@@ -3483,7 +3483,7 @@ fn emitDataRelocations(
34833483
try leb.writeULEB128(writer, offset);
34843484
try leb.writeULEB128(writer, symbol_index);
34853485
if (relocation.relocation_type.addendIsPresent()) {
3486-
try leb.writeULEB128(writer, relocation.addend orelse 0);
3486+
try leb.writeILEB128(writer, relocation.addend);
34873487
}
34883488
log.debug("Emit relocation: {}", .{relocation});
34893489
}

src/link/Wasm/Atom.zig

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,14 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
194194
const segment_name = segment_info[symbol.index].outputName(merge_segment);
195195
const segment_index = wasm_bin.data_segments.get(segment_name).?;
196196
const segment = wasm_bin.segments.items[segment_index];
197-
return target_atom.offset + segment.offset + (relocation.addend orelse 0);
197+
const rel_value = @intCast(i32, target_atom.offset + segment.offset) + relocation.addend;
198+
return @intCast(u32, rel_value);
198199
},
199200
.R_WASM_EVENT_INDEX_LEB => return symbol.index,
200201
.R_WASM_SECTION_OFFSET_I32 => {
201202
const target_atom = wasm_bin.symbol_atom.get(target_loc).?;
202-
return target_atom.offset + (relocation.addend orelse 0);
203+
const rel_value = @intCast(i32, target_atom.offset) + relocation.addend;
204+
return @intCast(u32, rel_value);
203205
},
204206
.R_WASM_FUNCTION_OFFSET_I32 => {
205207
const target_atom = wasm_bin.symbol_atom.get(target_loc).?;
@@ -214,7 +216,8 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
214216
if (current_atom == target_atom) break;
215217
current_atom = current_atom.next.?;
216218
}
217-
return target_atom.offset + offset + (relocation.addend orelse 0);
219+
const rel_value = @intCast(i32, target_atom.offset + offset) + relocation.addend;
220+
return @intCast(u32, rel_value);
218221
},
219222
}
220223
}

src/link/Wasm/Object.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ fn Parser(comptime ReaderType: type) type {
606606
.relocation_type = rel_type_enum,
607607
.offset = try leb.readULEB128(u32, reader),
608608
.index = try leb.readULEB128(u32, reader),
609-
.addend = if (rel_type_enum.addendIsPresent()) try leb.readULEB128(u32, reader) else null,
609+
.addend = if (rel_type_enum.addendIsPresent()) try leb.readILEB128(i32, reader) else 0,
610610
};
611611
log.debug("Found relocation: type({s}) offset({d}) index({d}) addend({?d})", .{
612612
@tagName(relocation.relocation_type),

src/link/Wasm/types.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub const Relocation = struct {
1212
/// When the type is `R_WASM_TYPE_INDEX_LEB`, it represents the index of the type.
1313
index: u32,
1414
/// Addend to add to the address.
15-
/// This field is only non-null for `R_WASM_MEMORY_ADDR_*`, `R_WASM_FUNCTION_OFFSET_I32` and `R_WASM_SECTION_OFFSET_I32`.
16-
addend: ?u32 = null,
15+
/// This field is only non-zero for `R_WASM_MEMORY_ADDR_*`, `R_WASM_FUNCTION_OFFSET_I32` and `R_WASM_SECTION_OFFSET_I32`.
16+
addend: i32 = 0,
1717

1818
/// All possible relocation types currently existing.
1919
/// This enum is exhaustive as the spec is WIP and new types

0 commit comments

Comments
 (0)