Skip to content

Commit 462fc0b

Browse files
committed
-Zharden-sls flag (target modifier) added to enable mitigation against straight line speculation (SLS)
1 parent ed439e2 commit 462fc0b

18 files changed

Lines changed: 245 additions & 18 deletions

File tree

compiler/rustc_codegen_gcc/src/gcc_util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_target::spec::Arch;
77

88
fn gcc_features_by_flags(sess: &Session, features: &mut Vec<String>) {
99
target_features::retpoline_features_by_flags(sess, features);
10+
target_features::sls_features_by_flags(sess, features);
1011
// FIXME: LLVM also sets +reserve-x18 here under some conditions.
1112
}
1213

compiler/rustc_codegen_llvm/src/llvm_util.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,7 @@ fn llvm_features_by_flags(sess: &Session, features: &mut Vec<String>) {
638638

639639
target_features::retpoline_features_by_flags(sess, features);
640640
target_features::sanitizer_features_by_flags(sess, features);
641+
target_features::sls_features_by_flags(sess, features);
641642

642643
// -Zfixed-x18
643644
if sess.opts.unstable_opts.fixed_x18 {

compiler/rustc_codegen_ssa/src/target_features.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_middle::query::Providers;
88
use rustc_middle::ty::TyCtxt;
99
use rustc_session::Session;
1010
use rustc_session::errors::feature_err;
11+
use rustc_session::config::HardenSls;
1112
use rustc_session::lint::builtin::AARCH64_SOFTFLOAT_NEON;
1213
use rustc_span::{Span, Symbol, edit_distance, sym};
1314
use rustc_target::spec::{Arch, SanitizerSet};
@@ -487,6 +488,18 @@ pub fn sanitizer_features_by_flags(sess: &Session, features: &mut Vec<String>) {
487488
}
488489
}
489490

491+
pub fn sls_features_by_flags(sess: &Session, features: &mut Vec<String>) {
492+
match &sess.opts.unstable_opts.harden_sls {
493+
HardenSls::None => (),
494+
HardenSls::All => {
495+
features.push("+harden-sls-ijmp".into());
496+
features.push("+harden-sls-ret".into());
497+
}
498+
HardenSls::Return => features.push("+harden-sls-ret".into()),
499+
HardenSls::IndirectJmp => features.push("+harden-sls-ijmp".into()),
500+
}
501+
}
502+
490503
pub(crate) fn provide(providers: &mut Providers) {
491504
*providers = Providers {
492505
rust_target_features: |tcx, cnum| {

compiler/rustc_session/src/config.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,10 +3069,11 @@ pub(crate) mod dep_tracking {
30693069
use super::{
30703070
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions,
30713071
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
3072-
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
3073-
LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
3074-
OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm,
3075-
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
3072+
HardenSls, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
3073+
LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel,
3074+
OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks,
3075+
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
3076+
WasiExecModel,
30763077
};
30773078
use crate::lint;
30783079
use crate::utils::NativeLib;
@@ -3175,6 +3176,7 @@ pub(crate) mod dep_tracking {
31753176
Polonius,
31763177
InliningThreshold,
31773178
FunctionReturn,
3179+
HardenSls,
31783180
Align,
31793181
);
31803182

@@ -3389,6 +3391,16 @@ pub enum FunctionReturn {
33893391
ThunkExtern,
33903392
}
33913393

3394+
/// The different settings that the `-Zharden-sls` flag can have.
3395+
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
3396+
pub enum HardenSls {
3397+
#[default]
3398+
None,
3399+
All,
3400+
Return,
3401+
IndirectJmp,
3402+
}
3403+
33923404
/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
33933405
/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
33943406
#[derive(Clone, Copy, Default, PartialEq, Debug)]

compiler/rustc_session/src/options.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,7 @@ mod desc {
834834
"either a boolean (`yes`, `no`, `on`, `off`, etc), or a non-negative number";
835835
pub(crate) const parse_llvm_module_flag: &str = "<key>:<type>:<value>:<behavior>. Type must currently be `u32`. Behavior should be one of (`error`, `warning`, `require`, `override`, `append`, `appendunique`, `max`, `min`)";
836836
pub(crate) const parse_function_return: &str = "`keep` or `thunk-extern`";
837+
pub(crate) const parse_harden_sls: &str = "`none`, `all`, `return` or `indirect-jmp`";
837838
pub(crate) const parse_wasm_c_abi: &str = "`spec`";
838839
pub(crate) const parse_mir_include_spans: &str =
839840
"either a boolean (`yes`, `no`, `on`, `off`, etc), or `nll` (default: `nll`)";
@@ -1986,6 +1987,17 @@ pub mod parse {
19861987
true
19871988
}
19881989

1990+
pub(crate) fn parse_harden_sls(slot: &mut HardenSls, v: Option<&str>) -> bool {
1991+
match v {
1992+
Some("none") => *slot = HardenSls::None,
1993+
Some("all") => *slot = HardenSls::All,
1994+
Some("return") => *slot = HardenSls::Return,
1995+
Some("indirect-jmp") => *slot = HardenSls::IndirectJmp,
1996+
_ => return false,
1997+
}
1998+
true
1999+
}
2000+
19892001
pub(crate) fn parse_wasm_c_abi(_slot: &mut (), v: Option<&str>) -> bool {
19902002
v == Some("spec")
19912003
}
@@ -2350,6 +2362,9 @@ options! {
23502362
graphviz_font: String = ("Courier, monospace".to_string(), parse_string, [UNTRACKED],
23512363
"use the given `fontname` in graphviz output; can be overridden by setting \
23522364
environment variable `RUSTC_GRAPHVIZ_FONT` (default: `Courier, monospace`)"),
2365+
harden_sls: HardenSls = (HardenSls::None, parse_harden_sls, [TRACKED] { TARGET_MODIFIER: HardenSls },
2366+
"flag to mitigate against straight line speculation (SLS) [none|all|return|indirect-jmp] \
2367+
(default: none)"),
23532368
has_thread_local: Option<bool> = (None, parse_opt_bool, [TRACKED],
23542369
"explicitly enable the `cfg(target_thread_local)` directive"),
23552370
help: bool = (false, parse_no_value, [UNTRACKED], "Print unstable compiler options"),

compiler/rustc_target/src/target_features.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//! Note that these are similar to but not always identical to LLVM's feature names,
33
//! and Rust adds some features that do not correspond to LLVM features at all.
44
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5-
use rustc_macros::StableHash;
5+
use rustc_data_structures::stable_hasher::{StableHash, StableHasher, StableHashCtxt};
66
use rustc_span::{Symbol, sym};
77

88
use crate::spec::{Arch, FloatAbi, LlvmAbi, RustcAbi, Target};
@@ -12,7 +12,7 @@ use crate::spec::{Arch, FloatAbi, LlvmAbi, RustcAbi, Target};
1212
pub const RUSTC_SPECIFIC_FEATURES: &[&str] = &["crt-static"];
1313

1414
/// Stability information for target features.
15-
#[derive(Debug, Copy, Clone, StableHash)]
15+
#[derive(Debug, Copy, Clone)]
1616
pub enum Stability {
1717
/// This target feature is stable, it can be used in `#[target_feature]` and
1818
/// `#[cfg(target_feature)]`.
@@ -37,18 +37,18 @@ pub enum Stability {
3737
}
3838
use Stability::*;
3939

40-
impl<CTX> HashStable<CTX> for Stability {
40+
impl StableHash for Stability {
4141
#[inline]
42-
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
43-
std::mem::discriminant(self).hash_stable(hcx, hasher);
42+
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
43+
std::mem::discriminant(self).stable_hash(hcx, hasher);
4444
match self {
4545
Stability::Stable => {}
4646
Stability::Unstable(nightly_feature) => {
47-
nightly_feature.hash_stable(hcx, hasher);
47+
nightly_feature.stable_hash(hcx, hasher);
4848
}
4949
Stability::Forbidden { reason, hard_error } => {
50-
reason.hash_stable(hcx, hasher);
51-
hard_error.hash_stable(hcx, hasher);
50+
reason.stable_hash(hcx, hasher);
51+
hard_error.stable_hash(hcx, hasher);
5252
}
5353
}
5454
}
@@ -458,6 +458,16 @@ static X86_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
458458
("fma4", Unstable(sym::fma4_target_feature), &["avx", "sse4a"]),
459459
("fxsr", Stable, &[]),
460460
("gfni", Stable, &["sse2"]),
461+
(
462+
"harden-sls-ijmp",
463+
Stability::Forbidden { reason: "use `harden-sls` compiler flag instead", hard_error: true },
464+
&[],
465+
),
466+
(
467+
"harden-sls-ret",
468+
Stability::Forbidden { reason: "use `harden-sls` compiler flag instead", hard_error: true },
469+
&[],
470+
),
461471
("kl", Stable, &["sse2"]),
462472
("lahfsahf", Unstable(sym::lahfsahf_target_feature), &[]),
463473
("lzcnt", Stable, &[]),

src/doc/rustc-dev-guide/src/tests/directives.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,14 @@ See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for ig
244244

245245
| Directive | Explanation | Supported test suites | Possible values |
246246
|---------------------|----------------------------------------------------------------------------------------------|--------------------------------------------|--------------------------------------------------------------------------------------------|
247-
| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
248-
| `edition` | The edition used to build the test | All except for `run-make`/`run-make-cargo` | Any valid `--edition` value |
249-
| `rustc-env` | Env var to set when running `rustc` | All except for `run-make`/`run-make-cargo` | `<KEY>=<VALUE>` |
250-
| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make`/`run-make-cargo` | Any env var name |
251-
| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
252-
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
247+
| `compile-flags` | Flags passed to `rustc` when building the test or aux file | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
248+
| `minicore-compile-flags` | Additional flags passed to `rustc` when building minicore | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
249+
| `non-aux-compile-flags` | Additional flags passed to `rustc` when building the test (not for auxiliary builds) | All except for `run-make`/`run-make-cargo` | Any valid `rustc` flags, e.g. `-Awarnings -Dfoo`. Cannot be `-Cincremental` or `--edition` |
250+
| `edition` | The edition used to build the test | All except for `run-make`/`run-make-cargo` | Any valid `--edition` value |
251+
| `rustc-env` | Env var to set when running `rustc` | All except for `run-make`/`run-make-cargo` | `<KEY>=<VALUE>` |
252+
| `unset-rustc-env` | Env var to unset when running `rustc` | All except for `run-make`/`run-make-cargo` | Any env var name |
253+
| `incremental` | Proper incremental support for tests outside of incremental test suite | `ui`, `crashes` | N/A |
254+
| `no-prefer-dynamic` | Don't use `-C prefer-dynamic`, don't build as a dylib via a `--crate-type=dylib` preset flag | `ui`, `crashes` | N/A |
253255

254256
<div class="warning">
255257

src/doc/rustc-dev-guide/src/tests/minicore.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ The `minicore` items must be kept up to date with `core`.
4444
For consistent diagnostic output between using `core` and `minicore`, any `diagnostic`
4545
attributes (e.g. `on_unimplemented`) should be replicated exactly in `minicore`.
4646

47+
## Specific compile flags
48+
`compile-flags` is used both for auxiliary builds (including minicore) and main test build.
49+
`minicore-compile-flags` directive may be used to provide compile flags for minicore build only.
50+
`non-aux-compile-flags` directive may be used to provide compile flags for main test only.
51+
4752
## Example codegen test that uses `minicore`
4853

4954
```rust,no_run

src/tools/compiletest/src/directives.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ pub(crate) struct TestProps {
207207
pub(crate) add_minicore: bool,
208208
/// Add these flags to the build of `minicore`.
209209
pub(crate) minicore_compile_flags: Vec<String>,
210+
/// Add these flags to the non-auxiliary build.
211+
pub(crate) non_aux_compile_flags: Vec<String>,
210212
/// Whether line annotations are required for the given error kind.
211213
pub(crate) dont_require_annotations: HashSet<ErrorKind>,
212214
/// Whether pretty printers should be disabled in gdb.
@@ -259,6 +261,7 @@ mod directives {
259261
pub(crate) const NO_AUTO_CHECK_CFG: &str = "no-auto-check-cfg";
260262
pub(crate) const ADD_MINICORE: &str = "add-minicore";
261263
pub(crate) const MINICORE_COMPILE_FLAGS: &str = "minicore-compile-flags";
264+
pub(crate) const NON_AUX_COMPILE_FLAGS: &'static str = "non-aux-compile-flags";
262265
pub(crate) const DISABLE_GDB_PRETTY_PRINTERS: &str = "disable-gdb-pretty-printers";
263266
pub(crate) const COMPARE_OUTPUT_BY_LINES: &str = "compare-output-by-lines";
264267
}
@@ -316,6 +319,7 @@ impl TestProps {
316319
no_auto_check_cfg: false,
317320
add_minicore: false,
318321
minicore_compile_flags: vec![],
322+
non_aux_compile_flags: vec![],
319323
dont_require_annotations: Default::default(),
320324
disable_gdb_pretty_printers: false,
321325
compare_output_by_lines: false,

src/tools/compiletest/src/directives/directive_names.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ pub(crate) const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
202202
"needs-xray",
203203
"no-auto-check-cfg",
204204
"no-prefer-dynamic",
205+
"non-aux-compile-flags",
205206
"normalize-stderr",
206207
"normalize-stderr-32bit",
207208
"normalize-stderr-64bit",

0 commit comments

Comments
 (0)