Skip to content

Commit

Permalink
Rollup merge of rust-lang#124655 - Darksonn:fixed-x18, r=lqd,estebank
Browse files Browse the repository at this point in the history
Add `-Zfixed-x18`

This PR is a follow-up to rust-lang#124323 that proposes a different implementation. Please read the description of that PR for motivation.

See the equivalent flag in [the clang docs](https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-ffixed-x18).

MCP: rust-lang/compiler-team#748
Fixes rust-lang#121970
r? rust-lang/compiler
  • Loading branch information
matthiaskrgr authored May 29, 2024
2 parents a83f933 + 4aafecb commit d0311c1
Show file tree
Hide file tree
Showing 8 changed files with 100 additions and 1 deletion.
2 changes: 2 additions & 0 deletions compiler/rustc_codegen_llvm/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ codegen_llvm_error_creating_import_library =
codegen_llvm_error_writing_def_file =
Error writing .DEF file: {$error}
codegen_llvm_fixed_x18_invalid_arch = the `-Zfixed-x18` flag is not supported on the `{$arch}` architecture
codegen_llvm_from_llvm_diag = {$message}
codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_name} ({$kind}): {$message}
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,9 @@ pub struct MismatchedDataLayout<'a> {
pub(crate) struct InvalidTargetFeaturePrefix<'a> {
pub feature: &'a str,
}

#[derive(Diagnostic)]
#[diag(codegen_llvm_fixed_x18_invalid_arch)]
pub(crate) struct FixedX18InvalidArch<'a> {
pub arch: &'a str,
}
11 changes: 10 additions & 1 deletion compiler/rustc_codegen_llvm/src/llvm_util.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::back::write::create_informational_target_machine;
use crate::errors::{
InvalidTargetFeaturePrefix, PossibleFeature, TargetFeatureDisableOrEnable,
FixedX18InvalidArch, InvalidTargetFeaturePrefix, PossibleFeature, TargetFeatureDisableOrEnable,
UnknownCTargetFeature, UnknownCTargetFeaturePrefix, UnstableCTargetFeature,
};
use crate::llvm;
Expand Down Expand Up @@ -615,6 +615,15 @@ 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 {
if sess.target.arch != "aarch64" {
sess.dcx().emit_fatal(FixedX18InvalidArch { arch: &sess.target.arch });
} else {
features.push("+reserve-x18".into());
}
}

if diagnostics && let Some(f) = check_tied_features(sess, &featsmap) {
sess.dcx().emit_err(TargetFeatureDisableOrEnable {
features: f,
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)));
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1678,6 +1678,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)"),
Expand Down
32 changes: 32 additions & 0 deletions src/doc/unstable-book/src/compiler-flags/fixed-x18.md
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions tests/codegen/fixed-x18.rs
Original file line number Diff line number Diff line change
@@ -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{{.*}} }
}
25 changes: 25 additions & 0 deletions tests/ui/abi/fixed_x18.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// This tests that -Zfixed-x18 causes a compilation failure on targets other than aarch64.
// Behavior on aarch64 is tested by tests/codegen/fixed-x18.rs.
//
//@ revisions: x64 i686 arm riscv32 riscv64
//@ error-pattern: the `-Zfixed-x18` flag is not supported
//@ dont-check-compiler-stderr
//
//@ compile-flags: -Zfixed-x18
//@ [x64] needs-llvm-components: x86
//@ [x64] compile-flags: --target=x86_64-unknown-linux-gnu --crate-type=rlib
//@ [i686] needs-llvm-components: x86
//@ [i686] compile-flags: --target=i686-unknown-linux-gnu --crate-type=rlib
//@ [arm] needs-llvm-components: arm
//@ [arm] compile-flags: --target=armv7-unknown-linux-gnueabihf --crate-type=rlib
//@ [riscv32] needs-llvm-components: riscv
//@ [riscv32] compile-flags: --target=riscv32i-unknown-none-elf --crate-type=rlib
//@ [riscv64] needs-llvm-components: riscv
//@ [riscv64] compile-flags: --target=riscv64gc-unknown-none-elf --crate-type=rlib

#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]

#[lang = "sized"]
trait Sized {}

0 comments on commit d0311c1

Please sign in to comment.