authorgravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-11-01 15:05:09+01:00
committergravatar for luuk@degram.devLuuk de Gram <luuk@degram.dev> 2022-11-01 15:05:09+01:00
log66bcc55e0196bd43746a09a79668c7c495bd1f89
treece5e5918602e157634415093009183ba370a44ec
parentbd32206b4449e329c9ef6ba4fd19746234f474f8
signaturelock-open Commit is signed but in an unrecognized format.

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 <name>|<module> where module is also known as the library name.

1 files changed, 12 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+12-2
...@@ -1279,8 +1279,18 @@ pub const Object = struct {...@@ -1279,8 +1279,18 @@ pub const Object = struct {
1279 const llvm_global = self.decl_map.get(decl_index) orelse return;1279 const llvm_global = self.decl_map.get(decl_index) orelse return;
1280 const decl = module.declPtr(decl_index);1280 const decl = module.declPtr(decl_index);
1281 if (decl.isExtern()) {1281 if (decl.isExtern()) {
1282 llvm_global.setValueName(decl.name);1282 const is_wasm_fn = module.getTarget().isWasm() and try decl.isFunction();
1283 if (self.getLlvmGlobal(decl.name)) |other_global| {1283 const mangle_name = is_wasm_fn and
1284 decl.getExternFn().?.lib_name != null and
1285 !std.mem.eql(u8, std.mem.sliceTo(decl.getExternFn().?.lib_name.?, 0), "c");
1286 const decl_name = if (mangle_name) name: {
1287 const tmp = try std.fmt.allocPrintZ(module.gpa, "{s}|{s}", .{ decl.name, decl.getExternFn().?.lib_name.? });
1288 break :name tmp.ptr;
1289 } else decl.name;
1290 defer if (mangle_name) module.gpa.free(std.mem.sliceTo(decl_name, 0));
1291
1292 llvm_global.setValueName(decl_name);
1293 if (self.getLlvmGlobal(decl_name)) |other_global| {
1284 if (other_global != llvm_global) {1294 if (other_global != llvm_global) {
1285 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});1295 log.debug("updateDeclExports isExtern()=true setValueName({s}) conflict", .{decl.name});
1286 try self.extern_collisions.put(module.gpa, decl_index, {});1296 try self.extern_collisions.put(module.gpa, decl_index, {});