@@ -3438,6 +3438,32 @@ fn add_lld_args(
3438
3438
// this, `wasm-component-ld`, which is overridden if this option is passed.
3439
3439
if !sess. target . is_like_wasm {
3440
3440
cmd. cc_arg ( "-fuse-ld=lld" ) ;
3441
+
3442
+ // GNU ld and LLD have opposite defaults on some section garbage-collection features. For
3443
+ // example, the somewhat popular `linkme` crate and its dependents rely in practice on this
3444
+ // difference: when using lld, they need `-z nostart-stop-gc` to prevent encapsulation
3445
+ // symbols and sections from being garbage-collected.
3446
+ //
3447
+ // More information about all this can be found in:
3448
+ // - https://maskray.me/blog/2021-01-31-metadata-sections-comdat-and-shf-link-order
3449
+ // - https://lld.llvm.org/ELF/start-stop-gc
3450
+ //
3451
+ // So when using lld, we restore, for now, the traditional behavior to help migration, but
3452
+ // will remove it in the future.
3453
+ // Since this only disables an optimization, it shouldn't create issues, but is in theory
3454
+ // slightly suboptimal. However, it:
3455
+ // - doesn't have any visible impact on our benchmarks
3456
+ // - reduces the need to disable lld for the crates that depend on this
3457
+ //
3458
+ // Note that lld can detect some cases where this difference is relied on, and emits a
3459
+ // dedicated error to add this link arg. We could make use of this error to emit an FCW. As
3460
+ // of writing this, we don't do it, because lld is already enabled by default on nightly
3461
+ // without this mitigation: no working project would see the FCW, so we do this to help
3462
+ // stabilization.
3463
+ //
3464
+ // FIXME: emit an FCW if linking fails due its absence, and then remove this link-arg in the
3465
+ // future.
3466
+ cmd. link_arg ( "-znostart-stop-gc" ) ;
3441
3467
}
3442
3468
3443
3469
if !flavor. is_gnu ( ) {
0 commit comments