diff options
| author | Thom Chiovoloni <chiovolonit@gmail.com> | 2022-02-06 13:51:11 -0800 |
|---|---|---|
| committer | Thom Chiovoloni <chiovolonit@gmail.com> | 2022-05-11 01:29:56 -0700 |
| commit | 54133cfcf49c68886a7cd8046007ea14e3d3944d (patch) | |
| tree | 09f22cb6e789c937d4edccc8f8450b0328d31efe | |
| parent | ecd44958e0a21110d09862ee080d95a4ca6c52f8 (diff) | |
| download | rust-54133cfcf49c68886a7cd8046007ea14e3d3944d.tar.gz rust-54133cfcf49c68886a7cd8046007ea14e3d3944d.zip | |
Only compile #[used] as llvm.compiler.used for ELF targets
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/consts.rs | 36 | ||||
| -rw-r--r-- | compiler/rustc_codegen_ssa/src/traits/statics.rs | 4 |
2 files changed, 36 insertions, 4 deletions
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs index 4d3f3f318b8..98b412f9397 100644 --- a/compiler/rustc_codegen_llvm/src/consts.rs +++ b/compiler/rustc_codegen_llvm/src/consts.rs @@ -535,11 +535,41 @@ impl<'ll> StaticMethods for CodegenCx<'ll, '_> { // The semantics of #[used] in Rust only require the symbol to make it into the // object file. It is explicitly allowed for the linker to strip the symbol if it - // is dead. As such, use llvm.compiler.used instead of llvm.used. + // is dead, which means we are allowed use `llvm.compiler.used` instead of + // `llvm.used` here. + // // Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique // sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs - // in some versions of the gold linker. - self.add_compiler_used_global(g); + // in the handling of `.init_array` (the static constructor list) in versions of + // the gold linker (prior to the one released with binutils 2.36). + // + // However, unconditional use of `llvm.compiler.used` caused a nontrivial amount of + // ecosystem breakage, especially on Mach-O targets. To resolve this, we compile it + // as llvm.used on ELF targets and llvm.compiler.used elsewhere, which and should be + // equivalent to how we compiled `#[used]` before LLVM 13, as `llvm.used` and + // `llvm.compiler.used` were treated the same on ELF targets prior in earlier LLVM + // versions (additionally, it seems to be how Clang handles `__attribute__((used))`, + // perhaps for similar compatibility-motivated reasons). + // + // See https://github.com/rust-lang/rust/issues/47384#issuecomment-1019080146 and + // following comments for some discussion of this. + // + // The final wrinkle is it's not really clear how to tell if we're going to output + // ELF, so it's been approximated as "not like wasm, osx, or windows", which is + // not exactly correct, but is pretty close and hopefully handles all the platforms + // platforms where old versions of `ld.gold` are likely to show up. + // + // All this is subject to change in the future. Which is a good thing, because this + // probably should be firmed up somehow! + let seems_like_elf = !(self.tcx.sess.target.is_like_osx + || self.tcx.sess.target.is_like_windows + || self.tcx.sess.target.is_like_wasm); + + if seems_like_elf { + self.add_compiler_used_global(g); + } else { + self.add_used_global(g); + } } if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) { // `USED` and `USED_LINKER` can't be used together. diff --git a/compiler/rustc_codegen_ssa/src/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs index a2a3cb56c78..413d31bb942 100644 --- a/compiler/rustc_codegen_ssa/src/traits/statics.rs +++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs @@ -13,7 +13,9 @@ pub trait StaticMethods: BackendTypes { /// Same as add_used_global(), but only prevent the compiler from potentially removing an /// otherwise unused symbol. The linker is still permitted to drop it. /// - /// This corresponds to the semantics of the `#[used]` attribute. + /// This corresponds to the documented semantics of the `#[used]` attribute, although + /// on some targets (non-ELF), we may use `add_used_global` for `#[used]` statics + /// instead. fn add_compiler_used_global(&self, global: Self::Value); } |
