| ... | ... | @@ -111,7 +111,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { |
| 111 | 111 | .R_WASM_GLOBAL_INDEX_I32, |
| 112 | 112 | .R_WASM_MEMORY_ADDR_I32, |
| 113 | 113 | .R_WASM_SECTION_OFFSET_I32, |
| 114 | | => std.mem.writeInt(u32, atom.code.items[reloc.offset - atom.original_offset ..][0..4], @as(u32, @intCast(value)), .little), |
| 114 | => std.mem.writeInt(u32, atom.code.items[reloc.offset - atom.original_offset ..][0..4], @as(u32, @truncate(value)), .little), |
| 115 | 115 | .R_WASM_TABLE_INDEX_I64, |
| 116 | 116 | .R_WASM_MEMORY_ADDR_I64, |
| 117 | 117 | => std.mem.writeInt(u64, atom.code.items[reloc.offset - atom.original_offset ..][0..8], value, .little), |
| ... | ... | @@ -124,7 +124,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { |
| 124 | 124 | .R_WASM_TABLE_NUMBER_LEB, |
| 125 | 125 | .R_WASM_TYPE_INDEX_LEB, |
| 126 | 126 | .R_WASM_MEMORY_ADDR_TLS_SLEB, |
| 127 | | => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset - atom.original_offset ..][0..5], @as(u32, @intCast(value))), |
| 127 | => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset - atom.original_offset ..][0..5], @as(u32, @truncate(value))), |
| 128 | 128 | .R_WASM_MEMORY_ADDR_LEB64, |
| 129 | 129 | .R_WASM_MEMORY_ADDR_SLEB64, |
| 130 | 130 | .R_WASM_TABLE_INDEX_SLEB64, |
| ... | ... | @@ -140,6 +140,13 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { |
| 140 | 140 | fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 { |
| 141 | 141 | const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin); |
| 142 | 142 | const symbol = target_loc.getSymbol(wasm_bin); |
| 143 | if (relocation.relocation_type != .R_WASM_TYPE_INDEX_LEB and |
| 144 | symbol.tag != .section and |
| 145 | symbol.isDead()) |
| 146 | { |
| 147 | const val = atom.thombstone(wasm_bin) orelse relocation.addend; |
| 148 | return @bitCast(val); |
| 149 | } |
| 143 | 150 | switch (relocation.relocation_type) { |
| 144 | 151 | .R_WASM_FUNCTION_INDEX_LEB => return symbol.index, |
| 145 | 152 | .R_WASM_TABLE_NUMBER_LEB => return symbol.index, |
| ... | ... | @@ -170,30 +177,43 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa |
| 170 | 177 | if (symbol.isUndefined()) { |
| 171 | 178 | return 0; |
| 172 | 179 | } |
| 173 | | const va = @as(i64, @intCast(symbol.virtual_address)); |
| 180 | const va: i33 = @intCast(symbol.virtual_address); |
| 174 | 181 | return @intCast(va + relocation.addend); |
| 175 | 182 | }, |
| 176 | 183 | .R_WASM_EVENT_INDEX_LEB => return symbol.index, |
| 177 | 184 | .R_WASM_SECTION_OFFSET_I32 => { |
| 178 | 185 | const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?; |
| 179 | 186 | const target_atom = wasm_bin.getAtom(target_atom_index); |
| 180 | | const rel_value: i32 = @intCast(target_atom.offset); |
| 187 | const rel_value: i33 = @intCast(target_atom.offset); |
| 181 | 188 | return @intCast(rel_value + relocation.addend); |
| 182 | 189 | }, |
| 183 | 190 | .R_WASM_FUNCTION_OFFSET_I32 => { |
| 184 | | const target_atom_index = wasm_bin.symbol_atom.get(target_loc) orelse { |
| 185 | | return @as(u32, @bitCast(@as(i32, -1))); |
| 186 | | }; |
| 191 | if (symbol.isUndefined()) { |
| 192 | const val = atom.thombstone(wasm_bin) orelse relocation.addend; |
| 193 | return @bitCast(val); |
| 194 | } |
| 195 | const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?; |
| 187 | 196 | const target_atom = wasm_bin.getAtom(target_atom_index); |
| 188 | | const offset: u32 = 11 + Wasm.getULEB128Size(target_atom.size); // Header (11 bytes fixed-size) + body size (leb-encoded) |
| 189 | | const rel_value: i32 = @intCast(target_atom.offset + offset); |
| 197 | const rel_value: i33 = @intCast(target_atom.offset); |
| 190 | 198 | return @intCast(rel_value + relocation.addend); |
| 191 | 199 | }, |
| 192 | 200 | .R_WASM_MEMORY_ADDR_TLS_SLEB, |
| 193 | 201 | .R_WASM_MEMORY_ADDR_TLS_SLEB64, |
| 194 | 202 | => { |
| 195 | | const va: i32 = @intCast(symbol.virtual_address); |
| 203 | const va: i33 = @intCast(symbol.virtual_address); |
| 196 | 204 | return @intCast(va + relocation.addend); |
| 197 | 205 | }, |
| 198 | 206 | } |
| 199 | 207 | } |
| 208 | |
| 209 | // For a given `Atom` returns whether it has a thombstone value or not. |
| 210 | /// This defines whether we want a specific value when a section is dead. |
| 211 | fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 { |
| 212 | const atom_name = atom.symbolLoc().getName(wasm); |
| 213 | if (std.mem.eql(u8, atom_name, ".debug_ranges") or std.mem.eql(u8, atom_name, ".debug_loc")) { |
| 214 | return -2; |
| 215 | } else if (std.mem.startsWith(u8, atom_name, ".debug_")) { |
| 216 | return -1; |
| 217 | } |
| 218 | return null; |
| 219 | } |