Commit 3f22bb96f3
Changed files (1)
src
link
Wasm
src/link/Wasm/Atom.zig
@@ -111,7 +111,7 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
.R_WASM_GLOBAL_INDEX_I32,
.R_WASM_MEMORY_ADDR_I32,
.R_WASM_SECTION_OFFSET_I32,
- => std.mem.writeInt(u32, atom.code.items[reloc.offset - atom.original_offset ..][0..4], @as(u32, @intCast(value)), .little),
+ => std.mem.writeInt(u32, atom.code.items[reloc.offset - atom.original_offset ..][0..4], @as(u32, @truncate(value)), .little),
.R_WASM_TABLE_INDEX_I64,
.R_WASM_MEMORY_ADDR_I64,
=> 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 {
.R_WASM_TABLE_NUMBER_LEB,
.R_WASM_TYPE_INDEX_LEB,
.R_WASM_MEMORY_ADDR_TLS_SLEB,
- => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset - atom.original_offset ..][0..5], @as(u32, @intCast(value))),
+ => leb.writeUnsignedFixed(5, atom.code.items[reloc.offset - atom.original_offset ..][0..5], @as(u32, @truncate(value))),
.R_WASM_MEMORY_ADDR_LEB64,
.R_WASM_MEMORY_ADDR_SLEB64,
.R_WASM_TABLE_INDEX_SLEB64,
@@ -140,6 +140,13 @@ pub fn resolveRelocs(atom: *Atom, wasm_bin: *const Wasm) void {
fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
const target_loc = (Wasm.SymbolLoc{ .file = atom.file, .index = relocation.index }).finalLoc(wasm_bin);
const symbol = target_loc.getSymbol(wasm_bin);
+ if (relocation.relocation_type != .R_WASM_TYPE_INDEX_LEB and
+ symbol.tag != .section and
+ symbol.isDead())
+ {
+ const val = atom.thombstone(wasm_bin) orelse relocation.addend;
+ return @bitCast(val);
+ }
switch (relocation.relocation_type) {
.R_WASM_FUNCTION_INDEX_LEB => return symbol.index,
.R_WASM_TABLE_NUMBER_LEB => return symbol.index,
@@ -170,30 +177,43 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa
if (symbol.isUndefined()) {
return 0;
}
- const va = @as(i64, @intCast(symbol.virtual_address));
+ const va: i33 = @intCast(symbol.virtual_address);
return @intCast(va + relocation.addend);
},
.R_WASM_EVENT_INDEX_LEB => return symbol.index,
.R_WASM_SECTION_OFFSET_I32 => {
const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?;
const target_atom = wasm_bin.getAtom(target_atom_index);
- const rel_value: i32 = @intCast(target_atom.offset);
+ const rel_value: i33 = @intCast(target_atom.offset);
return @intCast(rel_value + relocation.addend);
},
.R_WASM_FUNCTION_OFFSET_I32 => {
- const target_atom_index = wasm_bin.symbol_atom.get(target_loc) orelse {
- return @as(u32, @bitCast(@as(i32, -1)));
- };
+ if (symbol.isUndefined()) {
+ const val = atom.thombstone(wasm_bin) orelse relocation.addend;
+ return @bitCast(val);
+ }
+ const target_atom_index = wasm_bin.symbol_atom.get(target_loc).?;
const target_atom = wasm_bin.getAtom(target_atom_index);
- const offset: u32 = 11 + Wasm.getULEB128Size(target_atom.size); // Header (11 bytes fixed-size) + body size (leb-encoded)
- const rel_value: i32 = @intCast(target_atom.offset + offset);
+ const rel_value: i33 = @intCast(target_atom.offset);
return @intCast(rel_value + relocation.addend);
},
.R_WASM_MEMORY_ADDR_TLS_SLEB,
.R_WASM_MEMORY_ADDR_TLS_SLEB64,
=> {
- const va: i32 = @intCast(symbol.virtual_address);
+ const va: i33 = @intCast(symbol.virtual_address);
return @intCast(va + relocation.addend);
},
}
}
+
+// For a given `Atom` returns whether it has a thombstone value or not.
+/// This defines whether we want a specific value when a section is dead.
+fn thombstone(atom: Atom, wasm: *const Wasm) ?i64 {
+ const atom_name = atom.symbolLoc().getName(wasm);
+ if (std.mem.eql(u8, atom_name, ".debug_ranges") or std.mem.eql(u8, atom_name, ".debug_loc")) {
+ return -2;
+ } else if (std.mem.startsWith(u8, atom_name, ".debug_")) {
+ return -1;
+ }
+ return null;
+}