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/11572/head
parent
ab857c4963
commit
046379e629
|
@ -1268,7 +1268,7 @@ extern "C" WEAK void __cxa_pure_virtual(void)
|
|||
extern uint32_t __mbed_sbrk_start;
|
||||
extern uint32_t __mbed_krbs_start;
|
||||
/* 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_krbs_start_0;
|
||||
|
@ -1276,19 +1276,18 @@ extern uint32_t __mbed_krbs_start_0;
|
|||
extern "C" WEAK caddr_t _sbrk(int incr)
|
||||
{
|
||||
static uint32_t heap = (uint32_t) &__mbed_sbrk_start_0;
|
||||
static bool once = true;
|
||||
uint32_t prev_heap = heap;
|
||||
uint32_t new_heap = heap + incr;
|
||||
|
||||
/**
|
||||
* If the new address is outside 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 we exceed the first region, start allocating from the second region.
|
||||
*/
|
||||
if (once && (new_heap > (uint32_t) &__mbed_krbs_start_0)) {
|
||||
once = false;
|
||||
if (prev_heap <= (uint32_t) &__mbed_krbs_start_0 && new_heap > (uint32_t) &__mbed_krbs_start_0) {
|
||||
prev_heap = (uint32_t) &__mbed_sbrk_start;
|
||||
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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue