This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
[patch] ARM semihosted heap limits
- From: Paul Brook <paul at codesourcery dot com>
- To: newlib at sourceware dot org
- Date: Thu, 5 Apr 2007 19:27:47 +0100
- Subject: [patch] ARM semihosted heap limits
The ARM semihosting syscalls (as used by the default arm-none-eabi newlib
configuration) provide a mechanism for the host to inform the program of the
heap memory area.
Currently newlib ignores these, and uses the area between the end of the data
segment and the stack.
The patch below makes the _sbrk implementation honour these values, and
gracefully fall back to the old behaviour is they are not
available/specified.
Tested on arm-none-eabi with a variety of semihosting implementations.
Ok?
Paul
2007-04-05 Paul Brook <paul@codesourcery.com>
libgloss/
* arm/crt0.S: Define __heap_base__ and __heap_limit__.
* arm/syscalls.c (_sbrk): Use them.
newlib/
* libc/sys/arm/crt0.S: Define __heap_base__ and __heap_limit__.
* libc/sys/arm/syscalls.c (_sbrk): Use them.
Index: libgloss/arm/crt0.S
===================================================================
RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/crt0.S,v
retrieving revision 1.5
diff -u -p -r1.5 crt0.S
--- libgloss/arm/crt0.S 7 Feb 2006 18:46:23 -0000 1.5
+++ libgloss/arm/crt0.S 5 Apr 2007 18:03:26 -0000
@@ -325,7 +325,7 @@ change_back:
.align 0
.LC0:
#ifdef ARM_RDI_MONITOR
- .word HeapBase
+ .word __heap_base__
#else
#ifndef ARM_RDP_MONITOR
/* Changes by toralf: Provide alternative "stack" variable whose value
@@ -384,8 +384,10 @@ change_back:
.data
/* Data returned by monitor SWI. */
.global __stack_base__
-HeapBase: .word 0
-HeapLimit: .word 0
+.global __heap_base__
+.global __heap_limit__
+__heap_base__: .word 0
+__heap_limit__: .word 0
__stack_base__: .word 0
StackLimit: .word 0
CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */
Index: libgloss/arm/syscalls.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/libgloss/arm/syscalls.c,v
retrieving revision 1.14
diff -u -p -r1.14 syscalls.c
--- libgloss/arm/syscalls.c 3 Jan 2007 16:55:25 -0000 1.14
+++ libgloss/arm/syscalls.c 5 Apr 2007 18:10:42 -0000
@@ -443,19 +443,36 @@ _getpid (int n)
n = n;
}
+extern char * __heap_limit__ __attribute__((weak));
+extern char * __heap_base__ __attribute__((weak));
+
caddr_t
_sbrk (int incr)
{
extern char end asm ("end"); /* Defined by the linker. */
static char * heap_end;
+ static char * heap_base;
char * prev_heap_end;
- if (heap_end == NULL)
- heap_end = & end;
-
+ if (heap_base == NULL)
+ {
+ /* If no heap base is provided then start from the end of the
+ data segment. */
+ if (&__heap_base__ && __heap_base__)
+ heap_base = __heap_base__;
+ else
+ heap_base = &end;
+ heap_end = heap_base;
+ }
+
prev_heap_end = heap_end;
-
- if (heap_end + incr > stack_ptr)
+
+ /* Check if we will run over into the stack, or if we exceed a specified
+ heap limit. Avoid errors in the case where the heap is entirely above
+ the stack. */
+ if ((heap_base < stack_ptr && heap_end + incr > stack_ptr)
+ || (&__heap_limit__ && __heap_limit__
+ && heap_end + incr > __heap_limit__))
{
/* Some of the libstdc++-v3 tests rely upon detecting
out of memory errors, so do not abort here. */
Index: newlib/libc/sys/arm/crt0.S
===================================================================
RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/crt0.S,v
retrieving revision 1.12
diff -u -p -r1.12 crt0.S
--- newlib/libc/sys/arm/crt0.S 7 Feb 2006 18:44:54 -0000 1.12
+++ newlib/libc/sys/arm/crt0.S 5 Apr 2007 18:12:13 -0000
@@ -260,7 +260,7 @@ change_back:
.align 0
.LC0:
#ifdef ARM_RDI_MONITOR
- .word HeapBase
+ .word __heap_base__
#else
#ifndef ARM_RDP_MONITOR
#ifdef __pe__
@@ -292,8 +292,10 @@ change_back:
.data
/* Data returned by monitor SWI. */
.global __stack_base__
-HeapBase: .word 0
-HeapLimit: .word 0
+.global __heap_base__
+.global __heap_limit__
+__heap_base__: .word 0
+__heap_limit__: .word 0
__stack_base__: .word 0
StackLimit: .word 0
CommandLine: .space 256,0 /* Maximum length of 255 chars handled. */
Index: newlib/libc/sys/arm/syscalls.c
===================================================================
RCS file: /var/cvsroot/src-cvs/src/newlib/libc/sys/arm/syscalls.c,v
retrieving revision 1.13
diff -u -p -r1.13 syscalls.c
--- newlib/libc/sys/arm/syscalls.c 13 Jun 2006 20:50:24 -0000 1.13
+++ newlib/libc/sys/arm/syscalls.c 5 Apr 2007 18:12:13 -0000
@@ -472,19 +472,36 @@ _getpid (int n)
n = n;
}
+extern char * __heap_limit__ __attribute__((weak));
+extern char * __heap_base__ __attribute__((weak));
+
caddr_t
_sbrk (int incr)
{
extern char end asm ("end"); /* Defined by the linker. */
static char * heap_end;
+ static char * heap_base;
char * prev_heap_end;
- if (heap_end == NULL)
- heap_end = & end;
-
+ if (heap_base == NULL)
+ {
+ /* If no heap base is provided then start from the end of the
+ data segment. */
+ if (&__heap_base__ && __heap_base__)
+ heap_base = __heap_base__;
+ else
+ heap_base = &end;
+ heap_end = heap_base;
+ }
+
prev_heap_end = heap_end;
-
- if (heap_end + incr > stack_ptr)
+
+ /* Check if we will run over into the stack, or if we exceed a specified
+ heap limit. Avoid errors in the case where the heap is entirely above
+ the stack. */
+ if ((heap_base < stack_ptr && heap_end + incr > stack_ptr)
+ || (&__heap_limit__ && __heap_limit__
+ && heap_end + incr > __heap_limit__))
{
/* Some of the libstdc++-v3 tests rely upon detecting
out of memory errors, so do not abort here. */