authorgravatar for takeshi@tetrate.ioTakeshi Yoneda <takeshi@tetrate.io> 2021-07-02 15:20:17+09:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-31 13:39:15-07:00
log5d08e2b5d8a127d02758c7bcd4cd1b60bc7aa827
treea325768d6b430dadecbd841ef5c057879b5e6aa7
parentd38bd443efcfc14764269d6f3954f27f1b9c4ac0

Wasm,libc: fix wasm-ld failure in matching libc symbols.

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>

1 files changed, 18 insertions(+), 1 deletions(-)

src/stage1/codegen.cpp+18-1
...@@ -428,8 +428,18 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {...@@ -428,8 +428,18 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
428 // compiler as we're telling LLVM (using 'wasm-import-name' and428 // compiler as we're telling LLVM (using 'wasm-import-name' and
429 // 'wasm-import-name') what the real function name is and where to find429 // 'wasm-import-name') what the real function name is and where to find
430 // it.430 // it.
431 const bool use_mangled_name = target_is_wasm(g->zig_target) &&431 bool use_mangled_name = target_is_wasm(g->zig_target) &&
432 fn_proto->is_extern && fn_proto->lib_name != nullptr;432 fn_proto->is_extern && fn_proto->lib_name != nullptr;
433 // This is subtle but important to match libc symbols at static link time correctly.
434 // We treat "c" lib_name as a special library indicating that it should be defined
435 // in libc. But if we mangle a libc symbol name here with "c" module name, then wasm-ld cannot resolve
436 // the symbol. This is because at the static link time with wasm-ld, the linker does not
437 // take module names into account, and instead looking for a pure symbol name (i.e. function name)
438 // written into the ".linking" custom section (i.e. it does not use import section).
439 // This is the intended behavior of wasm-ld, because Wasm has a concept of host functions,
440 // which are undefined functions supposed to be resolved by host runtimes *with module names*
441 // at load times even if it is "static linked" with the linker.
442 use_mangled_name = use_mangled_name && (strcmp(buf_ptr(fn_proto->lib_name), "c") != 0);
433 // Pick a weird name to avoid collisions...443 // Pick a weird name to avoid collisions...
434 // This whole function should be burned to the ground.444 // This whole function should be burned to the ground.
435 Buf *mangled_symbol_buf = use_mangled_name ?445 Buf *mangled_symbol_buf = use_mangled_name ?
...@@ -452,6 +462,13 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {...@@ -452,6 +462,13 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) {
452 llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type);462 llvm_fn = LLVMAddFunction(g->module, symbol_name, fn_llvm_type);
453463
454 if (use_mangled_name) {464 if (use_mangled_name) {
465 // Note that "wasm-import-module"ed symbols will not be resolved
466 // in the future version of wasm-ld since the attribute basically means that
467 // "the symbol should be resolved at load time by runtimes", though
468 // the symbol is already mangled here and it is written into "linking" section
469 // used by wasm-ld to match symbols, so it should not be expected by users.
470 // tl;dr is that users should not put the lib_name specifier on extern statements
471 // if they want to link symbols with wasm-ld.
455 addLLVMFnAttrStr(llvm_fn, "wasm-import-name", unmangled_name);472 addLLVMFnAttrStr(llvm_fn, "wasm-import-name", unmangled_name);
456 addLLVMFnAttrStr(llvm_fn, "wasm-import-module", buf_ptr(fn_proto->lib_name));473 addLLVMFnAttrStr(llvm_fn, "wasm-import-module", buf_ptr(fn_proto->lib_name));
457 }474 }