Skip to content

Commit 4c35022

Browse files
rcvalleRamon de C Valle
authored and
Ramon de C Valle
committed
sanitizers: Add stable and unstable sanitizers
Add suppport for separating sanitizers support in stable and unstable for supported targets.
1 parent 7f2fc33 commit 4c35022

File tree

145 files changed

+607
-339
lines changed

Some content is hidden

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

145 files changed

+607
-339
lines changed

Diff for: compiler/rustc_codegen_llvm/src/abi.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_session::config;
1818
pub use rustc_target::abi::call::*;
1919
use rustc_target::abi::{self, HasDataLayout, Int, Size};
2020
pub use rustc_target::spec::abi::Abi;
21-
use rustc_target::spec::SanitizerSet;
2221

2322
use libc::c_uint;
2423
use smallvec::SmallVec;
@@ -82,7 +81,7 @@ fn get_attrs<'ll>(this: &ArgAttributes, cx: &CodegenCx<'ll, '_>) -> SmallVec<[&'
8281
attrs.push(llattr.create_attr(cx.llcx));
8382
}
8483
}
85-
} else if cx.tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
84+
} else if cx.tcx.sess.is_sanitizer_memory_enabled() {
8685
// If we're not optimising, *but* memory sanitizer is on, emit noundef, since it affects
8786
// memory sanitizer's behavior.
8887

Diff for: compiler/rustc_codegen_llvm/src/attributes.rs

+2-8
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub fn sanitize_attrs<'ll>(
6060
no_sanitize: SanitizerSet,
6161
) -> SmallVec<[&'ll Attribute; 4]> {
6262
let mut attrs = SmallVec::new();
63-
let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize;
63+
let enabled = cx.tcx.sess.opts.cg.sanitizer - no_sanitize;
6464
if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
6565
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
6666
}
@@ -192,13 +192,7 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
192192
// Currently stack probes seem somewhat incompatible with the address
193193
// sanitizer and thread sanitizer. With asan we're already protected from
194194
// stack overflow anyway so we don't really need stack probes regardless.
195-
if cx
196-
.sess()
197-
.opts
198-
.unstable_opts
199-
.sanitizer
200-
.intersects(SanitizerSet::ADDRESS | SanitizerSet::THREAD)
201-
{
195+
if cx.sess().is_sanitizer_address_enabled() || cx.sess().is_sanitizer_thread_enabled() {
202196
return None;
203197
}
204198

Diff for: compiler/rustc_codegen_ssa/src/back/link.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@ fn add_sanitizer_libraries(
12221222
return;
12231223
}
12241224

1225-
let sanitizer = sess.opts.unstable_opts.sanitizer;
1225+
let sanitizer = sess.opts.cg.sanitizer;
12261226
if sanitizer.contains(SanitizerSet::ADDRESS) {
12271227
link_sanitizer_runtime(sess, flavor, linker, "asan");
12281228
}
@@ -2350,11 +2350,7 @@ fn add_order_independent_options(
23502350
&& crate_type == CrateType::Executable
23512351
&& !matches!(flavor, LinkerFlavor::Gnu(Cc::Yes, _))
23522352
{
2353-
let prefix = if sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::ADDRESS) {
2354-
"asan/"
2355-
} else {
2356-
""
2357-
};
2353+
let prefix = if sess.is_sanitizer_address_enabled() { "asan/" } else { "" };
23582354
cmd.arg(format!("--dynamic-linker={prefix}ld.so.1"));
23592355
}
23602356

Diff for: compiler/rustc_codegen_ssa/src/back/symbol_export.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc_middle::ty::{self, SymbolName, TyCtxt};
1616
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
1717
use rustc_middle::util::Providers;
1818
use rustc_session::config::{CrateType, OomStrategy};
19-
use rustc_target::spec::{SanitizerSet, TlsModel};
19+
use rustc_target::spec::TlsModel;
2020

2121
pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
2222
crates_export_threshold(tcx.crate_types())
@@ -265,15 +265,15 @@ fn exported_symbols_provider_local(
265265
}));
266266
}
267267

