Skip to content

Commit 046379e

Browse files
committed
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.
1 parent ab857c4 commit 046379e

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

platform/source/mbed_retarget.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,27 +1268,26 @@ extern "C" WEAK void __cxa_pure_virtual(void)
12681268
extern uint32_t __mbed_sbrk_start;
12691269
extern uint32_t __mbed_krbs_start;
12701270
/* Additional RAM memory used for heap - please note this
1271-
* address should be lower address then the previous default address
1271+
* address must be lower address then the previous default address
12721272
*/
12731273
extern uint32_t __mbed_sbrk_start_0;
12741274
extern uint32_t __mbed_krbs_start_0;
12751275

12761276
extern "C" WEAK caddr_t _sbrk(int incr)
12771277
{
12781278
static uint32_t heap = (uint32_t) &__mbed_sbrk_start_0;
1279-
static bool once = true;
12801279
uint32_t prev_heap = heap;
12811280
uint32_t new_heap = heap + incr;
12821281

12831282
/**
1284-
* If the new address is outside the first region, start allocating from the second region.
1285-
* Jump to second region is done just once, and `static bool once` is used to keep track of that.
1283+
* If we exceed the first region, start allocating from the second region.
12861284
*/
1287-
if (once && (new_heap > (uint32_t) &__mbed_krbs_start_0)) {
1288-
once = false;
1285+
if (prev_heap <= (uint32_t) &__mbed_krbs_start_0 && new_heap > (uint32_t) &__mbed_krbs_start_0) {
12891286
prev_heap = (uint32_t) &__mbed_sbrk_start;
12901287
new_heap = prev_heap + incr;
1291-
} else if (new_heap > (uint32_t) &__mbed_krbs_start) {
1288+
}
1289+
1290+
if (new_heap > (uint32_t) &__mbed_krbs_start) {
12921291
/**
12931292
* If the new address is outside the second region, return out-of-memory.
12941293
*/

0 commit comments

Comments
 (0)