about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJames McGregor <james.mcgregor2@arm.com>2021-07-13 12:14:26 +0100
committerJamie Cunliffe <Jamie.Cunliffe@arm.com>2021-12-01 12:24:30 +0000
commit837cc1687f7c0d35a4e90a2f6bee377b5a2ecfd5 (patch)
tree8ce2820cee2ce31a9b54e93791dd8a7b48241039 /src
parent2446a215954a99f9d33019fad7d415ef9c083502 (diff)
downloadrust-837cc1687f7c0d35a4e90a2f6bee377b5a2ecfd5.tar.gz
rust-837cc1687f7c0d35a4e90a2f6bee377b5a2ecfd5.zip
Add codegen option for branch protection and pointer authentication on AArch64
The branch-protection codegen option enables the use of hint-space pointer
authentication code for AArch64 targets
Diffstat (limited to 'src')
-rw-r--r--src/doc/rustc/src/codegen-options/index.md23
-rw-r--r--src/test/assembly/aarch64-pointer-auth.rs22
-rw-r--r--src/test/codegen/branch-protection.rs41
-rw-r--r--src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile14
-rw-r--r--src/test/run-make-fulldeps/pointer-auth-link-with-c/test.c1
-rw-r--r--src/test/run-make-fulldeps/pointer-auth-link-with-c/test.rs8
6 files changed, 109 insertions, 0 deletions
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 0201b88417a..484242d86fe 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -7,6 +7,29 @@ a version of this list for your exact compiler by running `rustc -C help`.
 
 This option is deprecated and does nothing.
 
+## branch-protection
+
+This option lets you enable branch authentication instructions on AArch64.
+This option is ignored for non-AArch64 architectures.
+It takes some combination of the following values, separated by a `+`.
+
+- `pac-ret` - Enable pointer authentication for non-leaf functions.
+- `leaf` - Enable pointer authentication for all functions, including leaf functions.
+- `b-key` - Sign return addresses with key B, instead of the default key A.
+- `bti` - Enable branch target identification.
+
+`leaf` and `b-key` are only valid if `pac-ret` was previously specified.
+For example, `-C branch-protection=bti+pac-ret+leaf` is valid, but
+`-C branch-protection=bti+leaf+pac-ret` is not.
+
+Repeated values are ignored.
+For example, `-C branch-protection=pac-ret+leaf+pac-ret` is equivalent to
+`-C branch-protection=pac-ret+leaf`.
+
+Rust's standard library does not ship with BTI or pointer authentication enabled by default. \
+In Cargo projects the standard library can be recompiled with pointer authentication using the nightly
+[build-std](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std) feature.
+
 ## code-model
 
 This option lets you choose which code model to use. \
diff --git a/src/test/assembly/aarch64-pointer-auth.rs b/src/test/assembly/aarch64-pointer-auth.rs
new file mode 100644
index 00000000000..e778e67e1b3
--- /dev/null
+++ b/src/test/assembly/aarch64-pointer-auth.rs
@@ -0,0 +1,22 @@
+// Test that PAC instructions are emitted when branch-protection is specified.
+
+// min-llvm-version: 10.0.1
+// assembly-output: emit-asm
+// compile-flags: --target aarch64-unknown-linux-gnu
+// compile-flags: -C branch-protection=pac-ret+leaf
+// needs-llvm-components: aarch64
+
+#![feature(no_core, lang_items)]
+#![no_std]
+#![no_core]
+#![crate_type = "lib"]
+
+#[lang = "sized"]
+trait Sized {}
+
+// CHECK: hint #25
+// CHECK: hint #29
+#[no_mangle]
+pub fn test() -> u8 {
+    42
+}
diff --git a/src/test/codegen/branch-protection.rs b/src/test/codegen/branch-protection.rs
new file mode 100644
index 00000000000..79706cdf070
--- /dev/null
+++ b/src/test/codegen/branch-protection.rs
@@ -0,0 +1,41 @@
+// Test that the correct module flags are emitted with different branch protection flags.
+
+// revisions: bti pac-ret leaf b-key
+// min-llvm-version: 12.0.0
+// needs-llvm-components: aarch64
+// [bti] compile-flags: -C branch-protection=bti
+// [pac-ret] compile-flags: -C branch-protection=pac-ret
+// [leaf] compile-flags: -C branch-protection=pac-ret+leaf
+// [b-key] compile-flags: -C branch-protection=pac-ret+b-key
+// compile-flags: --target aarch64-unknown-linux-gnu
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![no_core]
+
+#[lang="sized"]
+trait Sized { }
+
+// A basic test function.
+pub fn test() {
+}
+
+// bti: !"branch-target-enforcement", i32 1
+// bti: !"sign-return-address", i32 0
+// bti: !"sign-return-address-all", i32 0
+// bti: !"sign-return-address-with-bkey", i32 0
+
+// pac-ret: !"branch-target-enforcement", i32 0
+// pac-ret: !"sign-return-address", i32 1
+// pac-ret: !"sign-return-address-all", i32 0
+// pac-ret: !"sign-return-address-with-bkey", i32 0
+
+// leaf: !"branch-target-enforcement", i32 0
+// leaf: !"sign-return-address", i32 1
+// leaf: !"sign-return-address-all", i32 1
+// leaf: !"sign-return-address-with-bkey", i32 0
+
+// b-key: !"branch-target-enforcement", i32 0
+// b-key: !"sign-return-address", i32 1
+// b-key: !"sign-return-address-all", i32 0
+// b-key: !"sign-return-address-with-bkey", i32 1
diff --git a/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile b/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile
new file mode 100644
index 00000000000..36d0f0e5a19
--- /dev/null
+++ b/src/test/run-make-fulldeps/pointer-auth-link-with-c/Makefile
@@ -0,0 +1,14 @@
+-include ../tools.mk
+
+# only-aarch64
+
+all:
+	$(COMPILE_OBJ) $(TMPDIR)/test.o test.c
+	$(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o
+	$(RUSTC) -C branch-protection=bti+pac-ret+leaf test.rs
+	$(call RUN,test)
+
+	$(COMPILE_OBJ) $(TMPDIR)/test.o test.c -mbranch-protection=bti+pac-ret+leaf
+	$(AR) rcs $(TMPDIR)/libtest.a $(TMPDIR)/test.o
+	$(RUSTC) -C branch-protection=bti+pac-ret+leaf test.rs
+	$(call RUN,test)
\ No newline at end of file
diff --git a/src/test/run-make-fulldeps/pointer-auth-link-with-c/test.c b/src/test/run-make-fulldeps/pointer-auth-link-with-c/test.c
new file mode 100644
index 00000000000..9fe07f82f9e
--- /dev/null
+++ b/src/test/run-make-fulldeps/pointer-auth-link-with-c/test.c
@@ -0,0 +1 @@
+int foo() { return 0; }
diff --git a/src/test/run-make-fulldeps/pointer-auth-link-with-c/test.rs b/src/test/run-make-fulldeps/pointer-auth-link-with-c/test.rs
new file mode 100644
index 00000000000..615ad0aeb3d
--- /dev/null
+++ b/src/test/run-make-fulldeps/pointer-auth-link-with-c/test.rs
@@ -0,0 +1,8 @@
+#[link(name = "test")]
+extern "C" {
+    fn foo() -> i32;
+}
+
+fn main() {
+    unsafe {foo();}
+}