authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-09-01 22:02:24+02:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-09-07 18:53:16+02:00
log46c932a2c9650f14ae8035d7382d825bfabdc0a5
treee819d6b20acb736af12a5b7f35ce4c34e17f3600
parentc347751338a4a1e2874207674fb47908fd601484
signaturelock-open Commit is signed but in an unrecognized format.

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.

3 files changed, 16 insertions(+), 6 deletions(-)

src/link/Wasm.zig+12
......@@ -221,6 +221,18 @@ pub const SymbolLoc = struct {
221221 }
222222 return wasm_bin.string_table.get(wasm_bin.symbols.items[self.index].name);
223223 }
224
225 /// From a given symbol location, returns the final location.
226 /// e.g. when a symbol was resolved and replaced by the symbol
227 /// in a different file, this will return said location.
228 /// If the symbol wasn't replaced by another, this will return
229 /// the given location itself.
230 pub fn finalLoc(self: SymbolLoc, wasm_bin: *const Wasm) SymbolLoc {
231 if (wasm_bin.discarded.get(self)) |new_loc| {
232 return new_loc.finalLoc(wasm_bin);
233 }
234 return self;
235 }
224236};
225237
226238/// Generic string table that duplicates strings
src/link/Wasm/Atom.zig+3-4
......@@ -145,7 +145,7 @@ pub fn resolveRelocs(self: *Atom, wasm_bin: *const Wasm) void {
145145/// All values will be represented as a `u64` as all values can fit within it.
146146/// The final value must be casted to the correct size.
147147fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wasm) u64 {
148 const target_loc: Wasm.SymbolLoc = .{ .file = self.file, .index = relocation.index };
148 const target_loc = (Wasm.SymbolLoc{ .file = self.file, .index = relocation.index }).finalLoc(wasm_bin);
149149 const symbol = target_loc.getSymbol(wasm_bin).*;
150150 switch (relocation.relocation_type) {
151151 .R_WASM_FUNCTION_INDEX_LEB => return symbol.index,
......@@ -174,8 +174,7 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
174174 => {
175175 std.debug.assert(symbol.tag == .data and !symbol.isUndefined());
176176 const merge_segment = wasm_bin.base.options.output_mode != .Obj;
177 const target_atom_loc = wasm_bin.discarded.get(target_loc) orelse target_loc;
178 const target_atom = wasm_bin.symbol_atom.get(target_atom_loc).?;
177 const target_atom = wasm_bin.symbol_atom.get(target_loc).?;
179178 const segment_info = if (target_atom.file) |object_index| blk: {
180179 break :blk wasm_bin.objects.items[object_index].segment_info;
181180 } else wasm_bin.segment_info.items;
......@@ -187,6 +186,6 @@ fn relocationValue(self: Atom, relocation: types.Relocation, wasm_bin: *const Wa
187186 .R_WASM_EVENT_INDEX_LEB => return symbol.index,
188187 .R_WASM_SECTION_OFFSET_I32,
189188 .R_WASM_FUNCTION_OFFSET_I32,
190 => return relocation.offset,
189 => return relocation.addend orelse 0,
191190 }
192191}
src/link/Wasm/Object.zig+1-2
......@@ -387,11 +387,10 @@ fn Parser(comptime ReaderType: type) type {
387387 .data = debug_content.ptr,
388388 .size = debug_size,
389389 .index = try self.object.string_table.put(gpa, name),
390 .offset = len - debug_size,
390 .offset = 0, // debug sections only contain 1 entry, so no need to calculate offset
391391 .section_index = section_index,
392392 });
393393 } else {
394 log.info("found unknown custom section '{s}' - skipping parsing", .{name});
395394 try reader.skipBytes(reader.context.bytes_left, .{});
396395 }
397396 },