Difference between revisions of "How does Newlib initialize the heap?"

From GNU Tools - Wiki
Jump to: navigation, search
(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...")
(No difference)

Revision as of 21:26, 24 April 2017

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 newlib. This is the function malloc() uses in order to define how much space is needed for an allocation.

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)
     {
       return (char *) -1;
     }
 
   return rv;
 }

RX:

 void*
 _sbrk (incr)
      int incr;
 {
    extern char   end; /* Set by linker.  */
    static char * heap_end;
    char *        prev_heap_end;
 
    if (heap_end == 0)
      heap_end = & end;
 
    prev_heap_end = heap_end;
    heap_end += incr;
 
    return (void *) prev_heap_end;
 }

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.