diff --git a/libgloss/arm/crt0.S b/libgloss/arm/crt0.S index cc1c370..cb9021d 100644 --- a/libgloss/arm/crt0.S +++ b/libgloss/arm/crt0.S @@ -123,6 +123,11 @@ #endif ldr r0, .LC0 /* point at values read */ + /* Set __heap_limit. */ + ldr r1, [r0, #4] + ldr r2, =__heap_limit + str r1, [r2] + ldr r1, [r0, #0] cmp r1, #0 bne .LC32 diff --git a/libgloss/arm/syscalls.c b/libgloss/arm/syscalls.c index 54e3d74..0ccad21 100644 --- a/libgloss/arm/syscalls.c +++ b/libgloss/arm/syscalls.c @@ -587,6 +587,9 @@ _getpid (int n __attribute__ ((unused))) return 1; } +/* Heap limit returned from SYS_HEAPINFO Angel semihost call. */ +uint __heap_limit = 0xcafedead; + caddr_t __attribute__((weak)) _sbrk (int incr) { @@ -599,7 +602,9 @@ _sbrk (int incr) prev_heap_end = heap_end; - if (heap_end + incr > stack_ptr) + if ((heap_end + incr > stack_ptr) + /* Honour heap limit if it's valid. */ + || (__heap_limit != 0xcafedead && heap_end + incr > __heap_limit)) { /* Some of the libstdc++-v3 tests rely upon detecting out of memory errors, so do not abort here. */