authorgravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-08-08 01:43:21+02:00
committergravatar for paul.verigo@gmail.comPavel Verigo <paul.verigo@gmail.com> 2026-08-11 20:00:12+02:00
logcce0b43270a57a884e7d7aeba25bc6953741156e
tree00be505cace3741b3ae69dd98e910302bb0a46ff
parent9d92d2ce93c52083fe405716a6cf05151384b76e

wasm: change symbol name for function if it uses library name

Fixes bug when `fn "js" log(...)` collide with compiler-rt `log` symbol, to fix I reuse logic/idea from llvm backend.

2 files changed, 28 insertions(+), 13 deletions(-)

src/link/Wasm.zig+24-11
......@@ -187,7 +187,7 @@ overaligned_uavs: std.array_hash_map.Auto(InternPool.Index, Alignment) = .empty,
187187zcu_funcs: std.array_hash_map.Auto(InternPool.Index, ZcuFunc) = .empty,
188188nav_exports: std.array_hash_map.Auto(NavExport, Zcu.Export.Index) = .empty,
189189uav_exports: std.array_hash_map.Auto(UavExport, Zcu.Export.Index) = .empty,
190imports: std.array_hash_map.Auto(InternPool.Nav.Index, void) = .empty,
190imports: std.array_hash_map.Auto(InternPool.Nav.Index, String) = .empty,
191191
192192dwarf: ?Dwarf = null,
193193
......@@ -409,7 +409,7 @@ pub const OutputFunctionIndex = enum(u32) {
409409 const ip = &zcu.intern_pool;
410410 return switch (ip.indexToKey(ip_index)) {
411411 .@"extern" => |ext| {
412 const name = wasm.getExistingString(ext.name.toSlice(ip)).?;
412 const name = wasm.imports.get(ext.owner_nav).?;
413413 return fromSymbolName(wasm, name);
414414 },
415415 else => fromResolution(wasm, .fromIpIndex(wasm, ip_index)).?,
......@@ -479,8 +479,8 @@ pub const OutputDataIndex = enum(u32) {
479479 const zcu = wasm.base.comp.zcu.?;
480480 const ip = &zcu.intern_pool;
481481 const nav = ip.getNav(nav_index);
482 if (nav.getExtern(ip)) |ext| {
483 return fromSymbolName(wasm, wasm.getExistingString(ext.name.toSlice(ip)).?);
482 if (nav.getExtern(ip) != null) {
483 return fromSymbolName(wasm, wasm.imports.get(nav_index).?);
484484 }
485485 const resolution: ObjectDataImport.Resolution = if (wasm.base.comp.config.output_mode == .Obj)
486486 .pack(wasm, .{ .nav_obj = @fromBackingInt(@intCast(wasm.navs_obj.getIndex(nav_index).?)) })
......@@ -2592,6 +2592,10 @@ pub const ZcuImportIndex = enum(u32) {
25922592 return &wasm.imports.keys()[@backingInt(index)];
25932593 }
25942594
2595 pub fn symbolName(index: ZcuImportIndex, wasm: *const Wasm) String {
2596 return wasm.imports.values()[@backingInt(index)];
2597 }
2598
25952599 pub fn flags(index: ZcuImportIndex, wasm: *const Wasm) SymbolFlags {
25962600 const zcu = wasm.base.comp.zcu.?;
25972601 const ip = &zcu.intern_pool;
......@@ -2613,7 +2617,7 @@ pub const ZcuImportIndex = enum(u32) {
26132617 },
26142618 .undefined = true,
26152619 .exported = wasm.missing_exports.contains(name_string),
2616 .explicit_name = false,
2620 .explicit_name = index.symbolName(wasm) != name_string,
26172621 .no_strip = false,
26182622 .tls = ext.is_threadlocal,
26192623 .absolute = false,
......@@ -3683,14 +3687,23 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
36833687 } else {
36843688 assert(!wasm.navs_exe.contains(ext.owner_nav));
36853689 }
3686 const name = try wasm.internString(ext.name.toSlice(ip));
3687 if (ext.lib_name.toSlice(ip)) |ext_name| _ = try wasm.internString(ext_name);
3690 const name_slice = ext.name.toSlice(ip);
3691 const name = try wasm.internString(name_slice);
3692 const symbol_name = if (ip.isFunctionType(nav.resolved.?.type)) symbol_name: {
3693 const lib_name = ext.lib_name.toSlice(ip) orelse break :symbol_name name;
3694 _ = try wasm.internString(lib_name);
3695 // match llvm backend behavior
3696 if (mem.eql(u8, lib_name, "c")) break :symbol_name name;
3697 const qualified_name = try std.fmt.allocPrint(gpa, "{s}|{s}", .{ name_slice, lib_name });
3698 defer gpa.free(qualified_name);
3699 break :symbol_name try wasm.internString(qualified_name);
3700 } else name;
36883701 try wasm.imports.ensureUnusedCapacity(gpa, 1);
36893702 try wasm.function_imports.ensureUnusedCapacity(gpa, 1);
36903703 try wasm.data_imports.ensureUnusedCapacity(gpa, 1);
3691 const zcu_import = wasm.addZcuImportReserved(ext.owner_nav);
3704 const zcu_import = wasm.addZcuImportReserved(ext.owner_nav, symbol_name);
36923705 if (ip.isFunctionType(nav.resolved.?.type)) {
3693 wasm.function_imports.putAssumeCapacity(name, .fromZcuImport(zcu_import, wasm));
3706 wasm.function_imports.putAssumeCapacity(symbol_name, .fromZcuImport(zcu_import, wasm));
36943707 // Ensure there is a corresponding function type table entry.
36953708 const fn_info = zcu.typeToFunc(.fromInterned(ext.ty)).?;
36963709 _ = try internFunctionType(wasm, fn_info.cc, fn_info.param_types.get(ip), .fromInterned(fn_info.return_type), fn_info.is_var_args, target);
......@@ -5073,9 +5086,9 @@ fn pointerSize(wasm: *const Wasm) u32 {
50735086 };
50745087}
50755088
5076fn addZcuImportReserved(wasm: *Wasm, nav_index: InternPool.Nav.Index) ZcuImportIndex {
5089fn addZcuImportReserved(wasm: *Wasm, nav_index: InternPool.Nav.Index, symbol_name: String) ZcuImportIndex {
50775090 const gop = wasm.imports.getOrPutAssumeCapacity(nav_index);
5078 gop.value_ptr.* = {};
5091 gop.value_ptr.* = symbol_name;
50795092 return @fromBackingInt(@intCast(gop.index));
50805093}
50815094
src/link/Wasm/Flush.zig+4-2
......@@ -1472,14 +1472,16 @@ pub fn finish(f: *Flush, wasm: *Wasm) !void {
14721472 // SYMTAB_FUNCTION
14731473 {
14741474 symbol_table_offsets.function = symbol_count;
1475 for (f.function_imports.values(), 0..) |i, function_index| {
1475 for (f.function_imports.keys(), f.function_imports.values(), 0..) |symbol_name, i, function_index| {
14761476 try binary_bytes.append(gpa, @backingInt(Object.Symbol.Tag.function));
14771477 const flags = i.flags(wasm);
14781478 assert(flags.undefined);
14791479 try appendLeb128(gpa, binary_bytes, flags.toAbiInteger());
14801480 try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(function_index)));
14811481 if (flags.explicit_name) {
1482 unreachable; // never set
1482 const name = symbol_name.slice(wasm);
1483 try appendLeb128(gpa, binary_bytes, @as(u32, @intCast(name.len)));
1484 try binary_bytes.appendSlice(gpa, name);
14831485 }
14841486 symbol_count += 1;
14851487 }