[PATCH] Fix realloc

Jakub Jelinek jakub@redhat.com
Wed Dec 27 08:56:00 GMT 2000


Hi!

realloc was using memcpy even for copies where source and destination might
overlap. Found with new alphaev6 memcpy during make check. Maybe we should sometimes
try using
void *memcpy (void *dst, const void *src, size_t len)
{
  memset(dst, 0xaf, len);
  return memmove(dst, src, len);
}
and see what crashes...

2000-12-27  Jakub Jelinek  <jakub@redhat.com>

	* malloc/malloc.c (memmove): Add prototypes.
	(MALLOC_MEMMOVE): Define.
	(chunk_realloc): Use it instead of MALLOC_COPY if source and
	destination might overlap.

--- libc/malloc/malloc.c.jj	Fri Sep 29 12:56:58 2000
+++ libc/malloc/malloc.c	Wed Dec 27 17:58:28 2000
@@ -415,9 +415,11 @@ extern "C" {
 #if __STD_C
 void* memset(void*, int, size_t);
 void* memcpy(void*, const void*, size_t);
+void* memmove(void*, const void*, size_t);
 #else
 Void_t* memset();
 Void_t* memcpy();
+Void_t* memmove();
 #endif
 #endif
 
@@ -462,6 +464,24 @@ do {                                    
   } else memcpy(dest, src, mcsz);                                             \
 } while(0)
 
+#define MALLOC_MEMMOVE(dest,src,nbytes)                                       \
+do {                                                                          \
+  INTERNAL_SIZE_T mcsz = (nbytes);                                            \
+  if(mcsz <= 9*sizeof(mcsz)) {                                                \
+    INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) (src);                        \
+    INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) (dest);                       \
+    if(mcsz >= 5*sizeof(mcsz)) {     *mcdst++ = *mcsrc++;                     \
+                                     *mcdst++ = *mcsrc++;                     \
+      if(mcsz >= 7*sizeof(mcsz)) {   *mcdst++ = *mcsrc++;                     \
+                                     *mcdst++ = *mcsrc++;                     \
+        if(mcsz >= 9*sizeof(mcsz)) { *mcdst++ = *mcsrc++;                     \
+                                     *mcdst++ = *mcsrc++; }}}                 \
+                                     *mcdst++ = *mcsrc++;                     \
+                                     *mcdst++ = *mcsrc++;                     \
+                                     *mcdst   = *mcsrc  ;                     \
+  } else memmove(dest, src, mcsz);                                            \
+} while(0)
+
 #else /* !USE_MEMCPY */
 
 /* Use Duff's device for good zeroing/copying performance. */
@@ -501,6 +521,8 @@ do {                                    
   }                                                                           \
 } while(0)
 
+#define MALLOC_MEMMOVE(dest,src,nbytes)
+
 #endif
 
 
@@ -3365,7 +3387,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_
             unlink(prev, bck, fwd);
             newp = prev;
             newsize += prevsize + nextsize;
-            MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
+            MALLOC_MEMMOVE(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
             top(ar_ptr) = chunk_at_offset(newp, nb);
             set_head(top(ar_ptr), (newsize - nb) | PREV_INUSE);
             set_head_size(newp, nb);
@@ -3380,7 +3402,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_
           unlink(prev, bck, fwd);
           newp = prev;
           newsize += nextsize + prevsize;
-          MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
+          MALLOC_MEMMOVE(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
           goto split;
         }
       }
@@ -3391,7 +3413,7 @@ arena* ar_ptr; mchunkptr oldp; INTERNAL_
         unlink(prev, bck, fwd);
         newp = prev;
         newsize += prevsize;
-        MALLOC_COPY(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
+        MALLOC_MEMMOVE(BOUNDED_N(chunk2mem(newp), oldsize), oldmem, oldsize);
         goto split;
       }
     }

	Jakub


More information about the Libc-hacker mailing list