-
-
Notifications
You must be signed in to change notification settings - Fork 14.1k
rustc: Stop passing --allow-undefined on wasm targets
#149868
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
base: main
Are you sure you want to change the base?
Conversation
This commit updates how the linker is invoked on WebAssembly targets
(all of them) to avoid passing the `--allow-undefined` flag to the
linker. Historically, if I remember this correctly, when `wasm-ld` was
first integrated this was practically required because at the time it
was otherwise impossible to import a function from the host into a wasm
binary. Or, at least, I'm pretty sure that was why this was added.
At the time, as the documentation around this option indicates, it was
known that this was going to be a hazard. This doesn't match behavior on
native, for example, and can easily paper over what should be a linker
error with some sort of other obscure runtime error. An example is that
this program currently compiles and links, it just prints null:
unsafe extern "C" {
static nonexistent: u8;
}
fn main() {
println!("{:?}", &raw const nonexistent);
}
This can easily lead to mistakes like rust-lang/libc/4880 and defer what
should be a compile-time link error to weird or unusual behavior at link
time. Additionally, in the intervening time since `wasm-ld` was first
introduced here, lots has changed and notably this program works as
expected:
#[link(wasm_import_module = "host")]
unsafe extern "C" {
fn foo();
}
fn main() {
unsafe {
foo();
}
}
Notably this continues to compile without error and the final wasm
binary indeed has an imported function from the host. What this change
means, however, is that this program:
unsafe extern "C" {
fn foo();
}
fn main() {
unsafe {
foo();
}
}
this currently compiles successfully and emits an import from the `env`
module. After this change, however, this will fail to compile with a
link error stating that the `foo` symbol is not defined.
|
These commits modify compiler targets. |
|
I'll clarify that process-wise I'm not exactly sure how to approach this. This is highly likely to break projects in practice but I don't know how to evaluate the quantity or breadth of breakage. If it's possible to do a wasm crater run or something like that I'd be happy to triage the results and/or send PRs to upstream projects. In the meantime though I wanted to get this on the radar as I should have done this ~years ago and it's long overdue that this change is made for wasm (my fault) |
|
It should be possible to run Crater with a custom target (https://github.com/rust-lang/crater/blob/master/docs/bot-usage.md#specifying-toolchains). I'll kick off a try job with the right artifacts (I think) at least. I'm not sure how much that will actually be helpful though in terms of what % of crates are actually supposed to build and do build for wasm32. One thought is that we could possibly phase this in for at least the wasi targets with the next preview (p4?) assuming that is coming down the line, or in theory with an edition of the leaf crate, but neither feel like amazing options. One other thought is that we could maybe FCW lint if we run the linker without --allow-undefined and if that fails re-run again with it, and if that works then emit a lint? Not sure how reliable the failure is. @bors try jobs=dist-x86_64-linux,dist-various-* |
This comment has been minimized.
This comment has been minimized.
rustc: Stop passing `--allow-undefined` on wasm targets try-job: dist-x86_64-linux try-job: dist-various-*
|
Oh nice! I'll attempt that here and see how it goes... @craterbot run start=master#f5209000832c9d3bc29c91f4daef4ca9f28dc797+target=wasm32-wasip1 end=try#23647e694de8d0904848ad068b2e0ec2dd098c37+target=wasm32-wasip1 mode=build-only
Agreed! I figure we can await the crater results and see if that provides a good signal of which path to take here, as I don't feel I have a great gut feeling myself here. |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
This commit updates how the linker is invoked on WebAssembly targets (all of them) to avoid passing the
--allow-undefinedflag to the linker. Historically, if I remember this correctly, whenwasm-ldwas first integrated this was practically required because at the time it was otherwise impossible to import a function from the host into a wasm binary. Or, at least, I'm pretty sure that was why this was added.At the time, as the documentation around this option indicates, it was known that this was going to be a hazard. This doesn't match behavior on native, for example, and can easily paper over what should be a linker error with some sort of other obscure runtime error. An example is that this program currently compiles and links, it just prints null:
This can easily lead to mistakes like rust-lang/libc#4880 and defer what should be a compile-time link error to weird or unusual behavior at link time. Additionally, in the intervening time since
wasm-ldwas first introduced here, lots has changed and notably this program works as expected:Notably this continues to compile without error and the final wasm binary indeed has an imported function from the host. What this change means, however, is that this program:
this currently compiles successfully and emits an import from the
envmodule. After this change, however, this will fail to compile with a link error stating that thefoosymbol is not defined.