Skip to content

Commit 91e927d

Browse files
author
David Koloski
committed
Relax restrictions on multiple sanitizers
Most combinations of LLVM sanitizers are legal-enough to enable simultaneously. This change will allow simultaneously enabling ASAN and shadow call stacks on supported platforms.
1 parent 982a58e commit 91e927d

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

compiler/rustc_session/src/session.rs

+3-11
Original file line numberDiff line numberDiff line change
@@ -1181,9 +1181,9 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
11811181
});
11821182
}
11831183
}
1184-
// Cannot mix and match sanitizers.
1185-
let mut sanitizer_iter = sess.opts.unstable_opts.sanitizer.into_iter();
1186-
if let (Some(first), Some(second)) = (sanitizer_iter.next(), sanitizer_iter.next()) {
1184+
1185+
// Cannot mix and match mutually-exclusive sanitizers.
1186+
if let Some((first, second)) = sess.opts.unstable_opts.sanitizer.mutually_exclusive() {
11871187
sess.dcx().emit_err(errors::CannotMixAndMatchSanitizers {
11881188
first: first.to_string(),
11891189
second: second.to_string(),
@@ -1218,14 +1218,6 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
12181218
sess.dcx().emit_err(errors::SanitizerCfiRequiresSingleCodegenUnit);
12191219
}
12201220

1221-
// LLVM CFI is incompatible with LLVM KCFI.
1222-
if sess.is_sanitizer_cfi_enabled() && sess.is_sanitizer_kcfi_enabled() {
1223-
sess.dcx().emit_err(errors::CannotMixAndMatchSanitizers {
1224-
first: "cfi".to_string(),
1225-
second: "kcfi".to_string(),
1226-
});
1227-
}
1228-
12291221
// Canonical jump tables requires CFI.
12301222
if sess.is_sanitizer_cfi_canonical_jump_tables_disabled() {
12311223
if !sess.is_sanitizer_cfi_enabled() {

compiler/rustc_target/src/spec/mod.rs

+33
Original file line numberDiff line numberDiff line change
@@ -1316,6 +1316,32 @@ bitflags::bitflags! {
13161316
rustc_data_structures::external_bitflags_debug! { SanitizerSet }
13171317

13181318
impl SanitizerSet {
1319+
const MUTUALLY_EXCLUSIVE: &'static [(SanitizerSet, SanitizerSet)] = &[
1320+
(SanitizerSet::MEMORY, SanitizerSet::ADDRESS),
1321+
(SanitizerSet::MEMORY, SanitizerSet::LEAK),
1322+
(SanitizerSet::THREAD, SanitizerSet::ADDRESS),
1323+
(SanitizerSet::THREAD, SanitizerSet::LEAK),
1324+
(SanitizerSet::THREAD, SanitizerSet::MEMORY),
1325+
(SanitizerSet::HWADDRESS, SanitizerSet::ADDRESS),
1326+
(SanitizerSet::HWADDRESS, SanitizerSet::MEMORY),
1327+
(SanitizerSet::HWADDRESS, SanitizerSet::THREAD),
1328+
(SanitizerSet::MEMTAG, SanitizerSet::ADDRESS),
1329+
(SanitizerSet::MEMTAG, SanitizerSet::HWADDRESS),
1330+
(SanitizerSet::KCFI, SanitizerSet::CFI),
1331+
(SanitizerSet::KERNELADDRESS, SanitizerSet::ADDRESS),
1332+
(SanitizerSet::KERNELADDRESS, SanitizerSet::LEAK),
1333+
(SanitizerSet::KERNELADDRESS, SanitizerSet::MEMORY),
1334+
(SanitizerSet::KERNELADDRESS, SanitizerSet::THREAD),
1335+
(SanitizerSet::KERNELADDRESS, SanitizerSet::HWADDRESS),
1336+
(SanitizerSet::KERNELADDRESS, SanitizerSet::MEMTAG),
1337+
(SanitizerSet::SAFESTACK, SanitizerSet::ADDRESS),
1338+
(SanitizerSet::SAFESTACK, SanitizerSet::LEAK),
1339+
(SanitizerSet::SAFESTACK, SanitizerSet::MEMORY),
1340+
(SanitizerSet::SAFESTACK, SanitizerSet::THREAD),
1341+
(SanitizerSet::SAFESTACK, SanitizerSet::HWADDRESS),
1342+
(SanitizerSet::SAFESTACK, SanitizerSet::KERNELADDRESS),
1343+
];
1344+
13191345
/// Return sanitizer's name
13201346
///
13211347
/// Returns none if the flags is a set of sanitizers numbering not exactly one.
@@ -1336,6 +1362,13 @@ impl SanitizerSet {
13361362
_ => return None,
13371363
})
13381364
}
1365+
1366+
pub fn mutually_exclusive(self) -> Option<(SanitizerSet, SanitizerSet)> {
1367+
Self::MUTUALLY_EXCLUSIVE
1368+
.into_iter()
1369+
.find(|&(a, b)| self.contains(*a) && self.contains(*b))
1370+
.copied()
1371+
}
13391372
}
13401373

13411374
/// Formats a sanitizer set as a comma separated list of sanitizers' names.

0 commit comments

Comments
 (0)