Skip to content

Commit 76d85de

Browse files
committed
codegen_llvm: Simplify logic for relaxing PIC into PIE
1 parent 0452725 commit 76d85de

File tree

6 files changed

+22
-36
lines changed

6 files changed

+22
-36
lines changed

src/librustc_codegen_llvm/back/write.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::back::profiling::{
77
use crate::base;
88
use crate::common;
99
use crate::consts;
10-
use crate::context::is_pie_binary;
10+
use crate::context::all_outputs_are_pic_executables;
1111
use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
1212
use crate::llvm_util;
1313
use crate::type_::Type;
@@ -75,19 +75,13 @@ pub fn write_output_file(
7575
}
7676
}
7777

78-
pub fn create_informational_target_machine(
79-
sess: &Session,
80-
find_features: bool,
81-
) -> &'static mut llvm::TargetMachine {
82-
target_machine_factory(sess, config::OptLevel::No, find_features)()
78+
pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine {
79+
target_machine_factory(sess, config::OptLevel::No)()
8380
.unwrap_or_else(|err| llvm_err(sess.diagnostic(), &err).raise())
8481
}
8582

86-
pub fn create_target_machine(
87-
tcx: TyCtxt<'_>,
88-
find_features: bool,
89-
) -> &'static mut llvm::TargetMachine {
90-
target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE), find_features)()
83+
pub fn create_target_machine(tcx: TyCtxt<'_>) -> &'static mut llvm::TargetMachine {
84+
target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))()
9185
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
9286
}
9387

@@ -128,13 +122,9 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
128122
}
129123
}
130124

131-
// If find_features is true this won't access `sess.crate_types` by assuming
132-
// that `is_pie_binary` is false. When we discover LLVM target features
133-
// `sess.crate_types` is uninitialized so we cannot access it.
134125
pub fn target_machine_factory(
135126
sess: &Session,
136127
optlvl: config::OptLevel,
137-
find_features: bool,
138128
) -> Arc<dyn Fn() -> Result<&'static mut llvm::TargetMachine, String> + Send + Sync> {
139129
let reloc_model = to_llvm_relocation_model(sess.relocation_model());
140130

@@ -177,7 +167,7 @@ pub fn target_machine_factory(
177167
let features = features.join(",");
178168
let features = CString::new(features).unwrap();
179169
let abi = SmallCStr::new(&sess.target.target.options.llvm_abiname);
180-
let is_pie_binary = !find_features && is_pie_binary(sess);
170+
let pic_is_pie = all_outputs_are_pic_executables(sess);
181171
let trap_unreachable = sess.target.target.options.trap_unreachable;
182172
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
183173

@@ -194,7 +184,7 @@ pub fn target_machine_factory(
194184
reloc_model,
195185
opt_level,
196186
use_softfp,
197-
is_pie_binary,
187+
pic_is_pie,
198188
ffunction_sections,
199189
fdata_sections,
200190
trap_unreachable,

src/librustc_codegen_llvm/context.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,14 @@ fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode {
103103
}
104104
}
105105

106-
pub fn is_pie_binary(sess: &Session) -> bool {
106+
/// PIE is potentially more effective than PIC, but can only be used in executables.
107+
/// If all our outputs are executables, then we can relax PIC to PIE when producing object code.
108+
/// If the list of crate types is not yet known we conservatively return `false`.
109+
pub fn all_outputs_are_pic_executables(sess: &Session) -> bool {
107110
sess.relocation_model() == RelocModel::Pic
108-
&& !sess.crate_types.borrow().iter().any(|ty| *ty != config::CrateType::Executable)
111+
&& sess.crate_types.try_get().map_or(false, |crate_types| {
112+
crate_types.iter().all(|ty| *ty == config::CrateType::Executable)
113+
})
109114
}
110115

111116
fn strip_function_ptr_alignment(data_layout: String) -> String {
@@ -138,7 +143,7 @@ pub unsafe fn create_module(
138143

139144
// Ensure the data-layout values hardcoded remain the defaults.
140145
if sess.target.target.options.is_builtin {
141-
let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false);
146+
let tm = crate::back::write::create_informational_target_machine(tcx.sess);
142147
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
143148
llvm::LLVMRustDisposeTargetMachine(tm);
144149

@@ -185,7 +190,7 @@ pub unsafe fn create_module(
185190
llvm::LLVMRustSetModulePICLevel(llmod);
186191
}
187192

188-
if is_pie_binary(sess) {
193+
if all_outputs_are_pic_executables(sess) {
189194
llvm::LLVMRustSetModulePIELevel(llmod);
190195
}
191196

src/librustc_codegen_llvm/lib.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
110110
&self,
111111
sess: &Session,
112112
optlvl: OptLevel,
113-
find_features: bool,
114113
) -> Arc<dyn Fn() -> Result<&'static mut llvm::TargetMachine, String> + Send + Sync> {
115-
back::write::target_machine_factory(sess, optlvl, find_features)
114+
back::write::target_machine_factory(sess, optlvl)
116115
}
117116
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
118117
llvm_util::target_cpu(sess)
@@ -353,19 +352,15 @@ impl ModuleLlvm {
353352
unsafe {
354353
let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
355354
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
356-
ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, false) }
355+
ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx) }
357356
}
358357
}
359358

360359
fn new_metadata(tcx: TyCtxt<'_>, mod_name: &str) -> Self {
361360
unsafe {
362361
let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
363362
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
364-
ModuleLlvm {
365-
llmod_raw,
366-
llcx,
367-
tm: create_informational_target_machine(&tcx.sess, false),
368-
}
363+
ModuleLlvm { llmod_raw, llcx, tm: create_informational_target_machine(tcx.sess) }
369364
}
370365
}
371366

src/librustc_codegen_llvm/llvm_util.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
270270
}
271271

272272
pub fn target_features(sess: &Session) -> Vec<Symbol> {
273-
let target_machine = create_informational_target_machine(sess, true);
273+
let target_machine = create_informational_target_machine(sess);
274274
target_feature_whitelist(sess)
275275
.iter()
276276
.filter_map(|&(feature, gate)| {
@@ -322,7 +322,7 @@ pub fn print_passes() {
322322

323323
pub(crate) fn print(req: PrintRequest, sess: &Session) {
324324
require_inited();
325-
let tm = create_informational_target_machine(sess, true);
325+
let tm = create_informational_target_machine(sess);
326326
unsafe {
327327
match req {
328328
PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),

src/librustc_codegen_ssa/back/write.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
10371037
regular_module_config: regular_config,
10381038
metadata_module_config: metadata_config,
10391039
allocator_module_config: allocator_config,
1040-
tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, ol, false)),
1040+
tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, ol)),
10411041
total_cgus,
10421042
msvc_imps_needed: msvc_imps_needed(tcx),
10431043
target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),

src/librustc_codegen_ssa/traits/backend.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,10 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
110110
tcx: TyCtxt<'_>,
111111
cgu_name: Symbol,
112112
) -> (ModuleCodegen<Self::Module>, u64);
113-
// If find_features is true this won't access `sess.crate_types` by assuming
114-
// that `is_pie_binary` is false. When we discover LLVM target features
115-
// `sess.crate_types` is uninitialized so we cannot access it.
116113
fn target_machine_factory(
117114
&self,
118115
sess: &Session,
119116
opt_level: config::OptLevel,
120-
find_features: bool,
121117
) -> Arc<dyn Fn() -> Result<Self::TargetMachine, String> + Send + Sync>;
122118
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
123119
}

0 commit comments

Comments
 (0)