about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-07-18 21:14:43 +0530
committerGitHub <noreply@github.com>2022-07-18 21:14:43 +0530
commita027b01f33e3280dff1a7be09d6090151d3f78a9 (patch)
treef6bfe00253a2bb38b997bfd862b1f2e48948fa0a /src/test
parent5ccdf1f6f7651001e3b15f48c6f2e5d0b56accf2 (diff)
parent530b5da49b822fd65214ecbe85455114e0ce725f (diff)
downloadrust-a027b01f33e3280dff1a7be09d6090151d3f78a9.tar.gz
rust-a027b01f33e3280dff1a7be09d6090151d3f78a9.zip
Rollup merge of #98998 - workingjubilee:naked-means-no-clothes-enforcement-technology, r=Amanieu
Remove branch target prologues from `#[naked] fn`

This patch hacks around rust-lang/rust#98768 for now via injecting appropriate attributes into the LLVMIR we emit for naked functions. I intend to pursue this upstream so that these attributes can be removed in general, but it's slow going wading through C++ for me.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/assembly/aarch64-naked-fn-no-bti-prolog.rs21
-rw-r--r--src/test/assembly/x86_64-naked-fn-no-cet-prolog.rs24
-rw-r--r--src/test/codegen/naked-noinline.rs2
3 files changed, 46 insertions, 1 deletions
diff --git a/src/test/assembly/aarch64-naked-fn-no-bti-prolog.rs b/src/test/assembly/aarch64-naked-fn-no-bti-prolog.rs
new file mode 100644
index 00000000000..79b0bb2d7ee
--- /dev/null
+++ b/src/test/assembly/aarch64-naked-fn-no-bti-prolog.rs
@@ -0,0 +1,21 @@
+// compile-flags: -C no-prepopulate-passes -Zbranch-protection=bti
+// assembly-output: emit-asm
+// needs-asm-support
+// only-aarch64
+
+#![crate_type = "lib"]
+#![feature(naked_functions)]
+use std::arch::asm;
+
+// The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
+// meaning "no prologue whatsoever, no, really, not one instruction."
+// Unfortunately, aarch64's "branch target identification" works via hints at landing sites.
+// LLVM implements this via making sure of that, even for functions with the naked attribute.
+// So, we must emit an appropriate instruction instead!
+#[no_mangle]
+#[naked]
+pub unsafe extern "C" fn _hlt() -> ! {
+    // CHECK-NOT: hint #34
+    // CHECK: hlt #0x1
+    asm!("hlt #1", options(noreturn))
+}
diff --git a/src/test/assembly/x86_64-naked-fn-no-cet-prolog.rs b/src/test/assembly/x86_64-naked-fn-no-cet-prolog.rs
new file mode 100644
index 00000000000..bedcded731d
--- /dev/null
+++ b/src/test/assembly/x86_64-naked-fn-no-cet-prolog.rs
@@ -0,0 +1,24 @@
+// compile-flags: -C no-prepopulate-passes -Zcf-protection=full
+// assembly-output: emit-asm
+// needs-asm-support
+// only-x86_64
+
+#![crate_type = "lib"]
+#![feature(naked_functions)]
+use std::arch::asm;
+
+// The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
+// meaning "no prologue whatsoever, no, really, not one instruction."
+// Unfortunately, x86's control-flow enforcement, specifically indirect branch protection,
+// works by using an instruction for each possible landing site,
+// and LLVM implements this via making sure of that.
+#[no_mangle]
+#[naked]
+pub unsafe extern "sysv64" fn will_halt() -> ! {
+    // CHECK-NOT: endbr{{32|64}}
+    // CHECK: hlt
+    asm!("hlt", options(noreturn))
+}
+
+// what about aarch64?
+// "branch-protection"=false
diff --git a/src/test/codegen/naked-noinline.rs b/src/test/codegen/naked-noinline.rs
index 13bc139ecd0..c0ac69f4ed7 100644
--- a/src/test/codegen/naked-noinline.rs
+++ b/src/test/codegen/naked-noinline.rs
@@ -28,4 +28,4 @@ pub unsafe fn g() {
     f();
 }
 
-// CHECK: attributes [[ATTR]] = { naked noinline{{.*}} }
+// CHECK: attributes [[ATTR]] = { naked{{.*}}noinline{{.*}} }