diff options
Diffstat (limited to 'compiler/rustc_session/src')
| -rw-r--r-- | compiler/rustc_session/src/config.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_session/src/errors.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_session/src/options.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_session/src/session.rs | 74 |
4 files changed, 99 insertions, 11 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 79eb31bb105..1252bbe66d1 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1036,6 +1036,14 @@ fn default_configuration(sess: &Session) -> CrateConfig { ret.insert((sym::sanitize, Some(symbol))); } + if sess.is_sanitizer_cfi_generalize_pointers_enabled() { + ret.insert((sym::sanitizer_cfi_generalize_pointers, None)); + } + + if sess.is_sanitizer_cfi_normalize_integers_enabled() { + ret.insert((sym::sanitizer_cfi_normalize_integers, None)); + } + if sess.opts.debug_assertions { ret.insert((sym::debug_assertions, None)); } diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index bd32adbbdbb..0df62c2064e 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -111,8 +111,24 @@ pub struct CannotMixAndMatchSanitizers { pub struct CannotEnableCrtStaticLinux; #[derive(Diagnostic)] -#[diag(session_sanitizer_cfi_enabled)] -pub struct SanitizerCfiEnabled; +#[diag(session_sanitizer_cfi_requires_lto)] +pub struct SanitizerCfiRequiresLto; + +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_canonical_jump_tables_requires_cfi)] +pub struct SanitizerCfiCanonicalJumpTablesRequiresCfi; + +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_generalize_pointers_requires_cfi)] +pub struct SanitizerCfiGeneralizePointersRequiresCfi; + +#[derive(Diagnostic)] +#[diag(session_sanitizer_cfi_normalize_integers_requires_cfi)] +pub struct SanitizerCfiNormalizeIntegersRequiresCfi; + +#[derive(Diagnostic)] +#[diag(session_split_lto_unit_requires_lto)] +pub struct SplitLtoUnitRequiresLto; #[derive(Diagnostic)] #[diag(session_unstable_virtual_function_elimination)] diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 8e8ad72ec8a..d75b09b12dd 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1659,6 +1659,12 @@ options! { "immediately print bugs registered with `delay_span_bug` (default: no)"), sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], "use a sanitizer"), + sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED], + "enable canonical jump tables (default: yes)"), + sanitizer_cfi_generalize_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED], + "enable generalizing pointer types (default: no)"), + sanitizer_cfi_normalize_integers: Option<bool> = (None, parse_opt_bool, [TRACKED], + "enable normalizing integer types (default: no)"), sanitizer_memory_track_origins: usize = (0, parse_sanitizer_memory_track_origins, [TRACKED], "enable origins tracking in MemorySanitizer"), sanitizer_recover: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED], @@ -1704,6 +1710,8 @@ options! { file which is ignored by the linker `single`: sections which do not require relocation are written into object file but ignored by the linker"), + split_lto_unit: Option<bool> = (None, parse_opt_bool, [TRACKED], + "enable LTO unit splitting (default: no)"), src_hash_algorithm: Option<SourceFileHashAlgorithm> = (None, parse_src_file_hash, [TRACKED], "hash algorithm of source files in debug info (`md5`, `sha1`, or `sha256`)"), #[rustc_lint_opt_deny_field_access("use `Session::stack_protector` instead of this field")] diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 14a8e8ff727..fcae6873135 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -766,10 +766,30 @@ impl Session { self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI) } + pub fn is_sanitizer_cfi_canonical_jump_tables_disabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_canonical_jump_tables == Some(false) + } + + pub fn is_sanitizer_cfi_canonical_jump_tables_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_canonical_jump_tables == Some(true) + } + + pub fn is_sanitizer_cfi_generalize_pointers_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_generalize_pointers == Some(true) + } + + pub fn is_sanitizer_cfi_normalize_integers_enabled(&self) -> bool { + self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true) + } + pub fn is_sanitizer_kcfi_enabled(&self) -> bool { self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) } + pub fn is_split_lto_unit_enabled(&self) -> bool { + self.opts.unstable_opts.split_lto_unit == Some(true) + } + /// Check whether this compile session and crate type use static crt. pub fn crt_static(&self, crate_type: Option<CrateType>) -> bool { if !self.target.crt_static_respected { @@ -1581,17 +1601,16 @@ fn validate_commandline_args_with_session_available(sess: &Session) { sess.emit_err(errors::CannotEnableCrtStaticLinux); } - // LLVM CFI and VFE both require LTO. - if sess.lto() != config::Lto::Fat { - if sess.is_sanitizer_cfi_enabled() { - sess.emit_err(errors::SanitizerCfiEnabled); - } - if sess.opts.unstable_opts.virtual_function_elimination { - sess.emit_err(errors::UnstableVirtualFunctionElimination); - } + // LLVM CFI requires LTO. + if sess.is_sanitizer_cfi_enabled() + && !(sess.lto() == config::Lto::Fat + || sess.lto() == config::Lto::Thin + || sess.opts.cg.linker_plugin_lto.enabled()) + { + sess.emit_err(errors::SanitizerCfiRequiresLto); } - // LLVM CFI and KCFI are mutually exclusive + // LLVM CFI is incompatible with LLVM KCFI. if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() { sess.emit_err(errors::CannotMixAndMatchSanitizers { first: "cfi".to_string(), @@ -1599,6 +1618,43 @@ fn validate_commandline_args_with_session_available(sess: &Session) { }); } + // Canonical jump tables requires CFI. + if sess.is_sanitizer_cfi_canonical_jump_tables_disabled() { + if !sess.is_sanitizer_cfi_enabled() { + sess.emit_err(errors::SanitizerCfiCanonicalJumpTablesRequiresCfi); + } + } + + // LLVM CFI pointer generalization requires CFI or KCFI. + if sess.is_sanitizer_cfi_generalize_pointers_enabled() { + if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) { + sess.emit_err(errors::SanitizerCfiGeneralizePointersRequiresCfi); + } + } + + // LLVM CFI integer normalization requires CFI or KCFI. + if sess.is_sanitizer_cfi_normalize_integers_enabled() { + if !(sess.is_sanitizer_cfi_enabled() || sess.is_sanitizer_kcfi_enabled()) { + sess.emit_err(errors::SanitizerCfiNormalizeIntegersRequiresCfi); + } + } + + // LTO unit splitting requires LTO. + if sess.is_split_lto_unit_enabled() + && !(sess.lto() == config::Lto::Fat + || sess.lto() == config::Lto::Thin + || sess.opts.cg.linker_plugin_lto.enabled()) + { + sess.emit_err(errors::SplitLtoUnitRequiresLto); + } + + // VFE requires LTO. + if sess.lto() != config::Lto::Fat { + if sess.opts.unstable_opts.virtual_function_elimination { + sess.emit_err(errors::UnstableVirtualFunctionElimination); + } + } + if sess.opts.unstable_opts.stack_protector != StackProtector::None { if !sess.target.options.supports_stack_protector { sess.emit_warning(errors::StackProtectorNotSupportedForTarget { |
