Skip to content

Commit 5dbccd2

Browse files
committed
add realtime sanitizer
1 parent a242c85 commit 5dbccd2

File tree

34 files changed

+240
-38
lines changed

34 files changed

+240
-38
lines changed

compiler/rustc_attr_parsing/src/attributes/codegen_attrs.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, SanitizerSet, UsedBy};
1+
use rustc_hir::attrs::{CoverageAttrKind, OptimizeAttr, RtsanSetting, SanitizerSet, UsedBy};
22
use rustc_session::parse::feature_err;
33

44
use super::prelude::*;
@@ -592,7 +592,8 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
592592
r#"memory = "on|off""#,
593593
r#"memtag = "on|off""#,
594594
r#"shadow_call_stack = "on|off""#,
595-
r#"thread = "on|off""#
595+
r#"thread = "on|off""#,
596+
r#"realtime = "nonblocking|blocking|caller""#,
596597
]);
597598

598599
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
@@ -606,6 +607,7 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
606607

607608
let mut on_set = SanitizerSet::empty();
608609
let mut off_set = SanitizerSet::empty();
610+
let mut rtsan = None;
609611

610612
for item in list.mixed() {
611613
let Some(item) = item.meta_item() else {
@@ -654,6 +656,17 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
654656
Some(sym::shadow_call_stack) => apply(SanitizerSet::SHADOWCALLSTACK),
655657
Some(sym::thread) => apply(SanitizerSet::THREAD),
656658
Some(sym::hwaddress) => apply(SanitizerSet::HWADDRESS),
659+
Some(sym::realtime) => match value.value_as_str() {
660+
Some(sym::nonblocking) => rtsan = Some(RtsanSetting::Nonblocking),
661+
Some(sym::blocking) => rtsan = Some(RtsanSetting::Blocking),
662+
Some(sym::caller) => rtsan = Some(RtsanSetting::Caller),
663+
_ => {
664+
cx.expected_specific_argument_strings(
665+
value.value_span,
666+
&[sym::nonblocking, sym::blocking, sym::caller],
667+
);
668+
}
669+
},
657670
_ => {
658671
cx.expected_specific_argument_strings(
659672
item.path().span(),
@@ -666,13 +679,14 @@ impl<S: Stage> SingleAttributeParser<S> for SanitizeParser {
666679
sym::shadow_call_stack,
667680
sym::thread,
668681
sym::hwaddress,
682+
sym::realtime,
669683
],
670684
);
671685
continue;
672686
}
673687
}
674688
}
675689

