Skip to content

Commit ce05553

Browse files
authored
Rollup merge of #71234 - maurer:init-array, r=cuviper
rustllvm: Use .init_array rather than .ctors LLVM TargetMachines default to using the (now-legacy) .ctors representation of init functions. Mixing .ctors and .init_array representations can cause issues when linking with lld. This happens in practice for: * Our profiling runtime which is currently implicitly built with .init_array since it is built by clang, which sets this field. * External C/C++ code that may be linked into the same process. Fixes: #71233
2 parents 1704dca + 0e7d5be commit ce05553

File tree

7 files changed

+23
-1
lines changed

7 files changed

+23
-1
lines changed

src/librustc_codegen_llvm/back/write.rs

+8
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,13 @@ pub fn target_machine_factory(
165165

166166
let asm_comments = sess.asm_comments();
167167
let relax_elf_relocations = sess.target.target.options.relax_elf_relocations;
168+
169+
let use_init_array = !sess
170+
.opts
171+
.debugging_opts
172+
.use_ctors_section
173+
.unwrap_or(sess.target.target.options.use_ctors_section);
174+
168175
Arc::new(move || {
169176
let tm = unsafe {
170177
llvm::LLVMRustCreateTargetMachine(
@@ -184,6 +191,7 @@ pub fn target_machine_factory(
184191
asm_comments,
185192
emit_stack_size_section,
186193
relax_elf_relocations,
194+
use_init_array,
187195
)
188196
};
189197

src/librustc_codegen_llvm/llvm/ffi.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,7 @@ extern "C" {
19561956
AsmComments: bool,
19571957
EmitStackSizeSection: bool,
19581958
RelaxELFRelocations: bool,
1959+
UseInitArray: bool,
19591960
) -> Option<&'static mut TargetMachine>;
19601961
pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
19611962
pub fn LLVMRustAddBuilderLibraryInfo(

src/librustc_interface/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ fn test_debugging_options_tracking_hash() {
571571
tracked!(tls_model, Some(TlsModel::GeneralDynamic));
572572
tracked!(treat_err_as_bug, Some(1));
573573
tracked!(unleash_the_miri_inside_of_you, true);
574+
tracked!(use_ctors_section, Some(true));
574575
tracked!(verify_llvm_ir, true);
575576
}
576577

src/librustc_session/options.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
10101010
`mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"),
10111011
unstable_options: bool = (false, parse_bool, [UNTRACKED],
10121012
"adds unstable command line options to rustc interface (default: no)"),
1013+
use_ctors_section: Option<bool> = (None, parse_opt_bool, [TRACKED],
1014+
"use legacy .ctors section for initializers rather than .init_array"),
10131015
verbose: bool = (false, parse_bool, [UNTRACKED],
10141016
"in general, enable more debug printouts (default: no)"),
10151017
verify_llvm_ir: bool = (false, parse_bool, [TRACKED],

src/librustc_target/spec/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,10 @@ pub struct TargetOptions {
882882

883883
/// Additional arguments to pass to LLVM, similar to the `-C llvm-args` codegen option.
884884
pub llvm_args: Vec<String>,
885+
886+
/// Whether to use legacy .ctors initialization hooks rather than .init_array. Defaults
887+
/// to false (uses .init_array).
888+
pub use_ctors_section: bool,
885889
}
886890

887891
impl Default for TargetOptions {
@@ -972,6 +976,7 @@ impl Default for TargetOptions {
972976
llvm_abiname: "".to_string(),
973977
relax_elf_relocations: false,
974978
llvm_args: vec![],
979+
use_ctors_section: false,
975980
}
976981
}
977982
}
@@ -1312,6 +1317,7 @@ impl Target {
13121317
key!(llvm_abiname);
13131318
key!(relax_elf_relocations, bool);
13141319
key!(llvm_args, list);
1320+
key!(use_ctors_section, bool);
13151321

13161322
if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
13171323
for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -1541,6 +1547,7 @@ impl ToJson for Target {
15411547
target_option_val!(llvm_abiname);
15421548
target_option_val!(relax_elf_relocations);
15431549
target_option_val!(llvm_args);
1550+
target_option_val!(use_ctors_section);
15441551

15451552
if default.abi_blacklist != self.options.abi_blacklist {
15461553
d.insert(

src/librustc_target/spec/netbsd_base.rs

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub fn opts() -> TargetOptions {
2323
pre_link_args: args,
2424
position_independent_executables: true,
2525
relro_level: RelroLevel::Full,
26+
use_ctors_section: true,
2627
..Default::default()
2728
}
2829
}

src/rustllvm/PassWrapper.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,8 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
447447
bool Singlethread,
448448
bool AsmComments,
449449
bool EmitStackSizeSection,
450-
bool RelaxELFRelocations) {
450+
bool RelaxELFRelocations,
451+
bool UseInitArray) {
451452

452453
auto OptLevel = fromRust(RustOptLevel);
453454
auto RM = fromRust(RustReloc);
@@ -473,6 +474,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
473474
Options.MCOptions.PreserveAsmComments = AsmComments;
474475
Options.MCOptions.ABIName = ABIStr;
475476
Options.RelaxELFRelocations = RelaxELFRelocations;
477+
Options.UseInitArray = UseInitArray;
476478

477479
if (TrapUnreachable) {
478480
// Tell LLVM to codegen `unreachable` into an explicit trap instruction.

0 commit comments

Comments
 (0)