]> Git Repo - J-u-boot.git/blobdiff - common/dlmalloc.c
Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-sunxi
[J-u-boot.git] / common / dlmalloc.c
index f48cd2a333db31738e51c86cff1b5228ee3c5994..62e8557daa70ebeadc724feeee63558570c1cb9d 100644 (file)
@@ -8,14 +8,13 @@
  * as file malloc-2.6.6.c.
  */
 
  * as file malloc-2.6.6.c.
  */
 
-#include <common.h>
-#include <log.h>
-#include <asm/global_data.h>
-
 #if CONFIG_IS_ENABLED(UNIT_TEST)
 #define DEBUG
 #endif
 
 #if CONFIG_IS_ENABLED(UNIT_TEST)
 #define DEBUG
 #endif
 
+#include <log.h>
+#include <asm/global_data.h>
+
 #include <malloc.h>
 #include <asm/io.h>
 #include <valgrind/memcheck.h>
 #include <malloc.h>
 #include <asm/io.h>
 #include <valgrind/memcheck.h>
@@ -32,6 +31,21 @@ void malloc_stats();
 
 DECLARE_GLOBAL_DATA_PTR;
 
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifdef MCHECK_HEAP_PROTECTION
+ #define STATIC_IF_MCHECK static
+ #undef MALLOC_COPY
+ #undef MALLOC_ZERO
+static inline void MALLOC_ZERO(void *p, size_t sz) { memset(p, 0, sz); }
+static inline void MALLOC_COPY(void *dest, const void *src, size_t sz) { memcpy(dest, src, sz); }
+#else
+ #define STATIC_IF_MCHECK
+ #define mALLOc_impl mALLOc
+ #define fREe_impl fREe
+ #define rEALLOc_impl rEALLOc
+ #define mEMALIGn_impl mEMALIGn
+ #define cALLOc_impl cALLOc
+#endif
+
 /*
   Emulation of sbrk for WIN32
   All code within the ifdef WIN32 is untested by me.
 /*
   Emulation of sbrk for WIN32
   All code within the ifdef WIN32 is untested by me.
@@ -39,7 +53,6 @@ DECLARE_GLOBAL_DATA_PTR;
   Thanks to Martin Fong and others for supplying this.
 */
 
   Thanks to Martin Fong and others for supplying this.
 */
 
-
 #ifdef WIN32
 
 #define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
 #ifdef WIN32
 
 #define AlignPage(add) (((add) + (malloc_getpagesize-1)) & \
@@ -80,7 +93,7 @@ GmListElement* makeGmListElement (void* bas)
        return this;
 }
 
        return this;
 }
 
-void gcleanup ()
+void gcleanup (void)
 {
        BOOL rval;
        assert ( (head == NULL) || (head->base == (void*)gAddressBase));
 {
        BOOL rval;
        assert ( (head == NULL) || (head->base == (void*)gAddressBase));
@@ -141,7 +154,6 @@ void* findRegion (void* start_address, unsigned long size)
 
 }
 
 
 }
 
-
 void* wsbrk (long size)
 {
        void* tmp;
 void* wsbrk (long size)
 {
        void* tmp;
@@ -222,13 +234,10 @@ gAllocatedSize))
 
 #endif
 
 
 #endif
 
-
-
 /*
   Type declarations
 */
 
 /*
   Type declarations
 */
 
-
 struct malloc_chunk
 {
   INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
 struct malloc_chunk
 {
   INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */
@@ -256,7 +265,6 @@ typedef struct malloc_chunk* mchunkptr;
 
     An allocated chunk looks like this:
 
 
     An allocated chunk looks like this:
 
-
     chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of previous chunk, if allocated            | |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of previous chunk, if allocated            | |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -270,7 +278,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |             Size of chunk                                     |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
            |             Size of chunk                                     |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
-
     Where "chunk" is the front of the chunk for the purpose of most of
     the malloc code, but "mem" is the pointer that is returned to the
     user.  "Nextchunk" is the beginning of the next contiguous chunk.
     Where "chunk" is the front of the chunk for the purpose of most of
     the malloc code, but "mem" is the pointer that is returned to the
     user.  "Nextchunk" is the beginning of the next contiguous chunk.
@@ -387,14 +394,10 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 #define aligned_OK(m)    (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
 
 
 #define aligned_OK(m)    (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
 
-
-
-
 /*
   Physical chunk operations
 */
 
 /*
   Physical chunk operations
 */
 
-
 /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
 
 #define PREV_INUSE 0x1
 /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */
 
 #define PREV_INUSE 0x1
@@ -407,7 +410,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 #define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
 
 
 #define SIZE_BITS (PREV_INUSE|IS_MMAPPED)
 
-
 /* Ptr to next physical malloc_chunk. */
 
 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
 /* Ptr to next physical malloc_chunk. */
 
 #define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) ))
@@ -417,14 +419,10 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 #define prev_chunk(p)\
    ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
 
 #define prev_chunk(p)\
    ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) ))
 
