mirror of https://github.com/ARMmbed/mbed-os.git
Tighten GCC 2-region _sbrk
When moving to the second heap region due to overflowing the first region, the `_sbrk` implementation assumed the allocation would fit in the second region, and didn't check for that overflowing too. Problem revealed in `stats_heap` test with GCC 8 on K64F - the allocation attempt for 1GiB crashed, as `_sbrk` indicated 1GiB was available at the start of the second region. second region. Presumably older versions of newlib fault that allocation attempt before passing to `_sbrk`. While there, adjust the code to not use a separate static `bool`, saving RAM. We can track with just one pointer, as order of the two regions is fixed, and already relied on by newlib.pull/11696/head
parent
74715c71f7
commit
0a58c80b56
|
@ -1268,7 +1268,7 @@ extern "C" WEAK void __cxa_pure_virtual(void)
|
||||||
extern uint32_t __mbed_sbrk_start;
|
extern uint32_t __mbed_sbrk_start;
|
||||||
extern uint32_t __mbed_krbs_start;
|
extern uint32_t __mbed_krbs_start;
|
||||||
/* Additional RAM memory used for heap - please note this
|
/* Additional RAM memory used for heap - please note this
|
||||||
* address should be lower address then the previous default address
|
* address must be lower address then the previous default address
|
||||||
*/
|
*/
|
||||||
extern uint32_t __mbed_sbrk_start_0;
|
extern uint32_t __mbed_sbrk_start_0;
|
||||||
extern uint32_t __mbed_krbs_start_0;
|
extern uint32_t __mbed_krbs_start_0;
|
||||||
|
@ -1276,19 +1276,18 @@ extern uint32_t __mbed_krbs_start_0;
|
||||||
extern "C" WEAK caddr_t _sbrk(int incr)
|
extern "C" WEAK caddr_t _sbrk(int incr)
|
||||||
{
|
{
|
||||||
static uint32_t heap = (uint32_t) &__mbed_sbrk_start_0;
|
static uint32_t heap = (uint32_t) &__mbed_sbrk_start_0;
|
||||||
static bool once = true;
|
|
||||||
uint32_t prev_heap = heap;
|
uint32_t prev_heap = heap;
|
||||||
uint32_t new_heap = heap + incr;
|
uint32_t new_heap = heap + incr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the new address is outside the first region, start allocating from the second region.
|
* If we exceed the first region, start allocating from the second region.
|
||||||
* Jump to second region is done just once, and `static bool once` is used to keep track of that.
|
|
||||||
*/
|
*/
|
||||||
if (once && (new_heap > (uint32_t) &__mbed_krbs_start_0)) {
|
if (prev_heap <= (uint32_t) &__mbed_krbs_start_0 && new_heap > (uint32_t) &__mbed_krbs_start_0) {
|
||||||
once = false;
|
|
||||||
prev_heap = (uint32_t) &__mbed_sbrk_start;
|
prev_heap = (uint32_t) &__mbed_sbrk_start;
|
||||||
new_heap = prev_heap + incr;
|
new_heap = prev_heap + incr;
|
||||||
} else if (new_heap > (uint32_t) &__mbed_krbs_start) {
|
}
|
||||||
|
|
||||||
|
if (new_heap > (uint32_t) &__mbed_krbs_start) {
|
||||||
/**
|
/**
|
||||||
* If the new address is outside the second region, return out-of-memory.
|
* If the new address is outside the second region, return out-of-memory.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue