Skip to content

Commit 9ee9c2f

Browse files
committed
Add default sanitizers to TargetOptions
Some sanitizers are part of a system's ABI, like the shadow call stack on Aarch64 and RISC-V Fuchsia. Typically ABI options have other spellings, but LLVM has, for historical reasons, marked this as a sanitizer instead of an alternate ABI option. As a result, Fuchsia targets may not be compiled against the correct ABI unless this option is set. This hasn't caused correctness problems, since the backend reserves the SCS register, and thus preserves its value. But this is an issue for unwinding, as the SCS will not be an array of PCs describing the call complete call chain, and will have gaps from callers that don't use the correct ABI. In the long term, I'd like to see all the sanitizer configs that all frontends copy from clang moved into llvm's libFrontend, and exposed so that frontend consumers can use a small set of simple APIs to use sanitizers in a consistent way across the LLVM ecosystem, but that work is not yet ready today.
1 parent 6f34f4e commit 9ee9c2f

File tree

5 files changed

+19
-1
lines changed

5 files changed

+19
-1
lines changed

compiler/rustc_codegen_llvm/src/attributes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ pub(crate) fn sanitize_attrs<'ll>(
9696
no_sanitize: SanitizerSet,
9797
) -> SmallVec<[&'ll Attribute; 4]> {
9898
let mut attrs = SmallVec::new();
99-
let enabled = cx.tcx.sess.opts.unstable_opts.sanitizer - no_sanitize;
99+
let enabled = (cx.sess().target.default_sanitizers | cx.tcx.sess.opts.unstable_opts.sanitizer)
100+
- no_sanitize;
100101
if enabled.contains(SanitizerSet::ADDRESS) || enabled.contains(SanitizerSet::KERNELADDRESS) {
101102
attrs.push(llvm::AttributeKind::SanitizeAddress.create_attr(cx.llcx));
102103
}

compiler/rustc_target/src/spec/json.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,11 @@ impl Target {
214214
supported_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b);
215215
}
216216

217+
if let Some(default_sanitizers) = json.default_sanitizers {
218+
base.default_sanitizers =
219+
default_sanitizers.into_iter().fold(SanitizerSet::empty(), |a, b| a | b);
220+
}
221+
217222
forward!(generate_arange_section);
218223
forward!(supports_stack_protector);
219224
forward!(small_data_threshold_support);
@@ -392,6 +397,7 @@ impl ToJson for Target {
392397
target_option_val!(split_debuginfo);
393398
target_option_val!(supported_split_debuginfo);
394399
target_option_val!(supported_sanitizers);
400+
target_option_val!(default_sanitizers);
395401
target_option_val!(c_enum_min_bits);
396402
target_option_val!(generate_arange_section);
397403
target_option_val!(supports_stack_protector);
@@ -612,6 +618,7 @@ struct TargetSpecJson {
612618
split_debuginfo: Option<SplitDebuginfo>,
613619
supported_split_debuginfo: Option<StaticCow<[SplitDebuginfo]>>,
614620
supported_sanitizers: Option<Vec<SanitizerSet>>,
621+
default_sanitizers: Option<Vec<SanitizerSet>>,
615622
generate_arange_section: Option<bool>,
616623
supports_stack_protector: Option<bool>,
617624
small_data_threshold_support: Option<SmallDataThresholdSupport>,

compiler/rustc_target/src/spec/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2319,6 +2319,13 @@ pub struct TargetOptions {
23192319
/// distributed with the target, the sanitizer should still appear in this list for the target.
23202320
pub supported_sanitizers: SanitizerSet,
23212321

2322+
/// The sanitizers that are enabled by default on this target.
2323+
///
2324+
/// Note that the support here is at a codegen level. If the machine code with sanitizer
2325+
/// enabled can generated on this target, but the necessary supporting libraries are not
2326+
/// distributed with the target, the sanitizer should still appear in this list for the target.
2327+
pub default_sanitizers: SanitizerSet,
2328+
23222329
/// Minimum number of bits in #[repr(C)] enum. Defaults to the size of c_int
23232330
pub c_enum_min_bits: Option<u64>,
23242331

@@ -2567,6 +2574,7 @@ impl Default for TargetOptions {
25672574
// `Off` is supported by default, but targets can remove this manually, e.g. Windows.
25682575
supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
25692576
supported_sanitizers: SanitizerSet::empty(),
2577+
default_sanitizers: SanitizerSet::empty(),
25702578
c_enum_min_bits: None,
25712579
generate_arange_section: true,
25722580
supports_stack_protector: true,

compiler/rustc_target/src/spec/targets/aarch64_unknown_fuchsia.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub(crate) fn target() -> Target {
1212
| SanitizerSet::CFI
1313
| SanitizerSet::LEAK
1414
| SanitizerSet::SHADOWCALLSTACK;
15+
base.default_sanitizers = SanitizerSet::SHADOWCALLSTACK;
1516
base.supports_xray = true;
1617

1718
base.add_pre_link_args(

compiler/rustc_target/src/spec/targets/riscv64gc_unknown_fuchsia.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub(crate) fn target() -> Target {
99
base.max_atomic_width = Some(64);
1010
base.stack_probes = StackProbeType::Inline;
1111
base.supported_sanitizers = SanitizerSet::SHADOWCALLSTACK;
12+
base.default_sanitizers = SanitizerSet::SHADOWCALLSTACK;
1213
base.supports_xray = true;
1314

1415
Target {

0 commit comments

Comments
 (0)