about summary refs log tree commit diff
path: root/src/librustc_codegen_llvm
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-04-23 21:10:01 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2020-04-26 11:18:48 +0300
commit76d85de22359d7a924b84dde6830650e92e44b89 (patch)
treee59a405edef738f846ab612c0a02d4baddbeb597 /src/librustc_codegen_llvm
parent045272558309a7600cb4618db5a2c52384f1d14e (diff)
codegen_llvm: Simplify logic for relaxing PIC into PIE
Diffstat (limited to 'src/librustc_codegen_llvm')
-rw-r--r--src/librustc_codegen_llvm/back/write.rs24
-rw-r--r--src/librustc_codegen_llvm/context.rs13
-rw-r--r--src/librustc_codegen_llvm/lib.rs11
-rw-r--r--src/librustc_codegen_llvm/llvm_util.rs4
4 files changed, 21 insertions, 31 deletions
diff --git a/src/librustc_codegen_llvm/back/write.rs b/src/librustc_codegen_llvm/back/write.rs
index 8fa577d8712..bf79c5b593e 100644
--- a/src/librustc_codegen_llvm/back/write.rs
+++ b/src/librustc_codegen_llvm/back/write.rs
@@ -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,
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index f614df6045c..df442609052 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -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);
     }
 
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 9d6f2150841..330d6ea75d2 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -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) }
         }
     }
 
diff --git a/src/librustc_codegen_llvm/llvm_util.rs b/src/librustc_codegen_llvm/llvm_util.rs
index 6f16b0fb79c..a36e95771e8 100644
--- a/src/librustc_codegen_llvm/llvm_util.rs
+++ b/src/librustc_codegen_llvm/llvm_util.rs
@@ -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),