mirror of
https://github.com/ziglang/zig.git
synced 2026-01-07 14:03:26 +00:00
wasm-linker: discard symbol when both undefined
During symbol resolution when both symbols are undefined, we must discard the new symbol with a reference to the existing symbol. This ensures the original symbol remains undefined. This fixes symbol resolution when linking with WASI-libC.
This commit is contained in:
parent
cbbf8c8a2d
commit
2339b25fd4
@ -600,27 +600,34 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
|
||||
}
|
||||
|
||||
if (existing_sym.isUndefined() and symbol.isUndefined()) {
|
||||
const existing_name = if (existing_loc.file) |file_index| blk: {
|
||||
const obj = wasm.objects.items[file_index];
|
||||
const name_index = obj.findImport(symbol.tag.externalType(), existing_sym.index).module_name;
|
||||
break :blk obj.string_table.get(name_index);
|
||||
} else blk: {
|
||||
const name_index = wasm.imports.get(existing_loc).?.module_name;
|
||||
break :blk wasm.string_table.get(name_index);
|
||||
};
|
||||
// only verify module/import name for function symbols
|
||||
if (symbol.tag == .function) {
|
||||
const existing_name = if (existing_loc.file) |file_index| blk: {
|
||||
const obj = wasm.objects.items[file_index];
|
||||
const name_index = obj.findImport(symbol.tag.externalType(), existing_sym.index).module_name;
|
||||
break :blk obj.string_table.get(name_index);
|
||||
} else blk: {
|
||||
const name_index = wasm.imports.get(existing_loc).?.module_name;
|
||||
break :blk wasm.string_table.get(name_index);
|
||||
};
|
||||
|
||||
const module_index = object.findImport(symbol.tag.externalType(), symbol.index).module_name;
|
||||
const module_name = object.string_table.get(module_index);
|
||||
if (!mem.eql(u8, existing_name, module_name)) {
|
||||
log.err("symbol '{s}' module name mismatch. Expected '{s}', but found '{s}'", .{
|
||||
sym_name,
|
||||
existing_name,
|
||||
module_name,
|
||||
});
|
||||
log.err(" first definition in '{s}'", .{existing_file_path});
|
||||
log.err(" next definition in '{s}'", .{object.name});
|
||||
return error.ModuleNameMismatch;
|
||||
const module_index = object.findImport(symbol.tag.externalType(), symbol.index).module_name;
|
||||
const module_name = object.string_table.get(module_index);
|
||||
if (!mem.eql(u8, existing_name, module_name)) {
|
||||
log.err("symbol '{s}' module name mismatch. Expected '{s}', but found '{s}'", .{
|
||||
sym_name,
|
||||
existing_name,
|
||||
module_name,
|
||||
});
|
||||
log.err(" first definition in '{s}'", .{existing_file_path});
|
||||
log.err(" next definition in '{s}'", .{object.name});
|
||||
return error.ModuleNameMismatch;
|
||||
}
|
||||
}
|
||||
|
||||
// both undefined so skip overwriting existing symbol and discard the new symbol
|
||||
try wasm.discarded.put(wasm.base.allocator, location, existing_loc);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existing_sym.tag == .global) {
|
||||
@ -646,8 +653,10 @@ fn resolveSymbolsInObject(wasm: *Wasm, object_index: u16) !void {
|
||||
}
|
||||
}
|
||||
|
||||
// when both symbols are weak, we skip overwriting
|
||||
if (existing_sym.isWeak() and symbol.isWeak()) {
|
||||
// when both symbols are weak, we skip overwriting unless the existing
|
||||
// symbol is weak and the new one isn't, in which case we *do* overwrite it.
|
||||
if (existing_sym.isWeak() and symbol.isWeak()) blk: {
|
||||
if (existing_sym.isUndefined() and !symbol.isUndefined()) break :blk;
|
||||
try wasm.discarded.put(wasm.base.allocator, location, existing_loc);
|
||||
continue;
|
||||
}
|
||||
@ -1935,7 +1944,9 @@ fn setupStart(wasm: *Wasm) !void {
|
||||
return error.MissingSymbol;
|
||||
};
|
||||
|
||||
const symbol_loc = wasm.globals.get(symbol_name_offset).?;
|
||||
const symbol_loc = wasm.globals.get(symbol_name_offset) orelse {
|
||||
log.err("Entry symbol '{s}' not found", .{entry_name});
|
||||
};
|
||||
const symbol = symbol_loc.getSymbol(wasm);
|
||||
if (symbol.tag != .function) {
|
||||
log.err("Entry symbol '{s}' is not a function", .{entry_name});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user