Skip to content

Commit 5473462

Browse files
authored
Merge pull request #548 from thejpster/paint-stack
Adds a `paint-stack` feature.
2 parents b0d2e45 + 0df6752 commit 5473462

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

cortex-m-rt/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ device = []
4646
set-sp = []
4747
set-vtor = []
4848
zero-init-ram = []
49+
paint-stack = []
4950

5051
[package.metadata.docs.rs]
5152
features = ["device"]

cortex-m-rt/examples/qemu.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
#![no_main]
22
#![no_std]
33

4-
use core::fmt::Write;
4+
use core::{
5+
fmt::Write,
6+
sync::atomic::{AtomicU32, Ordering},
7+
};
8+
9+
static DATA_VAL: AtomicU32 = AtomicU32::new(1234);
10+
11+
static BSS_VAL: AtomicU32 = AtomicU32::new(0);
512

613
#[cortex_m_rt::entry]
714
fn main() -> ! {
815
let x = 42;
916

1017
loop {
1118
let mut hstdout = cortex_m_semihosting::hio::hstdout().unwrap();
12-
write!(hstdout, "x = {}\n", x).unwrap();
19+
// check that .data and .bss were initialised OK
20+
if DATA_VAL.load(Ordering::Relaxed) == 1234 && BSS_VAL.load(Ordering::Relaxed) == 0 {
21+
_ = writeln!(hstdout, "x = {}", x);
22+
}
1323
cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_SUCCESS);
1424
}
1525
}

cortex-m-rt/src/lib.rs

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@
185185
//! value to the `_ram_end` value from the linker script. This is not usually required, but might be
186186
//! necessary to properly initialize memory integrity measures on some hardware.
187187
//!
188+
//! ## `paint-stack`
189+
//!
190+
//! Everywhere between `__sheap` and `___stack_start` is painted with the fixed value
191+
//! `STACK_PAINT_VALUE`, which is `0xCCCC_CCCC`.
192+
//! You can then inspect memory during debugging to determine how much of the stack has been used -
193+
//! where the stack has been used the 'paint' will have been 'scrubbed off' and the memory will
194+
//! have a value other than `STACK_PAINT_VALUE`.
195+
//!
188196
//! # Inspection
189197
//!
190198
//! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
@@ -225,7 +233,7 @@
225233
//! using the `main` symbol so you will also find that symbol in your program.
226234
//!
227235
//! - `DefaultHandler`. This is the default handler. If not overridden using `#[exception] fn
228-
//! DefaultHandler(..` this will be an infinite loop.
236+
//! DefaultHandler(..` this will be an infinite loop.
229237
//!
230238
//! - `HardFault` and `_HardFault`. These function handle the hard fault handling and what they
231239
//! do depends on whether the hard fault is overridden and whether the trampoline is enabled (which it is by default).
@@ -467,6 +475,12 @@
467475

468476
extern crate cortex_m_rt_macros as macros;
469477

478+
/// The 32-bit value the stack is painted with before the program runs.
479+
// Note: keep this value in-sync with the start-up assembly code, as we can't
480+
// use const values in `global_asm!` yet.
481+
#[cfg(feature = "paint-stack")]
482+
pub const STACK_PAINT_VALUE: u32 = 0xcccc_cccc;
483+
470484
#[cfg(cortex_m)]
471485
use core::arch::global_asm;
472486
use core::fmt;
@@ -545,24 +559,37 @@ cfg_global_asm! {
545559
"ldr r0, =__sbss
546560
ldr r1, =__ebss
547561
movs r2, #0
548-
2:
562+
0:
563+
cmp r1, r0
564+
beq 1f
565+
stm r0!, {{r2}}
566+
b 0b
567+
1:",
568+
569+
// If enabled, paint stack/heap RAM with 0xcccccccc.
570+
// `__sheap` and `_stack_start` come from the linker script.
571+
#[cfg(feature = "paint-stack")]
572+
"ldr r0, =__sheap
573+
ldr r1, =_stack_start
574+
ldr r2, =0xcccccccc // This must match STACK_PAINT_VALUE
575+
0:
549576
cmp r1, r0
550-
beq 3f
577+
beq 1f
551578
stm r0!, {{r2}}
552-
b 2b
553-
3:",
579+
b 0b
580+
1:",
554581

555582
// Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the linker script.
556583
"ldr r0, =__sdata
557584
ldr r1, =__edata
558585
ldr r2, =__sidata
559-
4:
586+
0:
560587
cmp r1, r0
561-
beq 5f
588+
beq 1f
562589
ldm r2!, {{r3}}
563590
stm r0!, {{r3}}
564-
b 4b
565-
5:",
591+
b 0b
592+
1:",
566593

567594
// Potentially enable an FPU.
568595
// SCB.CPACR is 0xE000_ED88.
@@ -872,6 +899,7 @@ pub static __ONCE__: () = ();
872899
/// Registers stacked (pushed onto the stack) during an exception.
873900
#[derive(Clone, Copy)]
874901
#[repr(C)]
902+
#[allow(dead_code)]
875903
pub struct ExceptionFrame {
876904
r0: u32,
877905
r1: u32,

0 commit comments

Comments
 (0)