-
 /* Treat space at ptr + offset as a chunk */
 
 #define chunk_at_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
 
 /* Treat space at ptr + offset as a chunk */
 
 #define chunk_at_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
 
-
-
-
 /*
   Dealing with use bits
 */
 /*
   Dealing with use bits
 */
@@ -461,9 +459,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 #define clear_inuse_bit_at_offset(p, s)\
  (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
 
 #define clear_inuse_bit_at_offset(p, s)\
  (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE))
 
-
-
-
 /*
   Dealing with size fields
 */
 /*
   Dealing with size fields
 */
@@ -484,10 +479,6 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 #define set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
 
 
 #define set_foot(p, s)   (((mchunkptr)((char*)(p) + (s)))->prev_size = (s))
 
-
-
-
-
 /*
    Bins
 
 /*
    Bins
 
@@ -541,7 +532,6 @@ typedef struct malloc_chunk* mbinptr;
 #define top            (av_[2])          /* The topmost chunk */
 #define last_remainder (bin_at(1))       /* remainder from last split */
 
 #define top            (av_[2])          /* The topmost chunk */
 #define last_remainder (bin_at(1))       /* remainder from last split */
 
-
 /*
    Because top initially points to its own bin with initial
    zero size, thus forcing extension on the first malloc request,
 /*
    Because top initially points to its own bin with initial
    zero size, thus forcing extension on the first malloc request,
@@ -575,19 +565,6 @@ static mbinptr av_[NAV * 2 + 2] = {
  IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
 };
 
  IAV(120), IAV(121), IAV(122), IAV(123), IAV(124), IAV(125), IAV(126), IAV(127)
 };
 
-#ifdef CONFIG_NEEDS_MANUAL_RELOC
-static void malloc_bin_reloc(void)
-{
-       mbinptr *p = &av_[2];
-       size_t i;
-
-       for (i = 2; i < ARRAY_SIZE(av_); ++i, ++p)
-               *p = (mbinptr)((ulong)*p + gd->reloc_off);
-}
-#else
-static inline void malloc_bin_reloc(void) {}
-#endif
-
 #ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
 static void malloc_init(void);
 #endif
 #ifdef CONFIG_SYS_MALLOC_DEFAULT_TO_INIT
 static void malloc_init(void);
 #endif
@@ -596,6 +573,9 @@ ulong mem_malloc_start = 0;
 ulong mem_malloc_end = 0;
 ulong mem_malloc_brk = 0;
 
 ulong mem_malloc_end = 0;
 ulong mem_malloc_brk = 0;
 
+static bool malloc_testing;    /* enable test mode */
+static int malloc_max_allocs;  /* return NULL after this many calls to malloc() */
+
 void *sbrk(ptrdiff_t increment)
 {
        ulong old = mem_malloc_brk;
 void *sbrk(ptrdiff_t increment)
 {
        ulong old = mem_malloc_brk;
@@ -628,10 +608,9 @@ void mem_malloc_init(ulong start, ulong size)
 
        debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
              mem_malloc_end);
 
        debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
              mem_malloc_end);
-#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
+#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
        memset((void *)mem_malloc_start, 0x0, size);
 #endif
        memset((void *)mem_malloc_start, 0x0, size);
 #endif
-       malloc_bin_reloc();
 }
 
 /* field-extraction macros */
 }
 
 /* field-extraction macros */
@@ -668,8 +647,6 @@ void mem_malloc_init(ulong start, ulong size)
 
 #define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
 
 
 #define is_small_request(nb) (nb < MAX_SMALLBIN_SIZE - SMALLBIN_WIDTH)
 
