| author | |
| committer | |
| log | 7f508480f49b78817bf67579a8810d4499cbbc13 |
| tree | d1f9dbed875ae37d2ebf5997cc0d2cde9e3bdfa0 |
| parent | fa9327ac051031be21b6ccb494f31585d0b68915 |
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.5 files changed, 14 insertions(+), 11 deletions(-)
src/arch/wasm/Emit.zig+1-1| ... | ... | @@ -413,7 +413,7 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void { |
| 413 | 413 | .offset = mem_offset, |
| 414 | 414 | .index = mem.pointer, |
| 415 | 415 | .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), | |
| 417 | 417 | }); |
| 418 | 418 | } |
| 419 | 419 | } |
src/link/Wasm.zig+4-4| ... | ... | @@ -1080,7 +1080,7 @@ pub fn getDeclVAddr( |
| 1080 | 1080 | .index = target_symbol_index, |
| 1081 | 1081 | .offset = @intCast(u32, reloc_info.offset), |
| 1082 | 1082 | .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), | |
| 1084 | 1084 | }); |
| 1085 | 1085 | } |
| 1086 | 1086 | // we do not know the final address at this point, |
| ... | ... | @@ -2001,7 +2001,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { |
| 2001 | 2001 | .index = names_symbol_index, |
| 2002 | 2002 | .relocation_type = .R_WASM_MEMORY_ADDR_I32, |
| 2003 | 2003 | .offset = offset, |
| 2004 | .addend = addend, | |
| 2004 | .addend = @intCast(i32, addend), | |
| 2005 | 2005 | }); |
| 2006 | 2006 | atom.size += @intCast(u32, slice_ty.abiSize(wasm.base.options.target)); |
| 2007 | 2007 | addend += len; |
| ... | ... | @@ -3433,7 +3433,7 @@ fn emitCodeRelocations( |
| 3433 | 3433 | try leb.writeULEB128(writer, offset); |
| 3434 | 3434 | try leb.writeULEB128(writer, symbol_index); |
| 3435 | 3435 | if (relocation.relocation_type.addendIsPresent()) { |
| 3436 | try leb.writeULEB128(writer, relocation.addend orelse 0); | |
| 3436 | try leb.writeILEB128(writer, relocation.addend); | |
| 3437 | 3437 | } |
| 3438 | 3438 | log.debug("Emit relocation: {}", .{relocation}); |
| 3439 | 3439 | } |
| ... | ... | @@ -3483,7 +3483,7 @@ fn emitDataRelocations( |
| 3483 | 3483 | try leb.writeULEB128(writer, offset); |
| 3484 | 3484 | try leb.writeULEB128(writer, symbol_index); |
| 3485 | 3485 | if (relocation.relocation_type.addendIsPresent()) { |
| 3486 | try leb.writeULEB128(writer, relocation.addend orelse 0); | |
| 3486 | try leb.writeILEB128(writer, relocation.addend); | |
| 3487 | 3487 | } |
| 3488 | 3488 | log.debug("Emit relocation: {}", .{relocation}); |
| 3489 | 3489 | } |
src/link/Wasm/Atom.zig+6-3| ... | ... | @@ -194,12 +194,14 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa |
| 194 | 194 | const segment_name = segment_info[symbol.index].outputName(merge_segment); |
| 195 | 195 | const segment_index = wasm_bin.data_segments.get(segment_name).?; |
| 196 | 196 | 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); | |
| 198 | 199 | }, |
| 199 | 200 | .R_WASM_EVENT_INDEX_LEB => return symbol.index, |
| 200 | 201 | .R_WASM_SECTION_OFFSET_I32 => { |
| 201 | 202 | 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); | |
| 203 | 205 | }, |
| 204 | 206 | .R_WASM_FUNCTION_OFFSET_I32 => { |
| 205 | 207 | 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 |
| 214 | 216 | if (current_atom == target_atom) break; |
| 215 | 217 | current_atom = current_atom.next.?; |
| 216 | 218 | } |
| 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); | |
| 218 | 221 | }, |
| 219 | 222 | } |
| 220 | 223 | } |
src/link/Wasm/Object.zig+1-1| ... | ... | @@ -606,7 +606,7 @@ fn Parser(comptime ReaderType: type) type { |
| 606 | 606 | .relocation_type = rel_type_enum, |
| 607 | 607 | .offset = try leb.readULEB128(u32, reader), |
| 608 | 608 | .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, | |
| 610 | 610 | }; |
| 611 | 611 | log.debug("Found relocation: type({s}) offset({d}) index({d}) addend({?d})", .{ |
| 612 | 612 | @tagName(relocation.relocation_type), |
src/link/Wasm/types.zig+2-2| ... | ... | @@ -12,8 +12,8 @@ pub const Relocation = struct { |
| 12 | 12 | /// When the type is `R_WASM_TYPE_INDEX_LEB`, it represents the index of the type. |
| 13 | 13 | index: u32, |
| 14 | 14 | /// 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, | |
| 17 | 17 | |
| 18 | 18 | /// All possible relocation types currently existing. |
| 19 | 19 | /// This enum is exhaustive as the spec is WIP and new types |