diff --git a/arch/arm/src/armv7-m/Kconfig b/arch/arm/src/armv7-m/Kconfig index 11494554629..a6d30a013ea 100644 --- a/arch/arm/src/armv7-m/Kconfig +++ b/arch/arm/src/armv7-m/Kconfig @@ -65,6 +65,18 @@ config ARMV7M_OABI_TOOLCHAIN Most of the older buildroot toolchains are OABI and are named arm-nuttx-elf- vs. arm-nuttx-eabi- +config ARMV7M_STACKCHECK + bool "Stack for stack overflow on each function call" + default n + depends on ARCH_CHIP_STM32 + ---help--- + This check uses R10 to check for a stack overflow within each function + call. This has performances and code size impacts, but it will be able to + catch hard to find stack overflows. + + Currently only available only for the STM32 architecture. The changes + are not complex and patches for other architectures will be accepted. + config ARMV7M_ITMSYSLOG bool "ITM SYSLOG support" default n diff --git a/arch/arm/src/armv7-m/up_initialstate.c b/arch/arm/src/armv7-m/up_initialstate.c index d4c625b86f5..1cee9728812 100644 --- a/arch/arm/src/armv7-m/up_initialstate.c +++ b/arch/arm/src/armv7-m/up_initialstate.c @@ -93,6 +93,16 @@ void up_initial_state(struct tcb_s *tcb) xcp->regs[REG_SP] = (uint32_t)tcb->adj_stack_ptr; +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit value */ + + xcp->regs[REG_R10] = (uint32_t)tcb->stack_alloc_ptr + 64; + + /* Fill the stack with a watermark value */ + + memset(tcb->stack_alloc_ptr, 0xff, tcb->adj_stack_size); +#endif + /* Save the task entry point (stripping off the thumb bit) */ xcp->regs[REG_PC] = (uint32_t)tcb->start & ~1; diff --git a/arch/arm/src/stm32/Make.defs b/arch/arm/src/stm32/Make.defs index 479167f0d2f..9c3585a3771 100644 --- a/arch/arm/src/stm32/Make.defs +++ b/arch/arm/src/stm32/Make.defs @@ -54,6 +54,10 @@ CMN_CSRCS += up_schedulesigaction.c up_sigdeliver.c up_stackframe.c CMN_CSRCS += up_systemreset.c up_unblocktask.c up_usestack.c up_doirq.c CMN_CSRCS += up_hardfault.c up_svcall.c up_vfork.c +ifeq ($(CONFIG_ARMV7M_STACKCHECK),y) +CMN_CSRCS += up_stackcheck.c +endif + ifeq ($(CONFIG_ARMV7M_CMNVECTOR),y) CMN_ASRCS += up_exception.S CMN_CSRCS += up_vectors.c diff --git a/arch/arm/src/stm32/stm32_start.c b/arch/arm/src/stm32/stm32_start.c index e115a63ccf8..8147e3dbd06 100644 --- a/arch/arm/src/stm32/stm32_start.c +++ b/arch/arm/src/stm32/stm32_start.c @@ -2,7 +2,7 @@ * arch/arm/src/stm32/stm32_start.c * arch/arm/src/chip/stm32_start.c * - * Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2009, 2011-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -88,6 +88,16 @@ static void go_os_start(void *pv, unsigned int nbytes) # define showprogress(c) #endif +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef CONFIG_ARMV7M_STACKCHECK +/* we need to get r10 set before we can allow instrumentation calls */ + +void __start(void) __attribute__ ((no_instrument_function)); +#endif + /**************************************************************************** * Name: stm32_fpuconfig * @@ -235,7 +245,13 @@ void __start(void) const uint32_t *src; uint32_t *dest; - /* Configure the uart so that we can get debug output as soon as possible */ +#ifdef CONFIG_ARMV7M_STACKCHECK + /* Set the stack limit before we attempt to call any functions */ + + __asm__ volatile ("sub r10, sp, %0" : : "r" (CONFIG_IDLETHREAD_STACKSIZE - 64) : ); +#endif + + /* Configure the UART so that we can get debug output as soon as possible */ stm32_clockconfig(); stm32_fpuconfig();