-
-
 /*
     To help compensate for the large number of bins, a one-level index
     structure is used for bin-by-bin searching.  `binblocks' is a
 /*
     To help compensate for the large number of bins, a one-level index
     structure is used for bin-by-bin searching.  `binblocks' is a
@@ -691,10 +668,6 @@ void mem_malloc_init(ulong start, ulong size)
 #define mark_binblock(ii)   (binblocks_w = (mbinptr)(binblocks_r | idx2binblock(ii)))
 #define clear_binblock(ii)  (binblocks_w = (mbinptr)(binblocks_r & ~(idx2binblock(ii))))
 
 #define mark_binblock(ii)   (binblocks_w = (mbinptr)(binblocks_r | idx2binblock(ii)))
 #define clear_binblock(ii)  (binblocks_w = (mbinptr)(binblocks_r & ~(idx2binblock(ii))))
 
-
-
-
-
 /*  Other static bookkeeping data */
 
 /* variables holding tunable values */
 /*  Other static bookkeeping data */
 
 /* variables holding tunable values */
@@ -767,7 +740,6 @@ static void malloc_init(void)
 
 #ifdef DEBUG
 
 
 #ifdef DEBUG
 
-
 /*
   These routines make a number of assertions about the states
   of data structures that should be true at all times. If any
 /*
   These routines make a number of assertions about the states
   of data structures that should be true at all times. If any
@@ -796,7 +768,6 @@ static void do_check_chunk(p) mchunkptr p;
 
 }
 
 
 }
 
-
 #if __STD_C
 static void do_check_free_chunk(mchunkptr p)
 #else
 #if __STD_C
 static void do_check_free_chunk(mchunkptr p)
 #else
@@ -882,13 +853,11 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
   /* ... and alignment */
   assert(aligned_OK(chunk2mem(p)));
 
   /* ... and alignment */
   assert(aligned_OK(chunk2mem(p)));
 
-
   /* ... and was allocated at front of an available chunk */
   assert(prev_inuse(p));
 
 }
 
   /* ... and was allocated at front of an available chunk */
   assert(prev_inuse(p));
 
 }
 
-
 #define check_free_chunk(P)  do_check_free_chunk(P)
 #define check_inuse_chunk(P) do_check_inuse_chunk(P)
 #define check_chunk(P) do_check_chunk(P)
 #define check_free_chunk(P)  do_check_free_chunk(P)
 #define check_inuse_chunk(P) do_check_inuse_chunk(P)
 #define check_chunk(P) do_check_chunk(P)
@@ -900,13 +869,10 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
 #define check_malloced_chunk(P,N)
 #endif
 
 #define check_malloced_chunk(P,N)
 #endif
 
-
-
 /*
   Macro-based internal utilities
 */
 
 /*
   Macro-based internal utilities
 */
 
-
 /*
   Linking chunks in bin lists.
   Call these only with variables, not arbitrary expressions, as arguments.
 /*
   Linking chunks in bin lists.
   Call these only with variables, not arbitrary expressions, as arguments.
@@ -917,7 +883,6 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
   putting it ahead of others of same size.
 */
 
   putting it ahead of others of same size.
 */
 
-
 #define frontlink(P, S, IDX, BK, FD)                                          \
 {                                                                             \
   if (S < MAX_SMALLBIN_SIZE)                                                  \
 #define frontlink(P, S, IDX, BK, FD)                                          \
 {                                                                             \
   if (S < MAX_SMALLBIN_SIZE)                                                  \
@@ -947,7 +912,6 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
   }                                                                           \
 }
 
   }                                                                           \
 }
 
-
 /* take a chunk off a list */
 
 #define unlink(P, BK, FD)                                                     \
 /* take a chunk off a list */
 
 #define unlink(P, BK, FD)                                                     \
@@ -971,10 +935,6 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s;
 #define clear_last_remainder \
   (last_remainder->fd = last_remainder->bk = last_remainder)
 
 #define clear_last_remainder \
   (last_remainder->fd = last_remainder->bk = last_remainder)
 
-
-
-
-
 /* Routines dealing with mmap(). */
 
 #if HAVE_MMAP
 /* Routines dealing with mmap(). */
 
 #if HAVE_MMAP
@@ -1216,12 +1176,8 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
   assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
 }
 
   assert(((unsigned long)((char*)top + top_size) & (pagesz - 1)) == 0);
 }
 
-
-
-
 /* Main public routines */
 
 /* Main public routines */
 
-
 /*
   Malloc Algorthim:
 
 /*
   Malloc Algorthim:
 
@@ -1272,7 +1228,6 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
         contiguous memory. Thus, it should be safe to intersperse
         mallocs with other sbrk calls.
 
         contiguous memory. Thus, it should be safe to intersperse
         mallocs with other sbrk calls.
 
-
       All allocations are made from the the `lowest' part of any found
       chunk. (The implementation invariant is that prev_inuse is
       always true of any allocated chunk; i.e., that each allocated
       All allocations are made from the the `lowest' part of any found
       chunk. (The implementation invariant is that prev_inuse is
       always true of any allocated chunk; i.e., that each allocated
@@ -1281,10 +1236,11 @@ static void malloc_extend_top(nb) INTERNAL_SIZE_T nb;
 
 */
 
 
 */
 
