Skip to content

Commit

Permalink
Merge pull request #548 from thejpster/paint-stack
Browse files Browse the repository at this point in the history
Adds a `paint-stack` feature.
  • Loading branch information
adamgreig authored Aug 15, 2024
2 parents b0d2e45 + 0df6752 commit 5473462
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 11 deletions.
1 change: 1 addition & 0 deletions cortex-m-rt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ device = []
set-sp = []
set-vtor = []
zero-init-ram = []
paint-stack = []

[package.metadata.docs.rs]
features = ["device"]
14 changes: 12 additions & 2 deletions cortex-m-rt/examples/qemu.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
#![no_main]
#![no_std]

use core::fmt::Write;
use core::{
fmt::Write,
sync::atomic::{AtomicU32, Ordering},
};

static DATA_VAL: AtomicU32 = AtomicU32::new(1234);

static BSS_VAL: AtomicU32 = AtomicU32::new(0);

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

loop {
let mut hstdout = cortex_m_semihosting::hio::hstdout().unwrap();
write!(hstdout, "x = {}\n", x).unwrap();
// check that .data and .bss were initialised OK
if DATA_VAL.load(Ordering::Relaxed) == 1234 && BSS_VAL.load(Ordering::Relaxed) == 0 {
_ = writeln!(hstdout, "x = {}", x);
}
cortex_m_semihosting::debug::exit(cortex_m_semihosting::debug::EXIT_SUCCESS);
}
}
Expand Down
46 changes: 37 additions & 9 deletions cortex-m-rt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,14 @@
//! value to the `_ram_end` value from the linker script. This is not usually required, but might be
//! necessary to properly initialize memory integrity measures on some hardware.
//!
//! ## `paint-stack`
//!
//! Everywhere between `__sheap` and `___stack_start` is painted with the fixed value
//! `STACK_PAINT_VALUE`, which is `0xCCCC_CCCC`.
//! You can then inspect memory during debugging to determine how much of the stack has been used -
//! where the stack has been used the 'paint' will have been 'scrubbed off' and the memory will
//! have a value other than `STACK_PAINT_VALUE`.
//!
//! # Inspection
//!
//! This section covers how to inspect a binary that builds on top of `cortex-m-rt`.
Expand Down Expand Up @@ -225,7 +233,7 @@
//! using the `main` symbol so you will also find that symbol in your program.
//!
//! - `DefaultHandler`. This is the default handler. If not overridden using `#[exception] fn
//! DefaultHandler(..` this will be an infinite loop.
//! DefaultHandler(..` this will be an infinite loop.
//!
//! - `HardFault` and `_HardFault`. These function handle the hard fault handling and what they
//! do depends on whether the hard fault is overridden and whether the trampoline is enabled (which it is by default).
Expand Down Expand Up @@ -467,6 +475,12 @@

extern crate cortex_m_rt_macros as macros;

/// The 32-bit value the stack is painted with before the program runs.
// Note: keep this value in-sync with the start-up assembly code, as we can't
// use const values in `global_asm!` yet.
#[cfg(feature = "paint-stack")]
pub const STACK_PAINT_VALUE: u32 = 0xcccc_cccc;

#[cfg(cortex_m)]
use core::arch::global_asm;
use core::fmt;
Expand Down Expand Up @@ -545,24 +559,37 @@ cfg_global_asm! {
"ldr r0, =__sbss
ldr r1, =__ebss
movs r2, #0
2:
0:
cmp r1, r0
beq 1f
stm r0!, {{r2}}
b 0b
1:",

// If enabled, paint stack/heap RAM with 0xcccccccc.
// `__sheap` and `_stack_start` come from the linker script.
#[cfg(feature = "paint-stack")]
"ldr r0, =__sheap
ldr r1, =_stack_start
ldr r2, =0xcccccccc // This must match STACK_PAINT_VALUE
0:
cmp r1, r0
beq 3f
beq 1f
stm r0!, {{r2}}
b 2b
3:",
b 0b
1:",

// Initialise .data memory. `__sdata`, `__sidata`, and `__edata` come from the linker script.
"ldr r0, =__sdata
ldr r1, =__edata
ldr r2, =__sidata
4:
0:
cmp r1, r0
beq 5f
beq 1f
ldm r2!, {{r3}}
stm r0!, {{r3}}
b 4b
5:",
b 0b
1:",

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

0 comments on commit 5473462

Please sign in to comment.