diff options
Diffstat (limited to 'src/librustc_codegen_llvm/context.rs')
| -rw-r--r-- | src/librustc_codegen_llvm/context.rs | 38 |
1 files changed, 12 insertions, 26 deletions
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index d385c073074..df442609052 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -21,7 +21,7 @@ use rustc_session::Session; use rustc_span::source_map::{Span, DUMMY_SP}; use rustc_span::symbol::Symbol; use rustc_target::abi::{HasDataLayout, LayoutOf, PointeeInfo, Size, TargetDataLayout, VariantIdx}; -use rustc_target::spec::{HasTargetSpec, Target}; +use rustc_target::spec::{HasTargetSpec, RelocModel, Target}; use std::cell::{Cell, RefCell}; use std::ffi::CStr; @@ -87,22 +87,6 @@ pub struct CodegenCx<'ll, 'tcx> { local_gen_sym_counter: Cell<usize>, } -pub fn get_reloc_model(sess: &Session) -> llvm::RelocMode { - let reloc_model_arg = match sess.opts.cg.relocation_model { - Some(ref s) => &s[..], - None => &sess.target.target.options.relocation_model[..], - }; - - match crate::back::write::RELOC_MODEL_ARGS.iter().find(|&&arg| arg.0 == reloc_model_arg) { - Some(x) => x.1, - _ => { - sess.err(&format!("{:?} is not a valid relocation mode", reloc_model_arg)); - sess.abort_if_errors(); - bug!(); - } - } -} - fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode { let tls_model_arg = match sess.opts.debugging_opts.tls_model { Some(ref s) => &s[..], @@ -119,12 +103,14 @@ fn get_tls_model(sess: &Session) -> llvm::ThreadLocalMode { } } -fn is_any_library(sess: &Session) -> bool { - sess.crate_types.borrow().iter().any(|ty| *ty != config::CrateType::Executable) -} - -pub fn is_pie_binary(sess: &Session) -> bool { - !is_any_library(sess) && get_reloc_model(sess) == llvm::RelocMode::PIC +/// 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.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 { @@ -157,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); @@ -200,11 +186,11 @@ pub unsafe fn create_module( let llvm_target = SmallCStr::new(&sess.target.target.llvm_target); llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr()); - if get_reloc_model(sess) == llvm::RelocMode::PIC { + if sess.relocation_model() == RelocModel::Pic { llvm::LLVMRustSetModulePICLevel(llmod); } - if is_pie_binary(sess) { + if all_outputs_are_pic_executables(sess) { llvm::LLVMRustSetModulePIELevel(llmod); } |