+STATIC_IF_MCHECK
 #if __STD_C
 #if __STD_C
-Void_t* mALLOc(size_t bytes)
+Void_t* mALLOc_impl(size_t bytes)
 #else
 #else
-Void_t* mALLOc(bytes) size_t bytes;
+Void_t* mALLOc_impl(bytes) size_t bytes;
 #endif
 {
   mchunkptr victim;                  /* inspected/selected chunk */
 #endif
 {
   mchunkptr victim;                  /* inspected/selected chunk */
@@ -1302,11 +1258,16 @@ Void_t* mALLOc(bytes) size_t bytes;
 
   INTERNAL_SIZE_T nb;
 
 
   INTERNAL_SIZE_T nb;
 
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
                return malloc_simple(bytes);
 #endif
 
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
                return malloc_simple(bytes);
 #endif
 
+  if (CONFIG_IS_ENABLED(UNIT_TEST) && malloc_testing) {
+    if (--malloc_max_allocs < 0)
+      return NULL;
+  }
+
   /* check if mem_malloc_init() was run */
   if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
     /* not initialized yet */
   /* check if mem_malloc_init() was run */
   if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
     /* not initialized yet */
@@ -1505,7 +1466,6 @@ Void_t* mALLOc(bytes) size_t bytes;
     }
   }
 
     }
   }
 
-
   /* Try to use top chunk */
 
   /* Require that there be a remainder, ensuring top always exists  */
   /* Try to use top chunk */
 
   /* Require that there be a remainder, ensuring top always exists  */
@@ -1536,9 +1496,6 @@ Void_t* mALLOc(bytes) size_t bytes;
 
 }
 
 
 }
 
-
-
-
 /*
 
   free() algorithm :
 /*
 
   free() algorithm :
@@ -1560,11 +1517,11 @@ Void_t* mALLOc(bytes) size_t bytes;
 
 */
 
 
 */
 
-
+STATIC_IF_MCHECK
 #if __STD_C
 #if __STD_C
-void fREe(Void_t* mem)
+void fREe_impl(Void_t* mem)
 #else
 #else
-void fREe(mem) Void_t* mem;
+void fREe_impl(mem) Void_t* mem;
 #endif
 {
   mchunkptr p;         /* chunk corresponding to mem */
 #endif
 {
   mchunkptr p;         /* chunk corresponding to mem */
@@ -1578,7 +1535,7 @@ void fREe(mem) Void_t* mem;
   mchunkptr fwd;       /* misc temp for linking */
   int       islr;      /* track whether merging with last_remainder */
 
   mchunkptr fwd;       /* misc temp for linking */
   int       islr;      /* track whether merging with last_remainder */
 
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
        /* free() is a no-op - all the memory will be freed on relocation */
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                VALGRIND_FREELIKE_BLOCK(mem, SIZE_SZ);
        /* free() is a no-op - all the memory will be freed on relocation */
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                VALGRIND_FREELIKE_BLOCK(mem, SIZE_SZ);
@@ -1655,17 +1612,12 @@ void fREe(mem) Void_t* mem;
       unlink(next, bck, fwd);
   }
 
       unlink(next, bck, fwd);
   }
 
-
   set_head(p, sz | PREV_INUSE);
   set_foot(p, sz);
   if (!islr)
     frontlink(p, sz, idx, bck, fwd);
 }
 
   set_head(p, sz | PREV_INUSE);
   set_foot(p, sz);
   if (!islr)
     frontlink(p, sz, idx, bck, fwd);
 }
 
-
-
-
-
 /*
 
   Realloc algorithm:
 /*
 
   Realloc algorithm:
@@ -1698,14 +1650,13 @@ void fREe(mem) Void_t* mem;
     and allowing it would also allow too many other incorrect
     usages of realloc to be sensible.
 
     and allowing it would also allow too many other incorrect
     usages of realloc to be sensible.
 
-
 */
 
 */
 
-
+STATIC_IF_MCHECK
 #if __STD_C
 #if __STD_C
-Void_t* rEALLOc(Void_t* oldmem, size_t bytes)
+Void_t* rEALLOc_impl(Void_t* oldmem, size_t bytes)
 #else
 #else
-Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
+Void_t* rEALLOc_impl(oldmem, bytes) Void_t* oldmem; size_t bytes;
 #endif
 {
   INTERNAL_SIZE_T    nb;      /* padded request size */
 #endif
 {
   INTERNAL_SIZE_T    nb;      /* padded request size */
@@ -1731,7 +1682,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
 
 #ifdef REALLOC_ZERO_BYTES_FREES
   if (!bytes) {
 
 #ifdef REALLOC_ZERO_BYTES_FREES
   if (!bytes) {
-       fREe(oldmem);
+       fREe_impl(oldmem);
        return NULL;
   }
 #endif
        return NULL;
   }
 #endif
@@ -1739,9 +1690,9 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   if ((long)bytes < 0) return NULL;
 
   /* realloc of null is supposed to be same as malloc */
   if ((long)bytes < 0) return NULL;
 
   /* realloc of null is supposed to be same as malloc */
-  if (oldmem == NULL) return mALLOc(bytes);
+  if (oldmem == NULL) return mALLOc_impl(bytes);
 
 
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                /* This is harder to support and should not be needed */
                panic("pre-reloc realloc() is not supported");
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                /* This is harder to support and should not be needed */
                panic("pre-reloc realloc() is not supported");
@@ -1751,7 +1702,6 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   newp    = oldp    = mem2chunk(oldmem);
   newsize = oldsize = chunksize(oldp);
 
   newp    = oldp    = mem2chunk(oldmem);
   newsize = oldsize = chunksize(oldp);
 
-
   nb = request2size(bytes);
 
 #if HAVE_MMAP
   nb = request2size(bytes);
 
 #if HAVE_MMAP
@@ -1764,7 +1714,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
     /* Note the extra SIZE_SZ overhead. */
     if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
     /* Must alloc, copy, free. */
     /* Note the extra SIZE_SZ overhead. */
     if(oldsize - SIZE_SZ >= nb) return oldmem; /* do nothing */
     /* Must alloc, copy, free. */
-    newmem = mALLOc(bytes);
+    newmem = mALLOc_impl(bytes);
     if (!newmem)
        return NULL; /* propagate failure */
     MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
     if (!newmem)
        return NULL; /* propagate failure */
     MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ);
@@ -1875,7 +1825,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
 
     /* Must allocate */
 
 
     /* Must allocate */
 
-    newmem = mALLOc (bytes);
+    newmem = mALLOc_impl (bytes);
 
     if (newmem == NULL)  /* propagate failure */
       return NULL;
 
     if (newmem == NULL)  /* propagate failure */
       return NULL;
@@ -1892,14 +1842,13 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
 
     /* Otherwise copy, free, and exit */
     MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
 
     /* Otherwise copy, free, and exit */
     MALLOC_COPY(newmem, oldmem, oldsize - SIZE_SZ);
-    fREe(oldmem);
+    fREe_impl(oldmem);
     return newmem;
   } else {
     VALGRIND_RESIZEINPLACE_BLOCK(oldmem, 0, bytes, SIZE_SZ);
     VALGRIND_MAKE_MEM_DEFINED(oldmem, bytes);
   }
 
     return newmem;
   } else {
     VALGRIND_RESIZEINPLACE_BLOCK(oldmem, 0, bytes, SIZE_SZ);
     VALGRIND_MAKE_MEM_DEFINED(oldmem, bytes);
   }
 
-
  split:  /* split off extra room in old or expanded chunk */
 
   if (newsize - nb >= MINSIZE) /* split off remainder */
  split:  /* split off extra room in old or expanded chunk */
 
   if (newsize - nb >= MINSIZE) /* split off remainder */
@@ -1911,7 +1860,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
     set_inuse_bit_at_offset(remainder, remainder_size);
     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
                              false);
     set_inuse_bit_at_offset(remainder, remainder_size);
     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
                              false);
-    fREe(chunk2mem(remainder)); /* let free() deal with it */
+    fREe_impl(chunk2mem(remainder)); /* let free() deal with it */
   }
   else
   {
   }
   else
   {
@@ -1923,9 +1872,6 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   return chunk2mem(newp);
 }
 
   return chunk2mem(newp);
 }
 
-
-
-
 /*
 
   memalign algorithm:
 /*
 
   memalign algorithm:
@@ -1944,11 +1890,11 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
 
 */
 
 
 */
 
-
+STATIC_IF_MCHECK
 #if __STD_C
 #if __STD_C
