Difference between revisions of "How does Newlib initialize the heap?"
From GNU Tools - Wiki
(Created page with "== '''How does Newlib initialize the heap? (RL78, RX, ARM targets)''' == When using the '''Newlib Library''', the user must overwrite the _sbrk/sbrk_r function implemented in...") |
|||
(3 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== '''How does Newlib initialize the heap? (RL78, RX, ARM targets)''' == | == '''How does Newlib initialize the heap? (RL78, RX, ARM targets)''' == | ||
− | When using the '''Newlib Library''', | + | When using the '''Newlib Library''', users must overwrite the _sbrk/sbrk_r function implemented in newlib. This is the function malloc() uses in order to define how much space is needed for an allocation. |
+ | |||
+ | Users of the '''Newlib-Nano Library''' must provide an implementation of the sbrk() function, since there is no default implementation included. | ||
Below are some examples of the default _sbrk function, depending on the toolchain used: | Below are some examples of the default _sbrk function, depending on the toolchain used: | ||
Line 22: | Line 24: | ||
|| heap < rv) | || heap < rv) | ||
{ | { | ||
+ | errno = ENOMEM; | ||
return (char *) -1; | return (char *) -1; | ||
} | } | ||
Line 30: | Line 33: | ||
'''RX:''' | '''RX:''' | ||
− | void* | + | extern void __set_heaptop (void * ptr); |
− | _sbrk ( | + | char * |
− | + | _sbrk (int adj) | |
{ | { | ||
− | + | extern char end; | |
− | + | static char * heap = & end; | |
− | + | char * rv = heap; | |
− | + | heap += adj; | |
− | + | __set_heaptop (heap); | |
− | + | return rv; | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
} | } | ||
+ | |||
'''ARM:''' | '''ARM:''' |
Latest revision as of 13:06, 13 January 2023
How does Newlib initialize the heap? (RL78, RX, ARM targets)
When using the Newlib Library, users must overwrite the _sbrk/sbrk_r function implemented in newlib. This is the function malloc() uses in order to define how much space is needed for an allocation.
Users of the Newlib-Nano Library must provide an implementation of the sbrk() function, since there is no default implementation included.
Below are some examples of the default _sbrk function, depending on the toolchain used:
RL78:
char * _sbrk (int adj) { extern char end; //end of the bss section (start of heap) static char * heap = & end; char * rv = heap; char * heaptop = (char *) &adj; heap += adj; /* The allocated chunk spans our stack? */ if (rv < heaptop && heap > heaptop /* The allocated chunk spans our address space? */ || heap < rv) { errno = ENOMEM; return (char *) -1; } return rv; }
RX:
extern void __set_heaptop (void * ptr); char * _sbrk (int adj) { extern char end; static char * heap = & end; char * rv = heap; heap += adj; __set_heaptop (heap); return rv; }
ARM:
register char * stack_ptr asm ("sp"); caddr_t __attribute__((weak)) _sbrk (int incr) { extern char end asm ("end"); /* Defined by the linker. */ static char * heap_end; char * prev_heap_end; if (heap_end == NULL) heap_end = & end; prev_heap_end = heap_end; if (heap_end + incr > stack_ptr) { /* Some of the libstdc++-v3 tests rely upon detecting out of memory errors, so do not abort here. */ #if 0 extern void abort (void); _write (1, "_sbrk: Heap and stack collision\n", 32); abort (); #else errno = ENOMEM; return (caddr_t) -1; #endif } heap_end += incr; return (caddr_t) prev_heap_end; }
These are the functions to overwrite if there is a need to set your own heap.