From 70c3d0a2a1b3aeb97f5835dc481a767ecea909a4 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 19 May 2023 10:49:46 +0200 Subject: Hardfault trampoline is now optional --- cortex-m-rt/macros/src/lib.rs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 27ee2f1..b529ef2 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -232,7 +232,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { #f ) } - Exception::HardFault => { + Exception::HardFault if cfg!(feature = "hardfault-trampoline") => { let valid_signature = f.sig.constness.is_none() && f.vis == Visibility::Inherited && f.sig.abi.is_none() @@ -283,6 +283,39 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { #f ) } + Exception::HardFault => { + let valid_signature = f.sig.constness.is_none() + && f.vis == Visibility::Inherited + && f.sig.abi.is_none() + && f.sig.inputs.len() == 0 + && f.sig.generics.params.is_empty() + && f.sig.generics.where_clause.is_none() + && f.sig.variadic.is_none() + && match f.sig.output { + ReturnType::Default => false, + ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)), + }; + + if !valid_signature { + return parse::Error::new( + fspan, + "`HardFault` handler must have signature `unsafe fn() -> !`", + ) + .to_compile_error() + .into(); + } + + f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site()); + + quote!( + #[export_name = "HardFault"] + // Only emit link_section when building for embedded targets, + // because some hosted platforms (used to check the build) + // cannot handle the long link section names. + #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] + #f + ) + } Exception::NonMaskableInt | Exception::Other => { let valid_signature = f.sig.constness.is_none() && f.vis == Visibility::Inherited -- cgit v1.2.3 From 9ba8c6a8053b215204eefbd9c4a9de9d0a19d50a Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 19 May 2023 10:57:49 +0200 Subject: Fix clippy warnings --- cortex-m-rt/macros/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index b529ef2..e9be224 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -287,7 +287,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let valid_signature = f.sig.constness.is_none() && f.vis == Visibility::Inherited && f.sig.abi.is_none() - && f.sig.inputs.len() == 0 + && f.sig.inputs.is_empty() && f.sig.generics.params.is_empty() && f.sig.generics.where_clause.is_none() && f.sig.variadic.is_none() @@ -667,7 +667,7 @@ fn check_attr_whitelist(attrs: &[Attribute], caller: WhiteListCaller) -> Result< } }; - return Err(parse::Error::new(attr.span(), &err_str) + return Err(parse::Error::new(attr.span(), err_str) .to_compile_error() .into()); } -- cgit v1.2.3 From 54877baa685c63f085cc50adc251bb3af5bdfb2b Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 16 Jun 2023 11:46:56 +0200 Subject: Removed the feature flag and moved the trampoline into the macro --- cortex-m-rt/CHANGELOG.md | 4 +- cortex-m-rt/Cargo.toml | 2 - cortex-m-rt/macros/Cargo.toml | 3 - cortex-m-rt/macros/src/lib.rs | 226 +++++++++++++++++++++++++++++------------- cortex-m-rt/src/lib.rs | 44 -------- 5 files changed, 159 insertions(+), 120 deletions(-) (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/CHANGELOG.md b/cortex-m-rt/CHANGELOG.md index 28ec16c..40dad58 100644 --- a/cortex-m-rt/CHANGELOG.md +++ b/cortex-m-rt/CHANGELOG.md @@ -9,9 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Add `zero-init-ram` feature to initialize RAM with zeros on startup. This can be necessary on safety-critical hardware to properly initialize memory integrity measures. -- Add `hardfault-trampoline` feature that is enabled by default which enables - the previously required hardfault trampoline. Now when this feature is not active, there will be - no trampoline and the function you write is the exact function that is used as hardfault handler. +- Add optional `exception` argument for `HardFault`. It has one option `trampoline` which is true by default. When set to false, no trampoline will be created and the function will be called as the exception handler directly. ## [v0.7.3] diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml index 03cd7f6..3305d34 100644 --- a/cortex-m-rt/Cargo.toml +++ b/cortex-m-rt/Cargo.toml @@ -42,12 +42,10 @@ name = "compiletest" required-features = ["device"] [features] -default = ["hardfault-trampoline"] device = [] set-sp = [] set-vtor = [] zero-init-ram = [] -hardfault-trampoline = ["cortex-m-rt-macros/hardfault-trampoline"] [package.metadata.docs.rs] features = ["device"] diff --git a/cortex-m-rt/macros/Cargo.toml b/cortex-m-rt/macros/Cargo.toml index 287ad9c..f548e19 100644 --- a/cortex-m-rt/macros/Cargo.toml +++ b/cortex-m-rt/macros/Cargo.toml @@ -21,6 +21,3 @@ proc-macro2 = "1.0" [dependencies.syn] features = ["extra-traits", "full"] version = "2.0" - -[features] -hardfault-trampoline = [] diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index e9be224..527dcc4 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -10,8 +10,11 @@ use quote::quote; use std::collections::HashSet; use std::iter; use syn::{ - parse, parse_macro_input, spanned::Spanned, AttrStyle, Attribute, FnArg, Ident, Item, ItemFn, - ItemStatic, ReturnType, Stmt, Type, Visibility, + parse::{self, Parse}, + parse_macro_input, + spanned::Spanned, + AttrStyle, Attribute, FnArg, Ident, Item, ItemFn, ItemStatic, ReturnType, Stmt, Type, + Visibility, }; #[proc_macro_attribute] @@ -113,21 +116,73 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { #[derive(Debug, PartialEq)] enum Exception { DefaultHandler, - HardFault, + HardFault(HardFaultArgs), NonMaskableInt, Other, } +#[derive(Debug, PartialEq)] +struct HardFaultArgs { + trampoline: bool, +} + +impl Default for HardFaultArgs { + fn default() -> Self { + Self { trampoline: true } + } +} + +impl Parse for HardFaultArgs { + fn parse(input: parse::ParseStream) -> syn::Result { + let mut items = Vec::new(); + // Read a list of `ident = value,` + loop { + if input.is_empty() { + break; + } + + let name = input.parse::()?; + input.parse::()?; + let value = input.parse::()?; + + items.push((name, value)); + + if input.is_empty() { + break; + } + + input.parse::()?; + } + + let mut args = Self::default(); + + for (name, value) in items { + match name.to_string().as_str() { + "trampoline" => match value { + syn::Lit::Bool(val) => { + args.trampoline = val.value(); + } + _ => { + return Err(syn::Error::new_spanned( + value, + "Not a valid value. `trampoline` takes a boolean literal", + )) + } + }, + _ => { + return Err(syn::Error::new_spanned(name, "Not a valid argument name")); + } + } + } + + Ok(args) + } +} + #[proc_macro_attribute] pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let mut f = parse_macro_input!(input as ItemFn); - if !args.is_empty() { - return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") - .to_compile_error() - .into(); - } - if let Err(error) = check_attr_whitelist(&f.attrs, WhiteListCaller::Exception) { return error; } @@ -137,14 +192,34 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { let ident_s = ident.to_string(); let exn = match &*ident_s { - "DefaultHandler" => Exception::DefaultHandler, - "HardFault" => Exception::HardFault, - "NonMaskableInt" => Exception::NonMaskableInt, + "DefaultHandler" => { + if !args.is_empty() { + return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") + .to_compile_error() + .into(); + } + Exception::DefaultHandler + } + "HardFault" => Exception::HardFault(parse_macro_input!(args)), + "NonMaskableInt" => { + if !args.is_empty() { + return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") + .to_compile_error() + .into(); + } + 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) "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall" | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other, _ => { + if !args.is_empty() { + return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") + .to_compile_error() + .into(); + } + return parse::Error::new(ident.span(), "This is not a valid exception name") .to_compile_error() .into(); @@ -153,7 +228,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { if f.sig.unsafety.is_none() { match exn { - Exception::DefaultHandler | Exception::HardFault | Exception::NonMaskableInt => { + Exception::DefaultHandler | Exception::HardFault(_) | Exception::NonMaskableInt => { // These are unsafe to define. let name = if exn == Exception::DefaultHandler { "`DefaultHandler`".to_string() @@ -232,17 +307,24 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { #f ) } - Exception::HardFault if cfg!(feature = "hardfault-trampoline") => { + Exception::HardFault(args) => { let valid_signature = f.sig.constness.is_none() && f.vis == Visibility::Inherited && f.sig.abi.is_none() - && f.sig.inputs.len() == 1 - && match &f.sig.inputs[0] { - FnArg::Typed(arg) => match arg.ty.as_ref() { - Type::Reference(r) => r.lifetime.is_none() && r.mutability.is_none(), + && if args.trampoline { + match &f.sig.inputs[0] { + FnArg::Typed(arg) => match arg.ty.as_ref() { + Type::Reference(r) => { + r.lifetime.is_none() + && r.mutability.is_none() + && f.sig.inputs.len() == 1 + } + _ => false, + }, _ => false, - }, - _ => false, + } + } else { + f.sig.inputs.is_empty() } && f.sig.generics.params.is_empty() && f.sig.generics.where_clause.is_none() @@ -255,66 +337,74 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { if !valid_signature { return parse::Error::new( fspan, - "`HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`", + if args.trampoline { + "`HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !`" + } else { + "`HardFault` handler must have signature `unsafe fn() -> !`" + }, ) .to_compile_error() .into(); } f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site()); - let tramp_ident = Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); - let ident = &f.sig.ident; - let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); + if args.trampoline { + let tramp_ident = + Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); + let ident = &f.sig.ident; - quote!( - #(#cfgs)* - #(#attrs)* - #[doc(hidden)] - #[export_name = "HardFault"] - // Only emit link_section when building for embedded targets, - // because some hosted platforms (used to check the build) - // cannot handle the long link section names. - #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] - pub unsafe extern "C" fn #tramp_ident(frame: &::cortex_m_rt::ExceptionFrame) { - #ident(frame) - } + let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); - #f - ) - } - Exception::HardFault => { - let valid_signature = f.sig.constness.is_none() - && f.vis == Visibility::Inherited - && f.sig.abi.is_none() - && f.sig.inputs.is_empty() - && f.sig.generics.params.is_empty() - && f.sig.generics.where_clause.is_none() - && f.sig.variadic.is_none() - && match f.sig.output { - ReturnType::Default => false, - ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)), - }; + quote!( + #(#cfgs)* + #(#attrs)* + #[doc(hidden)] + #[export_name = "HardFault"] + // Only emit link_section when building for embedded targets, + // because some hosted platforms (used to check the build) + // cannot handle the long link section names. + #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] + pub unsafe extern "C" fn #tramp_ident(frame: &::cortex_m_rt::ExceptionFrame) { + #ident(frame) + } - if !valid_signature { - return parse::Error::new( - fspan, - "`HardFault` handler must have signature `unsafe fn() -> !`", + #f + + // HardFault exceptions are bounced through this trampoline which grabs the stack pointer at + // the time of the exception and passes it to the user's HardFault handler in r0. + // Depending on the stack mode in EXC_RETURN, fetches stack from either MSP or PSP. + core::arch::global_asm!( + ".cfi_sections .debug_frame + .section .HardFaultTrampoline, \"ax\" + .global HardFaultTrampline + .type HardFaultTrampline,%function + .thumb_func + .cfi_startproc + HardFaultTrampoline:", + "mov r0, lr + movs r1, #4 + tst r0, r1 + bne 0f + mrs r0, MSP + b HardFault + 0: + mrs r0, PSP + b HardFault", + ".cfi_endproc + .size HardFaultTrampoline, . - HardFaultTrampoline", + ); + ) + } else { + quote!( + #[export_name = "HardFault"] + // Only emit link_section when building for embedded targets, + // because some hosted platforms (used to check the build) + // cannot handle the long link section names. + #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] + #f ) - .to_compile_error() - .into(); } - - f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site()); - - quote!( - #[export_name = "HardFault"] - // Only emit link_section when building for embedded targets, - // because some hosted platforms (used to check the build) - // cannot handle the long link section names. - #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] - #f - ) } Exception::NonMaskableInt | Exception::Other => { let valid_signature = f.sig.constness.is_none() diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index a39d32a..6456a5e 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -455,31 +455,6 @@ extern crate cortex_m_rt_macros as macros; use core::arch::global_asm; use core::fmt; -// HardFault exceptions are bounced through this trampoline which grabs the stack pointer at -// the time of the exception and passes it to the user's HardFault handler in r0. -// Depending on the stack mode in EXC_RETURN, fetches stack from either MSP or PSP. -#[cfg(all(cortex_m, feature = "hardfault-trampoline"))] -global_asm!( - ".cfi_sections .debug_frame - .section .HardFaultTrampoline, \"ax\" - .global HardFaultTrampline - .type HardFaultTrampline,%function - .thumb_func - .cfi_startproc - HardFaultTrampoline:", - "mov r0, lr - movs r1, #4 - tst r0, r1 - bne 0f - mrs r0, MSP - b HardFault - 0: - mrs r0, PSP - b HardFault", - ".cfi_endproc - .size HardFaultTrampoline, . - HardFaultTrampoline", -); - /// Parse cfg attributes inside a global_asm call. #[cfg(cortex_m)] macro_rules! cfg_global_asm { @@ -1058,19 +1033,8 @@ pub fn heap_start() -> *mut u32 { #[no_mangle] pub static __RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; -#[allow(unused_variables)] #[doc(hidden)] #[cfg_attr(cortex_m, link_section = ".HardFault.default")] -#[cfg(feature = "hardfault-trampoline")] -#[no_mangle] -pub unsafe extern "C" fn HardFault_(ef: &ExceptionFrame) -> ! { - #[allow(clippy::empty_loop)] - loop {} -} - -#[doc(hidden)] -#[cfg_attr(cortex_m, link_section = ".HardFault.default")] -#[cfg(not(feature = "hardfault-trampoline"))] #[no_mangle] pub unsafe extern "C" fn HardFault_() -> ! { #[allow(clippy::empty_loop)] @@ -1125,9 +1089,6 @@ extern "C" { fn NonMaskableInt(); - #[cfg(feature = "hardfault-trampoline")] - fn HardFaultTrampoline(); - #[cfg(not(feature = "hardfault-trampoline"))] fn HardFault(); #[cfg(not(armv6m))] @@ -1167,11 +1128,6 @@ pub static __EXCEPTIONS: [Vector; 14] = [ handler: NonMaskableInt, }, // Exception 3: Hard Fault Interrupt. - #[cfg(feature = "hardfault-trampoline")] - Vector { - handler: HardFaultTrampoline, - }, - #[cfg(not(feature = "hardfault-trampoline"))] Vector { handler: HardFault }, // Exception 4: Memory Management Interrupt [not on Cortex-M0 variants]. #[cfg(not(armv6m))] -- cgit v1.2.3 From 540d1de34aa69b3ec262b7461c51394ac140418d Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Tue, 20 Jun 2023 21:22:11 +0200 Subject: Added more tests and fixed a panic --- cortex-m-rt/macros/src/lib.rs | 44 +++++++++++++--------- .../compile-fail/hard-fault-bad-signature-2.rs | 18 +++++++++ .../compile-fail/hard-fault-bad-signature-3.rs | 18 +++++++++ 3 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs create mode 100644 cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 527dcc4..cd92b85 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -7,8 +7,8 @@ extern crate proc_macro; use proc_macro::TokenStream; use proc_macro2::Span; use quote::quote; -use std::collections::HashSet; use std::iter; +use std::{collections::HashSet, fmt::Display}; use syn::{ parse::{self, Parse}, parse_macro_input, @@ -121,6 +121,17 @@ enum Exception { Other, } +impl Display for Exception { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Exception::DefaultHandler => write!(f, "`DefaultHandler`"), + Exception::HardFault(_) => write!(f, "`HardFault` handler"), + Exception::NonMaskableInt => write!(f, "`NonMaskableInt` handler"), + Exception::Other => write!(f, "Other exception handler"), + } + } +} + #[derive(Debug, PartialEq)] struct HardFaultArgs { trampoline: bool, @@ -212,14 +223,16 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { // 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) "MemoryManagement" | "BusFault" | "UsageFault" | "SecureFault" | "SVCall" - | "DebugMonitor" | "PendSV" | "SysTick" => Exception::Other, - _ => { + | "DebugMonitor" | "PendSV" | "SysTick" => { if !args.is_empty() { return parse::Error::new(Span::call_site(), "This attribute accepts no arguments") .to_compile_error() .into(); } + Exception::Other + } + _ => { return parse::Error::new(ident.span(), "This is not a valid exception name") .to_compile_error() .into(); @@ -230,11 +243,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { match exn { Exception::DefaultHandler | Exception::HardFault(_) | Exception::NonMaskableInt => { // These are unsafe to define. - let name = if exn == Exception::DefaultHandler { - "`DefaultHandler`".to_string() - } else { - format!("`{:?}` handler", exn) - }; + let name = format!("{}", 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(); @@ -312,17 +321,16 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { && f.vis == Visibility::Inherited && f.sig.abi.is_none() && if args.trampoline { - match &f.sig.inputs[0] { - FnArg::Typed(arg) => match arg.ty.as_ref() { - Type::Reference(r) => { - r.lifetime.is_none() - && r.mutability.is_none() - && f.sig.inputs.len() == 1 - } + f.sig.inputs.len() == 1 + && match &f.sig.inputs[0] { + FnArg::Typed(arg) => match arg.ty.as_ref() { + Type::Reference(r) => { + r.lifetime.is_none() && r.mutability.is_none() + } + _ => false, + }, _ => false, - }, - _ => false, - } + } } else { f.sig.inputs.is_empty() } diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs new file mode 100644 index 0000000..d20d832 --- /dev/null +++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-2.rs @@ -0,0 +1,18 @@ +#![no_main] +#![no_std] + +extern crate cortex_m_rt; +extern crate panic_halt; + +use cortex_m_rt::{entry, exception, ExceptionFrame}; + +#[entry] +fn foo() -> ! { + loop {} +} + +#[exception(trampoline = true)] +unsafe fn HardFault() -> ! { + //~^ ERROR `HardFault` handler must have signature `unsafe fn(&ExceptionFrame) -> !` + loop {} +} diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs new file mode 100644 index 0000000..62c8439 --- /dev/null +++ b/cortex-m-rt/tests/compile-fail/hard-fault-bad-signature-3.rs @@ -0,0 +1,18 @@ +#![no_main] +#![no_std] + +extern crate cortex_m_rt; +extern crate panic_halt; + +use cortex_m_rt::{entry, exception, ExceptionFrame}; + +#[entry] +fn foo() -> ! { + loop {} +} + +#[exception(trampoline = false)] +unsafe fn HardFault(_ef: &ExceptionFrame) -> ! { + //~^ ERROR `HardFault` handler must have signature `unsafe fn() -> !` + loop {} +} -- cgit v1.2.3 From 3bd46e56e4e4c138cb51900f47280cc991f51702 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 21 Jul 2023 13:23:49 +0200 Subject: Changed some names around so everything should be called correctly --- cortex-m-rt/macros/src/lib.rs | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index cd92b85..80ac665 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -368,11 +368,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { #(#cfgs)* #(#attrs)* #[doc(hidden)] - #[export_name = "HardFault"] - // Only emit link_section when building for embedded targets, - // because some hosted platforms (used to check the build) - // cannot handle the long link section names. - #[cfg_attr(target_os = "none", link_section = ".HardFault.user")] + #[export_name = "HardFaultUser"] pub unsafe extern "C" fn #tramp_ident(frame: &::cortex_m_rt::ExceptionFrame) { #ident(frame) } @@ -384,23 +380,23 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { // Depending on the stack mode in EXC_RETURN, fetches stack from either MSP or PSP. core::arch::global_asm!( ".cfi_sections .debug_frame - .section .HardFaultTrampoline, \"ax\" - .global HardFaultTrampline - .type HardFaultTrampline,%function + .section .HardFault.user, \"ax\" + .global HardFault + .type HardFault,%function .thumb_func .cfi_startproc - HardFaultTrampoline:", - "mov r0, lr - movs r1, #4 - tst r0, r1 - bne 0f - mrs r0, MSP - b HardFault + HardFault:", + "mov r0, lr + movs r1, #4 + tst r0, r1 + bne 0f + mrs r0, MSP + b HardFaultUser 0: - mrs r0, PSP - b HardFault", + mrs r0, PSP + b HardFaultUser", ".cfi_endproc - .size HardFaultTrampoline, . - HardFaultTrampoline", + .size HardFault, . - HardFault", ); ) } else { -- cgit v1.2.3 From f07d5b3241cb2e70c37d049caab64d75ef32860b Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 21 Jul 2023 14:16:46 +0200 Subject: Changed setup for better compiler diagnostics. We won't get a nasty assembly error anymore --- cortex-m-rt/macros/src/lib.rs | 18 ++++++++++----- .../hard-fault-twice-mixed-trampoline.rs | 26 ++++++++++++++++++++++ cortex-m-rt/tests/compile-fail/hard-fault-twice.rs | 2 +- 3 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index 80ac665..d89bdea 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -356,10 +356,10 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { } f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site()); + let tramp_ident = + Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); if args.trampoline { - let tramp_ident = - Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); let ident = &f.sig.ident; let (ref cfgs, ref attrs) = extract_cfgs(f.attrs.clone()); @@ -368,8 +368,8 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { #(#cfgs)* #(#attrs)* #[doc(hidden)] - #[export_name = "HardFaultUser"] - pub unsafe extern "C" fn #tramp_ident(frame: &::cortex_m_rt::ExceptionFrame) { + #[export_name = "_HardFault"] + unsafe extern "C" fn #tramp_ident(frame: &::cortex_m_rt::ExceptionFrame) { #ident(frame) } @@ -391,16 +391,22 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { tst r0, r1 bne 0f mrs r0, MSP - b HardFaultUser + b _HardFault 0: mrs r0, PSP - b HardFaultUser", + b _HardFault", ".cfi_endproc .size HardFault, . - HardFault", ); ) } else { quote!( + #[doc(hidden)] + #[export_name = "_HardFault"] + unsafe extern "C" fn #tramp_ident() { + // This trampoline has no function except making the compiler diagnostics better. + } + #[export_name = "HardFault"] // Only emit link_section when building for embedded targets, // because some hosted platforms (used to check the build) diff --git a/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs b/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs new file mode 100644 index 0000000..3610170 --- /dev/null +++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice-mixed-trampoline.rs @@ -0,0 +1,26 @@ +#![no_main] +#![no_std] + +extern crate cortex_m_rt; +extern crate panic_halt; + +use cortex_m_rt::{entry, exception, ExceptionFrame}; + +#[entry] +fn foo() -> ! { + loop {} +} + +#[exception(trampoline = false)] +unsafe fn HardFault() -> ! { + loop {} +} + +pub mod reachable { + use cortex_m_rt::{exception, ExceptionFrame}; + + #[exception] //~ ERROR symbol `_HardFault` is already defined + unsafe fn HardFault(_ef: &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 03b79a5..af80127 100644 --- a/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs +++ b/cortex-m-rt/tests/compile-fail/hard-fault-twice.rs @@ -19,7 +19,7 @@ unsafe fn HardFault(_ef: &ExceptionFrame) -> ! { pub mod reachable { use cortex_m_rt::{exception, ExceptionFrame}; - #[exception] //~ ERROR symbol `HardFault` is already defined + #[exception] //~ ERROR symbol `_HardFault` is already defined unsafe fn HardFault(_ef: &ExceptionFrame) -> ! { loop {} } -- cgit v1.2.3 From ce12620be0e51f9a8bbe6bb67cfc131201b55f34 Mon Sep 17 00:00:00 2001 From: Dion Dokter Date: Fri, 21 Jul 2023 14:17:07 +0200 Subject: fmt --- cortex-m-rt/macros/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'cortex-m-rt/macros/src') diff --git a/cortex-m-rt/macros/src/lib.rs b/cortex-m-rt/macros/src/lib.rs index d89bdea..0477405 100644 --- a/cortex-m-rt/macros/src/lib.rs +++ b/cortex-m-rt/macros/src/lib.rs @@ -356,8 +356,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream { } f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site()); - let tramp_ident = - Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); + let tramp_ident = Ident::new(&format!("{}_trampoline", f.sig.ident), Span::call_site()); if args.trampoline { let ident = &f.sig.ident; -- cgit v1.2.3