Closed
Description
It is currently impossible to generate a Wasm module that imports/exports a shared memory using a Rust program. Here is the example program I'm using (though this is not a terribly important detail):
#[no_mangle]
pub extern "C" fn foo(buffer: &mut [u8]) {
buffer[0] = 42;
}
Using rustc
we quickly realize that we need the standard library to be re-compiled:
rustc
failure
$ rustc kernel.rs --target wasm32-wasi --crate-type=cdylib -o kernel.wasm -C link-args="--shared-memory" -C target-feature='+atomics,+bulk-memory'
warning: `extern` fn uses type `[u8]`, which is not FFI-safe
--> kernel.rs:2:31
|
2 | pub extern "C" fn foo(buffer: &mut [u8]) {
| ^^^^^^^^^ not FFI-safe
|
= note: `#[warn(improper_ctypes_definitions)]` on by default
= help: consider using a raw pointer instead
= note: slices have no C equivalent
error: linking with `rust-lld` failed: exit status: 1
|
= note: "rust-lld" "-flavor" "wasm" "--rsp-quoting=posix" "--export" "foo" "--export=__heap_base" "--export=__data_end" "-z" "stack-size=1048576" "--stack-first" "--allow-undefined" "--fatal-warnings" "--no-demangle" "kernel.kernel.60cb7d37-cgu.0.rcgu.o" "kernel.48d2wi2ixzyq818c.rcgu.o" "-L" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libstd-6f7050c4e4ec9320.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libpanic_abort-78698fb72740e3b3.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libwasi-b308087294ddc3a3.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/librustc_demangle-c3cb9e7f51bfddcf.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libstd_detect-86a001d569055eb2.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libhashbrown-e91bcb3cc72b7036.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libminiz_oxide-4b07e23d8098c45f.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libadler-532bcb16b36dcd82.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/librustc_std_workspace_alloc-bbe752709827e6d6.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libunwind-91f05440fcb54365.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libcfg_if-a5e499ce0ca89889.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/liblibc-1174a7249caf0203.rlib" "-l" "c" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/liballoc-3540f6751174d304.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/librustc_std_workspace_core-7699117473607845.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libcore-918655349c5fe03e.rlib" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/libcompiler_builtins-b340a4e3801671de.rlib" "-L" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib" "-L" "/.../.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/wasm32-wasi/lib/self-contained" "-o" "kernel.wasm" "--gc-sections" "--no-entry" "-O0" "--shared-memory"
= note: rust-lld: error: --shared-memory is disallowed by std-6f7050c4e4ec9320.std.91000efc-cgu.0.rcgu.o because it was not compiled with 'atomics' or 'bulk-memory' features.
error: aborting due to previous error; 1 warning emitted
To re-compile the standard library, I stick the kernel into a Cargo project but unfortunately the re-compile fails:
cargo
failure
$ tree kernel
kernel
├── Cargo.lock
├── Cargo.toml
└── src
└── lib.rs -> ../../kernel.rs
$ cd kernel
$ cat Cargo.toml | grep cdylib
crate-type = ["cdylib"]
$ RUSTFLAGS="-C target-feature=+atomics,+bulk-memory -C link-args=--shared-memory" cargo +nightly build --target wasm32-wasi --release -Z build-std
Compiling std v0.0.0 (/.../.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std)
error[E0432]: unresolved import `crate::sys::futex`
--> /.../.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys_common/thread_parker/futex.rs:4:17
|
4 | use crate::sys::futex::{futex_wait, futex_wake};
| ^^^^^ could not find `futex` in `sys`
error[E0425]: cannot find function `env_lock` in this scope
--> /.../.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/wasi/os.rs:149:22
|
149 | let _guard = env_lock();
| ^^^^^^^^ not found in this scope
error[E0425]: cannot find function `env_lock` in this scope
--> /.../.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/wasi/os.rs:181:22
|
181 | let _guard = env_lock();
| ^^^^^^^^ not found in this scope
error[E0425]: cannot find function `env_lock` in this scope
--> /.../.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/wasi/os.rs:196:22
|
196 | let _guard = env_lock();
| ^^^^^^^^ not found in this scope
error[E0425]: cannot find function `env_lock` in this scope
--> /.../.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/wasi/os.rs:205:22
|
205 | let _guard = env_lock();
| ^^^^^^^^ not found in this scope
Some errors have detailed explanations: E0425, E0432.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `std` due to 5 previous errors
I would have expected that to succeed (as documented in #77839). I think I've identified the places that would need to be fixed in the standard library but I wanted to document this issue here first; perhaps there is something I missed? Here are the versions I used above:
$ cargo --version
cargo 1.63.0 (fd9c4297c 2022-07-01)
$ rustc --version
rustc 1.63.0 (4b91a6ea7 2022-08-08)