Skip to content

Commit 7c01564

Browse files
committed
Use llvm.compiler.used insetad of llvm.used
The #[used] attribute explicitly only requires symbols to be retained in object files, but allows the linker to drop them if dead. This corresponds to llvm.compiler.used semantics. The motivation to change this *now* is that https://reviews.llvm.org/D97448 starts emitting #[used] symbols into unique sections with SHF_GNU_RETAIN flag. This triggers a bug in some version of gold, resulting in the ARGV_INIT_ARRAY symbol part of the .init_array section to be incorrectly placed.
1 parent 154c840 commit 7c01564

File tree

5 files changed

+16
-8
lines changed

5 files changed

+16
-8
lines changed

compiler/rustc_codegen_llvm/src/base.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,12 @@ pub fn compile_codegen_unit(
157157
}
158158

159159
// Finalize code coverage by injecting the coverage map. Note, the coverage map will
160-
// also be added to the `llvm.used` variable, created next.
160+
// also be added to the `llvm.compiler.used` variable, created next.
161161
if cx.sess().instrument_coverage() {
162162
cx.coverageinfo_finalize();
163163
}
164164

165-
// Create the llvm.used variable
165+
// Create the llvm.compiler.used variable
166166
// This variable has type [N x i8*] and is stored in the llvm.metadata section
167167
if !cx.used_statics().borrow().is_empty() {
168168
cx.create_used_variable()

compiler/rustc_codegen_llvm/src/consts.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ impl StaticMethods for CodegenCx<'ll, 'tcx> {
479479
}
480480
}
481481

482-
/// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*.
482+
/// Add a global value to a list to be stored in the `llvm.compiler.used` variable, an array of i8*.
483483
fn add_used_global(&self, global: &'ll Value) {
484484
let cast = unsafe { llvm::LLVMConstPointerCast(global, self.type_i8p()) };
485485
self.used_statics.borrow_mut().push(cast);

compiler/rustc_codegen_llvm/src/context.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ pub struct CodegenCx<'ll, 'tcx> {
7171
/// to constants.)
7272
pub statics_to_rauw: RefCell<Vec<(&'ll Value, &'ll Value)>>,
7373

74-
/// Statics that will be placed in the llvm.used variable
75-
/// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
74+
/// Statics that will be placed in the llvm.compiler.used variable
75+
/// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
7676
pub used_statics: RefCell<Vec<&'ll Value>>,
7777

7878
/// Mapping of non-scalar types to llvm types and field remapping if needed.
@@ -447,7 +447,13 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
447447
}
448448

449449
fn create_used_variable(&self) {
450-
let name = cstr!("llvm.used");
450+
// The semantics of #[used] in Rust only require the symbol to make it into the object
451+
// file. It is explicitly allowed for the linker to strip the symbol if it is dead.
452+
// As such, use llvm.compiler.used instead of llvm.used.
453+
// Additionally, https://reviews.llvm.org/D97448 in LLVM 13 started emitting unique
454+
// sections with SHF_GNU_RETAIN flag for llvm.used symbols, which may trigger bugs in
455+
// some versions of the gold linker.
456+
let name = cstr!("llvm.compiler.used");
451457
let section = cstr!("llvm.metadata");
452458
let array =
453459
self.const_array(&self.type_ptr_to(self.type_i8()), &*self.used_statics.borrow());

compiler/rustc_feature/src/accepted.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ declare_features! (
178178
/// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
179179
/// This defines the behavior of panics.
180180
(accepted, panic_handler, "1.30.0", Some(44489), None),
181-
/// Allows `#[used]` to preserve symbols (see llvm.used).
181+
/// Allows `#[used]` to preserve symbols (see llvm.compiler.used).
182182
(accepted, used, "1.30.0", Some(40289), None),
183183
/// Allows `crate` in paths.
184184
(accepted, crate_in_paths, "1.30.0", Some(45477), None),

src/test/run-make-fulldeps/coverage-llvmir/filecheck.testprog.txt

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ CHECK-SAME: section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
2828
CHECK: @__llvm_prf_nm = private constant
2929
CHECK-SAME: section "[[INSTR_PROF_NAME]]", align 1
3030

31-
CHECK: @llvm.used = appending global
31+
CHECK: @llvm.compiler.used = appending global
3232
CHECK-SAME: i8* bitcast ({ {{.*}} }* @__llvm_coverage_mapping to i8*)
3333
WINDOWS-SAME: i8* bitcast (i32 ()* @__llvm_profile_runtime_user to i8*)
34+
CHECK-SAME: section "llvm.metadata"
35+
CHECK: @llvm.used = appending global
3436
CHECK-SAME: i8* getelementptr inbounds ({{.*}}* @__llvm_prf_nm, i32 0, i32 0)
3537
CHECK-SAME: section "llvm.metadata"
3638

0 commit comments

Comments
 (0)