* added lib/calloc.c, lib/free.c, lib/realloc.c, include/stddef.h
authormaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 27 Jul 2004 20:03:35 +0000 (20:03 +0000)
committermaartenbrock <maartenbrock@4a8a32a2-be11-0410-ad9d-d568d2c75423>
Tue, 27 Jul 2004 20:03:35 +0000 (20:03 +0000)
* updated lib/malloc.c, lib/libsdcc.lib, lib/Makefile.in, include/malloc.h

git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3406 4a8a32a2-be11-0410-ad9d-d568d2c75423

device/include/malloc.h
device/include/stddef.h [new file with mode: 0644]
device/lib/Makefile.in
device/lib/calloc.c [new file with mode: 0644]
device/lib/free.c [new file with mode: 0644]
device/lib/libsdcc.lib
device/lib/malloc.c
device/lib/realloc.c [new file with mode: 0644]

index 4a1a00ac5ec174213a5c6c7369b07ef993d2fe02..6e217a4c167892cbade767329fe618af06c6dbf0 100644 (file)
 #ifndef __SDCC51_MALLOC_H
 #define __SDCC51_MALLOC_H
 #include <sdcc-lib.h>
-
-#ifndef NULL
-# define NULL (void *)0
-#endif
+#include <stddef.h>
 
 #if _SDCC_MALLOC_TYPE_MLH
-void *malloc (unsigned int);
-void free(void *p);
+
+void * calloc (size_t nmemb, size_t size);
+void * malloc (size_t size);
+void * realloc (void * ptr, size_t size);
+void free (void * ptr);
 
 #else
 
@@ -41,22 +41,25 @@ void free(void *p);
 MEMHEADER
 {
       MEMHEADER xdata *  next;
-      MEMHEADER xdata *  prev;
       unsigned int       len;
-      unsigned char      mem[1];
+      unsigned char      mem[];
 };
 
 #ifdef SDCC_STACK_AUTO
 
-extern void init_dynamic_memory(MEMHEADER xdata *  , unsigned int ) reentrant;
-extern void xdata * malloc (unsigned int ) reentrant;
-extern void free (void xdata * p) reentrant;
+extern void init_dynamic_memory(void xdata * heap, unsigned int size) reentrant;
+extern void xdata * calloc (size_t nmemb, size_t size) reentrant;
+extern void xdata * malloc (size_t size) reentrant;
+extern void xdata * realloc (void * ptr, size_t size) reentrant;
+extern void free (void * ptr) reentrant;
 
 #else
 
-extern void init_dynamic_memory(MEMHEADER xdata *  , unsigned int );
-extern void xdata * malloc (unsigned int );
-extern void free (void xdata *  p);
+extern void init_dynamic_memory(void xdata * heap, unsigned int size);
+extern void xdata * calloc (size_t nmemb, size_t size);
+extern void xdata * malloc (size_t size);
+extern void xdata * realloc (void * ptr, size_t size);
+extern void free (void * ptr);
 
 #endif
 #endif
diff --git a/device/include/stddef.h b/device/include/stddef.h
new file mode 100644 (file)
index 0000000..908b588
--- /dev/null
@@ -0,0 +1,35 @@
+/*-------------------------------------------------------------------------
+   stddef.h - ANSI functions forward declarations
+
+   Written By -  Maarten Brock / sourceforge.brock@dse.nl (June 2004)
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this library; if not, write to the Free Software
+   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+-------------------------------------------------------------------------*/
+
+#ifndef __SDC51_STDDEF_H
+#define __SDC51_STDDEF_H 1
+
+#ifndef NULL
+  #define NULL (void *)0
+#endif
+
+#ifndef _SIZE_T_DEFINED
+#define _SIZE_T_DEFINED
+  typedef unsigned int size_t;
+#endif
+
+#define offsetof(s,m)   (size_t)&(((s *)0)->m)
+
+#endif
index 50feb387ab0ce14193f2bfe76056d32c506bbabe..d791eedf8cecb6d81f17316940d54f6bfcc8388b 100644 (file)
@@ -58,8 +58,10 @@ SOURCES              = _atof.c _atoi.c _atol.c _autobaud.c _bp.c _schar2fs.c \
                  _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
