rustc: Stop passing `--allow-undefined` on wasm targets
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();
}
}
This continues to compile without error and the final wasm binary indeed has an imported function from the host. 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.
- Hide common linker output behind `linker-info`
- Add tests
- Account for different capitalization on windows-gnu when removing
"warning" prefix
- Add some more comments
- Add macOS deployment-target test
- Ignore linker warnings from trying to statically link glibc
I don't know what's going on in `nofile-limit.rs` but I want no part
of it.
- Use a fake linker so tests are platform-independent
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.
`tests/ui`: A New Order [0/28]
> [!NOTE]
>
> Intermediate commits are intended to help review, but will be squashed prior to merge.
These are the some last tests that didn’t make it into the main twenty-eightology of PRs. Part of rust-lang/rust#133895.
r? ```@jieyouxu```
use `--dynamic-list` for exporting executable symbols
closesrust-lang/rust#101610
cc rust-lang/rust#84161https://sourceware.org/binutils/docs-2.39/ld/VERSION.html:
> --dynamic-list=dynamic-list-file
Specify the name of a dynamic list file to the linker. This is typically used when creating shared libraries to specify a list of global symbols whose references shouldn’t be bound to the definition within the shared library, or creating dynamically linked executables to specify a list of symbols which should be added to the symbol table in the executable. This option is only meaningful on ELF platforms which support shared libraries.
`ld.lld --help`:
> --dynamic-list=<file>: Similar to --export-dynamic-symbol-list. When creating a shared object, this additionally implies -Bsymbolic but does not set DF_SYMBOLIC
> --export-dynamic-symbol-list=file: Read a list of dynamic symbol patterns. Apply --export-dynamic-symbol on each pattern
> --export-dynamic-symbol=glob: (executable) Put matched symbols in the dynamic symbol table. (shared object) References to matched non-local STV_DEFAULT symbols shouldn't be bound to definitions within the shared object. Does not imply -Bsymbolic.
> --export-dynamic: Put symbols in the dynamic symbol table
Use `--dynamic-list` because it's older than `--export-dynamic-symbol-list` (binutils 2.35)
try-job: dist-i586-gnu-i586-i686-musl
- update existing tests for stabilization
- ensure `-Clink-self-contained=-linker` is only stable on x64 linux
- test invalid `-Clink-self-contained` components