-Void_t* mEMALIGn(size_t alignment, size_t bytes)
+Void_t* mEMALIGn_impl(size_t alignment, size_t bytes)
 #else
 #else
-Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
+Void_t* mEMALIGn_impl(alignment, bytes) size_t alignment; size_t bytes;
 #endif
 {
   INTERNAL_SIZE_T    nb;      /* padded  request size */
 #endif
 {
   INTERNAL_SIZE_T    nb;      /* padded  request size */
@@ -1963,7 +1909,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
 
   if ((long)bytes < 0) return NULL;
 
 
   if ((long)bytes < 0) return NULL;
 
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                return memalign_simple(alignment, bytes);
        }
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                return memalign_simple(alignment, bytes);
        }
@@ -1971,7 +1917,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
 
   /* If need less alignment than we give anyway, just relay to malloc */
 
 
   /* If need less alignment than we give anyway, just relay to malloc */
 
-  if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes);
+  if (alignment <= MALLOC_ALIGNMENT) return mALLOc_impl(bytes);
 
   /* Otherwise, ensure that it is at least a minimum chunk size */
 
 
   /* Otherwise, ensure that it is at least a minimum chunk size */
 
@@ -1980,7 +1926,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   /* Call malloc with worst case padding to hit alignment. */
 
   nb = request2size(bytes);
   /* Call malloc with worst case padding to hit alignment. */
 
   nb = request2size(bytes);
-  m  = (char*)(mALLOc(nb + alignment + MINSIZE));
+  m  = (char*)(mALLOc_impl(nb + alignment + MINSIZE));
 
   /*
   * The attempt to over-allocate (with a size large enough to guarantee the
 
   /*
   * The attempt to over-allocate (with a size large enough to guarantee the
@@ -1996,7 +1942,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
      * Use bytes not nb, since mALLOc internally calls request2size too, and
      * each call increases the size to allocate, to account for the header.
      */
      * Use bytes not nb, since mALLOc internally calls request2size too, and
      * each call increases the size to allocate, to account for the header.
      */
-    m  = (char*)(mALLOc(bytes));
+    m  = (char*)(mALLOc_impl(bytes));
     /* Aligned -> return it */
     if ((((unsigned long)(m)) % alignment) == 0)
       return m;
     /* Aligned -> return it */
     if ((((unsigned long)(m)) % alignment) == 0)
       return m;
@@ -2004,10 +1950,10 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
      * Otherwise, try again, requesting enough extra space to be able to
      * acquire alignment.
      */
      * Otherwise, try again, requesting enough extra space to be able to
      * acquire alignment.
      */
-    fREe(m);
+    fREe_impl(m);
     /* Add in extra bytes to match misalignment of unexpanded allocation */
     extra = alignment - (((unsigned long)(m)) % alignment);
     /* Add in extra bytes to match misalignment of unexpanded allocation */
     extra = alignment - (((unsigned long)(m)) % alignment);
-    m  = (char*)(mALLOc(bytes + extra));
+    m  = (char*)(mALLOc_impl(bytes + extra));
     /*
      * m might not be the same as before. Validate that the previous value of
      * extra still works for the current value of m.
     /*
      * m might not be the same as before. Validate that the previous value of
      * extra still works for the current value of m.
@@ -2016,7 +1962,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
     if (m) {
       extra2 = alignment - (((unsigned long)(m)) % alignment);
       if (extra2 > extra) {
     if (m) {
       extra2 = alignment - (((unsigned long)(m)) % alignment);
       if (extra2 > extra) {
-        fREe(m);
+        fREe_impl(m);
         m = NULL;
       }
     }
         m = NULL;
       }
     }
@@ -2066,7 +2012,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
     set_head(newp, newsize | PREV_INUSE);
     set_inuse_bit_at_offset(newp, newsize);
     set_head_size(p, leadsize);
     set_head(newp, newsize | PREV_INUSE);
     set_inuse_bit_at_offset(newp, newsize);
     set_head_size(p, leadsize);
-    fREe(chunk2mem(p));
+    fREe_impl(chunk2mem(p));
     p = newp;
     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(p), bytes, SIZE_SZ, false);
 
     p = newp;
     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(p), bytes, SIZE_SZ, false);
 
@@ -2084,7 +2030,7 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
     set_head_size(p, nb);
     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
                              false);
     set_head_size(p, nb);
     VALGRIND_MALLOCLIKE_BLOCK(chunk2mem(remainder), remainder_size, SIZE_SZ,
                              false);
-    fREe(chunk2mem(remainder));
+    fREe_impl(chunk2mem(remainder));
   }
 
   check_inuse_chunk(p);
   }
 
   check_inuse_chunk(p);
@@ -2092,9 +2038,6 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
 
 }
 
 
 }
 
-
-
-
 /*
     valloc just invokes memalign with alignment argument equal
     to the page size of the system (or as near to this as can
 /*
     valloc just invokes memalign with alignment argument equal
     to the page size of the system (or as near to this as can
@@ -2115,7 +2058,6 @@ Void_t* vALLOc(bytes) size_t bytes;
   that will accommodate request
 */
 
   that will accommodate request
 */
 
-
 #if __STD_C
 Void_t* pvALLOc(size_t bytes)
 #else
 #if __STD_C
 Void_t* pvALLOc(size_t bytes)
 #else
@@ -2132,10 +2074,11 @@ Void_t* pvALLOc(bytes) size_t bytes;
 
 */
 
 
 */
 
+STATIC_IF_MCHECK
 #if __STD_C
 #if __STD_C
-Void_t* cALLOc(size_t n, size_t elem_size)
+Void_t* cALLOc_impl(size_t n, size_t elem_size)
 #else
 #else
-Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
+Void_t* cALLOc_impl(n, elem_size) size_t n; size_t elem_size;
 #endif
 {
   mchunkptr p;
 #endif
 {
   mchunkptr p;
@@ -2143,15 +2086,14 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
 
   INTERNAL_SIZE_T sz = n * elem_size;
 
 
   INTERNAL_SIZE_T sz = n * elem_size;
 
-
   /* check if expand_top called, in which case don't need to clear */
   /* check if expand_top called, in which case don't need to clear */
-#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
+#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
 #if MORECORE_CLEARS
   mchunkptr oldtop = top;
   INTERNAL_SIZE_T oldtopsize = chunksize(top);
 #endif
 #endif
 #if MORECORE_CLEARS
   mchunkptr oldtop = top;
   INTERNAL_SIZE_T oldtopsize = chunksize(top);
 #endif
 #endif
-  Void_t* mem = mALLOc (sz);
+  Void_t* mem = mALLOc_impl (sz);
 
   if ((long)n < 0) return NULL;
 
 
   if ((long)n < 0) return NULL;
 
@@ -2159,7 +2101,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
     return NULL;
   else
   {
     return NULL;
   else
   {
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                memset(mem, 0, sz);
                return mem;
        if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
                memset(mem, 0, sz);
                return mem;
@@ -2169,14 +2111,13 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
 
     /* Two optional cases in which clearing not necessary */
 
 
     /* Two optional cases in which clearing not necessary */
 
-
 #if HAVE_MMAP
     if (chunk_is_mmapped(p)) return mem;
 #endif
 
     csz = chunksize(p);
 
 #if HAVE_MMAP
     if (chunk_is_mmapped(p)) return mem;
 #endif
 
     csz = chunksize(p);
 
-#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
+#if CONFIG_IS_ENABLED(SYS_MALLOC_CLEAR_ON_INIT)
 #if MORECORE_CLEARS
     if (p == oldtop && csz > oldtopsize)
     {
 #if MORECORE_CLEARS
     if (p == oldtop && csz > oldtopsize)
     {
@@ -2210,7 +2151,89 @@ void cfree(mem) Void_t *mem;
 }
 #endif
 
 }
 #endif
 
+#ifdef MCHECK_HEAP_PROTECTION
+ #include "mcheck_core.inc.h"
+ #if !__STD_C
+  #error "must have __STD_C"
+ #endif
+
+Void_t *mALLOc(size_t bytes)
+{
+       mcheck_pedantic_prehook();
+       size_t fullsz = mcheck_alloc_prehook(bytes);
+       void *p = mALLOc_impl(fullsz);
+
+       if (!p)
+               return p;
+       return mcheck_alloc_posthook(p, bytes);
+}
+
+void fREe(Void_t *mem) { fREe_impl(mcheck_free_prehook(mem)); }
+
+Void_t *rEALLOc(Void_t *oldmem, size_t bytes)
+{
+       mcheck_pedantic_prehook();
+       if (bytes == 0) {
+               if (oldmem)
+                       fREe(oldmem);
+               return NULL;
+       }
+
+       if (oldmem == NULL)
+               return mALLOc(bytes);
+
+       void *p = mcheck_reallocfree_prehook(oldmem);
+       size_t newsz = mcheck_alloc_prehook(bytes);
+
+       p = rEALLOc_impl(p, newsz);
+       if (!p)
+               return p;
+       return mcheck_alloc_noclean_posthook(p, bytes);
+}
+
+Void_t *mEMALIGn(size_t alignment, size_t bytes)
+{
+       mcheck_pedantic_prehook();
+       size_t fullsz = mcheck_memalign_prehook(alignment, bytes);
+       void *p = mEMALIGn_impl(alignment, fullsz);
+
+       if (!p)
+               return p;
+       return mcheck_memalign_posthook(alignment, p, bytes);
+}
+
+// pvALLOc, vALLOc - redirect to mEMALIGn, defined here, so they need no wrapping.
+
+Void_t *cALLOc(size_t n, size_t elem_size)
+{
+       mcheck_pedantic_prehook();
+       // NB: here is no overflow check.
+       size_t fullsz = mcheck_alloc_prehook(n * elem_size);
+       void *p = cALLOc_impl(1, fullsz);
+
+       if (!p)
+               return p;
+       return mcheck_alloc_noclean_posthook(p, n * elem_size);
+}
+
+// mcheck API {
+int mcheck_pedantic(mcheck_abortfunc_t f)
+{
+       mcheck_initialize(f, 1);
+       return 0;
+}
+
+int mcheck(mcheck_abortfunc_t f)
+{
+       mcheck_initialize(f, 0);
+       return 0;
+}
+
+void mcheck_check_all(void) { mcheck_pedantic_check(); }
 
 
+enum mcheck_status mprobe(void *__ptr) { return mcheck_mprobe(__ptr); }
+// mcheck API }
+#endif
 
 /*
 
 
 /*
 
@@ -2291,8 +2314,6 @@ int malloc_trim(pad) size_t pad;
   }
 }
 
   }
 }
 
-
-
 /*
   malloc_usable_size:
 
 /*
   malloc_usable_size:
 
@@ -2326,13 +2347,10 @@ size_t malloc_usable_size(mem) Void_t* mem;
   }
 }
 
   }
 }
 
-
-
-
 /* Utility to update current_mallinfo for malloc_stats and mallinfo() */
 
 #ifdef DEBUG
 /* Utility to update current_mallinfo for malloc_stats and mallinfo() */
 
 #ifdef DEBUG
-static void malloc_update_mallinfo()
+static void malloc_update_mallinfo(void)
 {
   int i;
   mbinptr b;
 {
   int i;
   mbinptr b;
@@ -2371,8 +2389,6 @@ static void malloc_update_mallinfo()
 }
 #endif /* DEBUG */
 
 }
 #endif /* DEBUG */
 
-
-
 /*
 
   malloc_stats:
 /*
 
   malloc_stats:
@@ -2389,7 +2405,7 @@ static void malloc_update_mallinfo()
 */
 
 #ifdef DEBUG
 */
 
 #ifdef DEBUG
-void malloc_stats()
+void malloc_stats(void)
 {
   malloc_update_mallinfo();
   printf("max system bytes = %10u\n",
 {
   malloc_update_mallinfo();
   printf("max system bytes = %10u\n",
@@ -2410,16 +2426,13 @@ void malloc_stats()
 */
 
 #ifdef DEBUG
 */
 
 #ifdef DEBUG
-struct mallinfo mALLINFo()
+struct mallinfo mALLINFo(void)
 {
   malloc_update_mallinfo();
   return current_mallinfo;
 }
 #endif /* DEBUG */
 
 {
   malloc_update_mallinfo();
   return current_mallinfo;
 }
 #endif /* DEBUG */
 
-
-
-
 /*
   mallopt:
 
 /*
   mallopt:
 
@@ -2461,7 +2474,7 @@ int mALLOPt(param_number, value) int param_number; int value;
 
 int initf_malloc(void)
 {
 
 int initf_malloc(void)
 {
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
        assert(gd->malloc_base);        /* Set up by crt0.S */
        gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
        gd->malloc_ptr = 0;
        assert(gd->malloc_base);        /* Set up by crt0.S */
        gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN);
        gd->malloc_ptr = 0;
@@ -2470,6 +2483,17 @@ int initf_malloc(void)
        return 0;
 }
 
        return 0;
 }
 
+void malloc_enable_testing(int max_allocs)
+{
+       malloc_testing = true;
+       malloc_max_allocs = max_allocs;
+}
+
+void malloc_disable_testing(void)
+{
+       malloc_testing = false;
+}
+
 /*
 
 History:
 /*
 
 History:
This page took 0.055002 seconds and 4 git commands to generate.