Skip to content

Commit

Permalink
Auto merge of #71579 - Dylan-DPC:rollup-h9om2g3, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 5 pull requests

Successful merges:

 - #71490 (Cleanup and document `-C relocation-model`)
 - #71562 (fix more clippy warnings)
 - #71571 (Fix since attribute for nonzero_bitor impl's)
 - #71574 (proc_macro: Fix since attributes for new Span methods)
 - #71575 (Fix stable(since) attribute for BTreeMap::remove_entry)

Failed merges:

r? @ghost
  • Loading branch information
bors committed Apr 26, 2020
2 parents ec1f28f + aa9dc69 commit 7f3b3df
Show file tree
Hide file tree
Showing 47 changed files with 247 additions and 189 deletions.
43 changes: 39 additions & 4 deletions src/doc/rustc/src/codegen-options/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -319,11 +319,46 @@ to a valid `.profdata` file. See the chapter on

## relocation-model

This option lets you choose which
[relocation](https://en.wikipedia.org/wiki/Relocation_\(computing\)) model to
use.
This option controls generation of
[position-independent code (PIC)](https://en.wikipedia.org/wiki/Position-independent_code).

To find the valid options for this flag, run `rustc --print relocation-models`.
Supported values for this option are:

#### Primary relocation models

- `static` - non-relocatable code, machine instructions may use absolute addressing modes.

- `pic` - fully relocatable position independent code,
machine instructions need to use relative addressing modes.
Equivalent to the "uppercase" `-fPIC` or `-fPIE` options in other compilers,
depending on the produced crate types.
This is the default model for majority of supported targets.

#### Special relocation models

- `dynamic-no-pic` - relocatable external references, non-relocatable code.
Only makes sense on Darwin and is rarely used.
If StackOverflow tells you to use this as an opt-out of PIC or PIE, don't believe it,
use `-C relocation-model=static` instead.
- `ropi`, `rwpi` and `ropi-rwpi` - relocatable code and read-only data, relocatable read-write data,
and combination of both, respectively.
Only makes sense for certain embedded ARM targets.
- `default` - relocation model default to the current target.
Only makes sense as an override for some other explicitly specified relocation model
previously set on the command line.

Supported values can also be discovered by running `rustc --print relocation-models`.

#### Linking effects

In addition to codegen effects, `relocation-model` has effects during linking.

If the relocation model is `pic` and the current target supports position-independent executables
(PIE), the linker will be instructed (`-pie`) to produce one.
If the target doesn't support both position-independent and statically linked executables,
then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`,
and the linker is instructed (`-static`) to produce a statically linked
but not position-independent executable.

## remark

Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/collections/binary_heap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1269,7 +1269,7 @@ impl<'a, T: Ord> Drop for DrainSorted<'a, T> {

impl<'r, 'a, T: Ord> Drop for DropGuard<'r, 'a, T> {
fn drop(&mut self) {
while let Some(_) = self.0.inner.pop() {}
while self.0.inner.pop().is_some() {}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/collections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// assert_eq!(map.remove_entry(&1), Some((1, "a")));
/// assert_eq!(map.remove_entry(&1), None);
/// ```
#[stable(feature = "btreemap_remove_entry", since = "1.44.0")]
#[stable(feature = "btreemap_remove_entry", since = "1.45.0")]
pub fn remove_entry<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, V)>
where
K: Borrow<Q>,
Expand Down
2 changes: 1 addition & 1 deletion src/liballoc/collections/linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ unsafe impl<#[may_dangle] T> Drop for LinkedList<T> {
fn drop(&mut self) {
// Continue the same loop we do below. This only runs when a destructor has
// panicked. If another one panics this will abort.
while let Some(_) = self.0.pop_front_node() {}
while self.0.pop_front_node().is_some() {}
}
}

Expand Down
10 changes: 5 additions & 5 deletions src/libcore/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
}
}

#[stable(feature = "nonzero_bitor", since = "1.43.0")]
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOr for $Ty {
type Output = Self;
#[inline]
Expand All @@ -122,7 +122,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
}
}

#[stable(feature = "nonzero_bitor", since = "1.43.0")]
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOr<$Int> for $Ty {
type Output = Self;
#[inline]
Expand All @@ -134,7 +134,7 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
}
}

#[stable(feature = "nonzero_bitor", since = "1.43.0")]
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOr<$Ty> for $Int {
type Output = $Ty;
#[inline]
Expand All @@ -146,15 +146,15 @@ assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", s
}
}

#[stable(feature = "nonzero_bitor", since = "1.43.0")]
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOrAssign for $Ty {
#[inline]
fn bitor_assign(&mut self, rhs: Self) {
*self = *self | rhs;
}
}

#[stable(feature = "nonzero_bitor", since = "1.43.0")]
#[stable(feature = "nonzero_bitor", since = "1.45.0")]
impl BitOrAssign<$Int> for $Ty {
#[inline]
fn bitor_assign(&mut self, rhs: $Int) {
Expand Down
4 changes: 2 additions & 2 deletions src/libproc_macro/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,14 +351,14 @@ impl Span {

/// Creates a new span with the same line/column information as `self` but
/// that resolves symbols as though it were at `other`.
#[stable(feature = "proc_macro_span_resolved_at", since = "1.43.0")]
#[stable(feature = "proc_macro_span_resolved_at", since = "1.45.0")]
pub fn resolved_at(&self, other: Span) -> Span {
Span(self.0.resolved_at(other.0))
}

/// Creates a new span with the same name resolution behavior as `self` but
/// with the line/column information of `other`.
#[stable(feature = "proc_macro_span_located_at", since = "1.43.0")]
#[stable(feature = "proc_macro_span_located_at", since = "1.45.0")]
pub fn located_at(&self, other: Span) -> Span {
other.resolved_at(*self)
}
Expand Down
48 changes: 20 additions & 28 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::back::profiling::{
use crate::base;
use crate::common;
use crate::consts;
use crate::context::{get_reloc_model, 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;
Expand All @@ -25,6 +25,7 @@ use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{self, Lto, OutputType, Passes, Sanitizer, SwitchWithOptPath};
use rustc_session::Session;
use rustc_target::spec::RelocModel;

use libc::{c_char, c_int, c_uint, c_void, size_t};
use std::ffi::CString;
Expand All @@ -35,16 +36,6 @@ use std::slice;
use std::str;
use std::sync::Arc;

pub const RELOC_MODEL_ARGS: [(&str, llvm::RelocMode); 7] = [
("pic", llvm::RelocMode::PIC),
("static", llvm::RelocMode::Static),
("default", llvm::RelocMode::Default),
("dynamic-no-pic", llvm::RelocMode::DynamicNoPic),
("ropi", llvm::RelocMode::ROPI),
("rwpi", llvm::RelocMode::RWPI),
("ropi-rwpi", llvm::RelocMode::ROPI_RWPI),
];

pub const CODE_GEN_MODEL_ARGS: &[(&str, llvm::CodeModel)] = &[
("small", llvm::CodeModel::Small),
("kernel", llvm::CodeModel::Kernel),
Expand Down Expand Up @@ -84,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())
}

Expand Down Expand Up @@ -126,15 +111,22 @@ fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel
}
}

// 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 to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
match relocation_model {
RelocModel::Static => llvm::RelocModel::Static,
RelocModel::Pic => llvm::RelocModel::PIC,
RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic,
RelocModel::Ropi => llvm::RelocModel::ROPI,
RelocModel::Rwpi => llvm::RelocModel::RWPI,
RelocModel::RopiRwpi => llvm::RelocModel::ROPI_RWPI,
}
}

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 = get_reloc_model(sess);
let reloc_model = to_llvm_relocation_model(sess.relocation_model());

let (opt_level, _) = to_llvm_opt_settings(optlvl);
let use_softfp = sess.opts.cg.soft_float;
Expand Down Expand Up @@ -175,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;

Expand All @@ -192,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,
Expand Down
38 changes: 12 additions & 26 deletions src/librustc_codegen_llvm/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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[..],
Expand All @@ -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 {
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}

Expand Down
15 changes: 6 additions & 9 deletions src/librustc_codegen_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -201,7 +200,9 @@ impl CodegenBackend for LlvmCodegenBackend {
match req {
PrintRequest::RelocationModels => {
println!("Available relocation models:");
for &(name, _) in back::write::RELOC_MODEL_ARGS.iter() {
for name in
&["static", "pic", "dynamic-no-pic", "ropi", "rwpi", "ropi-rwpi", "default"]
{
println!(" {}", name);
}
println!();
Expand Down Expand Up @@ -351,19 +352,15 @@ 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) }
}
}

fn new_metadata(tcx: TyCtxt<'_>, mod_name: &str) -> Self {
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) }
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,7 @@ pub struct SanitizerOptions {
/// LLVMRelocMode
#[derive(Copy, Clone, PartialEq)]
#[repr(C)]
pub enum RelocMode {
Default,
pub enum RelocModel {
Static,
PIC,
DynamicNoPic,
Expand Down Expand Up @@ -1946,7 +1945,7 @@ extern "C" {
Features: *const c_char,
Abi: *const c_char,
Model: CodeModel,
Reloc: RelocMode,
Reloc: RelocModel,
Level: CodeGenOptLevel,
UseSoftFP: bool,
PositionIndependentExecutable: bool,
Expand Down
Loading

0 comments on commit 7f3b3df

Please sign in to comment.