diff options
| author | Andrew Brown <andrew.brown@intel.com> | 2022-01-28 09:48:59 -0800 |
|---|---|---|
| committer | Andrew Brown <andrew.brown@intel.com> | 2022-02-14 08:31:24 -0800 |
| commit | 8d6c973c7f77e63a9c5d1ce4b7c71a37fcc46f4d (patch) | |
| tree | 03755fd5c6fcf21d8ba43522d9ec872398b46dcd /compiler/rustc_session | |
| parent | b321742c6c27494897a88cd5ac17ac20aa3469a1 (diff) | |
| download | rust-8d6c973c7f77e63a9c5d1ce4b7c71a37fcc46f4d.tar.gz rust-8d6c973c7f77e63a9c5d1ce4b7c71a37fcc46f4d.zip | |
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>`. Co-authored-by: BlackHoleFox <blackholefoxdev@gmail.com>
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], |
