Skip to content

Commit b0392c5

Browse files
committed
Add -Zindirect-branch-cs-prefix option
This is intended to be used for Linux kernel RETPOLINE builds. Signed-off-by: Miguel Ojeda <[email protected]>
1 parent fa0e75e commit b0392c5

File tree

9 files changed

+89
-5
lines changed

9 files changed

+89
-5
lines changed

compiler/rustc_session/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ session_hexadecimal_float_literal_not_supported = hexadecimal float literal is n
4949
session_incompatible_linker_flavor = linker flavor `{$flavor}` is incompatible with the current target
5050
.note = compatible flavors are: {$compatible_list}
5151
52+
session_indirect_branch_cs_prefix_requires_x86_or_x86_64 = `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64
53+
5254
session_instrumentation_not_supported = {$us} instrumentation is not supported for this target
5355
5456
session_int_literal_too_large = integer literal is too large

compiler/rustc_session/src/errors.rs

+4
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,10 @@ pub(crate) struct FunctionReturnRequiresX86OrX8664;
471471
#[diag(session_function_return_thunk_extern_requires_non_large_code_model)]
472472
pub(crate) struct FunctionReturnThunkExternRequiresNonLargeCodeModel;
473473

474+
#[derive(Diagnostic)]
475+
#[diag(session_indirect_branch_cs_prefix_requires_x86_or_x86_64)]
476+
pub(crate) struct IndirectBranchCsPrefixRequiresX86OrX8664;
477+
474478
#[derive(Diagnostic)]
475479
#[diag(session_unsupported_regparm)]
476480
pub(crate) struct UnsupportedRegparm {

compiler/rustc_session/src/options.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2287,7 +2287,7 @@ options! {
22872287
- hash collisions of query keys
22882288
- hash collisions when creating dep-nodes"),
22892289
indirect_branch_cs_prefix: bool = (false, parse_bool, [TRACKED TARGET_MODIFIER],
2290-
"add cs prefix to call and jmp to indirect thunk (default: no)"),
2290+
"add `cs` prefix to `call` and `jmp` to indirect thunks (default: no)"),
22912291
inline_llvm: bool = (true, parse_bool, [TRACKED],
22922292
"enable LLVM inlining (default: yes)"),
22932293
inline_mir: Option<bool> = (None, parse_opt_bool, [TRACKED],

compiler/rustc_session/src/session.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,12 @@ fn validate_commandline_args_with_session_available(sess: &Session) {
13761376
}
13771377
}
13781378

1379+
if sess.opts.unstable_opts.indirect_branch_cs_prefix {
1380+
if sess.target.arch != "x86" && sess.target.arch != "x86_64" {
1381+
sess.dcx().emit_err(errors::IndirectBranchCsPrefixRequiresX86OrX8664);
1382+
}
1383+
}
1384+
13791385
if let Some(regparm) = sess.opts.unstable_opts.regparm {
13801386
if regparm > 3 {
13811387
sess.dcx().emit_err(errors::UnsupportedRegparm { regparm });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# `indirect-branch-cs-prefix`
2+
3+
The tracking issue for this feature is: https://github.com/rust-lang/rust/issues/116852.
4+
5+
------------------------
6+
7+
Option `-Zindirect-branch-cs-prefix` controls whether a `cs` prefix is added to
8+
`call` and `jmp` to indirect thunks.
9+
10+
It is equivalent to [Clang]'s and [GCC]'s `-mindirect-branch-cs-prefix`. The
11+
Linux kernel uses it for RETPOLINE builds. For details, see
12+
[LLVM commit 6f867f910283]("[X86] Support ``-mindirect-branch-cs-prefix`` for
13+
call and jmp to indirect thunk") which introduces the feature.
14+
15+
Only x86 is supported.
16+
17+
[Clang]: https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-mindirect-branch-cs-prefix
18+
[GCC]: https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html#index-mindirect-branch-cs-prefix
19+
[LLVM commit 6f867f910283]: https://github.com/llvm/llvm-project/commit/6f867f9102838ebe314c1f3661fdf95700386e5a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Test that the `cs` prefix is (not) added into a `call` and a `jmp` to the
2+
// indirect thunk when the `-Zindirect-branch-cs-prefix` flag is (not) set.
3+
4+
//@ revisions: unset set
5+
//@ assembly-output: emit-asm
6+
//@ compile-flags: -Copt-level=3 -Cunsafe-allow-abi-mismatch=retpoline,retpoline-external-thunk,indirect-branch-cs-prefix -Zretpoline-external-thunk
7+
//@ [set] compile-flags: -Zindirect-branch-cs-prefix
8+
//@ only-x86_64
9+
// TODO: This may be required here too: ignore-apple Symbol is called `___x86_return_thunk` (Darwin's extra underscore)
10+
// TODO: This may be required here too: ignore-sgx Tests incompatible with LVI mitigations
11+
12+
#![crate_type = "lib"]
13+
14+
// CHECK-LABEL: foo:
15+
#[no_mangle]
16+
pub fn foo(g: fn()) {
17+
// unset-NOT: cs
18+
// unset: callq {{__x86_indirect_thunk.*}}
19+
// set: cs
20+
// set: callq {{__x86_indirect_thunk.*}}
21+
g();
22+
23+
// unset-NOT: cs
24+
// unset: jmp {{__x86_indirect_thunk.*}}
25+
// set: cs
26+
// set: jmp {{__x86_indirect_thunk.*}}
27+
g();
28+
}
+4-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Test that the `indirect_branch_cs_prefix` module attribute is (not) emitted when the
2-
// `-Zindirect-branch-cs-prefix` flag is (not) set.
1+
// Test that the `indirect_branch_cs_prefix` module attribute is (not)
2+
// emitted when the `-Zindirect-branch-cs-prefix` flag is (not) set.
33

44
//@ add-core-stubs
55
//@ revisions: unset set
@@ -11,8 +11,8 @@
1111
#![feature(no_core, lang_items)]
1212
#![no_core]
1313

14-
#[lang = "sized"]
15-
trait Sized {}
14+
extern crate minicore;
15+
use minicore::*;
1616

1717
// unset-NOT: !{{[0-9]+}} = !{i32 4, !"indirect_branch_cs_prefix", i32 1}
1818
// set: !{{[0-9]+}} = !{i32 4, !"indirect_branch_cs_prefix", i32 1}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
error: `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64
2+
3+
error: aborting due to 1 previous error
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//@ revisions: x86 x86_64 aarch64
2+
3+
//@ compile-flags: -Zindirect-branch-cs-prefix
4+
5+
//@[x86] check-pass
6+
//@[x86] needs-llvm-components: x86
7+
//@[x86] compile-flags: --target i686-unknown-linux-gnu
8+
9+
//@[x86_64] check-pass
10+
//@[x86_64] needs-llvm-components: x86
11+
//@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
12+
13+
//@[aarch64] check-fail
14+
//@[aarch64] needs-llvm-components: aarch64
15+
//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
16+
17+
#![feature(no_core)]
18+
#![no_core]
19+
#![no_main]
20+
21+
//[aarch64]~? ERROR `-Zindirect-branch-cs-prefix` is only supported on x86 and x86_64

0 commit comments

Comments
 (0)