about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlice Ryhl <aliceryhl@google.com>2024-05-03 14:32:01 +0200
committerAlice Ryhl <aliceryhl@google.com>2024-05-03 14:32:08 +0200
commit40f0172c6aed0b2fb055c19108d226f8fb410f8c (patch)
treed06225635b01a71129568d86100bfc182204cdee
parent79734f1db8dbe322192dea32c0f6b80ab14c4c1d (diff)
downloadrust-40f0172c6aed0b2fb055c19108d226f8fb410f8c.tar.gz
rust-40f0172c6aed0b2fb055c19108d226f8fb410f8c.zip
Add -Zfixed-x18
Signed-off-by: Alice Ryhl <aliceryhl@google.com>
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs5
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--src/doc/unstable-book/src/compiler-flags/fixed-x18.md32
-rw-r--r--tests/codegen/fixed-x18.rs22
5 files changed, 62 insertions, 0 deletions
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 5552b381025..dbce7f43e62 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -615,6 +615,11 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
         .flatten();
     features.extend(feats);
 
+    // -Zfixed-x18
+    if sess.opts.unstable_opts.fixed_x18 {
+        features.push("+reserve-x18".into());
+    }
+
     if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
         sess.dcx().emit_err(TargetFeatureDisableOrEnable {
             features: f,
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index db150cc1f87..12cbc72a821 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -773,6 +773,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(emit_thin_lto, false);
     tracked!(export_executable_symbols, true);
     tracked!(fewer_names, Some(true));
+    tracked!(fixed_x18, true);
     tracked!(flatten_format_args, false);
     tracked!(force_unstable_if_unmarked, true);
     tracked!(fuel, Some(("abc".to_string(), 99)));
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 7355e5b6953..48b6278f2f3 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1684,6 +1684,8 @@ options! {
     fewer_names: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR) \
         (default: no)"),
+    fixed_x18: bool = (false, parse_bool, [TRACKED],
+        "make the x18 register reserved on AArch64 (default: no)"),
     flatten_format_args: bool = (true, parse_bool, [TRACKED],
         "flatten nested format_args!() and literals into a simplified format_args!() call \
         (default: yes)"),
diff --git a/src/doc/unstable-book/src/compiler-flags/fixed-x18.md b/src/doc/unstable-book/src/compiler-flags/fixed-x18.md
new file mode 100644
index 00000000000..8c8bff5fa29
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/fixed-x18.md
@@ -0,0 +1,32 @@
+# `fixed-x18`
+
+This option prevents the compiler from using the x18 register. It is only
+supported on aarch64.
+
+From the [ABI spec][arm-abi]:
+
+> X18 is the platform register and is reserved for the use of platform ABIs.
+> This is an additional temporary register on platforms that don't assign a
+> special meaning to it.
+
+This flag only has an effect when the x18 register would otherwise be considered
+a temporary register. When the flag is applied, x18 is always a reserved
+register.
+
+This flag is intended for use with the shadow call stack sanitizer. Generally,
+when that sanitizer is enabled, the x18 register is used to store a pointer to
+the shadow stack. Enabling this flag prevents the compiler from overwriting the
+shadow stack pointer with temporary data, which is necessary for the sanitizer
+to work correctly.
+
+Currently, the `-Zsanitizer=shadow-call-stack` flag is only supported on
+platforms that always treat x18 as a reserved register, and the `-Zfixed-x18`
+flag is not required to use the sanitizer on such platforms. However, the
+sanitizer may be supported on targets where this is not the case in the future.
+
+It is undefined behavior for `-Zsanitizer=shadow-call-stack` code to call into
+code where x18 is a temporary register. On the other hand, when you are *not*
+using the shadow call stack sanitizer, compilation units compiled with and
+without the `-Zfixed-x18` flag are compatible with each other.
+
+[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
diff --git a/tests/codegen/fixed-x18.rs b/tests/codegen/fixed-x18.rs
new file mode 100644
index 00000000000..4997a39a726
--- /dev/null
+++ b/tests/codegen/fixed-x18.rs
@@ -0,0 +1,22 @@
+// Test that the `reserve-x18` target feature is (not) emitted when
+// the `-Zfixed-x18` flag is (not) set.
+
+//@ revisions: unset set
+//@ needs-llvm-components: aarch64
+//@ compile-flags: --target aarch64-unknown-none
+//@ [set] compile-flags: -Zfixed-x18
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+#[no_mangle]
+pub fn foo() {
+    // CHECK: @foo() unnamed_addr #0
+
+    // unset-NOT: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+reserve-x18{{.*}} }
+    // set: attributes #0 = { {{.*}}"target-features"="{{[^"]*}}+reserve-x18{{.*}} }
+}