Rollup merge of #137685 - lqd:nostart-stop-gc, r=petrochenkov
self-contained linker: conservatively default to `-znostart-stop-gc` on x64 linux To help stabilization, this PR disables an LLD optimization on x64 linux with respect to `--gc-sections` and encapsulation symbols: it will reduce the number of crates needing to opt-out of lld due to this bfd / lld difference. For example, all the people using [linkme](https://github.com/dtolnay/linkme), which [doesn't work with lld](https://github.com/dtolnay/linkme/issues/63) or on nightly, need to disable lld. More information about all this, and the historical differences, can be found in: - https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order - https://lld.llvm.org/ELF/start-stop-gc This optimization has [no visible impact](https://github.com/rust-lang/rust/pull/137685#issuecomment-2686116312) on our benchmarks, so we can use it by default and have a safer/more conservative starting point to remove friction during migration. We can them emit an FCW for the cases where lld detects reliance on encapsulation symbols without `-znostart-stop-gc`, and then revert back to lld's default after a while. No one compiling on nightly relies on this difference, obviously, so doing an FCW is not necessary until after lld is used on stable. I've tested that this correctly links on `linkme` examples. I've also quickly tried to crate an rmake test but the setup with encapsulation symbols is annoying to reproduce: a few link section/name attributes is not enough, we also need to collect symbols between the encapsulation symbols, without referencing them in code, for `-znostart-stop-gc` to only impact this... It should of course be doable though, maybe ````@Kobzol```` will look into it if they have time. r? ````@petrochenkov````
This commit is contained in:
commit
dfae8e8e4c
1 changed files with 29 additions and 0 deletions
|
@ -3382,6 +3382,35 @@ fn add_lld_args(
|
||||||
// this, `wasm-component-ld`, which is overridden if this option is passed.
|
// this, `wasm-component-ld`, which is overridden if this option is passed.
|
||||||
if !sess.target.is_like_wasm {
|
if !sess.target.is_like_wasm {
|
||||||
cmd.cc_arg("-fuse-ld=lld");
|
cmd.cc_arg("-fuse-ld=lld");
|
||||||
|
|
||||||
|
// On ELF platforms like at least x64 linux, GNU ld and LLD have opposite defaults on some
|
||||||
|
// section garbage-collection features. For example, the somewhat popular `linkme` crate and
|
||||||
|
// its dependents rely in practice on this difference: when using lld, they need `-z
|
||||||
|
// nostart-stop-gc` to prevent encapsulation symbols and sections from being
|
||||||
|
// garbage-collected.
|
||||||
|
//
|
||||||
|
// More information about all this can be found in:
|
||||||
|
// - https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order
|
||||||
|
// - https://lld.llvm.org/ELF/start-stop-gc
|
||||||
|
//
|
||||||
|
// So when using lld, we restore, for now, the traditional behavior to help migration, but
|
||||||
|
// will remove it in the future.
|
||||||
|
// Since this only disables an optimization, it shouldn't create issues, but is in theory
|
||||||
|
// slightly suboptimal. However, it:
|
||||||
|
// - doesn't have any visible impact on our benchmarks
|
||||||
|
// - reduces the need to disable lld for the crates that depend on this
|
||||||
|
//
|
||||||
|
// Note that lld can detect some cases where this difference is relied on, and emits a
|
||||||
|
// dedicated error to add this link arg. We could make use of this error to emit an FCW. As
|
||||||
|
// of writing this, we don't do it, because lld is already enabled by default on nightly
|
||||||
|
// without this mitigation: no working project would see the FCW, so we do this to help
|
||||||
|
// stabilization.
|
||||||
|
//
|
||||||
|
// FIXME: emit an FCW if linking fails due its absence, and then remove this link-arg in the
|
||||||
|
// future.
|
||||||
|
if sess.target.llvm_target == "x86_64-unknown-linux-gnu" {
|
||||||
|
cmd.link_arg("-znostart-stop-gc");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !flavor.is_gnu() {
|
if !flavor.is_gnu() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue