Skip to content

Commit 70c3d0a

Browse files
committed
Hardfault trampoline is now optional
1 parent 82fa94d commit 70c3d0a

File tree

4 files changed

+56
-2
lines changed

4 files changed

+56
-2
lines changed

cortex-m-rt/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ name = "compiletest"
4242
required-features = ["device"]
4343

4444
[features]
45+
default = ["hardfault-trampoline"]
4546
device = []
4647
set-sp = []
4748
set-vtor = []
4849
zero-init-ram = []
50+
hardfault-trampoline = ["cortex-m-rt-macros/hardfault-trampoline"]
4951

5052
[package.metadata.docs.rs]
5153
features = ["device"]

cortex-m-rt/macros/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,6 @@ proc-macro2 = "1.0"
2121
[dependencies.syn]
2222
features = ["extra-traits", "full"]
2323
version = "2.0"
24+
25+
[features]
26+
hardfault-trampoline = []

cortex-m-rt/macros/src/lib.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
232232
#f
233233
)
234234
}
235-
Exception::HardFault => {
235+
Exception::HardFault if cfg!(feature = "hardfault-trampoline") => {
236236
let valid_signature = f.sig.constness.is_none()
237237
&& f.vis == Visibility::Inherited
238238
&& f.sig.abi.is_none()
@@ -283,6 +283,39 @@ pub fn exception(args: TokenStream, input: TokenStream) -> TokenStream {
283283
#f
284284
)
285285
}
286+
Exception::HardFault => {
287+
let valid_signature = f.sig.constness.is_none()
288+
&& f.vis == Visibility::Inherited
289+
&& f.sig.abi.is_none()
290+
&& f.sig.inputs.len() == 0
291+
&& f.sig.generics.params.is_empty()
292+
&& f.sig.generics.where_clause.is_none()
293+
&& f.sig.variadic.is_none()
294+
&& match f.sig.output {
295+
ReturnType::Default => false,
296+
ReturnType::Type(_, ref ty) => matches!(**ty, Type::Never(_)),
297+
};
298+
299+
if !valid_signature {
300+
return parse::Error::new(
301+
fspan,
302+
"`HardFault` handler must have signature `unsafe fn() -> !`",
303+
)
304+
.to_compile_error()
305+
.into();
306+
}
307+
308+
f.sig.ident = Ident::new(&format!("__cortex_m_rt_{}", f.sig.ident), Span::call_site());
309+
310+
quote!(
311+
#[export_name = "HardFault"]
312+
// Only emit link_section when building for embedded targets,
313+
// because some hosted platforms (used to check the build)
314+
// cannot handle the long link section names.
315+
#[cfg_attr(target_os = "none", link_section = ".HardFault.user")]
316+
#f
317+
)
318+
}
286319
Exception::NonMaskableInt | Exception::Other => {
287320
let valid_signature = f.sig.constness.is_none()
288321
&& f.vis == Visibility::Inherited

cortex-m-rt/src/lib.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ use core::fmt;
458458
// HardFault exceptions are bounced through this trampoline which grabs the stack pointer at
459459
// the time of the exception and passes it to the user's HardFault handler in r0.
460460
// Depending on the stack mode in EXC_RETURN, fetches stack from either MSP or PSP.
461-
#[cfg(cortex_m)]
461+
#[cfg(all(cortex_m, feature = "hardfault-trampoline"))]
462462
global_asm!(
463463
".cfi_sections .debug_frame
464464
.section .HardFaultTrampoline, \"ax\"
@@ -1061,12 +1061,22 @@ pub static __RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset;
10611061
#[allow(unused_variables)]
10621062
#[doc(hidden)]
10631063
#[cfg_attr(cortex_m, link_section = ".HardFault.default")]
1064+
#[cfg(feature = "hardfault-trampoline")]
10641065
#[no_mangle]
10651066
pub unsafe extern "C" fn HardFault_(ef: &ExceptionFrame) -> ! {
10661067
#[allow(clippy::empty_loop)]
10671068
loop {}
10681069
}
10691070

1071+
#[doc(hidden)]
1072+
#[cfg_attr(cortex_m, link_section = ".HardFault.default")]
1073+
#[cfg(not(feature = "hardfault-trampoline"))]
1074+
#[no_mangle]
1075+
pub unsafe extern "C" fn HardFault_() -> ! {
1076+
#[allow(clippy::empty_loop)]
1077+
loop {}
1078+
}
1079+
10701080
#[doc(hidden)]
10711081
#[no_mangle]
10721082
pub unsafe extern "C" fn DefaultHandler_() -> ! {
@@ -1115,7 +1125,10 @@ extern "C" {
11151125

11161126
fn NonMaskableInt();
11171127

1128+
#[cfg(feature = "hardfault-trampoline")]
11181129
fn HardFaultTrampoline();
1130+
#[cfg(not(feature = "hardfault-trampoline"))]
1131+
fn HardFault();
11191132

11201133
#[cfg(not(armv6m))]
11211134
fn MemoryManagement();
@@ -1154,9 +1167,12 @@ pub static __EXCEPTIONS: [Vector; 14] = [
11541167
handler: NonMaskableInt,
11551168
},
11561169
// Exception 3: Hard Fault Interrupt.
1170+
#[cfg(feature = "hardfault-trampoline")]
11571171
Vector {
11581172
handler: HardFaultTrampoline,
11591173
},
1174+
#[cfg(not(feature = "hardfault-trampoline"))]
1175+
Vector { handler: HardFault },
11601176
// Exception 4: Memory Management Interrupt [not on Cortex-M0 variants].
11611177
#[cfg(not(armv6m))]
11621178
Vector {

0 commit comments

Comments
 (0)