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.
Pass -pg to linker when using -Zinstrument-mcount
This selects a slightly different crt on gnu targets which enables the profiler within glibc.
This makes using gprof a little easier with Rust binaries. Otherwise, rustc must be passed `-Clink-args=-pg` to ensure the correct startup code is linked.
Both zstd and zlib are *known* compression algorithms, they just may not
be supported by the backend. We shouldn't mislead users into e.g.
thinking they made a typo.
When encountering an unmet predicate, when we point at the trait impls that do exist, if they are all for the same self type, tweak the wording to make it less verbose.
sess: `-Zbranch-protection` is a target modifier
`-Zbranch-protection` only makes sense if the entire crate graph has the option set, otherwise the security properties that branch protection provides won't be effective - hence a target modifier. This flag is unstable so I don't think this warrants an MCP.
Use a proc macro to observe the incremental session directory and do
something platform specific so that renaming the '-working' session
directory during finalize_session_directory will fail. On Unix,
change the permissions on the parent directory to be read-only. On
Windows, open and leak a file inside the `-working` directory.
LLVM does not support host feature detection (only host cpu
detection) on apple platforms. As such, the returned feature
string will be empty. Adding this empty string to the target-features
attribute results in a verifier error on LLVM 22.
Fix this by not adding the empty string to the target features.
The reason why this was not caught by the target-cpu-native test
is that it requires a function that adds *some* target features,
otherwise the attribute is omitted entirely. We achieve this with
a somewhat peculiar construction that enables `neon` if it's
already enabled. (This is to avoid enabling it on softfloat targets.)
Clang and gcc use this option to control linking behavior too. Some
targets need to be linked against a special crt which enables
profiling at runtime.
This makes using gprof a little easier with Rust binaries. Otherwise,
rustc must be passed `-Clink-args=-pg` to ensure the correct startup
code is linked.
rustdoc: rename `--emit` names
These new names are pithier and match up with the rest of our terminology:
- `--emit=html-static-files` matches the default name of the directory that it actually emits, which is `static.files` (the hyphen is used for emit because every other emit option uses hyphens, but the directory uses a dot because we don't want its name to conflict with a crate).
- `--emit=html-non-static-files` matches the convention that emit is a noun, not an adjective, and it logically groups with other data formats.
This commit changes the docs, but leaves in support for the old names, to break the cycle with cargo and docs.rs. This commit needs merged, then cargo and docs.rs will be updated to use the new names, then, finally, the old names will be removed.
CC https://github.com/rust-lang/rust/pull/146220#issuecomment-3976454076
These new names are pithier and match up with the rest of our
terminology:
- `--emit=html-static-files` matches the default name of the directory that
it actually emits, which is `static.files` (the hyphen is used for
emit because every other emit option uses hyphens, but the directory
uses a dot because we don't want its name to conflict with a crate).
- `--emit=html-non-static-files` matches the convention that emit is a noun,
not an adjective. It also matches up with static-files, and it
logically groups with other data formats.
This commit changes the docs, but leaves in support for the old names,
to break the cycle with cargo and docs.rs. This commit needs merged,
then cargo and docs.rs will be updated to use the new names, then,
finally, the old names will be removed.
`-Zbranch-protection` only makes sense if the entire crate graph has
the option set, otherwise the security properties that branch protection
provides won't be effective. This flag is unstable so I don't think this
warrants an MCP.
- 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
Cleanup of c-variadic link test
Some changes pulled out of https://github.com/rust-lang/rust/pull/152980 that are just cosmetic, but will help make the code run on embedded targets.
r? jieyouxu
rustdoc: make `--emit` and `--out-dir` mimic rustc
The behavior in the test case matches rustc's:
test-dingus % ls
main.rs
test-dingus % mkdir foobar
test-dingus % rustc --emit=dep-info main.rs --out-dir=foobar
test-dingus % ls
foobar main.rs
test-dingus % ls foobar
main.d
test-dingus % rustc --emit=dep-info=testfile.d main.rs --out-dir=foobar
test-dingus % ls
foobar main.rs testfile.d
test-dingus % ls foobar
main.d
CC https://github.com/rust-lang/rust/pull/146220#issuecomment-3936957755
The behavior in the test case matches rustc's:
test-dingus % ls
main.rs
test-dingus % mkdir foobar
test-dingus % rustc --emit=dep-info main.rs --out-dir=foobar
test-dingus % ls
foobar main.rs
test-dingus % ls foobar
main.d
test-dingus % rustc --emit=dep-info=testfile.d main.rs --out-dir=foobar
test-dingus % ls
foobar main.rs testfile.d
test-dingus % ls foobar
main.d
As far as I can tell it was introduced to allow fat LTO with
-Clinker-plugin-lto. Later a change was made to automatically disable
ThinLTO summary generation when -Clinker-plugin-lto -Clto=fat is used,
so we can safely remove it.
Remove "failed to resolve" and use the same format we use in other resolution errors "cannot find `name`".
```
error[E0433]: cannot find `nonexistent` in `existent`
--> $DIR/custom_attr_multisegment_error.rs:5:13
|
LL | #[existent::nonexistent]
| ^^^^^^^^^^^ could not find `nonexistent` in `existent`
```
Set crt_static_allow_dylibs to true for Emscripten target
And add a test. This is followup work to rust-lang/rust#151704. It introduced a regression where cargo is now unwilling to build cdylibs for Emscripten because `crt_static_default` is `true` but `crt_static_allows_dylibs` is `false`. Unfortunately the added test does not fail without the change because the validation logic is in Cargo, not in rustc. But it's good to have some coverage of this anyways.
Use fewer intermediate functions for short backtraces in queries
If we make sure that `compute_fn` in the query's vtable is actually named `__rust_begin_short_backtrace`, we can avoid the need for some additional intermediate functions and stack frames.
This is similar to how the `get_query_incr` and `get_query_non_incr` functions are actually named `__rust_end_short_backtrace`.
---
Before/after comparison: https://github.com/rust-lang/rust/pull/151739#issuecomment-3815432527
---
- Earlier draft of this PR: https://github.com/rust-lang/rust/pull/151719
- Introduction of this backtrace-trimming: https://github.com/rust-lang/rust/pull/108938
And add a test. This is followup work to PR 151704. It introduced a regression where
cargo is now unwilling to build cdylibs for Emscripten because `crt_static_default` is
`true` but `crt_static_allows_dylibs` is `false`. Unfortunately the added test does not
fail without the change because the validation logic is in Cargo, not in rustc. But it's
good to have some coverage of this anyways.
link modifier `export-symbols`: export all global symbols from selected uptream c static libraries
In order to be able to export symbols from a specified upstream C static library, I redesigned a solution that, compared to a previous PR rust-lang/rust#150335 I submitted, will not have any extra symbols leaking out.
The following points should be noted:
- This attribute will select and import the `Global` symbols of the first matching library it finds.
- Developers should ensure that there are no libraries with the same name.
- This modifier is only compatible with `static` linking kind
- By default, upstream C static libraries will not export their `Global` symbols regardless of whether `LTO` optimization is enabled. However, after enabling this attribute, if the upstream C static library has `LTO` optimization enabled, the compiler will issue an error to inform the developer that the linked C library is invalid.
The test code is the same as the PR rust-lang/rust#150335.
Here are the results:
1. `cargo +include-libs rustc --release -- -L. -lstatic:+export-symbols=c_add`
(or you can use `#[link(name = "c_add", kind= "static", modifier = "+export-symbols")]` in the file)
```bash
U abort@GLIBC_2.2.5
U bcmp@GLIBC_2.2.5
0000000000014f60 T c_add
U calloc@GLIBC_2.2.5
U close@GLIBC_2.2.5
0000000000014f70 T c_sub
w __cxa_finalize@GLIBC_2.2.5
w __cxa_thread_atexit_impl@GLIBC_2.18
U dl_iterate_phdr@GLIBC_2.2.5
0000000000014ee0 T downstream_add
U __errno_location@GLIBC_2.2.5
U free@GLIBC_2.2.5
U fstat64@GLIBC_2.33
U getcwd@GLIBC_2.2.5
U getenv@GLIBC_2.2.5
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U lseek64@GLIBC_2.2.5
U malloc@GLIBC_2.2.5
U memcpy@GLIBC_2.14
U memmove@GLIBC_2.2.5
U memset@GLIBC_2.2.5
U mmap64@GLIBC_2.2.5
U munmap@GLIBC_2.2.5
U open64@GLIBC_2.2.5
U posix_memalign@GLIBC_2.2.5
U pthread_key_create@GLIBC_2.34
U pthread_key_delete@GLIBC_2.34
U pthread_setspecific@GLIBC_2.34
U read@GLIBC_2.2.5
U readlink@GLIBC_2.2.5
U realloc@GLIBC_2.2.5
U realpath@GLIBC_2.3
U stat64@GLIBC_2.33
w statx@GLIBC_2.28
U strlen@GLIBC_2.2.5
U syscall@GLIBC_2.2.5
U __tls_get_addr@GLIBC_2.3
U _Unwind_Backtrace@GCC_3.3
U _Unwind_DeleteException@GCC_3.0
U _Unwind_GetDataRelBase@GCC_3.0
U _Unwind_GetIP@GCC_3.0
U _Unwind_GetIPInfo@GCC_4.2.0
U _Unwind_GetLanguageSpecificData@GCC_3.0
U _Unwind_GetRegionStart@GCC_3.0
U _Unwind_GetTextRelBase@GCC_3.0
U _Unwind_RaiseException@GCC_3.0
U _Unwind_Resume@GCC_3.0
U _Unwind_SetGR@GCC_3.0
U _Unwind_SetIP@GCC_3.0
U write@GLIBC_2.2.5
U writev@GLIBC_2.2.5
```
3. `cargo +nightly rustc --release -- -L ./`
```bash
U abort@GLIBC_2.2.5
U bcmp@GLIBC_2.2.5
U calloc@GLIBC_2.2.5
U close@GLIBC_2.2.5
w __cxa_finalize@GLIBC_2.2.5
w __cxa_thread_atexit_impl@GLIBC_2.18
U dl_iterate_phdr@GLIBC_2.2.5
0000000000011e10 T downstream_add
U __errno_location@GLIBC_2.2.5
U free@GLIBC_2.2.5
U fstat64@GLIBC_2.33
U getcwd@GLIBC_2.2.5
U getenv@GLIBC_2.2.5
w gettid@GLIBC_2.30
w __gmon_start__
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
U lseek64@GLIBC_2.2.5
U malloc@GLIBC_2.2.5
U memcpy@GLIBC_2.14
U memmove@GLIBC_2.2.5
U memset@GLIBC_2.2.5
U mmap64@GLIBC_2.2.5
U munmap@GLIBC_2.2.5
U open64@GLIBC_2.2.5
U posix_memalign@GLIBC_2.2.5
U pthread_key_create@GLIBC_2.34
U pthread_key_delete@GLIBC_2.34
U pthread_setspecific@GLIBC_2.34
U read@GLIBC_2.2.5
U readlink@GLIBC_2.2.5
U realloc@GLIBC_2.2.5
U realpath@GLIBC_2.3
U stat64@GLIBC_2.33
w statx@GLIBC_2.28
U strlen@GLIBC_2.2.5
U syscall@GLIBC_2.2.5
U __tls_get_addr@GLIBC_2.3
U _Unwind_Backtrace@GCC_3.3
U _Unwind_GetDataRelBase@GCC_3.0
U _Unwind_GetIP@GCC_3.0
U _Unwind_GetIPInfo@GCC_4.2.0
U _Unwind_GetLanguageSpecificData@GCC_3.0
U _Unwind_GetRegionStart@GCC_3.0
U _Unwind_GetTextRelBase@GCC_3.0
U _Unwind_RaiseException@GCC_3.0
U _Unwind_Resume@GCC_3.0
U _Unwind_SetGR@GCC_3.0
U _Unwind_SetIP@GCC_3.0
U write@GLIBC_2.2.5
U writev@GLIBC_2.2.5
```
r? @bjorn3