Skip to content

rust-lld links WebAssembly imports during compilation #56309

Closed
@PiotrSikora

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

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