Blob Blame History Raw
--- valgrind/memcheck/mc_replace_strmem.c.jj	2011-06-08 17:26:29.000000000 +0200
+++ valgrind/memcheck/mc_replace_strmem.c	2011-06-09 14:49:11.000000000 +0200
@@ -558,11 +558,7 @@ MEMCHR(VG_Z_DYLD,        memchr)
 #endif
 
 
-#define MEMCPY(soname, fnname) \
-   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
-            ( void *dst, const void *src, SizeT len ); \
-   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
-            ( void *dst, const void *src, SizeT len ) \
+#define MEMCPY_BODY \
    { \
       if (is_overlap(dst, src, len, len)) \
          RECORD_OVERLAP_ERROR("memcpy", dst, src, len); \
@@ -628,6 +624,18 @@ MEMCHR(VG_Z_DYLD,        memchr)
       \
       return dst; \
    }
+#define MEMCPY(soname, fnname) \
+   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+            ( void *dst, const void *src, SizeT len ); \
+   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+            ( void *dst, const void *src, SizeT len ) \
+   MEMCPY_BODY
+#define MEMCPY_ZZ(soname, fnname) \
+   void* VG_REPLACE_FUNCTION_ZZ(soname,fnname) \
+            ( void *dst, const void *src, SizeT len ); \
+   void* VG_REPLACE_FUNCTION_ZZ(soname,fnname) \
+            ( void *dst, const void *src, SizeT len ) \
+   MEMCPY_BODY
 
 MEMCPY(VG_Z_LIBC_SONAME, memcpy)
 #if defined(VGO_linux)
@@ -636,6 +644,11 @@ MEMCPY(VG_Z_LD64_SO_1,   memcpy) /* ld64
 #elif defined(VGO_darwin)
 MEMCPY(VG_Z_DYLD,        memcpy)
 #endif
+#if defined(VGP_amd64_linux)
+/* In glibc 2.14+, memcpy@GLIBC_2.2.5 is an alias to memmove and only
+   memcpy@@GLIBC_2.14 is a real memcpy.  */
+MEMCPY_ZZ(VG_Z_LIBC_SONAME, memcpyZAZAGLIBCZu2Zd14) /* memcpy@@GLIBC_2.14 */
+#endif
 /* icc9 blats these around all over the place.  Not only in the main
    executable but various .so's.  They are highly tuned and read
    memory beyond the source boundary (although work correctly and
@@ -738,11 +751,7 @@ MEMSET(VG_Z_DYLD,        memset)
 #endif
 
 
-#define MEMMOVE(soname, fnname) \
-   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
-            (void *dstV, const void *srcV, SizeT n); \
-   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
-            (void *dstV, const void *srcV, SizeT n) \
+#define MEMMOVE_BODY \
    { \
       SizeT i; \
       Char* dst = (Char*)dstV; \
@@ -758,12 +767,31 @@ MEMSET(VG_Z_DYLD,        memset)
       } \
       return dst; \
    }
+#define MEMMOVE(soname, fnname) \
+   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+            (void *dstV, const void *srcV, SizeT n); \
+   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
+            (void *dstV, const void *srcV, SizeT n) \
+   MEMMOVE_BODY
+#define MEMMOVE_ZZ(soname, fnname) \
+   void* VG_REPLACE_FUNCTION_ZZ(soname,fnname) \
+            (void *dstV, const void *srcV, SizeT n); \
+   void* VG_REPLACE_FUNCTION_ZZ(soname,fnname) \
+            (void *dstV, const void *srcV, SizeT n) \
+   MEMMOVE_BODY
 
 MEMMOVE(VG_Z_LIBC_SONAME, memmove)
 #if defined(VGO_darwin)
 MEMMOVE(VG_Z_DYLD,        memmove)
 #endif
-
+#if defined(VGP_amd64_linux)
+/* In glibc 2.14+, memcpy@GLIBC_2.2.5 is an alias to memmove and only
+   memcpy@@GLIBC_2.14 is a real memcpy.  It would be nice for
+   memcpy@GLIBC_2.2.5 to differentiate based on whether the caller
+   was calling memmove or memcpy@GLIBC_2.2.5, for now just treat
+   all such calls as memmove.  */
+MEMMOVE_ZZ(VG_Z_LIBC_SONAME, memcpyZAGLIBCZu2Zd2Zd5) /* memcpy@GLIBC_2.2.5 */
+#endif
 
 #define BCOPY(soname, fnname) \
    void VG_REPLACE_FUNCTION_ZU(soname,fnname) \