diff options
| author | bors <bors@rust-lang.org> | 2022-02-15 21:20:49 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-02-15 21:20:49 +0000 |
| commit | 09cb29c64c2a0e15debf2d6fca2bc7c71a682033 (patch) | |
| tree | df86070b727397e8efc2908e24f90140ed808489 /compiler/rustc_session | |
| parent | bfb2856f271fcb647b3cad1b88b29ec97bbab2a3 (diff) | |
| parent | 8d6c973c7f77e63a9c5d1ce4b7c71a37fcc46f4d (diff) | |
| download | rust-09cb29c64c2a0e15debf2d6fca2bc7c71a682033.tar.gz rust-09cb29c64c2a0e15debf2d6fca2bc7c71a682033.zip | |
Auto merge of #93439 - abrown:cf-protection, r=nagisa
Add support for control-flow protection This change adds a flag for configuring control-flow protection in the LLVM backend. In Clang, this flag is exposed as `-fcf-protection` with options `none|branch|return|full`. This convention is followed for `rustc`, though as a codegen option: `rustc -Z cf-protection=<none|branch|return|full>`. Tracking issue for future work is #93754.
Diffstat (limited to 'compiler/rustc_session')
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 22 |
2 files changed, 43 insertions, 4 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 79962d5db89..68e7cc3dc98 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -63,6 +63,22 @@ pub enum CFGuard { Checks, } +/// The different settings that the `-Z cf-protection` flag can have. +#[derive(Clone, Copy, PartialEq, Hash, Debug)] +pub enum CFProtection { + /// Do not enable control-flow protection + None, + + /// Emit control-flow protection for branches (enables indirect branch tracking). + Branch, + + /// Emit control-flow protection for returns. + Return, + + /// Emit control-flow protection for both branches and returns. + Full, +} + #[derive(Clone, Copy, Debug, PartialEq, Hash)] pub enum OptLevel { No, // -O0 @@ -2630,11 +2646,11 @@ impl PpMode { /// we have an opt-in scheme here, so one is hopefully forced to think about /// how the hash should be calculated when adding a new command-line argument. crate mod dep_tracking { - use super::LdImpl; use super::{ - BranchProtection, CFGuard, CrateType, DebugInfo, ErrorOutputType, InstrumentCoverage, - LinkerPluginLto, LocationDetail, LtoCli, OptLevel, OutputType, OutputTypes, Passes, - SourceFileHashAlgorithm, SwitchWithOptPath, SymbolManglingVersion, TrimmedDefPaths, + BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType, + InstrumentCoverage, LdImpl, LinkerPluginLto, LocationDetail, LtoCli, OptLevel, OutputType, + OutputTypes, Passes, SourceFileHashAlgorithm, SwitchWithOptPath, SymbolManglingVersion, + TrimmedDefPaths, }; use crate::lint; use crate::options::WasiExecModel; @@ -2715,6 +2731,7 @@ crate mod dep_tracking { NativeLibKind, SanitizerSet, CFGuard, + CFProtection, TargetTriple, Edition, LinkerPluginLto, diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index ae1b638c344..c069144fa9f 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -380,6 +380,7 @@ mod desc { pub const parse_sanitizer_memory_track_origins: &str = "0, 1, or 2"; pub const parse_cfguard: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`"; + pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)"; pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`"; pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavor::one_of(); pub const parse_optimization_fuel: &str = "crate=integer"; @@ -695,6 +696,25 @@ mod parse { true } + crate fn parse_cfprotection(slot: &mut CFProtection, v: Option<&str>) -> bool { + if v.is_some() { + let mut bool_arg = None; + if parse_opt_bool(&mut bool_arg, v) { + *slot = if bool_arg.unwrap() { CFProtection::Full } else { CFProtection::None }; + return true; + } + } + + *slot = match v { + None | Some("none") => CFProtection::None, + Some("branch") => CFProtection::Branch, + Some("return") => CFProtection::Return, + Some("full") => CFProtection::Full, + Some(_) => return false, + }; + true + } + crate fn parse_linker_flavor(slot: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool { match v.and_then(LinkerFlavor::from_str) { Some(lf) => *slot = Some(lf), @@ -1142,6 +1162,8 @@ options! { "select which borrowck is used (`mir` or `migrate`) (default: `migrate`)"), branch_protection: BranchProtection = (BranchProtection::default(), parse_branch_protection, [TRACKED], "set options for branch target identification and pointer authentication on AArch64"), + cf_protection: CFProtection = (CFProtection::None, parse_cfprotection, [TRACKED], + "instrument control-flow architecture protection"), cgu_partitioning_strategy: Option<String> = (None, parse_opt_string, [TRACKED], "the codegen unit partitioning strategy to use"), chalk: bool = (false, parse_bool, [TRACKED], |
