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

From GNU Tools - Wiki
Jump to: navigation, search
Line 1: Line 1:
== '''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.
 
 
 
 
== '''How does Newlib initialize the heap? (RL78, RX, ARM targets)''' ==
 
== '''How does Newlib initialize the heap? (RL78, RX, ARM targets)''' ==
  

Revision as of 12:20, 31 May 2019

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)
     {
       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.