mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 01:51:29 +00:00
Merge mc_replace_strmem.c, hg_intercepts.c and drd_strmem_intercepts.c
Move memcheck/mc_replace_strmem.c to shared/vg_replace_strmem.c and
add several intercepts for SSE-variants. Include that source file from
drd/drd_strmem_intercepts.c, helgrind/hg_intercepts.c and
memcheck/mc_replace_strmem.c.
Merge memcheck/tests/filter_memcpy into tests/filter_stderr_basic.
Update tests/check_headers_and_includes.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13719
This commit is contained in:
parent
98a63bf1d4
commit
39c447e4a9
@ -30,510 +30,4 @@
|
||||
The GNU General Public License is contained in the file COPYING.
|
||||
*/
|
||||
|
||||
#include "pub_tool_basics.h"
|
||||
#include "pub_tool_hashtable.h"
|
||||
#include "pub_tool_redir.h"
|
||||
#include "pub_tool_tooliface.h"
|
||||
#include "pub_tool_clreq.h"
|
||||
|
||||
|
||||
/*---------------------- strrchr ----------------------*/
|
||||
|
||||
#define STRRCHR(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ); \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20010,soname,fnname)( const char* s, int c ) \
|
||||
{ \
|
||||
HChar ch = (HChar)c; \
|
||||
const HChar* p = s; \
|
||||
const HChar* last = NULL; \
|
||||
while (True) { \
|
||||
if (*p == ch) last = p; \
|
||||
if (*p == 0) return (HChar *)last; \
|
||||
p++; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Apparently rindex() is the same thing as strrchr()
|
||||
#if defined(VGO_linux)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, strrchr)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, rindex)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, __GI_strrchr)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse2_no_bsf)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, __strrchr_sse42)
|
||||
STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
|
||||
#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
|
||||
STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
|
||||
#endif
|
||||
#elif defined(VGO_darwin)
|
||||
//STRRCHR(VG_Z_LIBC_SONAME, strrchr)
|
||||
//STRRCHR(VG_Z_LIBC_SONAME, rindex)
|
||||
//STRRCHR(VG_Z_DYLD, strrchr)
|
||||
//STRRCHR(VG_Z_DYLD, rindex)
|
||||
STRRCHR(VG_Z_LIBC_SONAME, strrchr)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strchr ----------------------*/
|
||||
|
||||
#define STRCHR(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname,fnname)(const char* s, int c); \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname,fnname)(const char* s, int c) \
|
||||
{ \
|
||||
HChar ch = (HChar)c; \
|
||||
const HChar* p = s; \
|
||||
while (True) { \
|
||||
if (*p == ch) return (HChar *)p; \
|
||||
if (*p == 0) return NULL; \
|
||||
p++; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Apparently index() is the same thing as strchr()
|
||||
#if defined(VGO_linux)
|
||||
STRCHR(VG_Z_LIBC_SONAME, strchr)
|
||||
STRCHR(VG_Z_LIBC_SONAME, __GI_strchr)
|
||||
STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2)
|
||||
STRCHR(VG_Z_LIBC_SONAME, __strchr_sse2_no_bsf)
|
||||
STRCHR(VG_Z_LIBC_SONAME, index)
|
||||
STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
|
||||
STRCHR(VG_Z_LD_LINUX_SO_2, index)
|
||||
STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
|
||||
STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
|
||||
#elif defined(VGO_darwin)
|
||||
STRCHR(VG_Z_LIBC_SONAME, strchr)
|
||||
STRCHR(VG_Z_LIBC_SONAME, index)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strnlen ----------------------*/
|
||||
|
||||
#define STRNLEN(soname, fnname) \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ); \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* str, SizeT n ) \
|
||||
{ \
|
||||
SizeT i = 0; \
|
||||
while (i < n && str[i] != 0) i++; \
|
||||
return i; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRNLEN(VG_Z_LIBC_SONAME, strnlen)
|
||||
#elif defined(VGO_darwin)
|
||||
STRNLEN(VG_Z_LIBC_SONAME, strnlen)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strlen ----------------------*/
|
||||
|
||||
// Note that this replacement often doesn't get used because gcc inlines
|
||||
// calls to strlen() with its own built-in version. This can be very
|
||||
// confusing if you aren't expecting it. Other small functions in this file
|
||||
// may also be inline by gcc.
|
||||
#define STRLEN(soname, fnname) \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
|
||||
{ \
|
||||
SizeT i = 0; \
|
||||
while (str[i] != 0) i++; \
|
||||
return i; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRLEN(VG_Z_LIBC_SONAME, strlen)
|
||||
STRLEN(VG_Z_LIBC_SONAME, __GI_strlen)
|
||||
STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2)
|
||||
STRLEN(VG_Z_LIBC_SONAME, __strlen_sse2_no_bsf)
|
||||
STRLEN(VG_Z_LIBC_SONAME, __strlen_sse42)
|
||||
STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
|
||||
STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
|
||||
#elif defined(VGO_darwin)
|
||||
STRLEN(VG_Z_LIBC_SONAME, strlen)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strcpy ----------------------*/
|
||||
|
||||
#define STRCPY(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname, fnname)(char* dst, const char* src); \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname, fnname)(char* dst, const char* src) \
|
||||
{ \
|
||||
HChar* dst_orig = dst; \
|
||||
\
|
||||
while (*src) *dst++ = *src++; \
|
||||
*dst = 0; \
|
||||
\
|
||||
return dst_orig; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRCPY(VG_Z_LIBC_SONAME, strcpy)
|
||||
STRCPY(VG_Z_LIBC_SONAME, __GI_strcpy)
|
||||
#elif defined(VGO_darwin)
|
||||
STRCPY(VG_Z_LIBC_SONAME, strcpy)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strncpy ----------------------*/
|
||||
|
||||
#define STRNCPY(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
|
||||
(char* dst, const char* src, SizeT n); \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20090,soname,fnname) \
|
||||
(char* dst, const char* src, SizeT n) \
|
||||
{ \
|
||||
HChar* dst_orig = dst; \
|
||||
SizeT m = 0; \
|
||||
\
|
||||
while (m < n && *src) { m++; *dst++ = *src++; } \
|
||||
while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */ \
|
||||
\
|
||||
return dst_orig; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRNCPY(VG_Z_LIBC_SONAME, strncpy)
|
||||
STRNCPY(VG_Z_LIBC_SONAME, __GI_strncpy)
|
||||
STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2)
|
||||
STRNCPY(VG_Z_LIBC_SONAME, __strncpy_sse2_unaligned)
|
||||
#elif defined(VGO_darwin)
|
||||
//STRNCPY(VG_Z_LIBC_SONAME, strncpy)
|
||||
//STRNCPY(VG_Z_DYLD, strncpy)
|
||||
STRNCPY(VG_Z_LIBC_SONAME, strncpy)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strncmp ----------------------*/
|
||||
|
||||
#define STRNCMP(soname, fnname) \
|
||||
int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
|
||||
(const char* s1, const char* s2, SizeT nmax); \
|
||||
int VG_REPLACE_FUNCTION_EZU(20110,soname,fnname) \
|
||||
(const char* s1, const char* s2, SizeT nmax) \
|
||||
{ \
|
||||
SizeT n = 0; \
|
||||
while (True) { \
|
||||
if (n >= nmax) return 0; \
|
||||
if (*s1 == 0 && *s2 == 0) return 0; \
|
||||
if (*s1 == 0) return -1; \
|
||||
if (*s2 == 0) return 1; \
|
||||
\
|
||||
if (*(const UChar*)s1 < *(const UChar*)s2) return -1; \
|
||||
if (*(const UChar*)s1 > *(const UChar*)s2) return 1; \
|
||||
\
|
||||
s1++; s2++; n++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRNCMP(VG_Z_LIBC_SONAME, strncmp)
|
||||
STRNCMP(VG_Z_LIBC_SONAME, __GI_strncmp)
|
||||
STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse2)
|
||||
STRNCMP(VG_Z_LIBC_SONAME, __strncmp_sse42)
|
||||
#elif defined(VGO_darwin)
|
||||
//STRNCMP(VG_Z_LIBC_SONAME, strncmp)
|
||||
//STRNCMP(VG_Z_DYLD, strncmp)
|
||||
STRNCMP(VG_Z_LIBC_SONAME, strncmp)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strcmp ----------------------*/
|
||||
|
||||
#define STRCMP(soname, fnname) \
|
||||
int VG_REPLACE_FUNCTION_ZU(soname,fnname)(const char* s1, const char* s2); \
|
||||
int VG_REPLACE_FUNCTION_ZU(soname,fnname)(const char* s1, const char* s2) \
|
||||
{ \
|
||||
register UChar c1; \
|
||||
register UChar c2; \
|
||||
while (True) { \
|
||||
c1 = *(UChar *)s1; \
|
||||
c2 = *(UChar *)s2; \
|
||||
if (c1 != c2) break; \
|
||||
if (c1 == 0) break; \
|
||||
s1++; s2++; \
|
||||
} \
|
||||
if ((UChar)c1 < (UChar)c2) return -1; \
|
||||
if ((UChar)c1 > (UChar)c2) return 1; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRCMP(VG_Z_LIBC_SONAME, strcmp)
|
||||
STRCMP(VG_Z_LIBC_SONAME, __GI_strcmp)
|
||||
STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse2)
|
||||
STRCMP(VG_Z_LIBC_SONAME, __strcmp_sse42)
|
||||
STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
|
||||
STRCMP(VG_Z_LD64_SO_1, strcmp)
|
||||
#elif defined(VGO_darwin)
|
||||
STRCMP(VG_Z_LIBC_SONAME, strcmp)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- memchr ----------------------*/
|
||||
|
||||
#define MEMCHR(soname, fnname) \
|
||||
void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
|
||||
(const void *s, int c, SizeT n); \
|
||||
void* VG_REPLACE_FUNCTION_EZU(20170,soname,fnname) \
|
||||
(const void *s, int c, SizeT n) \
|
||||
{ \
|
||||
SizeT i; \
|
||||
UChar c0 = (UChar)c; \
|
||||
UChar* p = (UChar*)s; \
|
||||
for (i = 0; i < n; i++) \
|
||||
if (p[i] == c0) return (void*)(&p[i]); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
MEMCHR(VG_Z_LIBC_SONAME, memchr)
|
||||
MEMCHR(VG_Z_LIBC_SONAME, __GI_memchr)
|
||||
#elif defined(VGO_darwin)
|
||||
//MEMCHR(VG_Z_LIBC_SONAME, memchr)
|
||||
//MEMCHR(VG_Z_DYLD, memchr)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- memrchr ----------------------*/
|
||||
|
||||
#define MEMRCHR(soname, fnname) \
|
||||
void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
|
||||
(const void *s, int c, SizeT n); \
|
||||
void* VG_REPLACE_FUNCTION_EZU(20360,soname,fnname) \
|
||||
(const void *s, int c, SizeT n) \
|
||||
{ \
|
||||
SizeT i; \
|
||||
UChar c0 = (UChar)c; \
|
||||
UChar* p = (UChar*)s; \
|
||||
for (i = 0; i < n; i++) \
|
||||
if (p[n-1-i] == c0) return (void*)(&p[n-1-i]); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
|
||||
#elif defined(VGO_darwin)
|
||||
//MEMRCHR(VG_Z_LIBC_SONAME, memrchr)
|
||||
//MEMRCHR(VG_Z_DYLD, memrchr)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- memcpy ----------------------*/
|
||||
|
||||
#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) \
|
||||
{ \
|
||||
const Addr WS = sizeof(UWord); /* 8 or 4 */ \
|
||||
const Addr WM = WS - 1; /* 7 or 3 */ \
|
||||
\
|
||||
if (len > 0) { \
|
||||
if (dst < src) { \
|
||||
\
|
||||
/* Copying backwards. */ \
|
||||
SizeT n = len; \
|
||||
Addr d = (Addr)dst; \
|
||||
Addr s = (Addr)src; \
|
||||
\
|
||||
if (((s^d) & WM) == 0) { \
|
||||
/* s and d have same UWord alignment. */ \
|
||||
/* Pull up to a UWord boundary. */ \
|
||||
while ((s & WM) != 0 && n >= 1) \
|
||||
{ *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
|
||||
/* Copy UWords. */ \
|
||||
while (n >= WS) \
|
||||
{ *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
|
||||
if (n == 0) \
|
||||
return dst; \
|
||||
} \
|
||||
if (((s|d) & 1) == 0) { \
|
||||
/* Both are 16-aligned; copy what we can thusly. */ \
|
||||
while (n >= 2) \
|
||||
{ *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
|
||||
} \
|
||||
/* Copy leftovers, or everything if misaligned. */ \
|
||||
while (n >= 1) \
|
||||
{ *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
|
||||
\
|
||||
} else if (dst > src) { \
|
||||
\
|
||||
SizeT n = len; \
|
||||
Addr d = ((Addr)dst) + n; \
|
||||
Addr s = ((Addr)src) + n; \
|
||||
\
|
||||
/* Copying forwards. */ \
|
||||
if (((s^d) & WM) == 0) { \
|
||||
/* s and d have same UWord alignment. */ \
|
||||
/* Back down to a UWord boundary. */ \
|
||||
while ((s & WM) != 0 && n >= 1) \
|
||||
{ s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
|
||||
/* Copy UWords. */ \
|
||||
while (n >= WS) \
|
||||
{ s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
|
||||
if (n == 0) \
|
||||
return dst; \
|
||||
} \
|
||||
if (((s|d) & 1) == 0) { \
|
||||
/* Both are 16-aligned; copy what we can thusly. */ \
|
||||
while (n >= 2) \
|
||||
{ s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
|
||||
} \
|
||||
/* Copy leftovers, or everything if misaligned. */ \
|
||||
while (n >= 1) \
|
||||
{ s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
|
||||
\
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return dst; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpy)
|
||||
MEMCPY(VG_Z_LIBC_SONAME, __GI_memcpy)
|
||||
MEMCPY(VG_Z_LIBC_SONAME, __memcpy_sse2)
|
||||
MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
|
||||
MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
|
||||
/* 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
|
||||
never go across page boundaries), so give errors when run
|
||||
natively, at least for misaligned source arg. Just intercepting
|
||||
in the exe only until we understand more about the problem. See
|
||||
http://bugs.kde.org/show_bug.cgi?id=139776
|
||||
*/
|
||||
MEMCPY(NONE, _intel_fast_memcpy)
|
||||
|
||||
#elif defined(VGO_darwin)
|
||||
# if DARWIN_VERS <= DARWIN_10_6
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpy)
|
||||
# endif
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- memcmp ----------------------*/
|
||||
|
||||
#define MEMCMP(soname, fnname) \
|
||||
int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
|
||||
(const void *s1V, const void *s2V, SizeT n); \
|
||||
int VG_REPLACE_FUNCTION_EZU(20190,soname,fnname) \
|
||||
(const void *s1V, const void *s2V, SizeT n) \
|
||||
{ \
|
||||
int res; \
|
||||
UChar a0; \
|
||||
UChar b0; \
|
||||
const UChar* s1 = s1V; \
|
||||
const UChar* s2 = s2V; \
|
||||
\
|
||||
while (n != 0) { \
|
||||
a0 = s1[0]; \
|
||||
b0 = s2[0]; \
|
||||
s1 += 1; \
|
||||
s2 += 1; \
|
||||
res = ((int)a0) - ((int)b0); \
|
||||
if (res != 0) \
|
||||
return res; \
|
||||
n -= 1; \
|
||||
} \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
MEMCMP(VG_Z_LIBC_SONAME, memcmp)
|
||||
MEMCMP(VG_Z_LIBC_SONAME, __GI_memcmp)
|
||||
MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse2)
|
||||
MEMCMP(VG_Z_LIBC_SONAME, __memcmp_sse4_1)
|
||||
MEMCMP(VG_Z_LIBC_SONAME, bcmp)
|
||||
MEMCMP(VG_Z_LD_SO_1, bcmp)
|
||||
#elif defined(VGO_darwin)
|
||||
//MEMCMP(VG_Z_LIBC_SONAME, memcmp)
|
||||
//MEMCMP(VG_Z_LIBC_SONAME, bcmp)
|
||||
//MEMCMP(VG_Z_DYLD, memcmp)
|
||||
//MEMCMP(VG_Z_DYLD, bcmp)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- stpcpy ----------------------*/
|
||||
|
||||
/* Copy SRC to DEST, returning the address of the terminating '\0' in
|
||||
DEST. (minor variant of strcpy) */
|
||||
#define STPCPY(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
|
||||
(char* dst, const char* src); \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20200,soname,fnname) \
|
||||
(char* dst, const char* src) \
|
||||
{ \
|
||||
while (*src) *dst++ = *src++; \
|
||||
*dst = 0; \
|
||||
\
|
||||
return dst; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STPCPY(VG_Z_LIBC_SONAME, stpcpy)
|
||||
STPCPY(VG_Z_LIBC_SONAME, __GI_stpcpy)
|
||||
STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2)
|
||||
STPCPY(VG_Z_LIBC_SONAME, __stpcpy_sse2_unaligned)
|
||||
STPCPY(VG_Z_LD_LINUX_SO_2, stpcpy)
|
||||
STPCPY(VG_Z_LD_LINUX_X86_64_SO_2, stpcpy)
|
||||
#elif defined(VGO_darwin)
|
||||
//STPCPY(VG_Z_LIBC_SONAME, stpcpy)
|
||||
//STPCPY(VG_Z_DYLD, stpcpy)
|
||||
#endif
|
||||
|
||||
|
||||
/*---------------------- strstr ----------------------*/
|
||||
|
||||
#define STRSTR(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
|
||||
(const char* haystack, const char* needle); \
|
||||
char* VG_REPLACE_FUNCTION_EZU(20310,soname,fnname) \
|
||||
(const char* haystack, const char* needle) \
|
||||
{ \
|
||||
const HChar* h = haystack; \
|
||||
const HChar* n = needle; \
|
||||
\
|
||||
/* find the length of n, not including terminating zero */ \
|
||||
UWord nlen = 0; \
|
||||
while (n[nlen]) nlen++; \
|
||||
\
|
||||
/* if n is the empty string, match immediately. */ \
|
||||
if (nlen == 0) return (HChar *)h; \
|
||||
\
|
||||
/* assert(nlen >= 1); */ \
|
||||
HChar n0 = n[0]; \
|
||||
\
|
||||
while (1) { \
|
||||
const HChar hh = *h; \
|
||||
if (hh == 0) return NULL; \
|
||||
if (hh != n0) { h++; continue; } \
|
||||
\
|
||||
UWord i; \
|
||||
for (i = 0; i < nlen; i++) { \
|
||||
if (n[i] != h[i]) \
|
||||
break; \
|
||||
} \
|
||||
/* assert(i >= 0 && i <= nlen); */ \
|
||||
if (i == nlen) \
|
||||
return (HChar *)h; \
|
||||
\
|
||||
h++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRSTR(VG_Z_LIBC_SONAME, strstr)
|
||||
STRSTR(VG_Z_LIBC_SONAME, __strstr_sse2)
|
||||
STRSTR(VG_Z_LIBC_SONAME, __strstr_sse42)
|
||||
#elif defined(VGO_darwin)
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--- end ---*/
|
||||
/*--------------------------------------------------------------------*/
|
||||
#include "../shared/vg_replace_strmem.c"
|
||||
|
||||
@ -2434,201 +2434,7 @@ QT5_FUNC(void*, _ZN6QMutexD2Ev, void* self)
|
||||
/*--- overrun the input arrays. ---*/
|
||||
/*----------------------------------------------------------------*/
|
||||
|
||||
/* Copied verbatim from memcheck/mc_replace_strmem.c. When copying
|
||||
new functions, please keep them in the same order as they appear in
|
||||
mc_replace_strmem.c. */
|
||||
|
||||
|
||||
#define STRCHR(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ); \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( const char* s, int c ) \
|
||||
{ \
|
||||
HChar ch = (HChar)c ; \
|
||||
const HChar* p = s; \
|
||||
while (True) { \
|
||||
if (*p == ch) return (HChar *)p; \
|
||||
if (*p == 0) return NULL; \
|
||||
p++; \
|
||||
} \
|
||||
}
|
||||
|
||||
// Apparently index() is the same thing as strchr()
|
||||
#if defined(VGO_linux)
|
||||
STRCHR(VG_Z_LIBC_SONAME, strchr)
|
||||
STRCHR(VG_Z_LIBC_SONAME, index)
|
||||
STRCHR(VG_Z_LD_LINUX_SO_2, strchr)
|
||||
STRCHR(VG_Z_LD_LINUX_SO_2, index)
|
||||
STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, strchr)
|
||||
STRCHR(VG_Z_LD_LINUX_X86_64_SO_2, index)
|
||||
#elif defined(VGO_darwin)
|
||||
STRCHR(VG_Z_LIBC_SONAME, strchr)
|
||||
STRCHR(VG_Z_LIBC_SONAME, index)
|
||||
#endif
|
||||
|
||||
|
||||
// Note that this replacement often doesn't get used because gcc inlines
|
||||
// calls to strlen() with its own built-in version. This can be very
|
||||
// confusing if you aren't expecting it. Other small functions in this file
|
||||
// may also be inline by gcc.
|
||||
#define STRLEN(soname, fnname) \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ); \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname)( const char* str ) \
|
||||
{ \
|
||||
SizeT i = 0; \
|
||||
while (str[i] != 0) i++; \
|
||||
return i; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRLEN(VG_Z_LIBC_SONAME, strlen)
|
||||
STRLEN(VG_Z_LD_LINUX_SO_2, strlen)
|
||||
STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
|
||||
#elif defined(VGO_darwin)
|
||||
STRLEN(VG_Z_LIBC_SONAME, strlen)
|
||||
#endif
|
||||
|
||||
|
||||
#define STRCPY(soname, fnname) \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ); \
|
||||
char* VG_REPLACE_FUNCTION_ZU(soname, fnname) ( char* dst, const char* src ) \
|
||||
{ \
|
||||
HChar* dst_orig = dst; \
|
||||
\
|
||||
while (*src) *dst++ = *src++; \
|
||||
*dst = 0; \
|
||||
\
|
||||
return dst_orig; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRCPY(VG_Z_LIBC_SONAME, strcpy)
|
||||
#elif defined(VGO_darwin)
|
||||
STRCPY(VG_Z_LIBC_SONAME, strcpy)
|
||||
#endif
|
||||
|
||||
|
||||
#define STRCMP(soname, fnname) \
|
||||
int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
( const char* s1, const char* s2 ); \
|
||||
int VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
( const char* s1, const char* s2 ) \
|
||||
{ \
|
||||
register UChar c1; \
|
||||
register UChar c2; \
|
||||
while (True) { \
|
||||
c1 = *(UChar *)s1; \
|
||||
c2 = *(UChar *)s2; \
|
||||
if (c1 != c2) break; \
|
||||
if (c1 == 0) break; \
|
||||
s1++; s2++; \
|
||||
} \
|
||||
if ((UChar)c1 < (UChar)c2) return -1; \
|
||||
if ((UChar)c1 > (UChar)c2) return 1; \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRCMP(VG_Z_LIBC_SONAME, strcmp)
|
||||
STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
|
||||
STRCMP(VG_Z_LD64_SO_1, strcmp)
|
||||
#elif defined(VGO_darwin)
|
||||
STRCMP(VG_Z_LIBC_SONAME, strcmp)
|
||||
#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 ) \
|
||||
{ \
|
||||
const Addr WS = sizeof(UWord); /* 8 or 4 */ \
|
||||
const Addr WM = WS - 1; /* 7 or 3 */ \
|
||||
\
|
||||
if (len > 0) { \
|
||||
if (dst < src) { \
|
||||
\
|
||||
/* Copying backwards. */ \
|
||||
SizeT n = len; \
|
||||
Addr d = (Addr)dst; \
|
||||
Addr s = (Addr)src; \
|
||||
\
|
||||
if (((s^d) & WM) == 0) { \
|
||||
/* s and d have same UWord alignment. */ \
|
||||
/* Pull up to a UWord boundary. */ \
|
||||
while ((s & WM) != 0 && n >= 1) \
|
||||
{ *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
|
||||
/* Copy UWords. */ \
|
||||
while (n >= WS) \
|
||||
{ *(UWord*)d = *(UWord*)s; s += WS; d += WS; n -= WS; } \
|
||||
if (n == 0) \
|
||||
return dst; \
|
||||
} \
|
||||
if (((s|d) & 1) == 0) { \
|
||||
/* Both are 16-aligned; copy what we can thusly. */ \
|
||||
while (n >= 2) \
|
||||
{ *(UShort*)d = *(UShort*)s; s += 2; d += 2; n -= 2; } \
|
||||
} \
|
||||
/* Copy leftovers, or everything if misaligned. */ \
|
||||
while (n >= 1) \
|
||||
{ *(UChar*)d = *(UChar*)s; s += 1; d += 1; n -= 1; } \
|
||||
\
|
||||
} else if (dst > src) { \
|
||||
\
|
||||
SizeT n = len; \
|
||||
Addr d = ((Addr)dst) + n; \
|
||||
Addr s = ((Addr)src) + n; \
|
||||
\
|
||||
/* Copying forwards. */ \
|
||||
if (((s^d) & WM) == 0) { \
|
||||
/* s and d have same UWord alignment. */ \
|
||||
/* Back down to a UWord boundary. */ \
|
||||
while ((s & WM) != 0 && n >= 1) \
|
||||
{ s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
|
||||
/* Copy UWords. */ \
|
||||
while (n >= WS) \
|
||||
{ s -= WS; d -= WS; *(UWord*)d = *(UWord*)s; n -= WS; } \
|
||||
if (n == 0) \
|
||||
return dst; \
|
||||
} \
|
||||
if (((s|d) & 1) == 0) { \
|
||||
/* Both are 16-aligned; copy what we can thusly. */ \
|
||||
while (n >= 2) \
|
||||
{ s -= 2; d -= 2; *(UShort*)d = *(UShort*)s; n -= 2; } \
|
||||
} \
|
||||
/* Copy leftovers, or everything if misaligned. */ \
|
||||
while (n >= 1) \
|
||||
{ s -= 1; d -= 1; *(UChar*)d = *(UChar*)s; n -= 1; } \
|
||||
\
|
||||
} \
|
||||
} \
|
||||
\
|
||||
return dst; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpy)
|
||||
MEMCPY(VG_Z_LD_SO_1, memcpy) /* ld.so.1 */
|
||||
MEMCPY(VG_Z_LD64_SO_1, memcpy) /* ld64.so.1 */
|
||||
/* 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
|
||||
never go across page boundaries), so give errors when run
|
||||
natively, at least for misaligned source arg. Just intercepting
|
||||
in the exe only until we understand more about the problem. See
|
||||
http://bugs.kde.org/show_bug.cgi?id=139776
|
||||
*/
|
||||
MEMCPY(NONE, _intel_fast_memcpy)
|
||||
|
||||
#elif defined(VGO_darwin)
|
||||
# if DARWIN_VERS <= DARWIN_10_6
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpy)
|
||||
# endif
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse3x) /* memcpy$VARIANT$sse3x */
|
||||
MEMCPY(VG_Z_LIBC_SONAME, memcpyZDVARIANTZDsse42) /* memcpy$VARIANT$sse42 */
|
||||
|
||||
#endif
|
||||
|
||||
#include "../shared/vg_replace_strmem.c"
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--- end hg_intercepts.c ---*/
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -46,8 +46,7 @@ dist_noinst_SCRIPTS = \
|
||||
filter_stderr filter_xml \
|
||||
filter_strchr \
|
||||
filter_varinfo3 \
|
||||
filter_memcheck \
|
||||
filter_memcpy
|
||||
filter_memcheck
|
||||
|
||||
noinst_HEADERS = leak.h
|
||||
|
||||
@ -215,8 +214,7 @@ EXTRA_DIST = \
|
||||
sigprocmask.stderr.exp sigprocmask.stderr.exp2 sigprocmask.vgtest \
|
||||
static_malloc.stderr.exp static_malloc.vgtest \
|
||||
stpncpy.vgtest stpncpy.stderr.exp stpncpy.stdout.exp \
|
||||
strchr.stderr.exp strchr.stderr.exp2 strchr.stderr.exp-darwin \
|
||||
strchr.stderr.exp3 strchr.vgtest \
|
||||
strchr.stderr.exp strchr.stderr.exp3 strchr.vgtest \
|
||||
str_tester.stderr.exp str_tester.vgtest \
|
||||
supp-dir.vgtest supp-dir.stderr.exp \
|
||||
supp_unknown.stderr.exp supp_unknown.vgtest supp_unknown.supp \
|
||||
|
||||
@ -7,7 +7,7 @@ use strict;
|
||||
# A list of files specific to the tool at hand. Line numbers in
|
||||
# these files will be removed from backtrace entries matching these files.
|
||||
#---------------------------------------------------------------------
|
||||
my @tool_files = ( "mc_replace_strmem.c", "vg_replace_malloc.c" );
|
||||
my @tool_files = ( "vg_replace_strmem.c", "vg_replace_malloc.c" );
|
||||
|
||||
|
||||
sub massage_backtrace_line ($$$) {
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
#! /bin/sh
|
||||
|
||||
# mc_replace_strmem.c intercepts various memcpy glibc versions.
|
||||
# mc_replace_strmem.c str[n]cpy and __GI_str[n]cpy are the same.
|
||||
./filter_stderr "$@" |
|
||||
perl -p -e "s/: memcpy\@\@?GLIBC_[.1-9]+ \(mc_replace_strmem.c:...\)/: memcpy \(mc_replace_strmem.c:...\)/" |
|
||||
sed -e "s/: __GI_strcpy (mc_replace_strmem.c:/: strcpy (mc_replace_strmem.c:/" |
|
||||
sed -e "s/: __GI_strncpy (mc_replace_strmem.c:/: strncpy (mc_replace_strmem.c:/"
|
||||
@ -1,8 +1,6 @@
|
||||
#! /bin/sh
|
||||
|
||||
# mc_replace_strmem.c [r]index and [__GI_]str[r]chr are the same.
|
||||
# vg_replace_strmem.c [r]index and [__GI_]str[r]chr are the same.
|
||||
./filter_stderr "$@" |
|
||||
sed -e "s/: __GI_strchr (mc_replace_strmem.c:/: strchr (mc_replace_strmem.c:/" |
|
||||
sed -e "s/: strchr (mc_replace_strmem.c:/: index (mc_replace_strmem.c:/" |
|
||||
sed -e "s/: __GI_strrchr (mc_replace_strmem.c:/: strrchr (mc_replace_strmem.c:/" |
|
||||
sed -e "s/: strrchr (mc_replace_strmem.c:/: rindex (mc_replace_strmem.c:/"
|
||||
sed -e "s/: strchr (vg_replace_strmem.c:/: index (vg_replace_strmem.c:/;
|
||||
s/: strrchr (vg_replace_strmem.c:/: rindex (vg_replace_strmem.c:/"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: memcmp (mc_replace_strmem.c:...)
|
||||
at 0x........: memcmp (vg_replace_strmem.c:...)
|
||||
by 0x........: main (memcmptest.c:13)
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: bcmp (mc_replace_strmem.c:...)
|
||||
at 0x........: bcmp (vg_replace_strmem.c:...)
|
||||
by 0x........: main (memcmptest.c:13)
|
||||
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
Source and destination overlap in memcpy(0x........, 0x........, 21)
|
||||
at 0x........: memcpy (mc_replace_strmem.c:...)
|
||||
at 0x........: memcpy (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:40)
|
||||
|
||||
Source and destination overlap in memcpy(0x........, 0x........, 21)
|
||||
at 0x........: memcpy (mc_replace_strmem.c:...)
|
||||
at 0x........: memcpy (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:42)
|
||||
|
||||
Source and destination overlap in strncpy(0x........, 0x........, 21)
|
||||
at 0x........: strncpy (mc_replace_strmem.c:...)
|
||||
at 0x........: strncpy (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:45)
|
||||
|
||||
Source and destination overlap in strncpy(0x........, 0x........, 21)
|
||||
at 0x........: strncpy (mc_replace_strmem.c:...)
|
||||
at 0x........: strncpy (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:47)
|
||||
|
||||
Source and destination overlap in strcpy(0x........, 0x........)
|
||||
at 0x........: strcpy (mc_replace_strmem.c:...)
|
||||
at 0x........: strcpy (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:54)
|
||||
|
||||
Source and destination overlap in strncat(0x........, 0x........, 21)
|
||||
at 0x........: strncat (mc_replace_strmem.c:...)
|
||||
at 0x........: strncat (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:112)
|
||||
|
||||
Source and destination overlap in strncat(0x........, 0x........, 21)
|
||||
at 0x........: strncat (mc_replace_strmem.c:...)
|
||||
at 0x........: strncat (vg_replace_strmem.c:...)
|
||||
by 0x........: main (overlap.c:113)
|
||||
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
prog: overlap
|
||||
vgopts: -q
|
||||
stderr_filter: filter_memcpy
|
||||
|
||||
@ -1,16 +1,12 @@
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: index (mc_replace_strmem.c:...)
|
||||
at 0x........: index (vg_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: index (mc_replace_strmem.c:...)
|
||||
at 0x........: index (vg_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: rindex (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:16)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: rindex (mc_replace_strmem.c:...)
|
||||
at 0x........: rindex (vg_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:16)
|
||||
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: strchr (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: strchr (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: strrchr (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:16)
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: index (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: index (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: rindex (mc_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:16)
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: __GI_strchr (mc_replace_strmem.c:...)
|
||||
at 0x........: strchr (vg_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: __GI_strchr (mc_replace_strmem.c:...)
|
||||
at 0x........: strchr (vg_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:15)
|
||||
|
||||
Conditional jump or move depends on uninitialised value(s)
|
||||
at 0x........: __GI_strrchr (mc_replace_strmem.c:...)
|
||||
at 0x........: strrchr (vg_replace_strmem.c:...)
|
||||
by 0x........: main (strchr.c:16)
|
||||
|
||||
|
||||
1835
shared/vg_replace_strmem.c
Normal file
1835
shared/vg_replace_strmem.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -42,6 +42,7 @@ my %tool_dirs = (
|
||||
"helgrind", => 1,
|
||||
"callgrind" => 1,
|
||||
"cachegrind" => 1,
|
||||
"shared" => 1,
|
||||
"exp-bbv" => 1,
|
||||
"exp-dhat" => 1,
|
||||
"exp-sgcheck" => 1
|
||||
|
||||
@ -47,6 +47,10 @@ sed "/warning: line info addresses out of order/d" |
|
||||
# complete list of messages in the bash source file siglist.c.
|
||||
perl -n -e 'print if !/^(Segmentation fault|Alarm clock|Aborted|Bus error)( \(core dumped\))?$/' |
|
||||
|
||||
# Translate intercepted glibc functions back to their canonical name
|
||||
perl -p -e "s/: memcpy\@\@?GLIBC_[.1-9]+ \(vg_replace_strmem.c:...\)/: memcpy \(vg_replace_strmem.c:...\)/" |
|
||||
sed -e "s/: \(__GI_\|__\|\)\(memcmp\|memcpy\|strcpy\|strncpy\|strchr\|strrchr\)\(\|_sse4_1\|_sse42\|_sse2_unaligned\) (vg_replace_strmem.c:/: \2 (vg_replace_strmem.c:/" |
|
||||
|
||||
# Remove any ": dumping core" message as the user might have a
|
||||
# limit set that prevents the core dump
|
||||
sed "s/\(signal [0-9]* (SIG[A-Z]*)\): dumping core/\1/" |
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user