Commit dd85092982
Changed files (3)
src
link
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: {
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];
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);