-                 _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \
-                 _ulong2fs.c malloc.c serial.c ser_ir.c printfl.c \
+                 _strstr.c _strtok.c \
+                 _uchar2fs.c _uint2fs.c _ulong2fs.c \
+                 calloc.c malloc.c realloc.c free.c \
+                 serial.c ser_ir.c printfl.c \
                  printf_large.c vprintf.c puts.c gets.c \
                  assert.c _strcat.c time.c printf_fast.c bpx.c \
                  fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
@@ -83,14 +85,14 @@ Z80SOURCES      = _atof.c _atoi.c \
                  _modslong.c _modulong.c \
                  _mullong.c \
                  _divslong.c _divulong.c \
-                 malloc.c \
+                 calloc.c malloc.c realloc.c free.c \
                  _fs2schar.c _fs2sint.c _fs2slong.c \
                  _fs2uchar.c _fs2uint.c _fs2ulong.c _fsadd.c \
                  _fsdiv.c _fseq.c _fsgt.c _fslt.c _fsmul.c \
                  _fsneq.c _fssub.c \
                  _uchar2fs.c _uint2fs.c \
                  _ulong2fs.c \
-                 _slong2fs.c _sint2fs.c _schar2fs.c 
+                 _slong2fs.c _sint2fs.c _schar2fs.c
 
 Z80OBJECTS      = $(Z80SOURCES:%.c=$(PORTDIR)/%.o)
 
@@ -108,8 +110,10 @@ XA51SOURCES      = _atof.c _atoi.c _atol.c _schar2fs.c \
                  _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
-                 _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \
-                 _ulong2fs.c malloc.c puts.c gets.c \
+                 _strstr.c _strtok.c \
+                 _uchar2fs.c _uint2fs.c _ulong2fs.c \
+                 calloc.c malloc.c realloc.c free.c \
+                 puts.c gets.c \
                  printf_large.c puts.c gets.c \
                  assert.c _strcat.c time.c \
                  fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
@@ -134,8 +138,9 @@ HC08SOURCES = _atof.c _atoi.c _atol.c _schar2fs.c \
                  _spx.c _startup.c _strchr.c _strcmp.c _strcpy.c \
                  _strcspn.c _strlen.c _strncat.c _strncmp.c \
                  _strncpy.c _strpbrk.c _strrchr.c _strspn.c \
-                 _strstr.c _strtok.c _uchar2fs.c _uint2fs.c \
-                 _ulong2fs.c malloc.c \
+                 _strstr.c _strtok.c \
+                 _uchar2fs.c _uint2fs.c _ulong2fs.c \
+                 calloc.c malloc.c realloc.c free.c \
                  assert.c _strcat.c time.c \
                  fabsf.c frexpf.c ldexpf.c expf.c powf.c sincosf.c sinf.c \
                  cosf.c logf.c log10f.c sqrtf.c tancotf.c tanf.c cotf.c \
@@ -167,11 +172,11 @@ model-ds390:
        if [ "`grep ds390 ../../ports.build`" = ds390 ]; then \
          $(MAKE) MODELFLAGS="-mds390" PORT=ds390 objects; \
        fi
-       
+
 model-ds400:
        if [ "`grep ds400 ../../ports.build`" = ds400 ]; then \
          $(MAKE) MODELFLAGS="-mds400" PORT=ds400 objects; \
-       fi      
+       fi
 
 model-xa51:
        if [ "`grep xa51 ../../ports.build`" = xa51 ]; then \
@@ -197,7 +202,7 @@ objects-z80: build-dir $(Z80OBJECTS) port-specific-objects clean_intermediate
 model-hc08:
        if [ "`grep hc08 ../../ports.build`" = hc08 ]; then \
          $(MAKE) MODELFLAGS="-mhc08" PORT=hc08 objects-hc08; \
-       fi      
+       fi
 
 objects-hc08: build-dir $(HC08OBJECTS) port-specific-objects clean_intermediate
        cd $(PORTDIR); ls *$(OEXT) > $(PORT).lib
@@ -240,8 +245,8 @@ clean_intermediate-pic16:
 # Compiling and installing everything and runing test
 # ---------------------------------------------------
 install: all installdirs
