Description
Yesterday I was giving a closer look to file libraries/mbed/common/retarget.cpp
and especiallaly to the lines from line 474 to line 492 where function __sbrk()
gets defined for TOOLCHAIN_GCC_ARM
, which looks like this:
// Dynamic memory allocation related syscall.
extern "C" caddr_t _sbrk(int incr) {
static unsigned char* heap = (unsigned char*)&__end__;
unsigned char* prev_heap = heap;
unsigned char* new_heap = heap + incr;
https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/common/retarget.cpp#L482
#if defined(TARGET_ARM7)
if (new_heap >= stack_ptr) {
#elif defined(TARGET_CORTEX_A)
if (new_heap >= (unsigned char*)&__HeapLimit) { /* __HeapLimit is end of heap section */
#else
if (new_heap >= (unsigned char*)__get_MSP()) {
#endif
errno = ENOMEM;
return (caddr_t)-1;
}
heap = new_heap;
return (caddr_t) prev_heap;
}
My point here refers to line 484 where the availability of further heap space is checked by comparing the new_heap
end with the position of the current stack pointer (__get_MSP()
).
In my eyes, this is not a very secure/good way to check the availability of further heap space as in case at the moment of the call we are in the situation of low stack usage the check might pass and the memory added to the heap, while further on the stack might grow beyond its current value (i.e. as we are growing down __get_MSP()
might return a minor value) and such invade the already allocated heap space ...
Furthermore, even if less important, the usage of __get_MSP()
as heap limit implies a certain memory layout in which the heap and stack must be placed in the same memory bank and where the heap must be located immediately before the stack region, which on some platforms (e.g. STM32L476RG) limits the possible choices.
A solution to this issue might be to implement __sbrk()
as it is done for TARGET_CORTEX_A
(see line 482) also in case of a Cortex-M, i.e. using __HeapLimit
to delimit the heap space. But this requires a review of all linker scripts for the GNU toolchain for most likely all platforms.
What do you think?