268-
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::MEMORY) {
268+
if tcx.sess.is_sanitizer_memory_enabled() {
269269
let mut msan_weak_symbols = Vec::new();
270270

271271
// Similar to profiling, preserve weak msan symbol during LTO.
272-
if tcx.sess.opts.unstable_opts.sanitizer_recover.contains(SanitizerSet::MEMORY) {
272+
if tcx.sess.is_sanitizer_memory_enabled() {
273273
msan_weak_symbols.push("__msan_keep_going");
274274
}
275275

276-
if tcx.sess.opts.unstable_opts.sanitizer_memory_track_origins != 0 {
276+
if tcx.sess.is_sanitizer_memory_track_origins_enabled() {
277277
msan_weak_symbols.push("__msan_track_origins");
278278
}
279279

Diff for: compiler/rustc_codegen_ssa/src/back/write.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ impl ModuleConfig {
197197
false
198198
),
199199

200-
sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()),
200+
sanitizer: if_regular!(sess.opts.cg.sanitizer, SanitizerSet::empty()),
201201
sanitizer_dataflow_abilist: if_regular!(
202202
sess.opts.unstable_opts.sanitizer_dataflow_abilist.clone(),
203203
Vec::new()

Diff for: compiler/rustc_interface/src/tests.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ fn test_codegen_options_tracking_hash() {
625625
tracked!(profile_use, Some(PathBuf::from("abc")));
626626
tracked!(relocation_model, Some(RelocModel::Pic));
627627
tracked!(relro_level, Some(RelroLevel::Full));
628+
tracked!(sanitizer, SanitizerSet::ADDRESS);
628629
tracked!(soft_float, true);
629630
tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
630631
tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
@@ -824,7 +825,6 @@ fn test_unstable_options_tracking_hash() {
824825
tracked!(profiler_runtime, "abc".to_string());
825826
tracked!(relax_elf_relocations, Some(true));
826827
tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
827-
tracked!(sanitizer, SanitizerSet::ADDRESS);
828828
tracked!(sanitizer_cfi_canonical_jump_tables, None);
829829
tracked!(sanitizer_cfi_generalize_pointers, Some(true));
830830
tracked!(sanitizer_cfi_normalize_integers, Some(true));

Diff for: compiler/rustc_session/messages.ftl

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ session_branch_protection_requires_aarch64 = `-Zbranch-protection` is only suppo
33
44
session_cannot_enable_crt_static_linux = sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
55
6-
session_cannot_mix_and_match_sanitizers = `-Zsanitizer={$first}` is incompatible with `-Zsanitizer={$second}`
6+
session_cannot_mix_and_match_sanitizers = `-Csanitizer={$first}` is incompatible with `-Csanitizer={$second}`
77
88
session_cli_feature_diagnostic_help =
99
add `-Zcrate-attr="feature({$feature})"` to the command-line options to enable
@@ -86,15 +86,15 @@ session_profile_sample_use_file_does_not_exist = file `{$path}` passed to `-C pr
8686
8787
session_profile_use_file_does_not_exist = file `{$path}` passed to `-C profile-use` does not exist.
8888
89-
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Zsanitizer=cfi`
89+
session_sanitizer_cfi_canonical_jump_tables_requires_cfi = `-Zsanitizer-cfi-canonical-jump-tables` requires `-Csanitizer=cfi`
9090
91-
session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
91+
session_sanitizer_cfi_generalize_pointers_requires_cfi = `-Zsanitizer-cfi-generalize-pointers` requires `-Csanitizer=cfi` or `-Csanitizer=kcfi`
9292
93-
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Zsanitizer=cfi` or `-Zsanitizer=kcfi`
93+
session_sanitizer_cfi_normalize_integers_requires_cfi = `-Zsanitizer-cfi-normalize-integers` requires `-Csanitizer=cfi` or `-Csanitizer=kcfi`
9494
95-
session_sanitizer_cfi_requires_lto = `-Zsanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
95+
session_sanitizer_cfi_requires_lto = `-Csanitizer=cfi` requires `-Clto` or `-Clinker-plugin-lto`
9696
97-
session_sanitizer_cfi_requires_single_codegen_unit = `-Zsanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
97+
session_sanitizer_cfi_requires_single_codegen_unit = `-Csanitizer=cfi` with `-Clto` requires `-Ccodegen-units=1`
9898
9999
session_sanitizer_kcfi_requires_panic_abort = `-Z sanitizer=kcfi` requires `-C panic=abort`
100100

Diff for: compiler/rustc_session/src/config/cfg.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pub(crate) fn default_configuration(sess: &Session) -> Cfg {
131131
ins_sym!(sym::relocation_model, sess.target.relocation_model.desc_symbol());
132132
}
133133

134-
for mut s in sess.opts.unstable_opts.sanitizer {
134+
for mut s in sess.opts.cg.sanitizer {
135135
// KASAN is still ASAN under the hood, so it uses the same attribute.
136136
if s == SanitizerSet::KERNELADDRESS {
137137
s = SanitizerSet::ADDRESS;

Diff for: compiler/rustc_session/src/options.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,8 @@ options! {
15541554
"output remarks for these optimization passes (space separated, or \"all\")"),
15551555
rpath: bool = (false, parse_bool, [UNTRACKED],
15561556
"set rpath values in libs/exes (default: no)"),
1557+
sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
1558+
"use a sanitizer"),
15571559
save_temps: bool = (false, parse_bool, [UNTRACKED],
15581560
"save all temporary output files during compilation (default: no)"),
15591561
soft_float: bool = (false, parse_bool, [TRACKED],
@@ -1907,8 +1909,6 @@ options! {
19071909
remark_dir: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
19081910
"directory into which to write optimization remarks (if not specified, they will be \
19091911
written to standard error output)"),
1910-
sanitizer: SanitizerSet = (SanitizerSet::empty(), parse_sanitizers, [TRACKED],
1911-
"use a sanitizer"),
19121912
sanitizer_cfi_canonical_jump_tables: Option<bool> = (Some(true), parse_opt_bool, [TRACKED],
19131913
"enable canonical jump tables (default: yes)"),
19141914
sanitizer_cfi_generalize_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],

Diff for: compiler/rustc_session/src/session.rs

+28-11
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,12 @@ impl Session {
356356
self.instrument_coverage() && self.opts.unstable_opts.coverage_options.mcdc
357357
}
358358

359+
pub fn is_sanitizer_address_enabled(&self) -> bool {
360+
self.opts.cg.sanitizer.contains(SanitizerSet::ADDRESS)
361+
}
362+
359363
pub fn is_sanitizer_cfi_enabled(&self) -> bool {
360-
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::CFI)
364+
self.opts.cg.sanitizer.contains(SanitizerSet::CFI)
361365
}
362366

363367
pub fn is_sanitizer_cfi_canonical_jump_tables_disabled(&self) -> bool {
@@ -377,7 +381,19 @@ impl Session {
377381
}
378382

379383
pub fn is_sanitizer_kcfi_enabled(&self) -> bool {
380-
self.opts.unstable_opts.sanitizer.contains(SanitizerSet::KCFI)
384+
self.opts.cg.sanitizer.contains(SanitizerSet::KCFI)
385+
}
386+
387+
pub fn is_sanitizer_memory_enabled(&self) -> bool {
388+
self.opts.cg.sanitizer.contains(SanitizerSet::MEMORY)
389+
}
390+
391+
pub fn is_sanitizer_memory_track_origins_enabled(&self) -> bool {
392+
self.opts.unstable_opts.sanitizer_memory_track_origins != 0
393+
}
394+
395+
pub fn is_sanitizer_thread_enabled(&self) -> bool {
396+
self.opts.cg.sanitizer.contains(SanitizerSet::THREAD)
381397
}
382398

383399
pub fn is_split_lto_unit_enabled(&self) -> bool {
@@ -595,7 +611,7 @@ impl Session {
595611
// AddressSanitizer and KernelAddressSanitizer uses lifetimes to detect use after scope bugs.
596612
// MemorySanitizer uses lifetimes to detect use of uninitialized stack variables.
597613
// HWAddressSanitizer will use lifetimes to detect use after scope bugs in the future.
598-
|| self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
614+
|| self.opts.cg.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::KERNELADDRESS | SanitizerSet::MEMORY | SanitizerSet::HWADDRESS)
599615
}
600616

601617
pub fn diagnostic_width(&self) -> usize {
@@ -722,7 +738,7 @@ impl Session {
722738
let more_names = self.opts.output_types.contains_key(&OutputType::LlvmAssembly)
723739
|| self.opts.output_types.contains_key(&OutputType::Bitcode)
724740
// AddressSanitizer and MemorySanitizer use alloca name when reporting an issue.
725-
|| self.opts.unstable_opts.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY);
741+
|| self.opts.cg.sanitizer.intersects(SanitizerSet::ADDRESS | SanitizerSet::MEMORY);
726742
!more_names
727743
}
728744
}
@@ -1167,8 +1183,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
11671183
}
11681184

11691185
// Sanitizers can only be used on platforms that we know have working sanitizer codegen.
1170-
let supported_sanitizers = sess.target.options.supported_sanitizers;
1171-
let unsupported_sanitizers = sess.opts.unstable_opts.sanitizer - supported_sanitizers;
1186+
let supported_sanitizers = if sess.unstable_options() {
1187+
sess.target.options.supported_sanitizers.supported_sanitizers()
1188+
} else {
1189+
sess.target.options.supported_sanitizers.stable_sanitizers()
1190+
};
1191+
let unsupported_sanitizers = sess.opts.cg.sanitizer - supported_sanitizers;
11721192
match unsupported_sanitizers.into_iter().count() {
11731193
0 => {}
11741194
1 => {
@@ -1182,7 +1202,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
11821202
}
11831203
}
11841204
// Cannot mix and match sanitizers.
1185-
let mut sanitizer_iter = sess.opts.unstable_opts.sanitizer.into_iter();
1205+
let mut sanitizer_iter = sess.opts.cg.sanitizer.into_iter();
11861206
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
11871207
sess.dcx().emit_err(errors::CannotMixAndMatchSanitizers {
11881208
first: first.to_string(),
@@ -1191,10 +1211,7 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
11911211
}
11921212

11931213
// Cannot enable crt-static with sanitizers on Linux
1194-
if sess.crt_static(None)
1195-
&& !sess.opts.unstable_opts.sanitizer.is_empty()
1196-
&& !sess.target.is_like_msvc
1197-
{
1214+
if sess.crt_static(None) && !sess.opts.cg.sanitizer.is_empty() && !sess.target.is_like_msvc {
11981215
sess.dcx().emit_err(errors::CannotEnableCrtStaticLinux);
11991216
}
12001217

Diff for: compiler/rustc_target/src/spec/base/android.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::spec::{base, SanitizerSet, TargetOptions, TlsModel};
1+
use crate::spec::{base, SanitizerSet, SanitizerSupport, TargetOptions, TlsModel};
22

33
pub fn opts() -> TargetOptions {
44
let mut base = base::linux::opts();
@@ -7,7 +7,8 @@ pub fn opts() -> TargetOptions {
77
base.default_dwarf_version = 2;
88
base.tls_model = TlsModel::Emulated;
99
base.has_thread_local = false;
10-
base.supported_sanitizers = SanitizerSet::ADDRESS;
10+
base.supported_sanitizers =
11+
SanitizerSupport { stable: SanitizerSet::empty(), unstable: SanitizerSet::ADDRESS };
1112
// This is for backward compatibility, see https://github.com/rust-lang/rust/issues/49867
1213
// for context. (At that time, there was no `-C force-unwind-tables`, so the only solution
1314
// was to always emit `uwtable`).

0 commit comments

Comments
 (0)