Skip to content

rust-lld links WebAssembly imports during compilation #56309

Closed

Description

@PiotrSikora

It appears that rust-lld links WebAssembly imports during compilation, even though they should be only imported at runtime.

Code

#[link(wasm_import_module = "test")]
extern "C" {
    fn log(message_data: u32, message_size: u32);
}

#[no_mangle]
pub fn main() {
    let message = "Hello, world!";
    unsafe {
        log(message.as_ptr() as u32, message.len() as u32);
    }
}

Cargo (stable)

Build succeeds:

$ cargo build --target=wasm32-unknown-unknown --release --verbose
   Compiling wasm-log v0.0.1 (/home/piotrsikora/wasm-log)
     Running `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps`
    Finished release [optimized] target(s) in 0.49s

but there are no imports in the compiled WASM module:

$ wasm-dis target/wasm32-unknown-unknown/release/wasm_log.wasm | grep import
<empty>

and it actually inlines some log() function (probably from compiler-builtins).

Cargo (nightly)

Build fails due to a conflict between WebAssembly import (test.log) and compiler-builtins's log():

$ cargo +nightly build --target=wasm32-unknown-unknown --release --verbose
   Compiling wasm-log v0.0.1 (/home/piotrsikora/wasm-log)
     Running `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps`
error: linking with `rust-lld` failed: exit code: 1
  |
  = note: "rust-lld" "-flavor" "wasm" "-L" "/home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib" "/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps/wasm_log.wasm_log.ch5ijyk4-cgu.0.rcgu.o" "-o" "/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps/wasm_log.wasm" "--export" "main" "--gc-sections" "-O3" "-L" "/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps" "-L" "/home/piotrsikora/wasm-log/target/release/deps" "-L" "/home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib" "/home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcompiler_builtins-e275954395f12431.rlib" "--no-threads" "-z" "stack-size=1048576" "--stack-first" "--allow-undefined" "--no-entry" "--export-table" "--fatal-warnings"
  = note: rust-lld: error: function signature mismatch: log
          >>> defined as (I32, I32) -> void in /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps/wasm_log.wasm_log.ch5ijyk4-cgu.0.rcgu.o
          >>> defined as (F64) -> F64 in /home/piotrsikora/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-unknown-unknown/lib/libcompiler_builtins-e275954395f12431.rlib(compiler_builtins-e275954395f12431.compiler_builtins.2709pw9r-cgu.0.rcgu.o)


error: aborting due to previous error

error: Could not compile `wasm-log`.

Caused by:
  process didn't exit successfully: `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps` (exit code: 1)

Workaround

Simply changing the function name, either directly or by using #[link_name = "xlog"], to avoid the conflict works around the issue, but that's obviously far from perfect.

#[link(wasm_import_module = "test")]
extern "C" {
    #[link_name = "xlog"]
    fn log(message_data: u32, message_size: u32);
}

#[no_mangle]
pub fn main() {
    let message = "Hello, world!";
    unsafe {
        log(message.as_ptr() as u32, message.len() as u32);
    }
}
$ cargo +nightly build --target=wasm32-unknown-unknown --release --verbose
   Compiling wasm-log v0.0.1 (/home/piotrsikora/wasm-log)
     Running `rustc --crate-name wasm_log src/lib.rs --color always --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C panic=abort -C lto -C metadata=974cbcc98065209d --out-dir /home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps --target wasm32-unknown-unknown -L dependency=/home/piotrsikora/wasm-log/target/wasm32-unknown-unknown/release/deps -L dependency=/home/piotrsikora/wasm-log/target/release/deps`
    Finished release [optimized] target(s) in 0.36s
$ wasm-dis target/wasm32-unknown-unknown/release/wasm_log.wasm | grep import
 (import "test" "xlog" (func $xlog (param i32 i32)))

Version info

$ rustc --version --verbose
rustc 1.30.1 (1433507eb 2018-11-07)
binary: rustc
commit-hash: 1433507eba7d1a114e4c6f27ae0e1a74f60f20de
commit-date: 2018-11-07
host: x86_64-unknown-linux-gnu
release: 1.30.1
LLVM version: 8.0
$ rustc +nightly --version --verbose
rustc 1.32.0-nightly (6acbb5b65 2018-11-25)
binary: rustc
commit-hash: 6acbb5b65c06d82c867a94c54ce51dab4707ac61
commit-date: 2018-11-25
host: x86_64-unknown-linux-gnu
release: 1.32.0-nightly
LLVM version: 8.0

Activity

  1. alexcrichton commented on Nov 29, 2018

    @alexcrichton
    Member

    Thanks for the reprot! This is due to the fact that log is a built-in symbol for the mathematical log function. (this symbol is common across all platforms). As you've found though renaming does the trick!

  2. added
    A-linkageArea: linking into static, shared libraries and binaries
    O-wasmTarget: WASM (WebAssembly), http://webassembly.org/
    on Jan 27, 2019
  3. added a commit that references this issue on Dec 16, 2019
    aa0ef5a
  4. added a commit that references this issue on Dec 19, 2019
    74b1902
  5. added 2 commits that reference this issue on Dec 20, 2019
    8e9f09c
    43d1532
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-linkageArea: linking into static, shared libraries and binariesO-wasmTarget: WASM (WebAssembly), http://webassembly.org/

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions