mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-02 11:44:28 +00:00
codegen_llvm: Simplify logic for relaxing PIC into PIE
This commit is contained in:
parent
0452725583
commit
76d85de223
@ -7,7 +7,7 @@ use crate::back::profiling::{
|
||||
use crate::base;
|
||||
use crate::common;
|
||||
use crate::consts;
|
||||
use crate::context::is_pie_binary;
|
||||
use crate::context::all_outputs_are_pic_executables;
|
||||
use crate::llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
|
||||
use crate::llvm_util;
|
||||
use crate::type_::Type;
|
||||
@ -75,19 +75,13 @@ pub fn write_output_file(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_informational_target_machine(
|
||||
sess: &Session,
|
||||
find_features: bool,
|
||||
) -> &'static mut llvm::TargetMachine {
|
||||
target_machine_factory(sess, config::OptLevel::No, find_features)()
|
||||
pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine {
|
||||
target_machine_factory(sess, config::OptLevel::No)()
|
||||
.unwrap_or_else(|err| llvm_err(sess.diagnostic(), &err).raise())
|
||||
}
|
||||
|
||||
pub fn create_target_machine(
|
||||
tcx: TyCtxt<'_>,
|
||||
find_features: bool,
|
||||
) -> &'static mut llvm::TargetMachine {
|
||||
target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE), find_features)()
|
||||
pub fn create_target_machine(tcx: TyCtxt<'_>) -> &'static mut llvm::TargetMachine {
|
||||
target_machine_factory(&tcx.sess, tcx.backend_optimization_level(LOCAL_CRATE))()
|
||||
.unwrap_or_else(|err| llvm_err(tcx.sess.diagnostic(), &err).raise())
|
||||
}
|
||||
|
||||
@ -128,13 +122,9 @@ fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
|
||||
}
|
||||
}
|
||||
|
||||
// If find_features is true this won't access `sess.crate_types` by assuming
|
||||
// that `is_pie_binary` is false. When we discover LLVM target features
|
||||
// `sess.crate_types` is uninitialized so we cannot access it.
|
||||
pub fn target_machine_factory(
|
||||
sess: &Session,
|
||||
optlvl: config::OptLevel,
|
||||
find_features: bool,
|
||||
) -> Arc<dyn Fn() -> Result<&'static mut llvm::TargetMachine, String> + Send + Sync> {
|
||||
let reloc_model = to_llvm_relocation_model(sess.relocation_model());
|
||||
|
||||
@ -177,7 +167,7 @@ pub fn target_machine_factory(
|
||||
let features = features.join(",");
|
||||
let features = CString::new(features).unwrap();
|
||||
let abi = SmallCStr::new(&sess.target.target.options.llvm_abiname);
|
||||
let is_pie_binary = !find_features && is_pie_binary(sess);
|
||||
let pic_is_pie = all_outputs_are_pic_executables(sess);
|
||||
let trap_unreachable = sess.target.target.options.trap_unreachable;
|
||||
let emit_stack_size_section = sess.opts.debugging_opts.emit_stack_sizes;
|
||||
|
||||
@ -194,7 +184,7 @@ pub fn target_machine_factory(
|
||||
reloc_model,
|
||||
opt_level,
|
||||
use_softfp,
|
||||
is_pie_binary,
|
||||
pic_is_pie,
|
||||
ffunction_sections,
|
||||
fdata_sections,
|
||||
trap_unreachable,
|
||||
|
@ -103,9 +103,14 @@ fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_pie_binary(sess: &Session) -> bool {
|
||||
/// PIE is potentially more effective than PIC, but can only be used in executables.
|
||||
/// If all our outputs are executables, then we can relax PIC to PIE when producing object code.
|
||||
/// If the list of crate types is not yet known we conservatively return `false`.
|
||||
pub fn all_outputs_are_pic_executables(sess: &Session) -> bool {
|
||||
sess.relocation_model() == RelocModel::Pic
|
||||
&& !sess.crate_types.borrow().iter().any(|ty| *ty != config::CrateType::Executable)
|
||||
&& sess.crate_types.try_get().map_or(false, |crate_types| {
|
||||
crate_types.iter().all(|ty| *ty == config::CrateType::Executable)
|
||||
})
|
||||
}
|
||||
|
||||
fn strip_function_ptr_alignment(data_layout: String) -> String {
|
||||
@ -138,7 +143,7 @@ pub unsafe fn create_module(
|
||||
|
||||
// Ensure the data-layout values hardcoded remain the defaults.
|
||||
if sess.target.target.options.is_builtin {
|
||||
let tm = crate::back::write::create_informational_target_machine(&tcx.sess, false);
|
||||
let tm = crate::back::write::create_informational_target_machine(tcx.sess);
|
||||
llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
|
||||
llvm::LLVMRustDisposeTargetMachine(tm);
|
||||
|
||||
@ -185,7 +190,7 @@ pub unsafe fn create_module(
|
||||
llvm::LLVMRustSetModulePICLevel(llmod);
|
||||
}
|
||||
|
||||
if is_pie_binary(sess) {
|
||||
if all_outputs_are_pic_executables(sess) {
|
||||
llvm::LLVMRustSetModulePIELevel(llmod);
|
||||
}
|
||||
|
||||
|
@ -110,9 +110,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
|
||||
&self,
|
||||
sess: &Session,
|
||||
optlvl: OptLevel,
|
||||
find_features: bool,
|
||||
) -> Arc<dyn Fn() -> Result<&'static mut llvm::TargetMachine, String> + Send + Sync> {
|
||||
back::write::target_machine_factory(sess, optlvl, find_features)
|
||||
back::write::target_machine_factory(sess, optlvl)
|
||||
}
|
||||
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str {
|
||||
llvm_util::target_cpu(sess)
|
||||
@ -353,7 +352,7 @@ impl ModuleLlvm {
|
||||
unsafe {
|
||||
let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
|
||||
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
|
||||
ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx, false) }
|
||||
ModuleLlvm { llmod_raw, llcx, tm: create_target_machine(tcx) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -361,11 +360,7 @@ impl ModuleLlvm {
|
||||
unsafe {
|
||||
let llcx = llvm::LLVMRustContextCreate(tcx.sess.fewer_names());
|
||||
let llmod_raw = context::create_module(tcx, llcx, mod_name) as *const _;
|
||||
ModuleLlvm {
|
||||
llmod_raw,
|
||||
llcx,
|
||||
tm: create_informational_target_machine(&tcx.sess, false),
|
||||
}
|
||||
ModuleLlvm { llmod_raw, llcx, tm: create_informational_target_machine(tcx.sess) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ pub fn to_llvm_feature<'a>(sess: &Session, s: &'a str) -> &'a str {
|
||||
}
|
||||
|
||||
pub fn target_features(sess: &Session) -> Vec<Symbol> {
|
||||
let target_machine = create_informational_target_machine(sess, true);
|
||||
let target_machine = create_informational_target_machine(sess);
|
||||
target_feature_whitelist(sess)
|
||||
.iter()
|
||||
.filter_map(|&(feature, gate)| {
|
||||
@ -322,7 +322,7 @@ pub fn print_passes() {
|
||||
|
||||
pub(crate) fn print(req: PrintRequest, sess: &Session) {
|
||||
require_inited();
|
||||
let tm = create_informational_target_machine(sess, true);
|
||||
let tm = create_informational_target_machine(sess);
|
||||
unsafe {
|
||||
match req {
|
||||
PrintRequest::TargetCPUs => llvm::LLVMRustPrintTargetCPUs(tm),
|
||||
|
@ -1037,7 +1037,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
|
||||
regular_module_config: regular_config,
|
||||
metadata_module_config: metadata_config,
|
||||
allocator_module_config: allocator_config,
|
||||
tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, ol, false)),
|
||||
tm_factory: TargetMachineFactory(backend.target_machine_factory(tcx.sess, ol)),
|
||||
total_cgus,
|
||||
msvc_imps_needed: msvc_imps_needed(tcx),
|
||||
target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),
|
||||
|
@ -110,14 +110,10 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
|
||||
tcx: TyCtxt<'_>,
|
||||
cgu_name: Symbol,
|
||||
) -> (ModuleCodegen<Self::Module>, u64);
|
||||
// If find_features is true this won't access `sess.crate_types` by assuming
|
||||
// that `is_pie_binary` is false. When we discover LLVM target features
|
||||
// `sess.crate_types` is uninitialized so we cannot access it.
|
||||
fn target_machine_factory(
|
||||
&self,
|
||||
sess: &Session,
|
||||
opt_level: config::OptLevel,
|
||||
find_features: bool,
|
||||
) -> Arc<dyn Fn() -> Result<Self::TargetMachine, String> + Send + Sync>;
|
||||
fn target_cpu<'b>(&self, sess: &'b Session) -> &'b str;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user