| ... | @@ -111,7 +111,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { | ... | @@ -111,7 +111,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { |
| 111 | .R_WASM_GLOBAL_INDEX_I32, | 111 | .R_WASM_GLOBAL_INDEX_I32, |
| 112 | .R_WASM_MEMORY_ADDR_I32, | 112 | .R_WASM_MEMORY_ADDR_I32, |
| 113 | .R_WASM_SECTION_OFFSET_I32, | 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 | .R_WASM_TABLE_INDEX_I64, | 115 | .R_WASM_TABLE_INDEX_I64, |
| 116 | .R_WASM_MEMORY_ADDR_I64, | 116 | .R_WASM_MEMORY_ADDR_I64, |
| 117 | => std.mem.writeInt(u64, atom.code.items[reloc.offset - atom.original_offset ..][0..8], value, .little), | 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,7 +124,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { |
| 124 | .R_WASM_TABLE_NUMBER_LEB, | 124 | .R_WASM_TABLE_NUMBER_LEB, |
| 125 | .R_WASM_TYPE_INDEX_LEB, | 125 | .R_WASM_TYPE_INDEX_LEB, |
| 126 | .R_WASM_MEMORY_ADDR_TLS_SLEB, | 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 | .R_WASM_MEMORY_ADDR_LEB64, | 128 | .R_WASM_MEMORY_ADDR_LEB64, |
| 129 | .R_WASM_MEMORY_ADDR_SLEB64, | 129 | .R_WASM_MEMORY_ADDR_SLEB64, |
| 130 | .R_WASM_TABLE_INDEX_SLEB64, | 130 | .R_WASM_TABLE_INDEX_SLEB64, |
| ... | @@ -140,6 +140,13 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { | ... | @@ -140,6 +140,13 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void { |
| 140 | fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 { | 140 | fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 { |
| 141 | const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin); | 141 | const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin); |
| 142 | const symbol = target_loc.getSymbol(wasm_bin); | 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 | switch (relocation.relocation_type) { | 150 | switch (relocation.relocation_type) { |
| 144 | .R_WASM_FUNCTION_INDEX_LEB => return symbol.index, | 151 | .R_WASM_FUNCTION_INDEX_LEB => return symbol.index, |
| 145 | .R_WASM_TABLE_NUMBER_LEB => return symbol.index, | 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,30 +177,43 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa |
| 170 | if (symbol.isUndefined()) { | 177 | if (symbol.isUndefined()) { |
| 171 | return 0; | 178 | return 0; |
| 172 | } | 179 | } |
| 173 | const va = @as(i64, @intCast(symbol.virtual_address)); | 180 | const va: i33 = @intCast(symbol.virtual_address); |
| 174 | return @intCast(va + relocation.addend); | 181 | return @intCast(va + relocation.addend); |
| 175 | }, | 182 | }, |
| 176 | .R_WASM_EVENT_INDEX_LEB => return symbol.index, | 183 | .R_WASM_EVENT_INDEX_LEB => return symbol.index, |
| 177 | .R_WASM_SECTION_OFFSET_I32 => { | 184 | .R_WASM_SECTION_OFFSET_I32 => { |
| 178 | const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?; | 185 | const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?; |
| 179 | const target_atom = wasm_bin.getAtom(target_atom_index); | 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 | return @intCast(rel_value + relocation.addend); | 188 | return @intCast(rel_value + relocation.addend); |
| 182 | }, | 189 | }, |
| 183 | .R_WASM_FUNCTION_OFFSET_I32 => { | 190 | .R_WASM_FUNCTION_OFFSET_I32 => { |
| 184 | const target_atom_index = wasm_bin.symbol_atom.get(target_loc) orelse { | 191 | if (symbol.isUndefined()) { |
| 185 | return @as(u32, @bitCast(@as(i32, -1))); | 192 | const val = atom.thombstone(wasm_bin) orelse relocation.addend; |
| 186 | }; | 193 | return @bitCast(val); |
| | 194 | } |
| | 195 | const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?; |
| 187 | const target_atom = wasm_bin.getAtom(target_atom_index); | 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) | 197 | const rel_value: i33 = @intCast(target_atom.offset); |
| 189 | const rel_value: i32 = @intCast(target_atom.offset + offset); | | |
| 190 | return @intCast(rel_value + relocation.addend); | 198 | return @intCast(rel_value + relocation.addend); |
| 191 | }, | 199 | }, |
| 192 | .R_WASM_MEMORY_ADDR_TLS_SLEB, | 200 | .R_WASM_MEMORY_ADDR_TLS_SLEB, |
| 193 | .R_WASM_MEMORY_ADDR_TLS_SLEB64, | 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 | return @intCast(va + relocation.addend); | 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 | } |