diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index d8aab58ef1..6444b431be 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -1568,9 +1568,13 @@ fn allocateAtoms(wasm: *Wasm) !void { var atom: *Atom = entry.value_ptr.*.getFirst(); var offset: u32 = 0; while (true) { + const symbol_loc = atom.symbolLoc(); + if (!wasm.resolved_symbols.contains(symbol_loc)) { + atom = atom.next orelse break; + continue; + } offset = std.mem.alignForwardGeneric(u32, offset, atom.alignment); atom.offset = offset; - const symbol_loc = atom.symbolLoc(); log.debug("Atom '{s}' allocated from 0x{x:0>8} to 0x{x:0>8} size={d}", .{ symbol_loc.getName(wasm), offset, @@ -1578,7 +1582,7 @@ fn allocateAtoms(wasm: *Wasm) !void { atom.size, }); offset += atom.size; - try wasm.symbol_atom.put(wasm.base.allocator, atom.symbolLoc(), atom); // Update atom pointers + try wasm.symbol_atom.put(wasm.base.allocator, symbol_loc, atom); // Update atom pointers atom = atom.next orelse break; } segment.size = std.mem.alignForwardGeneric(u32, offset, segment.alignment); @@ -2579,14 +2583,16 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l var atom: *Atom = wasm.atoms.get(code_index).?.getFirst(); // The code section must be sorted in line with the function order. - var sorted_atoms = try std.ArrayList(*Atom).initCapacity(wasm.base.allocator, wasm.functions.count()); + var sorted_atoms = try std.ArrayList(*Atom).initCapacity(gpa, wasm.functions.count()); defer sorted_atoms.deinit(); while (true) { - if (!is_obj) { - atom.resolveRelocs(wasm); + if (wasm.resolved_symbols.contains(atom.symbolLoc())) { + if (!is_obj) { + atom.resolveRelocs(wasm); + } + sorted_atoms.appendAssumeCapacity(atom); } - sorted_atoms.appendAssumeCapacity(atom); atom = atom.next orelse break; } @@ -2641,6 +2647,10 @@ fn linkWithZld(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) l // fill in the offset table and the data segments var current_offset: u32 = 0; while (true) { + if (!wasm.resolved_symbols.contains(atom.symbolLoc())) { + atom = atom.next orelse break; + continue; + } if (!is_obj) { atom.resolveRelocs(wasm); } @@ -4170,15 +4180,23 @@ fn emitDataRelocations( try writeCustomSectionHeader(binary_bytes.items, header_offset, size); } -/// Searches for an a matching function signature, when not found -/// a new entry will be made. The index of the existing/new signature will be returned. -pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 { +pub fn getTypeIndex(wasm: *const Wasm, func_type: std.wasm.Type) ?u32 { var index: u32 = 0; while (index < wasm.func_types.items.len) : (index += 1) { if (wasm.func_types.items[index].eql(func_type)) return index; } + return null; +} + +/// Searches for an a matching function signature, when not found +/// a new entry will be made. The index of the existing/new signature will be returned. +pub fn putOrGetFuncType(wasm: *Wasm, func_type: std.wasm.Type) !u32 { + if (wasm.getTypeIndex(func_type)) |index| { + return index; + } // functype does not exist. + const index = @intCast(u32, wasm.func_types.items.len); const params = try wasm.base.allocator.dupe(std.wasm.Valtype, func_type.params); errdefer wasm.base.allocator.free(params); const returns = try wasm.base.allocator.dupe(std.wasm.Valtype, func_type.returns); diff --git a/src/link/Wasm/Atom.zig b/src/link/Wasm/Atom.zig index f716cd56ee..eb3a31b8a0 100644 --- a/src/link/Wasm/Atom.zig +++ b/src/link/Wasm/Atom.zig @@ -186,7 +186,11 @@ fn relocationValue(atom: Atom, relocation: types.Relocation, wasm_bin: *const Wa .R_WASM_MEMORY_ADDR_SLEB, .R_WASM_MEMORY_ADDR_SLEB64, => { - std.debug.assert(symbol.tag == .data and !symbol.isUndefined()); + std.debug.assert(symbol.tag == .data); + if (symbol.isUndefined()) { + return 0; + } + const merge_segment = wasm_bin.base.options.output_mode != .Obj; const target_atom = wasm_bin.symbol_atom.get(target_loc).?; const segment_info = if (target_atom.file) |object_index| blk: { diff --git a/src/link/Wasm/Object.zig b/src/link/Wasm/Object.zig index e5947228a5..8f49d68712 100644 --- a/src/link/Wasm/Object.zig +++ b/src/link/Wasm/Object.zig @@ -923,7 +923,7 @@ pub fn parseIntoAtoms(object: *Object, gpa: Allocator, object_index: u16, wasm_b try atom.relocs.append(gpa, reloc); if (relocation.isTableIndex()) { - try wasm_bin.function_table.putNoClobber(gpa, .{ + try wasm_bin.function_table.put(gpa, .{ .file = object_index, .index = relocation.index, }, 0); @@ -938,17 +938,17 @@ pub fn parseIntoAtoms(object: *Object, gpa: Allocator, object_index: u16, wasm_b .index = relocatable_data.getIndex(), })) |symbols| { atom.sym_index = symbols.pop(); + try wasm_bin.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom); // symbols referencing the same atom will be added as alias // or as 'parent' when they are global. while (symbols.popOrNull()) |idx| { + try wasm_bin.symbol_atom.putNoClobber(gpa, .{ .file = atom.file, .index = idx }, atom); const alias_symbol = object.symtable[idx]; - const symbol = object.symtable[atom.sym_index]; - if (alias_symbol.isGlobal() and symbol.isLocal()) { + if (alias_symbol.isGlobal()) { atom.sym_index = idx; } } - try wasm_bin.symbol_atom.putNoClobber(gpa, atom.symbolLoc(), atom); } const segment: *Wasm.Segment = &wasm_bin.segments.items[final_index];