Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use rustc_session::{Session, config};
use rustc_target::callconv::{
ArgAbi, ArgAttribute, ArgAttributes, ArgExtension, CastTarget, FnAbi, PassMode,
};
use rustc_target::spec::SanitizerSet;
use smallvec::SmallVec;

use crate::attributes::{self, llfn_attrs_from_instance};
Expand Down Expand Up @@ -92,7 +91,7 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
attrs.push(llattr.create_attr(cx.llcx));
}
}
} else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
} else if cx.tcx.sess.is_sanitizer_memory_enabled() {
// If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
// memory sanitizer's behavior.

Expand Down
10 changes: 2 additions & 8 deletions compiler/rustc_codegen_llvm/src/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>(
no_sanitize: SanitizerSet,
) -> SmallVec<[&'ll Attribute; 4]> {
let mut attrs = SmallVec::new();
let enabled = tcx.sess.opts.unstable_opts.sanitizer - no_sanitize;
let enabled = tcx.sess.opts.cg.sanitize - no_sanitize;
if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
}
Expand Down Expand Up @@ -239,13 +239,7 @@ fn probestack_attr<'ll, 'tcx>(cx: &SimpleCx<'ll>, tcx: TyCtxt<'tcx>) -> Option<&
// Currently stack probes seem somewhat incompatible with the address
// sanitizer and thread sanitizer. With asan we're already protected from
// stack overflow anyway so we don't really need stack probes regardless.
if tcx
.sess
.opts
.unstable_opts
.sanitizer
.intersects(SanitizerSet::ADDRESS | SanitizerSet::THREAD)
{
if tcx.sess.is_sanitizer_address_enabled() || tcx.sess.is_sanitizer_thread_enabled() {
return None;
}

Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_codegen_ssa/src/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,7 @@ fn add_sanitizer_libraries(
return;
}

let sanitizer = sess.opts.unstable_opts.sanitizer;
let sanitizer = sess.opts.cg.sanitize;
if sanitizer.contains(SanitizerSet::ADDRESS) {
link_sanitizer_runtime(sess, flavor, linker, "asan");
}
Expand Down Expand Up @@ -2496,11 +2496,7 @@ fn add_order_independent_options(
&& crate_type == CrateType::Executable
&& !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
{
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
"asan/"
} else {
""
};
let prefix = if sess.is_sanitizer_address_enabled() { "asan/" } else { "" };
cmd.link_arg(format!("--dynamic-linker={prefix}ld.so.1"));
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl ModuleConfig {
debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling,
instrument_coverage: if_regular!(sess.instrument_coverage(), false),

sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()),
sanitizer: if_regular!(sess.opts.cg.sanitize, SanitizerSet::empty()),
sanitizer_dataflow_abilist: if_regular!(
sess.opts.unstable_opts.sanitizer_dataflow_abilist.clone(),
Vec::new()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ fn test_codegen_options_tracking_hash() {
tracked!(profile_use, Some(PathBuf::from("abc")));
tracked!(relocation_model, Some(RelocModel::Pic));
tracked!(relro_level, Some(RelroLevel::Full));
tracked!(sanitize, SanitizerSet::ADDRESS);
tracked!(soft_float, true);
tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
Expand Down Expand Up @@ -858,7 +859,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(regparm, Some(3));
tracked!(relax_elf_relocations, Some(true));
tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
tracked!(sanitizer, SanitizerSet::ADDRESS);
tracked!(sanitizer_cfi_canonical_jump_tables, None);
tracked!(sanitizer_cfi_generalize_pointers, Some(true));
tracked!(sanitizer_cfi_normalize_integers, Some(true));
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/native_libs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ pub fn walk_native_lib_search_dirs<R>(
|| sess.target.os == "linux"
|| sess.target.os == "fuchsia"
|| sess.target.is_like_aix
|| sess.target.is_like_darwin && !sess.opts.unstable_opts.sanitizer.is_empty()
|| sess.target.is_like_darwin && !sess.opts.cg.sanitize.is_empty()
{
f(&sess.target_tlib_path.dir, false)?;
}
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_session/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only suppo
session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`
session_cannot_mix_and_match_sanitizers = `-Csanitize={$first}` is incompatible with `-Csanitize={$second}`
session_cli_feature_diagnostic_help =
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
Expand Down Expand Up @@ -92,15 +92,15 @@ session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C pr
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Csanitize=cfi`
session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Csanitize=cfi` or `-Csanitize=kcfi`
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Csanitize=cfi` or `-Csanitize=kcfi`
session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
session_sanitizer_cfi_requires_lto = `-Csanitize=cfi` requires `-Clto` or `-Clinker-plugin-lto`
session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
session_sanitizer_cfi_requires_single_codegen_unit = `-Csanitize=cfi` with `-Clto` requires `-Ccodegen-units=1`
session_sanitizer_kcfi_arity_requires_kcfi = `-Zsanitizer-kcfi-arity` requires `-Zsanitizer=kcfi`
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_session/src/config/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
ins_sym!(sym::relocation_model, sess.target.relocation_model.desc_symbol());
}

for mut s in sess.opts.unstable_opts.sanitizer {
for mut s in sess.opts.cg.sanitize {
// KASAN is still ASAN under the hood, so it uses the same attribute.
if s == SanitizerSet::KERNELADDRESS {
s = SanitizerSet::ADDRESS;
Expand Down
44 changes: 18 additions & 26 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ mod target_modifier_consistency_check {
r: Option<&TargetModifier>,
) -> bool {
// For kCFI, the helper flag -Zsanitizer-cfi-normalize-integers should also be a target modifier
if opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI) {
if opts.cg.sanitize.contains(SanitizerSet::KCFI) {
if let Some(r) = r {
return l.extend().tech_value == r.extend().tech_value;
} else {
Expand All @@ -136,18 +136,19 @@ impl TargetModifier {
pub fn consistent(&self, opts: &Options, other: Option<&TargetModifier>) -> bool {
assert!(other.is_none() || self.opt == other.unwrap().opt);
match self.opt {
OptionsTargetModifiers::UnstableOptions(unstable) => match unstable {
UnstableOptionsTargetModifiers::sanitizer => {
OptionsTargetModifiers::CodegenOptions(stable) => match stable {
CodegenOptionsTargetModifiers::sanitize => {
return target_modifier_consistency_check::sanitizer(self, other);
}
},
OptionsTargetModifiers::UnstableOptions(unstable) => match unstable {
UnstableOptionsTargetModifiers::sanitizer_cfi_normalize_integers => {
return target_modifier_consistency_check::sanitizer_cfi_normalize_integers(
opts, self, other,
);
}
_ => {}
},
_ => {}
};
match other {
Some(other) => self.extend().tech_value == other.extend().tech_value,
Expand Down Expand Up @@ -1239,25 +1240,14 @@ pub mod parse {
}

pub(crate) fn parse_sanitizers(slot: &mut SanitizerSet, v: Option<&str>) -> bool {
if let Some(v) = v {
for s in v.split(',') {
*slot |= match s {
"address" => SanitizerSet::ADDRESS,
"cfi" => SanitizerSet::CFI,
"dataflow" => SanitizerSet::DATAFLOW,
"kcfi" => SanitizerSet::KCFI,
"kernel-address" => SanitizerSet::KERNELADDRESS,
"leak" => SanitizerSet::LEAK,
"memory" => SanitizerSet::MEMORY,
"memtag" => SanitizerSet::MEMTAG,
"shadow-call-stack" => SanitizerSet::SHADOWCALLSTACK,
"thread" => SanitizerSet::THREAD,
"hwaddress" => SanitizerSet::HWADDRESS,
"safestack" => SanitizerSet::SAFESTACK,
_ => return false,
}
if let Some(s) = v {
let sanitizer_set = SanitizerSet::from_comma_list(s);
if sanitizer_set.is_ok() {
*slot |= sanitizer_set.unwrap();
true
} else {
false
}
true
} else {
false
}
Expand Down Expand Up @@ -2158,8 +2148,8 @@ options! {
"output remarks for these optimization passes (space separated, or \"all\")"),
rpath: bool = (false, parse_bool, [UNTRACKED],
"set rpath values in libs/exes (default: no)"),
save_temps: bool = (false, parse_bool, [UNTRACKED],
"save all temporary output files during compilation (default: no)"),
sanitize: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER],
"use one or multiple sanitizers"),
soft_float: bool = (false, parse_bool, [TRACKED],
"deprecated option: use soft float ABI (*eabihf targets only) (default: no)"),
#[rustc_lint_opt_deny_field_access("use `Session::split_debuginfo` instead of this field")]
Expand All @@ -2177,6 +2167,8 @@ options! {
This feature is unsafe."),
unsafe_allow_abi_mismatch: Vec<String> = (Vec::new(), parse_comma_list, [UNTRACKED],
"Allow incompatible target modifiers in dependency crates (comma separated list)"),
save_temps: bool = (false, parse_bool, [UNTRACKED],
"Allow incompatible target modifiers in dependency crates (comma separated list)"),
// tidy-alphabetical-end

// If you add a new option, please update:
Expand Down Expand Up @@ -2575,8 +2567,6 @@ written to standard error output)"),
retpoline_external_thunk: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
"enables retpoline-external-thunk, retpoline-indirect-branches and retpoline-indirect-calls \
target features (default: no)"),
sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER],
"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],
Expand All @@ -2594,6 +2584,8 @@ written to standard error output)"),
saturating_float_casts: Option<bool> = (None, parse_opt_bool, [TRACKED],
"make float->int casts UB-free: numbers outside the integer type's range are clipped to \
the max/min integer respectively, and NaN is mapped to 0 (default: yes)"),
sanitize: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED TARGET_MODIFIER],
"use one or multiple sanitizers"),
self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
parse_switch_with_opt_path, [UNTRACKED],
"run the self profiler and output the raw event data"),
Expand Down
57 changes: 45 additions & 12 deletions compiler/rustc_session/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,12 @@ impl Session {
&self.opts.unstable_opts.coverage_options
}

pub fn is_sanitizer_address_enabled(&self) -> bool {
self.opts.cg.sanitize.contains(SanitizerSet::ADDRESS)
}

pub fn is_sanitizer_cfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
self.opts.cg.sanitize.contains(SanitizerSet::CFI)
}

pub fn is_sanitizer_cfi_canonical_jump_tables_disabled(&self) -> bool {
Expand All @@ -348,12 +352,36 @@ impl Session {
self.opts.unstable_opts.sanitizer_cfi_normalize_integers == Some(true)
}

pub fn is_sanitizer_hwaddress_enabled(&self) -> bool {
self.opts.cg.sanitize.contains(SanitizerSet::HWADDRESS)
}

pub fn is_sanitizer_kcfi_arity_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer_kcfi_arity == Some(true)
}

pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
self.opts.cg.sanitize.contains(SanitizerSet::KCFI)
}

pub fn is_sanitizer_kernel_address_enabled(&self) -> bool {
self.opts.cg.sanitize.contains(SanitizerSet::KERNELADDRESS)
}

pub fn is_sanitizer_memory_enabled(&self) -> bool {
self.opts.cg.sanitize.contains(SanitizerSet::MEMORY)
}

pub fn is_sanitizer_memory_recover_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY)
}

pub fn is_sanitizer_memory_track_origins_enabled(&self) -> bool {
self.opts.unstable_opts.sanitizer_memory_track_origins != 0
}

pub fn is_sanitizer_thread_enabled(&self) -> bool {
self.opts.cg.sanitize.contains(SanitizerSet::THREAD)
}

pub fn is_split_lto_unit_enabled(&self) -> bool {
Expand Down Expand Up @@ -533,7 +561,10 @@ impl Session {
// AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs.
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
|| self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
|| self.is_sanitizer_address_enabled()
|| self.is_sanitizer_kernel_address_enabled()
|| self.is_sanitizer_memory_enabled()
|| self.is_sanitizer_hwaddress_enabled()
}

pub fn diagnostic_width(&self) -> usize {
Expand Down Expand Up @@ -683,7 +714,7 @@ impl Session {
let more_names = self.opts.output_types.contains_key(&OutputType::LlvmAssembly)
|| self.opts.output_types.contains_key(&OutputType::Bitcode)
// AddressSanitizer and MemorySanitizer use alloca name when reporting an issue.
|| self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY);
|| self.is_sanitizer_address_enabled() || self.is_sanitizer_memory_enabled();
!more_names
}
}
Expand Down Expand Up @@ -1187,14 +1218,19 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}
}

// Sanitizers can only be used on platforms that we know have working sanitizer codegen.
let supported_sanitizers = sess.target.options.supported_sanitizers;
let mut unsupported_sanitizers = sess.opts.unstable_opts.sanitizer - supported_sanitizers;
let supported_sanitizers = if sess.unstable_options() {
sess.target.options.supported_sanitizers | sess.target.options.stable_sanitizers
} else {
sess.target.options.stable_sanitizers
};
let mut unsupported_sanitizers = sess.opts.cg.sanitize - supported_sanitizers;

// Niche: if `fixed-x18`, or effectively switching on `reserved-x18` flag, is enabled
// we should allow Shadow Call Stack sanitizer.
if sess.opts.unstable_opts.fixed_x18 && sess.target.arch == "aarch64" {
unsupported_sanitizers -= SanitizerSet::SHADOWCALLSTACK;
}

match unsupported_sanitizers.into_iter().count() {
0 => {}
1 => {
Expand All @@ -1209,18 +1245,15 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
}

// Cannot mix and match mutually-exclusive sanitizers.
if let Some((first, second)) = sess.opts.unstable_opts.sanitizer.mutually_exclusive() {
if let Some((first, second)) = sess.opts.cg.sanitize.mutually_exclusive() {
sess.dcx().emit_err(errors::CannotMixAndMatchSanitizers {
first: first.to_string(),
second: second.to_string(),
});
}

// Cannot enable crt-static with sanitizers on Linux
if sess.crt_static(None)
&& !sess.opts.unstable_opts.sanitizer.is_empty()
&& !sess.target.is_like_msvc
{
if sess.crt_static(None) && !sess.opts.cg.sanitize.is_empty() && !sess.target.is_like_msvc {
sess.dcx().emit_err(errors::CannotEnableCrtStaticLinux);
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use super::crt_objects::CrtObjects;
use super::{
BinaryFormat, CodeModel, DebuginfoKind, FloatAbi, FramePointer, LinkArgsCli,
LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFlavorCli, LldFlavor,
MergeFunctions, PanicStrategy, RelocModel, RelroLevel, RustcAbi, SanitizerSet,
MergeFunctions, PanicStrategy, RelocModel, RelroLevel, RustcAbi,
SmallDataThresholdSupport, SplitDebuginfo, StackProbeType, StaticCow, SymbolVisibility, Target,
TargetKind, TargetOptions, TargetWarnings, TlsModel,
};
use crate::json::{Json, ToJson};
use crate::spec::AbiMap;
use crate::spec::{AbiMap, SanitizerSet};

impl Target {
/// Loads a target descriptor from a JSON object.
Expand Down Expand Up @@ -392,6 +392,7 @@ impl ToJson for Target {
target_option_val!(split_debuginfo);
target_option_val!(supported_split_debuginfo);
target_option_val!(supported_sanitizers);
target_option_val!(stable_sanitizers);
target_option_val!(c_enum_min_bits);
target_option_val!(generate_arange_section);
target_option_val!(supports_stack_protector);
Expand Down
Loading