Skip to content

Commit 40f0172

Browse files
committed
Add -Zfixed-x18
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
1 parent 79734f1 commit 40f0172

File tree

5 files changed

+62
-0
lines changed

5 files changed

+62
-0
lines changed

compiler/rustc_codegen_llvm/src/llvm_util.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,11 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
615615
.flatten();
616616
features.extend(feats);
617617

618+
// -Zfixed-x18
619+
if sess.opts.unstable_opts.fixed_x18 {
620+
features.push("+reserve-x18".into());
621+
}
622+
618623
if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
619624
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
620625
features: f,

compiler/rustc_interface/src/tests.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,7 @@ fn test_unstable_options_tracking_hash() {
773773
tracked!(emit_thin_lto, false);
774774
tracked!(export_executable_symbols, true);
775775
tracked!(fewer_names, Some(true));
776+
tracked!(fixed_x18, true);
776777
tracked!(flatten_format_args, false);
777778
tracked!(force_unstable_if_unmarked, true);
778779
tracked!(fuel, Some(("abc".to_string(), 99)));

compiler/rustc_session/src/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,6 +1684,8 @@ options! {
16841684
fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
16851685
"reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
16861686
(default: no)"),
1687+
fixed_x18: bool = (false, parse_bool, [TRACKED],
1688+
"make the x18 register reserved on AArch64 (default: no)"),
16871689
flatten_format_args: bool = (true, parse_bool, [TRACKED],
16881690
"flatten nested format_args!() and literals into a simplified format_args!() call \
16891691
(default: yes)"),
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# `fixed-x18`
2+
3+
This option prevents the compiler from using the x18 register. It is only
4+
supported on aarch64.
5+
6+
From the [ABI spec][arm-abi]:
7+
8+
> X18 is the platform register and is reserved for the use of platform ABIs.
9+
> This is an additional temporary register on platforms that don't assign a
10+
> special meaning to it.
11+
12+
This flag only has an effect when the x18 register would otherwise be considered
13+
a temporary register. When the flag is applied, x18 is always a reserved
14+
register.
15+
16+
This flag is intended for use with the shadow call stack sanitizer. Generally,
17+
when that sanitizer is enabled, the x18 register is used to store a pointer to
18+
the shadow stack. Enabling this flag prevents the compiler from overwriting the
19+
shadow stack pointer with temporary data, which is necessary for the sanitizer
20+
to work correctly.
21+
22+
Currently, the `-Zsanitizer=shadow-call-stack` flag is only supported on
23+
platforms that always treat x18 as a reserved register, and the `-Zfixed-x18`
24+
flag is not required to use the sanitizer on such platforms. However, the
25+
sanitizer may be supported on targets where this is not the case in the future.
26+
27+
It is undefined behavior for `-Zsanitizer=shadow-call-stack` code to call into
28+
code where x18 is a temporary register. On the other hand, when you are *not*
29+
using the shadow call stack sanitizer, compilation units compiled with and
30+
without the `-Zfixed-x18` flag are compatible with each other.
31+
32+
[arm-abi]: https://developer.arm.com/documentation/den0024/a/The-ABI-for-ARM-64-bit-Architecture/Register-use-in-the-AArch64-Procedure-Call-Standard/Parameters-in-general-purpose-registers

tests/codegen/fixed-x18.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Test that the `reserve-x18` target feature is (not) emitted when
2+
// the `-Zfixed-x18` flag is (not) set.
3+
4+
//@ revisions: unset set
5+
//@ needs-llvm-components: aarch64
6+
//@ compile-flags: --target aarch64-unknown-none
7+
//@ [set] compile-flags: -Zfixed-x18
8+
9+
#![crate_type = "lib"]
10+
#![feature(no_core, lang_items)]
11+
#![no_core]
12+
13+
#[lang = "sized"]
14+
trait Sized {}
15+
16+
#[no_mangle]
17+
pub fn foo() {
18+
// CHECK: @foo() unnamed_addr #0
19+
20+
// unset-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+reserve-x18{{.*}} }
21+
// set: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+reserve-x18{{.*}} }
22+
}

0 commit comments

Comments
 (0)