-       cp -r $(BUILDDIR)/* $(sdcc_libdir)
-       cp -r ds390 ds400 gbz80 z80 hc08 *.c $(sdcc_libdir)/src
+       cp -r -u $(BUILDDIR)/* $(sdcc_libdir)
+       cp -r -u ds390 ds400 gbz80 z80 hc08 *.c $(sdcc_libdir)/src
        rm -r `find $(sdcc_libdir)/src -name '*.rel' -or -name '*.dump*' -or -name '*.sym' -or -name '*.o' -or -name '*.lst' -or -name '*.asm' -or -name 'CVS'`
 
 # Deleting all the installed files
@@ -268,8 +273,8 @@ installdirs:
         mkdir -p $(sdcc_libdir)/$$model; \
        done
        [ -d $(sdcc_libdir)/ds390 ] || mkdir -p $(sdcc_libdir)/ds390
-       [ -d $(sdcc_libdir)/ds400 ] || mkdir -p $(sdcc_libdir)/ds400    
-       [ -d $(sdcc_libdir)/hc08 ] || mkdir -p $(sdcc_libdir)/hc08      
+       [ -d $(sdcc_libdir)/ds400 ] || mkdir -p $(sdcc_libdir)/ds400
+       [ -d $(sdcc_libdir)/hc08 ] || mkdir -p $(sdcc_libdir)/hc08
        [ -f $(sdcc_libdir)/pic16 ] || mkdir -p $(sdcc_libdir)/pic16
        mkdir -p $(sdcc_libdir)/src
 
diff --git a/device/lib/calloc.c b/device/lib/calloc.c
new file mode 100644 (file)
index 0000000..6abb424
--- /dev/null
@@ -0,0 +1,46 @@
+#include <sdcc-lib.h>
+#include <malloc.h>
+#include <string.h>
+
+//--------------------------------------------------------------------
+//Written by Maarten Brock, 2004
+//--------------------------------------------------------------------
+//calloc function implementation for embedded system
+//Non-ANSI keywords are C51 specific.
+// xdata - variable in external memory (just RAM)
+//--------------------------------------------------------------------
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+#define xdata
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+  MEMHEADER *   next;
+  MEMHEADER *   prev;
+  unsigned int  len;
+  unsigned char mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+#else
+
+#define HEADER_SIZE sizeof(MEMHEADER)
+
+#endif
+
+void xdata * calloc (size_t nmemb, size_t size)
+{
+  register void xdata * ptr;
+
+  ptr = malloc(nmemb * size);
+  if (ptr)
+  {
+    memset(ptr, 0, nmemb * size);
+  }
+  return ptr;
+}
+//END OF MODULE
diff --git a/device/lib/free.c b/device/lib/free.c
new file mode 100644 (file)
index 0000000..ff1c16c
--- /dev/null
@@ -0,0 +1,122 @@
+#include <sdcc-lib.h>
+#include <malloc.h>
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+  MEMHEADER *    next;
+  MEMHEADER *    prev;
+  unsigned int   len;
+  unsigned char  mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+/* These variables are defined through the crt0 functions. */
+/* Base of this variable is the first byte of the heap. */
+extern MEMHEADER _sdcc_heap_start;
+/* Address of this variable is the last byte of the heap. */
+extern char _sdcc_heap_end;
+
+MEMHEADER * _sdcc_prev_memheader;
+// apart from finding the header
+// this function also finds it's predecessor
+MEMHEADER *
+_sdcc_find_memheader(void * p)
+{
+  register MEMHEADER * pthis;
+  if (!p)
+    return NULL;
+  pthis = (MEMHEADER * )((char *)  p - HEADER_SIZE); //to start of header
+  _sdcc_prev_memheader = pthis->prev;
+
+  return (pthis);
+}
+
+void
+free (void *p)
+{
+  MEMHEADER *prev_header, *pthis;
+
+  if ( p ) //For allocated pointers only!
+    {
+      pthis = (MEMHEADER * )((char *)  p - HEADER_SIZE); //to start of header
+      if ( pthis->prev ) // For the regular header
+        {
+          prev_header = pthis->prev;
+          prev_header->next = pthis->next;
+          if (pthis->next)
+            {
+              pthis->next->prev = prev_header;
+            }
+        }
+      else
+        {
+          pthis->len = 0; //For the first header
+        }
+    }
+}
+
+#else
+
+            //--------------------------------------------------------------------
+            //Written by Dmitry S. Obukhov, 1997
+            //dso@usa.net
+            //--------------------------------------------------------------------
+            //Modified for SDCC by Sandeep Dutta, 1999
+            //sandeep.dutta@usa.net
+            //--------------------------------------------------------------------
+            //malloc and free functions implementation for embedded system
+            //Non-ANSI keywords are C51 specific.
+            // xdata - variable in external memory (just RAM)
+            //--------------------------------------------------------------------
+
+            #define HEADER_SIZE sizeof(MEMHEADER)
+
+            //Static here means: can be accessed from this module only
+            extern MEMHEADER xdata * _sdcc_first_memheader;
+
+            MEMHEADER xdata * _sdcc_prev_memheader;
+            // apart from finding the header
+            // this function also finds it's predecessor
+            MEMHEADER xdata * _sdcc_find_memheader(void xdata * p)
+            {
+              register MEMHEADER xdata * pthis;
+              register MEMHEADER xdata * cur_header;
+
+              if (!p)
+                  return NULL;
+              pthis = (MEMHEADER xdata *) p;
+              pthis -= 1; //to start of header
+              cur_header = _sdcc_first_memheader;
+              _sdcc_prev_memheader = NULL;
+              while (cur_header && pthis != cur_header)
+                {
+                  _sdcc_prev_memheader = cur_header;
+                  cur_header = cur_header->next;
+                }
+              return (cur_header);
+            }
+
+            void free (void * p)
+            {
+              register MEMHEADER xdata * pthis;
+
+              pthis = _sdcc_find_memheader(p);
+              if (pthis) //For allocated pointers only!
+              {
+                if (!_sdcc_prev_memheader)
+                {
+                  pthis->len = 0;
+                }
+                else
+                {
+                  _sdcc_prev_memheader->next = pthis->next;
+                }
+              }
+            }
+            //END OF MODULE
+#endif
index 867f96e6412c80c928d818579a7113db1663f170..77ef0bdff153a4576587e0a01a200a72f7c0a53f 100644 (file)
@@ -35,7 +35,10 @@ _bp
 _spx
 _atoi
 _atol
+calloc
 malloc
+realloc
+free
 serial
 _autobaud
 _startup
index 00439285906a51957f92bb4f4851a88f8cc5da80..cf6f905c3c2ad8a6c616529241b71c8de5c3c9bc 100644 (file)
@@ -7,15 +7,15 @@ typedef struct _MEMHEADER MEMHEADER;
 
 struct _MEMHEADER
 {
-  MEMHEADER *  next;
-  MEMHEADER *  prev;
-  unsigned int       len;
-  unsigned char      mem;
+  MEMHEADER *    next;
+  MEMHEADER *    prev;
+  unsigned int   len;
+  unsigned char  mem;
 };
 
 #define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
 
-/* These veriables are defined through the crt0 functions. */
+/* These variables are defined through the crt0 functions. */
 /* Base of this variable is the first byte of the heap. */
 extern MEMHEADER _sdcc_heap_start;
 /* Address of this variable is the last byte of the heap. */
@@ -58,14 +58,14 @@ malloc (unsigned int size)
 
       if ((((unsigned int)current_header->next) -
            ((unsigned int)current_header) -
-           current_header->len) >= size) 
+           current_header->len) >= size)
         {
           break; //if spare is more than need
         }
-      current_header = current_header->next;    //else try next             
-      if (!current_header->next)  
+      current_header = current_header->next;    //else try next
+      if (!current_header->next)
         {
-          return NULL;  //if end_of_list reached    
+          return NULL;  //if end_of_list reached
         }
     }
 
@@ -73,7 +73,7 @@ malloc (unsigned int size)
     { //This code works only for first_header in the list and only
       current_header->len = size; //for first allocation
       return &current_header->mem;
-    } 
+    }
   else
     {
       //else create new header at the begin of spare
@@ -90,30 +90,6 @@ malloc (unsigned int size)
     }
 }
 
-void
-free (void *p)
-{
-  MEMHEADER *prev_header, *pthis;
-
-  if ( p ) //For allocated pointers only!
-    {
-      pthis = (MEMHEADER * )((char *)  p - HEADER_SIZE); //to start of header
-      if ( pthis->prev ) // For the regular header
-        {
-          prev_header = pthis->prev;
-          prev_header->next = pthis->next;
-          if (pthis->next)
-            {
-              pthis->next->prev = prev_header;
-            }
-        }
-      else
-        {
-          pthis->len = 0; //For the first header
-        }
-    }
-}
-
 #else
 
             //--------------------------------------------------------------------
@@ -128,26 +104,16 @@ free (void *p)
             // xdata - variable in external memory (just RAM)
             //--------------------------------------------------------------------
 
-            #define MEMHEADER   struct MAH// Memory Allocation Header
-
-            MEMHEADER
-            {
-              MEMHEADER xdata *  next;
-              MEMHEADER xdata *  prev;
-              unsigned int       len;
-             unsigned char      mem;
-            };
+            #define HEADER_SIZE sizeof(MEMHEADER)
 
-            #define HEADER_SIZE (sizeof(MEMHEADER)-1)
+            MEMHEADER xdata * _sdcc_first_memheader;
 
-            //Static here means: can be accessed from this module only
-            static MEMHEADER xdata * FIRST_MEMORY_HEADER_PTR;
-            void init_dynamic_memory(MEMHEADER xdata * array, unsigned int size) 
+            void init_dynamic_memory(void xdata * heap, unsigned int size)
             {
 
             //This function MUST be called after the RESET.
-            //Parameters: array - pointer to memory allocated by the linker
-            //            size  - size of this memory pool
+            //Parameters: heap - pointer to memory allocated by the linker
+            //            size - size of this memory pool
             //Example:
             //     #define DYNAMIC_MEMORY_SIZE 0x2000
             //     .....
@@ -163,28 +129,28 @@ free (void *p)
             //         current_buffer = malloc(0x100);
             //
             //
+              MEMHEADER xdata * array = (MEMHEADER xdata *)heap;
 
-              if ( !array ) /*Reserved memory starts on 0x0000 but it's NULL...*/
+              if ( !array ) //Reserved memory starts at 0x0000 but that's NULL...
               {             //So, we lost one byte!
                  array = (MEMHEADER xdata * )((char xdata * ) array + 1) ;
-                 size --;
+                 size--;
               }
-              FIRST_MEMORY_HEADER_PTR = array;
+              _sdcc_first_memheader = array;
               //Reserve a mem for last header
-              array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - HEADER_SIZE);
-              array->next->next = (void xdata * ) NULL; //And mark it as last
-              array->prev       = (void xdata * ) NULL; //and mark first as first
+              array->next = (MEMHEADER xdata * )(((char xdata * ) array) + size - sizeof(MEMHEADER xdata *));
+              array->next->next = (MEMHEADER xdata * ) NULL; //And mark it as last
               array->len        = 0;    //Empty and ready.
             }
 
-            void  xdata * malloc (unsigned int size)
+            void xdata * malloc (unsigned int size)
             {
               register MEMHEADER xdata * current_header;
               register MEMHEADER xdata * new_header;
 
               if (size>(0xFFFF-HEADER_SIZE)) return (void xdata *) NULL; //To prevent overflow in next line
               size += HEADER_SIZE; //We need a memory for header too
-              current_header = FIRST_MEMORY_HEADER_PTR;
+              current_header = _sdcc_first_memheader;
               while (1)
               {
 
@@ -198,38 +164,20 @@ free (void *p)
                 if ((((unsigned int)current_header->next) -
                      ((unsigned int)current_header) -
                      current_header->len) >= size) break; //if spare is more than need
-                current_header = current_header->next;    //else try next             
+                current_header = current_header->next;    //else try next
                 if (!current_header->next)  return (void xdata *) NULL;  //if end_of_list reached
               }
               if (!current_header->len)
               { //This code works only for first_header in the list and only
                  current_header->len = size; //for first allocation
-                 return ((xdata *)&(current_header->mem));
+                 return current_header->mem;
               } //else create new header at the begin of spare
               new_header = (MEMHEADER xdata * )((char xdata *)current_header + current_header->len);
               new_header->next = current_header->next; //and plug it into the chain
-              new_header->prev = current_header;
               current_header->next  = new_header;
-              if (new_header->next)  new_header->next->prev = new_header;
               new_header->len  = size; //mark as used
-              return ((xdata *)&(new_header->mem));
+              return new_header->mem;
             }
 
-            void free (void xdata * p)
-            {
-              register MEMHEADER xdata * prev_header;
-              if ( p ) //For allocated pointers only!
-              {
-                  p = (MEMHEADER xdata * )((char xdata *)  p - HEADER_SIZE); //to start of header
-                  if ( ((MEMHEADER xdata * ) p)->prev ) // For the regular header
-                  {
-                    prev_header = ((MEMHEADER xdata * ) p)->prev;
-                    prev_header->next = ((MEMHEADER xdata * ) p)->next;
-                    if (((MEMHEADER xdata * ) p)->next)
-                      ((MEMHEADER xdata * ) p)->next->prev = prev_header;
-                  }
-                  else ((MEMHEADER xdata * ) p)->len = 0; //For the first header
-              }
-            }
             //END OF MODULE
 #endif
diff --git a/device/lib/realloc.c b/device/lib/realloc.c
new file mode 100644 (file)
index 0000000..54fde7f
--- /dev/null
@@ -0,0 +1,83 @@
+#include <sdcc-lib.h>
+#include <malloc.h>
+#include <string.h>
+
+//--------------------------------------------------------------------
+//Written by Maarten Brock, 2004
+//--------------------------------------------------------------------
+//realloc function implementation for embedded system
+//Non-ANSI keywords are C51 specific.
+// xdata - variable in external memory (just RAM)
+//--------------------------------------------------------------------
+
+#if _SDCC_MALLOC_TYPE_MLH
+
+#define xdata
+
+typedef struct _MEMHEADER MEMHEADER;
+
+struct _MEMHEADER
+{
+  MEMHEADER *   next;
+  MEMHEADER *   prev;
+  unsigned int  len;
+  unsigned char mem;
+};
+
+#define HEADER_SIZE (sizeof(MEMHEADER)-sizeof(char))
+
+#else
+
+#define HEADER_SIZE sizeof(MEMHEADER)
+
+#endif
+
+extern MEMHEADER xdata * _sdcc_prev_memheader;
+
+// apart from finding the header
+// this function also finds it's predecessor
+extern MEMHEADER xdata * _sdcc_find_memheader(void xdata * p);
+
+void xdata * realloc (void * p, size_t size)
+{
+  register MEMHEADER xdata * pthis;
+  register MEMHEADER xdata * pnew;
+
+  pthis = _sdcc_find_memheader(p);
+  if (pthis)
+  {
+    if (size>(0xFFFF-HEADER_SIZE)) return (void xdata *) NULL; //To prevent overflow in next line
+    size += HEADER_SIZE; //We need a memory for header too
+
+    if ((((unsigned int)pthis->next) - ((unsigned int)pthis)) >= size)
+    {//if spare is more than need
+      pthis->len = size;
+      return p;
+    }
+
+    if ((_sdcc_prev_memheader) &&
+        ((((unsigned int)pthis->next) -
+          ((unsigned int)_sdcc_prev_memheader) -
+          _sdcc_prev_memheader->len) >= size))
+    {
+      pnew = (MEMHEADER xdata * )((char xdata *)_sdcc_prev_memheader + _sdcc_prev_memheader->len);
+      _sdcc_prev_memheader->next = pnew;
+      memmove(pnew, pthis, pthis->len);
+      pnew->len = size;
+      return pnew->mem;
+    }
+
+    pnew = malloc(size - HEADER_SIZE);
+    if (pnew)
+    {
+      memcpy(pnew, pthis->mem, pthis->len - HEADER_SIZE);
+      free(p);
+    }
+    return pnew;
+  }
+  else
+  {
+       return malloc(size);
+  }
+}
+//END OF MODULE