Skip to content

Adds a paint-stack feature. #548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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