-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
wasm32-wasip1 depends on libc memset with no_std #130621
Comments
Have you tried compiling for the wasm32-unknown-unknown target? For the wasm32-wasip1 target memset comes from wasi-libc which you're disabling here through |
Is there documentation anywhere on wasi-libc being included as part of rust or the wasi spec? Here is
|
Documentation not really, but that's sort of the defining feature of the wasip1 target is that it's using WASI APIs through wasi-libc. In that sense I suspect that the documentation you seek may not exist. |
I would have not expected this behavior at all. Looks like wasm-unknown-unknown is the correct target for me but I didn't even realize wasi-libc was a thing until mentioned here. Its not even listed in the WASI-proposals |
What would be the best place for this documentation? |
Looks like clang++ does the same thing with similar c++ code. extern "C" void _start() {
int a[255] = {0};
} $ clang++ --target=wasm32 -flto -nostdlib -Wl,--no-entry -Wl,--export-all -o test.wasm test.cpp
wasm-ld: error: lto.tmp: undefined symbol: memset
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
$ clang++ --version
clang version 18.1.8
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin |
As to where to document this, I'm not sure! The behavior you're describing here matches native platforms as well, for example
It's more common than not that libc provides |
Maybe the WASI specification should state something about it? I think a few things need to happen here (just thoughts, open to ideas):
I've never had to care about libc and things like memset because it always just worked but I'm probably not going to be the first one to come across this behavior. |
Rustc doesn't because we pass rust/compiler/rustc_target/src/spec/base/wasm.rs Lines 31 to 40 in 74fd001
It does on targets where libc is expected to not be used like wasm32-unknown-unknown.
No, emscripten has it's own libc that provides memset.
Only for languages that natively interface with C. There are also AssemblyScript, the wasm port of C#, TeaVM (compiling Java to wasm), Hoot (compiling a Scheme to wasm) and more which do not use any libc. |
If you didn't have to care about it, that is almost certainly because you didn't use |
@bjorn3 awesome, thank you for the information, this is what I was looking for from the start. I'd like to possibly put this information somewhere but I don't believe rust has any official documentation on wasm stuff (or target specific behavior). I did find this: https://github.com/rustwasm/book Maybe a PR against this repo would be ideal for now? |
@bjorn3 I've been thinking about this and researching more since our last discussion. This is more than a documentation bug IMO. This should never be generated code for a WASI target because its not part of the WASI specification.
The truth is both rustc and clang generate this import when there is no standard library present. I'm assuming there are probably a handful of corner cases where libc methods are leaking through like this. I'm going to experiment and see if others work around this (wasi-sdk and emscripten). |
The wasm32-wasip1 target is meant to be used with wasi-libc, which provides memset. We document that memset and such are required by all rust code: https://doc.rust-lang.org/stable/core/#how-to-use-the-core-library For all targets where no libc is ever used, compiler-builtins provides these symbols, but on those where libc is used, like wasm32-wasip1, this is not possible however as the definitions in compiler-builtins would conflict with libc. |
It looks like this is the case because we can't separate with That link above about the core library is very useful information, thank you. I was under the assumption with my example above core isn't being used since there are no "imports" (using statements). |
It's not just libcore that needs memset and co. It is any LLVM or GCC compiled code that doesn't explicitly disable the dependency on compiler-builtins. And in addition rustc itself emits memcpy calls for every copy and move larger than two registers (though compiler backends may optimize this away in case of small copies). |
This might be a specific problem to clang/llvm and wasi-sdk from: https://doc.rust-lang.org/beta/rustc/platform-support/wasm32-unknown-unknown.html#requirements
From what I can see, (I'm still in process of verifying this). wasi-sdk provides a |
I've looked high and low between the WASM/WASI specifications and can't find what is the "correct" behavior here but the current rust behavior seems wrong to me.
I don't believe we should be trying to import memset from the "env" module:
wasm3 engine can't run this code either due to this:
Code
Cargo.toml
.cargo/config.toml
Meta
rustc --version --verbose
:wasm generated binary
The text was updated successfully, but these errors were encountered: