]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - common/dlmalloc.c
malloc: solve dead code issue in memalign()
[people/ms/u-boot.git] / common / dlmalloc.c
index d1cd561cb85544009cf71536137e051393dce0e5..5ea37dfb6e4c334db262b6726bfff0e1d5362508 100644 (file)
@@ -1,5 +1,9 @@
 #include <common.h>
 
+#ifdef CONFIG_SANDBOX
+#define DEBUG
+#endif
+
 #if 0  /* Moved to malloc.h */
 /* ---------- To make a malloc.h, start cutting here ------------ */
 
@@ -930,6 +934,8 @@ struct mallinfo mALLINFo();
 #endif /* 0 */                 /* Moved to malloc.h */
 
 #include <malloc.h>
+#include <asm/io.h>
+
 #ifdef DEBUG
 #if __STD_C
 static void malloc_update_mallinfo (void);
@@ -1527,8 +1533,11 @@ void mem_malloc_init(ulong start, ulong size)
        mem_malloc_end = start + size;
        mem_malloc_brk = start;
 
-       memset((void *)mem_malloc_start, 0, size);
-
+       debug("using memory %#lx-%#lx for malloc()\n", mem_malloc_start,
+             mem_malloc_end);
+#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
+       memset((void *)mem_malloc_start, 0x0, size);
+#endif
        malloc_bin_reloc();
 }
 
@@ -2174,6 +2183,11 @@ Void_t* mALLOc(bytes) size_t bytes;
 
   INTERNAL_SIZE_T nb;
 
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+       if (gd && !(gd->flags & GD_FLG_FULL_MALLOC_INIT))
+               return malloc_simple(bytes);
+#endif
+
   /* check if mem_malloc_init() was run */
   if ((mem_malloc_start == 0) && (mem_malloc_end == 0)) {
     /* not initialized yet */
@@ -2437,6 +2451,12 @@ void fREe(mem) Void_t* mem;
   mchunkptr fwd;       /* misc temp for linking */
   int       islr;      /* track whether merging with last_remainder */
 
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+       /* free() is a no-op - all the memory will be freed on relocation */
+       if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
+               return;
+#endif
+
   if (mem == NULL)                              /* free(0) has no effect */
     return;
 
@@ -2588,6 +2608,13 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   /* realloc of null is supposed to be same as malloc */
   if (oldmem == NULL) return mALLOc(bytes);
 
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+       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");
+       }
+#endif
+
   newp    = oldp    = mem2chunk(oldmem);
   newsize = oldsize = chunksize(oldp);
 
@@ -2802,6 +2829,28 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes;
   nb = request2size(bytes);
   m  = (char*)(mALLOc(nb + alignment + MINSIZE));
 
+  /*
+  * The attempt to over-allocate (with a size large enough to guarantee the
+  * ability to find an aligned region within allocated memory) failed.
+  *
+  * Try again, this time only allocating exactly the size the user wants. If
+  * the allocation now succeeds and just happens to be aligned, we can still
+  * fulfill the user's request.
+  */
+  if (m == NULL) {
+    /*
+     * 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));
+    /* Aligned -> return it */
+    if ((((unsigned long)(m)) % alignment) == 0)
+      return m;
+    /* Otherwise, fail */
+    fREe(m);
+    m = NULL;
+  }
+
   if (m == NULL) return NULL; /* propagate failure */
 
   p = mem2chunk(m);
@@ -2921,9 +2970,11 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
 
 
   /* check if expand_top called, in which case don't need to clear */
+#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
 #if MORECORE_CLEARS
   mchunkptr oldtop = top;
   INTERNAL_SIZE_T oldtopsize = chunksize(top);
+#endif
 #endif
   Void_t* mem = mALLOc (sz);
 
@@ -2933,6 +2984,12 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
     return NULL;
   else
   {
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+       if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
+               MALLOC_ZERO(mem, sz);
+               return mem;
+       }
+#endif
     p = mem2chunk(mem);
 
     /* Two optional cases in which clearing not necessary */
@@ -2944,12 +3001,14 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
 
     csz = chunksize(p);
 
+#ifdef CONFIG_SYS_MALLOC_CLEAR_ON_INIT
 #if MORECORE_CLEARS
     if (p == oldtop && csz > oldtopsize)
     {
       /* clear only the bytes from non-freshly-sbrked memory */
       csz = oldtopsize;
     }
+#endif
 #endif
 
     MALLOC_ZERO(mem, csz - SIZE_SZ);
@@ -3224,6 +3283,17 @@ int mALLOPt(param_number, value) int param_number; int value;
   }
 }
 
+int initf_malloc(void)
+{
+#ifdef CONFIG_SYS_MALLOC_F_LEN
+       assert(gd->malloc_base);        /* Set up by crt0.S */
+       gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
+       gd->malloc_ptr = 0;
+#endif
+
+       return 0;
+}
+
 /*
 
 History: