Skip to content

Commit 9e92106

Browse files
committed
Auto merge of rust-lang#74642 - Manishearth:rollup-148kz52, r=Manishearth
Rollup of 9 pull requests Successful merges: - rust-lang#73655 (va_args implementation for AAPCS.) - rust-lang#73893 (Stabilize control-flow-guard codegen option) - rust-lang#74237 (compiletest: Rewrite extract_*_version functions) - rust-lang#74454 (small coherence cleanup) - rust-lang#74528 (refactor and reword intra-doc link errors) - rust-lang#74568 (Apply rust-lang#66379 to `*mut T` `as_ref`) - rust-lang#74570 (Use forge links for prioritization procedure) - rust-lang#74589 (Update books) - rust-lang#74635 (Fix tooltip position if the documentation starts with a code block) Failed merges: r? @ghost
2 parents 69d68f9 + 05a2466 commit 9e92106

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+751
-635
lines changed

src/bootstrap/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ impl<'a> Builder<'a> {
12391239
&& self.config.control_flow_guard
12401240
&& compiler.stage >= 1
12411241
{
1242-
rustflags.arg("-Zcontrol-flow-guard");
1242+
rustflags.arg("-Ccontrol-flow-guard");
12431243
}
12441244

12451245
// For `cargo doc` invocations, make rustdoc print the Rust version into the docs

src/doc/rustc/src/codegen-options/index.md

+12
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ generated code, but may be slower to compile.
4242
The default value, if not specified, is 16 for non-incremental builds. For
4343
incremental builds the default is 256 which allows caching to be more granular.
4444

45+
## control-flow-guard
46+
47+
This flag controls whether LLVM enables the Windows [Control Flow
48+
Guard](https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard)
49+
platform security feature. This flag is currently ignored for non-Windows targets.
50+
It takes one of the following values:
51+
52+
* `y`, `yes`, `on`, `checks`, or no value: enable Control Flow Guard.
53+
* `nochecks`: emit Control Flow Guard metadata without runtime enforcement checks (this
54+
should only be used for testing purposes as it does not provide security enforcement).
55+
* `n`, `no`, `off`: do not enable Control Flow Guard (the default).
56+
4557
## debug-assertions
4658

4759
This flag lets you turn `cfg(debug_assertions)` [conditional

src/libcore/ptr/mut_ptr.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,22 @@ impl<T: ?Sized> *mut T {
4747
/// operation because the returned value could be pointing to invalid
4848
/// memory.
4949
///
50-
/// When calling this method, you have to ensure that if the pointer is
51-
/// non-NULL, then it is properly aligned, dereferenceable (for the whole
52-
/// size of `T`) and points to an initialized instance of `T`. This applies
53-
/// even if the result of this method is unused!
50+
/// When calling this method, you have to ensure that *either* the pointer is NULL *or*
51+
/// all of the following is true:
52+
/// - it is properly aligned
53+
/// - it must point to an initialized instance of T; in particular, the pointer must be
54+
/// "dereferencable" in the sense defined [here].
55+
///
56+
/// This applies even if the result of this method is unused!
5457
/// (The part about being initialized is not yet fully decided, but until
5558
/// it is, the only safe approach is to ensure that they are indeed initialized.)
5659
///
5760
/// Additionally, the lifetime `'a` returned is arbitrarily chosen and does
58-
/// not necessarily reflect the actual lifetime of the data. It is up to the
59-
/// caller to ensure that for the duration of this lifetime, the memory this
60-
/// pointer points to does not get written to outside of `UnsafeCell<U>`.
61+
/// not necessarily reflect the actual lifetime of the data. *You* must enforce
62+
/// Rust's aliasing rules. In particular, for the duration of this lifetime,
63+
/// the memory the pointer points to must not get mutated (except inside `UnsafeCell`).
64+
///
65+
/// [here]: crate::ptr#safety
6166
///
6267
/// # Examples
6368
///

src/librustc_codegen_llvm/builder.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -1330,7 +1330,12 @@ impl Builder<'a, 'll, 'tcx> {
13301330
self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
13311331
}
13321332

1333-
fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
1333+
pub(crate) fn phi(
1334+
&mut self,
1335+
ty: &'ll Type,
1336+
vals: &[&'ll Value],
1337+
bbs: &[&'ll BasicBlock],
1338+
) -> &'ll Value {
13341339
assert_eq!(vals.len(), bbs.len());
13351340
let phi = unsafe { llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED) };
13361341
unsafe {

src/librustc_codegen_llvm/context.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ pub unsafe fn create_module(
190190

191191
// Control Flow Guard is currently only supported by the MSVC linker on Windows.
192192
if sess.target.target.options.is_like_msvc {
193-
match sess.opts.debugging_opts.control_flow_guard {
193+
match sess.opts.cg.control_flow_guard {
194194
CFGuard::Disabled => {}
195195
CFGuard::NoChecks => {
196196
// Set `cfguard=1` module flag to emit metadata only.

src/librustc_codegen_llvm/va_arg.rs

+79-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ use crate::type_::Type;
33
use crate::type_of::LayoutLlvmExt;
44
use crate::value::Value;
55
use rustc_codegen_ssa::mir::operand::OperandRef;
6-
use rustc_codegen_ssa::traits::{
7-
BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods,
6+
use rustc_codegen_ssa::{
7+
common::IntPredicate,
8+
traits::{BaseTypeMethods, BuilderMethods, ConstMethods, DerivedTypeMethods},
89
};
910
use rustc_middle::ty::layout::HasTyCtxt;
1011
use rustc_middle::ty::Ty;
@@ -89,6 +90,81 @@ fn emit_ptr_va_arg(
8990
}
9091
}
9192

93+
fn emit_aapcs_va_arg(
94+
bx: &mut Builder<'a, 'll, 'tcx>,
95+
list: OperandRef<'tcx, &'ll Value>,
96+
target_ty: Ty<'tcx>,
97+
) -> &'ll Value {
98+
// Implementation of the AAPCS64 calling convention for va_args see
99+
// https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst
100+
let va_list_addr = list.immediate();
101+
let layout = bx.cx.layout_of(target_ty);
102+
103+
let mut maybe_reg = bx.build_sibling_block("va_arg.maybe_reg");
104+
let mut in_reg = bx.build_sibling_block("va_arg.in_reg");
105+
let mut on_stack = bx.build_sibling_block("va_arg.on_stack");
106+
let mut end = bx.build_sibling_block("va_arg.end");
107+
let zero = bx.const_i32(0);
108+
let offset_align = Align::from_bytes(4).unwrap();
109+
assert!(&*bx.tcx().sess.target.target.target_endian == "little");
110+
111+
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
112+
let (reg_off, reg_top_index, slot_size) = if gr_type {
113+
let gr_offs = bx.struct_gep(va_list_addr, 7);
114+
let nreg = (layout.size.bytes() + 7) / 8;
115+
(gr_offs, 3, nreg * 8)
116+
} else {
117+
let vr_off = bx.struct_gep(va_list_addr, 9);
118+
let nreg = (layout.size.bytes() + 15) / 16;
119+
(vr_off, 5, nreg * 16)
120+
};
121+
122+
// if the offset >= 0 then the value will be on the stack
123+
let mut reg_off_v = bx.load(reg_off, offset_align);
124+
let use_stack = bx.icmp(IntPredicate::IntSGE, reg_off_v, zero);
125+
bx.cond_br(use_stack, &on_stack.llbb(), &maybe_reg.llbb());
126+
127+
// The value at this point might be in a register, but there is a chance that
128+
// it could be on the stack so we have to update the offset and then check
129+
// the offset again.
130+
131+
if gr_type && layout.align.abi.bytes() > 8 {
132+
reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(15));
133+
reg_off_v = maybe_reg.and(reg_off_v, bx.const_i32(-16));
134+
}
135+
let new_reg_off_v = maybe_reg.add(reg_off_v, bx.const_i32(slot_size as i32));
136+
137+
maybe_reg.store(new_reg_off_v, reg_off, offset_align);
138+
139+
// Check to see if we have overflowed the registers as a result of this.
140+
// If we have then we need to use the stack for this value
141+
let use_stack = maybe_reg.icmp(IntPredicate::IntSGT, new_reg_off_v, zero);
142+
maybe_reg.cond_br(use_stack, &on_stack.llbb(), &in_reg.llbb());
143+
144+
let top = in_reg.struct_gep(va_list_addr, reg_top_index);
145+
let top = in_reg.load(top, bx.tcx().data_layout.pointer_align.abi);
146+
147+
// reg_value = *(@top + reg_off_v);
148+
let top = in_reg.gep(top, &[reg_off_v]);
149+
let top = in_reg.bitcast(top, bx.cx.type_ptr_to(layout.llvm_type(bx)));
150+
let reg_value = in_reg.load(top, layout.align.abi);
151+
in_reg.br(&end.llbb());
152+
153+
// On Stack block
154+
let stack_value =
155+
emit_ptr_va_arg(&mut on_stack, list, target_ty, false, Align::from_bytes(8).unwrap(), true);
156+
on_stack.br(&end.llbb());
157+
158+
let val = end.phi(
159+
layout.immediate_llvm_type(bx),
160+
&[reg_value, stack_value],
161+
&[&in_reg.llbb(), &on_stack.llbb()],
162+
);
163+
164+
*bx = end;
165+
val
166+
}
167+
92168
pub(super) fn emit_va_arg(
93169
bx: &mut Builder<'a, 'll, 'tcx>,
94170
addr: OperandRef<'tcx, &'ll Value>,
@@ -115,6 +191,7 @@ pub(super) fn emit_va_arg(
115191
("aarch64", _) if target.target_os == "ios" => {
116192
emit_ptr_va_arg(bx, addr, target_ty, false, Align::from_bytes(8).unwrap(), true)
117193
}
194+
("aarch64", _) => emit_aapcs_va_arg(bx, addr, target_ty),
118195
// Windows x86_64
119196
("x86_64", true) => {
120197
let target_ty_size = bx.cx.size_of(target_ty).bytes();

src/librustc_codegen_ssa/back/link.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1700,7 +1700,7 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
17001700
}
17011701

17021702
// OBJECT-FILES-NO, AUDIT-ORDER
1703-
if sess.opts.debugging_opts.control_flow_guard != CFGuard::Disabled {
1703+
if sess.opts.cg.control_flow_guard != CFGuard::Disabled {
17041704
cmd.control_flow_guard();
17051705
}
17061706

src/librustc_interface/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ fn test_codegen_options_tracking_hash() {
420420
// Make sure that changing a [TRACKED] option changes the hash.
421421
// This list is in alphabetical order.
422422
tracked!(code_model, Some(CodeModel::Large));
423+
tracked!(control_flow_guard, CFGuard::Checks);
423424
tracked!(debug_assertions, Some(true));
424425
tracked!(debuginfo, 0xdeadbeef);
425426
tracked!(embed_bitcode, false);
@@ -537,7 +538,6 @@ fn test_debugging_options_tracking_hash() {
537538
tracked!(binary_dep_depinfo, true);
538539
tracked!(chalk, true);
539540
tracked!(codegen_backend, Some("abc".to_string()));
540-
tracked!(control_flow_guard, CFGuard::Checks);
541541
tracked!(crate_attr, vec!["abc".to_string()]);
542542
tracked!(debug_macros, true);
543543
tracked!(dep_info_omit_d_target, true);

src/librustc_session/config.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub enum Strip {
103103
Symbols,
104104
}
105105

106-
/// The different settings that the `-Z control-flow-guard` flag can have.
106+
/// The different settings that the `-C control-flow-guard` flag can have.
107107
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
108108
pub enum CFGuard {
109109
/// Do not emit Control Flow Guard metadata or checks.

src/librustc_session/options.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,8 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
692692
"choose the code model to use (`rustc --print code-models` for details)"),
693693
codegen_units: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
694694
"divide crate into N units to optimize in parallel"),
695+
control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED],
696+
"use Windows Control Flow Guard (default: no)"),
695697
debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
696698
"explicitly enable the `cfg(debug_assertions)` directive"),
697699
debuginfo: usize = (0, parse_uint, [TRACKED],
@@ -809,8 +811,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
809811
"enable the experimental Chalk-based trait solving engine"),
810812
codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
811813
"the backend to use"),
812-
control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED],
813-
"use Windows Control Flow Guard (default: no)"),
814814
crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
815815
"inject the given attribute in the crate"),
816816
debug_macros: bool = (false, parse_bool, [TRACKED],

0 commit comments

Comments
 (0)