From 66bcc55e0196bd43746a09a79668c7c495bd1f89 Mon Sep 17 00:00:00 2001 From: Luuk de Gram Date: Tue, 1 Nov 2022 15:05:09 +0100 Subject: [PATCH] llvm: mangle extern Wasm functions When Wasm extern functions contain the same name, but have a different module name such as `extern "a"` vs `extern "b"` LLVM will currently resolve the two functions to the same symbol. By mangling the name of the symbol, we ensure the functions are resolved seperately. We mangle the name by applying | where module is also known as the library name. --- src/codegen/llvm.zig | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index d92a444ea45998c5e62e02bdf0839011a666babc..1290a207be09bc4565c35c0d746b8a1b27ce51aa 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -1279,8 +1279,18 @@ pub const Object = struct { const llvm_global = self.decl_map.get(decl_index) orelse return; const decl = module.declPtr(decl_index); if (decl.isExtern()) { - llvm_global.setValueName(decl.name); - if (self.getLlvmGlobal(decl.name)) |other_global| { + const is_wasm_fn = module.getTarget().isWasm() and try decl.isFunction(); + const mangle_name = is_wasm_fn and + decl.getExternFn().?.lib_name != null and + !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c"); + const decl_name = if (mangle_name) name: { + const tmp = try std.fmt.allocPrintZ(module.gpa, "{s}|{s}", .{ decl.name, decl.getExternFn().?.lib_name.? }); + break :name tmp.ptr; + } else decl.name; + defer if (mangle_name) module.gpa.free(std.mem.sliceTo(decl_name, 0)); + + llvm_global.setValueName(decl_name); + if (self.getLlvmGlobal(decl_name)) |other_global| { if (other_global != llvm_global) { log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name}); try self.extern_collisions.put(module.gpa, decl_index, {}); -- 2.54.0