Fix krealloc
authorRonald G. Minnich <rminnich@google.com>
Thu, 2 Jan 2014 17:16:02 +0000 (09:16 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 17 Jan 2014 22:35:29 +0000 (14:35 -0800)
It was fairly badly broken.

It's legal to call with a NULL pointer.

It's required to save the old contents to new :-), else it's not much of a RE-allocator.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/src/kmalloc.c

index 53e9721..6eecded 100644 (file)
@@ -124,12 +124,30 @@ void *kzmalloc_align(size_t size, int flags, size_t align)
 
 void *krealloc(void* buf, size_t size, int flags)
 {
-       struct kmalloc_tag *tag = (struct kmalloc_tag*)(buf -
+       void *nbuf;
+       int osize = 0;
+       if (buf){
+               struct kmalloc_tag *tag = (struct kmalloc_tag*)(buf -
                                                        sizeof(struct kmalloc_tag));
-       if (tag->my_cache->obj_size >= size)
-               return buf;
-       kfree(buf);
-       return kmalloc(size, flags);
+               if (tag->my_cache->obj_size >= size)
+                       return buf;
+               osize = tag->my_cache->obj_size;
+       }
+
+       nbuf = kmalloc(size, flags);
+
+       /* would be more interesting to user error(...) here. */
+       /* but in any event, NEVER destroy buf! */
+       if (! nbuf)
+               return NULL;
+
+       if (osize)
+               memmove(nbuf, buf, osize);
+
+       if (buf)
+               kfree(buf);
+
+       return nbuf;
 }
 
 void kfree(void *addr)