aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Schievink <jonasschievink@gmail.com> 2020-08-23 21:57:08 +0200
committerGravatar Jonas Schievink <jonasschievink@gmail.com> 2020-08-23 21:57:08 +0200
commit679d42223fe79759bc634675694c46ae8ba0ce62 (patch)
tree141c8540c6e2b90ddd1d8b46ca284b6422103289
parent972f60f50e48c07fda40d2b853558c7db9b5a4ff (diff)
downloadcortex-m-679d42223fe79759bc634675694c46ae8ba0ce62.tar.gz
cortex-m-679d42223fe79759bc634675694c46ae8ba0ce62.tar.zst
cortex-m-679d42223fe79759bc634675694c46ae8ba0ce62.zip
Make it unsafe to define NMI handlers
-rw-r--r--cortex-m-rt/macros/src/lib.rs42
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-hidden.rs2
-rw-r--r--cortex-m-rt/tests/compile-fail/default-handler-twice.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs24
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/hard-fault-twice.rs4
-rw-r--r--cortex-m-rt/tests/compile-fail/unsafe-init-static.rs4
9 files changed, 67 insertions, 25 deletions
diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs
index 3c532c0..7e54a5c 100644
--- a/cortex-m-rt/macros/src/lib.rs
+++ b/cortex-m-rt/macros/src/lib.rs
@@ -113,6 +113,14 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream {
.into()
}
+#[derive(Debug, PartialEq)]
+enum Exception {
+ DefaultHandler,
+ HardFault,
+ NonMaskableInt,
+ Other,
+}
+
#[proc_macro_attribute]
pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
let mut f = parse_macro_input!(input as ItemFn);
@@ -130,20 +138,15 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
let fspan = f.span();
let ident = f.sig.ident.clone();
- enum Exception {
- DefaultHandler,
- HardFault,
- Other,
- }
-
let ident_s = ident.to_string();
let exn = match &*ident_s {
"DefaultHandler" => Exception::DefaultHandler,
"HardFault" => Exception::HardFault,
+ "NonMaskableInt" => Exception::NonMaskableInt,
// NOTE that at this point we don't check if the exception is available on the target (e.g.
// MemoryManagement is not available on Cortex-M0)
- "NonMaskableInt" | "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault"
- | "SVCall" | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other,
+ "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall"
+ | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other,
_ => {
return parse::Error::new(ident.span(), "This is not a valid exception name")
.to_compile_error()
@@ -151,7 +154,22 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
}
};
- // XXX should we blacklist other attributes?
+ if f.sig.unsafety.is_none() {
+ match exn {
+ Exception::DefaultHandler | Exception::HardFault | Exception::NonMaskableInt => {
+ // These are unsafe to define.
+ let name = if exn == Exception::DefaultHandler {
+ format!("`DefaultHandler`")
+ } else {
+ format!("`{:?}` handler", exn)
+ };
+ return parse::Error::new(ident.span(), format_args!("defining a {} is unsafe and requires an `unsafe fn` (see the cortex-m-rt docs)", name))
+ .to_compile_error()
+ .into();
+ }
+ Exception::Other => {}
+ }
+ }
match exn {
Exception::DefaultHandler => {
@@ -174,7 +192,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
if !valid_signature {
return parse::Error::new(
fspan,
- "`DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`",
+ "`DefaultHandler` must have signature `unsafe fn(i16) [-> !]`",
)
.to_compile_error()
.into();
@@ -231,7 +249,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
if !valid_signature {
return parse::Error::new(
fspan,
- "`HardFault` handler must have signature `[unsafe] fn(&ExceptionFrame) -> !`",
+ "`HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`",
)
.to_compile_error()
.into();
@@ -257,7 +275,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
)
.into()
}
- Exception::Other => {
+ Exception::NonMaskableInt | Exception::Other => {
let valid_signature = f.sig.constness.is_none()
&& f.vis == Visibility::Inherited
&& f.sig.abi.is_none()
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
index 5436115..b590883 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-1.rs
@@ -12,5 +12,5 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16, undef: u32) {}
-//~^ ERROR `DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`
+unsafe fn DefaultHandler(_irqn: i16, undef: u32) {}
+//~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
index 1cca10c..0dadd6a 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-bad-signature-2.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16) -> u32 {
- //~^ ERROR `DefaultHandler` must have signature `[unsafe] fn(i16) [-> !]`
+unsafe fn DefaultHandler(_irqn: i16) -> u32 {
+ //~^ ERROR `DefaultHandler` must have signature `unsafe fn(i16) [-> !]`
0
}
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
index e57cb31..c658e2b 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-hidden.rs
@@ -18,5 +18,5 @@ mod hidden {
use cortex_m_rt::exception;
#[exception]
- fn DefaultHandler(_irqn: i16) {}
+ unsafe fn DefaultHandler(_irqn: i16) {}
}
diff --git a/cortex-m-rt/tests/compile-fail/default-handler-twice.rs b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
index ad1c3f9..bbf2edd 100644
--- a/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
+++ b/cortex-m-rt/tests/compile-fail/default-handler-twice.rs
@@ -12,11 +12,11 @@ fn foo() -> ! {
}
#[exception]
-fn DefaultHandler(_irqn: i16) {}
+unsafe fn DefaultHandler(_irqn: i16) {}
pub mod reachable {
use cortex_m_rt::exception;
#[exception] //~ ERROR symbol `DefaultHandler` is already defined
- fn DefaultHandler(_irqn: i16) {}
+ unsafe fn DefaultHandler(_irqn: i16) {}
}
diff --git a/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs b/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs
new file mode 100644
index 0000000..f5de2f8
--- /dev/null
+++ b/cortex-m-rt/tests/compile-fail/exception-nmi-unsafe.rs
@@ -0,0 +1,24 @@
+#![no_main]
+#![no_std]
+
+extern crate cortex_m_rt;
+extern crate panic_halt;
+
+use cortex_m_rt::{entry, exception};
+
+#[entry]
+fn foo() -> ! {
+ loop {}
+}
+
+#[exception]
+fn DefaultHandler(_irq: i16) {}
+//~^ ERROR defining a `DefaultHandler` is unsafe and requires an `unsafe fn`
+
+#[exception]
+fn HardFault() {}
+//~^ ERROR defining a `HardFault` handler is unsafe and requires an `unsafe fn`
+
+#[exception]
+fn NonMaskableInt() {}
+//~^ ERROR defining a `NonMaskableInt` handler is unsafe and requires an `unsafe fn`
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
index d3b4392..11b53dc 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-1.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
}
#[exception]
-fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
- //~^ ERROR `HardFault` handler must have signature `[unsafe] fn(&ExceptionFrame) -> !`
+unsafe fn HardFault(_ef: &ExceptionFrame, undef: u32) -> ! {
+ //~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`
loop {}
}
diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
index 030b54c..03b79a5 100644
--- a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
+++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs
@@ -12,7 +12,7 @@ fn foo() -> ! {
}
#[exception]
-fn HardFault(_ef: &ExceptionFrame) -> ! {
+unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
loop {}
}
@@ -20,7 +20,7 @@ pub mod reachable {
use cortex_m_rt::{exception, ExceptionFrame};
#[exception] //~ ERROR symbol `HardFault` is already defined
- fn HardFault(_ef: &ExceptionFrame) -> ! {
+ unsafe fn HardFault(_ef: &ExceptionFrame) -> ! {
loop {}
}
}
diff --git a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
index c040173..23105f1 100644
--- a/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
+++ b/cortex-m-rt/tests/compile-fail/unsafe-init-static.rs
@@ -29,12 +29,12 @@ fn SVCall() {
}
#[exception]
-fn DefaultHandler(_irq: i16) {
+unsafe fn DefaultHandler(_irq: i16) {
static mut X: u32 = init(); //~ ERROR requires unsafe
}
#[exception]
-fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
+unsafe fn HardFault(_frame: &cortex_m_rt::ExceptionFrame) -> ! {
static mut X: u32 = init(); //~ ERROR requires unsafe
loop {}
}