Skip to content

Commit cf42371

Browse files
committed
Auto merge of #140872 - bjorn3:elf_use_used_linker, r=nikic
Make #[used(linker)] the default on ELF too `#[used]` currently is an alias for `#[used(linker)]` on all platforms except ELF based ones where it is an alias for `#[used(compiler)]`. The latter has surprising behavior and the LLVM LangRef explicitly states that it "should only be used in rare circumstances, and should not be exposed to source languages." [^2] The reason `#[used]` still was an alias to `#[used(compiler)]` on ELF is because the gold linker has issues with it. Luckily gold has been deprecated with GCC 15 [^1] and seems to be unable to bootstrap rustc anyway [^3]. As such we shouldn't really care about supporting gold. This would also allow re-enabling start-stop-gc with lld. cc #93798 Likely fixes #85045 [^1]: https://lists.gnu.org/archive/html/info-gnu/2025-02/msg00001.html [^2]: https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable [^3]: #139425
2 parents ccf3198 + f8e9778 commit cf42371

File tree

3 files changed

+13
-37
lines changed

3 files changed

+13
-37
lines changed

compiler/rustc_codegen_llvm/src/consts.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -541,12 +541,12 @@ impl<'ll> CodegenCx<'ll, '_> {
541541
// in the handling of `.init_array` (the static constructor list) in versions of
542542
// the gold linker (prior to the one released with binutils 2.36).
543543
//
544-
// That said, we only ever emit these when compiling for ELF targets, unless
545-
// `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
546-
// on other targets, in particular MachO targets have *their* static constructor
547-
// lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
548-
// that check happens when assigning the `CodegenFnAttrFlags` in
549-
// `rustc_hir_analysis`, so we don't need to take care of it here.
544+
// That said, we only ever emit these when `#[used(compiler)]` is explicitly
545+
// requested. This is to avoid similar breakage on other targets, in particular
546+
// MachO targets have *their* static constructor lists broken if `llvm.compiler.used`
547+
// is emitted rather than `llvm.used`. However, that check happens when assigning
548+
// the `CodegenFnAttrFlags` in the `codegen_fn_attrs` query, so we don't need to
549+
// take care of it here.
550550
self.add_compiler_used_global(g);
551551
}
552552
if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,7 +1961,7 @@ fn add_post_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor
19611961
/// This method creates a synthetic object file, which contains undefined references to all symbols
19621962
/// that are necessary for the linking. They are only present in symbol table but not actually
19631963
/// used in any sections, so the linker will therefore pick relevant rlibs for linking, but
1964-
/// unused `#[no_mangle]` or `#[used]` can still be discard by GC sections.
1964+
/// unused `#[no_mangle]` or `#[used(compiler)]` can still be discard by GC sections.
19651965
///
19661966
/// There's a few internal crates in the standard library (aka libcore and
19671967
/// libstd) which actually have a circular dependence upon one another. This
@@ -1995,7 +1995,8 @@ fn add_linked_symbol_object(
19951995

19961996
if file.format() == object::BinaryFormat::MachO {
19971997
// Divide up the sections into sub-sections via symbols for dead code stripping.
1998-
// Without this flag, unused `#[no_mangle]` or `#[used]` cannot be discard on MachO targets.
1998+
// Without this flag, unused `#[no_mangle]` or `#[used(compiler)]` cannot be
1999+
// discard on MachO targets.
19992000
file.set_subsections_via_symbols();
20002001
}
20012002

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -195,35 +195,10 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
195195
tcx.dcx().emit_err(errors::ExpectedUsedSymbol { span: attr.span() });
196196
}
197197
None => {
198-
// Unfortunately, unconditionally using `llvm.used` causes
199-
// issues in handling `.init_array` with the gold linker,
200-
// but using `llvm.compiler.used` caused a nontrivial amount
201-
// of unintentional ecosystem breakage -- particularly on
202-
// Mach-O targets.
203-
//
204-
// As a result, we emit `llvm.compiler.used` only on ELF
205-
// targets. This is somewhat ad-hoc, but actually follows
206-
// our pre-LLVM 13 behavior (prior to the ecosystem
207-
// breakage), and seems to match `clang`'s behavior as well
208-
// (both before and after LLVM 13), possibly because they
209-
// have similar compatibility concerns to us. See
210-
// https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146
211-
// and following comments for some discussion of this, as
212-
// well as the comments in `rustc_codegen_llvm` where these
213-
// flags are handled.
214-
//
215-
// Anyway, to be clear: this is still up in the air
216-
// somewhat, and is subject to change in the future (which
217-
// is a good thing, because this would ideally be a bit
218-
// more firmed up).
219-
let is_like_elf = !(tcx.sess.target.is_like_darwin
220-
|| tcx.sess.target.is_like_windows
221-
|| tcx.sess.target.is_like_wasm);
222-
codegen_fn_attrs.flags |= if is_like_elf {
223-
CodegenFnAttrFlags::USED_COMPILER
224-
} else {
225-
CodegenFnAttrFlags::USED_LINKER
226-
};
198+
// Unconditionally using `llvm.used` causes issues in handling
199+
// `.init_array` with the gold linker. Luckily gold has been
200+
// deprecated with GCC 15 and rustc now warns about using gold.
201+
codegen_fn_attrs.flags |= CodegenFnAttrFlags::USED_LINKER
227202
}
228203
}
229204
}

0 commit comments

Comments
 (0)