How does Newlib initialize the heap?

From GNU Tools - Wiki
Revision as of 13:06, 13 January 2023 by Administrator (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

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.