Skip to content

Commit

Permalink
llvm: mangle extern Wasm functions
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Luukdegram committed Nov 1, 2022
1 parent bd32206 commit 66bcc55
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/codegen/llvm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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, {});
Expand Down

0 comments on commit 66bcc55

Please sign in to comment.