wasm-linker: perform debug relocations

This correctly performs a relocation for debug sections.
The result is that the wasm-linker can now correctly create
a binary from object files while preserving all debug information.
This commit is contained in:
Luuk de Gram 2022-09-01 22:02:24 +02:00
parent c347751338
commit 46c932a2c9
No known key found for this signature in database
GPG Key ID: A8CFE58E4DC7D664
3 changed files with 16 additions and 6 deletions

View File

@ -221,6 +221,18 @@ pub const SymbolLoc = struct {
}
return wasm_bin.string_table.get(wasm_bin.symbols.items[self.index].name);
}
/// From a given symbol location, returns the final location.
/// e.g. when a symbol was resolved and replaced by the symbol
/// in a different file, this will return said location.
/// If the symbol wasn't replaced by another, this will return
/// the given location itself.
pub fn finalLoc(self: SymbolLoc, wasm_bin: *const Wasm) SymbolLoc {
if (wasm_bin.discarded.get(self)) |new_loc| {
return new_loc.finalLoc(wasm_bin);
}
return self;
}
};
/// Generic string table that duplicates strings

View File

@ -145,7 +145,7 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) void {
/// All values will be represented as a `u64` as all values can fit within it.
/// The final value must be casted to the correct size.
fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
const target_loc: Wasm.SymbolLoc = .{ .file = self.file, .index = relocation.index };
const target_loc = (Wasm.SymbolLoc{ .file = self.file, .index = relocation.index }).finalLoc(wasm_bin);
const symbol = target_loc.getSymbol(wasm_bin).*;
switch (relocation.relocation_type) {
.R_WASM_FUNCTION_INDEX_LEB => return symbol.index,
@ -174,8 +174,7 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
=> {
std.debug.assert(symbol.tag == .data and !symbol.isUndefined());
const merge_segment = wasm_bin.base.options.output_mode != .Obj;
const target_atom_loc = wasm_bin.discarded.get(target_loc) orelse target_loc;
const target_atom = wasm_bin.symbol_atom.get(target_atom_loc).?;
const target_atom = wasm_bin.symbol_atom.get(target_loc).?;
const segment_info = if (target_atom.file) |object_index| blk: {
break :blk wasm_bin.objects.items[object_index].segment_info;
} else wasm_bin.segment_info.items;
@ -187,6 +186,6 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
.R_WASM_EVENT_INDEX_LEB => return symbol.index,
.R_WASM_SECTION_OFFSET_I32,
.R_WASM_FUNCTION_OFFSET_I32,
=> return relocation.offset,
=> return relocation.addend orelse 0,
}
}

View File

@ -387,11 +387,10 @@ fn Parser(comptime ReaderType: type) type {
.data = debug_content.ptr,
.size = debug_size,
.index = try self.object.string_table.put(gpa, name),
.offset = len - debug_size,
.offset = 0, // debug sections only contain 1 entry, so no need to calculate offset
.section_index = section_index,
});
} else {
log.info("found unknown custom section '{s}' - skipping parsing", .{name});
try reader.skipBytes(reader.context.bytes_left, .{});
}
},