--- 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) \