676-
Some(AttributeKind::Sanitize { on_set, off_set, span: cx.attr_span })
690+
Some(AttributeKind::Sanitize { on_set, off_set, rtsan, span: cx.attr_span })
677691
}
678692
}

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Set and unset common attributes on LLVM values.
2-
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr};
2+
use rustc_hir::attrs::{InlineAttr, InstructionSetAttr, OptimizeAttr, RtsanSetting};
33
use rustc_hir::def_id::DefId;
44
use rustc_middle::middle::codegen_fn_attrs::{
55
CodegenFnAttrFlags, CodegenFnAttrs, PatchableFunctionEntry, SanitizerFnAttrs,
@@ -131,6 +131,18 @@ pub(crate) fn sanitize_attrs<'ll, 'tcx>(
131131
if enabled.contains(SanitizerSet::SAFESTACK) {
132132
attrs.push(llvm::AttributeKind::SanitizeSafeStack.create_attr(cx.llcx));
133133
}
134+
if tcx.sess.opts.unstable_opts.sanitizer.contains(SanitizerSet::REALTIME) {
135+
match sanitizer_fn_attr.rtsan_setting {
136+
RtsanSetting::Nonblocking => {
137+
attrs.push(llvm::AttributeKind::SanitizeRealtimeNonblocking.create_attr(cx.llcx))
138+
}
139+
RtsanSetting::Blocking => {
140+
attrs.push(llvm::AttributeKind::SanitizeRealtimeBlocking.create_attr(cx.llcx))
141+
}
142+
// caller is the default, so no llvm attribute
143+
RtsanSetting::Caller => (),
144+
}
145+
}
134146
attrs
135147
}
136148

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ pub(crate) unsafe fn llvm_optimize(
630630
sanitize_memory: config.sanitizer.contains(SanitizerSet::MEMORY),
631631
sanitize_memory_recover: config.sanitizer_recover.contains(SanitizerSet::MEMORY),
632632
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
633+
sanitize_realtime: config.sanitizer.contains(SanitizerSet::REALTIME),
633634
sanitize_thread: config.sanitizer.contains(SanitizerSet::THREAD),
634635
sanitize_hwaddress: config.sanitizer.contains(SanitizerSet::HWADDRESS),
635636
sanitize_hwaddress_recover: config.sanitizer_recover.contains(SanitizerSet::HWADDRESS),

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ pub(crate) enum AttributeKind {
290290
DeadOnReturn = 44,
291291
CapturesReadOnly = 45,
292292
CapturesNone = 46,
293+
SanitizeRealtimeNonblocking = 47,
294+
SanitizeRealtimeBlocking = 48,
293295
}
294296

295297
/// LLVMIntPredicate
@@ -482,6 +484,7 @@ pub(crate) struct SanitizerOptions {
482484
pub sanitize_memory: bool,
483485
pub sanitize_memory_recover: bool,
484486
pub sanitize_memory_track_origins: c_int,
487+
pub sanitize_realtime: bool,
485488
pub sanitize_thread: bool,
486489
pub sanitize_hwaddress: bool,
487490
pub sanitize_hwaddress_recover: bool,

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,6 +1251,9 @@ fn add_sanitizer_libraries(
12511251
if sanitizer.contains(SanitizerSet::SAFESTACK) {
12521252
link_sanitizer_runtime(sess, flavor, linker, "safestack");
12531253
}
1254+
if sanitizer.contains(SanitizerSet::REALTIME) {
1255+
link_sanitizer_runtime(sess, flavor, linker, "rtsan");
1256+
}
12541257
}
12551258

12561259
fn link_sanitizer_runtime(

compiler/rustc_codegen_ssa/src/codegen_attrs.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -349,9 +349,10 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code
349349
codegen_fn_attrs.alignment =
350350
Ord::max(codegen_fn_attrs.alignment, tcx.sess.opts.unstable_opts.min_function_alignment);
351351

352-
// Compute the disabled sanitizers.
353-
codegen_fn_attrs.sanitizers.disabled |=
354-
tcx.sanitizer_settings_for(did).disabled;
352+
// Passed in sanitizer settings are always the default.
353+
assert!(codegen_fn_attrs.sanitizers == SanitizerFnAttrs::default());
354+
// Replace with #[sanitize] value
355+
codegen_fn_attrs.sanitizers = tcx.sanitizer_settings_for(did);
355356
// On trait methods, inherit the `#[align]` of the trait's method prototype.
356357
codegen_fn_attrs.alignment = Ord::max(codegen_fn_attrs.alignment, tcx.inherited_align(did));
357358

@@ -587,7 +588,7 @@ fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs
587588
};
588589

589590
// Check for a sanitize annotation directly on this def.
590-
if let Some((on_set, off_set)) = find_attr!(tcx.get_all_attrs(did), AttributeKind::Sanitize {on_set, off_set, ..} => (on_set, off_set))
591+
if let Some((on_set, off_set, rtsan)) = find_attr!(tcx.get_all_attrs(did), AttributeKind::Sanitize {on_set, off_set, rtsan, ..} => (on_set, off_set, rtsan))
591592
{
592593
// the on set is the set of sanitizers explicitly enabled.
593594
// we mask those out since we want the set of disabled sanitizers here
@@ -598,6 +599,11 @@ fn sanitizer_settings_for(tcx: TyCtxt<'_>, did: LocalDefId) -> SanitizerFnAttrs
598599
// the on set and off set are distjoint since there's a third option: unset.
599600
// a node may not set the sanitizer setting in which case it inherits from parents.
600601
// the code above in this function does this backtracking
602+
603+
// if rtsan was specified here override the parent
604+
if let Some(rtsan) = rtsan {
605+
settings.rtsan_setting = *rtsan;
606+
}
601607
}
602608
settings
603609
}

compiler/rustc_hir/src/attrs/data_structures.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,16 @@ pub struct DebugVisualizer {
382382
pub path: Symbol,
383383
}
384384

385+
#[derive(Clone, Copy, Debug, Decodable, Encodable, Eq, PartialEq)]
386+
#[derive(HashStable_Generic, PrintAttribute)]
387+
#[derive_const(Default)]
388+
pub enum RtsanSetting {
389+
Nonblocking,
390+
Blocking,
391+
#[default]
392+
Caller,
393+
}
394+
385395
/// Represents parsed *built-in* inert attributes.
386396
///
387397
/// ## Overview
@@ -683,7 +693,13 @@ pub enum AttributeKind {
683693
///
684694
/// the on set and off set are distjoint since there's a third option: unset.
685695
/// a node may not set the sanitizer setting in which case it inherits from parents.
686-
Sanitize { on_set: SanitizerSet, off_set: SanitizerSet, span: Span },
696+
/// rtsan is unset if None
697+
Sanitize {
698+
on_set: SanitizerSet,
699+
off_set: SanitizerSet,
700+
rtsan: Option<RtsanSetting>,
701+
span: Span,
702+
},
687703

688704
/// Represents `#[should_panic]`
689705
ShouldPanic { reason: Option<Symbol>, span: Span },

compiler/rustc_hir/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
// tidy-alphabetical-start
66
#![feature(associated_type_defaults)]
77
#![feature(closure_track_caller)]
8+
#![feature(const_default)]
9+
#![feature(const_trait_impl)]
810
#![feature(debug_closure_helpers)]
11+
#![feature(derive_const)]
912
#![feature(exhaustive_patterns)]
1013
#![feature(never_type)]
1114
#![feature(variant_count)]

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
3939
#include "llvm/Transforms/Instrumentation/InstrProfiling.h"
4040
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
41+
#include "llvm/Transforms/Instrumentation/RealtimeSanitizer.h"
4142
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
4243
#include "llvm/Transforms/Scalar/AnnotationRemarks.h"
4344
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
@@ -511,6 +512,7 @@ struct LLVMRustSanitizerOptions {
511512
bool SanitizeMemory;
512513
bool SanitizeMemoryRecover;
513514
int SanitizeMemoryTrackOrigins;
515+
bool SanitizerRealtime;
514516
bool SanitizeThread;
515517
bool SanitizeHWAddress;
516518
bool SanitizeHWAddressRecover;
@@ -766,6 +768,13 @@ extern "C" LLVMRustResult LLVMRustOptimize(
766768
MPM.addPass(HWAddressSanitizerPass(opts));
767769
});
768770
}
771+
if (SanitizerOptions->SanitizerRealtime) {
772+
OptimizerLastEPCallbacks.push_back([](ModulePassManager &MPM,
773+
OptimizationLevel Level,
774+
ThinOrFullLTOPhase phase) {
775+
MPM.addPass(RealtimeSanitizerPass());
776+
});
777+
}
769778
}
770779

771780
ModulePassManager MPM;

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,8 @@ enum class LLVMRustAttributeKind {
246246
DeadOnReturn = 44,
247247
CapturesReadOnly = 45,
248248
CapturesNone = 46,
249+
SanitizeRealtimeNonblocking = 47,
250+
SanitizeRealtimeBlocking = 48,
249251
};
250252

251253
static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
@@ -342,6 +344,10 @@ static Attribute::AttrKind fromRust(LLVMRustAttributeKind Kind) {
342344
case LLVMRustAttributeKind::CapturesReadOnly:
343345
case LLVMRustAttributeKind::CapturesNone:
344346
report_fatal_error("Should be handled separately");
347+
case LLVMRustAttributeKind::SanitizeRealtimeNonblocking:
348+
return Attribute::SanitizeRealtime;
349+
case LLVMRustAttributeKind::SanitizeRealtimeBlocking:
350+
return Attribute::SanitizeRealtimeBlocking;
345351
}
346352
report_fatal_error("bad LLVMRustAttributeKind");
347353
}

0 commit comments

Comments
 (0)