mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
Add intercepts for strstr, strpbrk, strcspn. These are needed for
glibc-2.11 when running on SSE4-enabled (virtual) CPUs, for the usual reason: to avoid ultra-optimised routines using the SSE 4.2 PCMPxSTRx instructions. I would not be surprised if it turned out that strspn was required, but I haven't seen a need for it so far. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11268
This commit is contained in:
parent
ebe90cdda2
commit
9a8dd3161a
@ -867,6 +867,123 @@ GLIBC25_MEMPCPY(VG_Z_LD_SO_1, mempcpy) /* ld.so.1 */
|
||||
GLIBC26___MEMCPY_CHK(VG_Z_LIBC_SONAME, __memcpy_chk)
|
||||
|
||||
|
||||
#define STRSTR(soname, fnname) \
|
||||
void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
(void* haystack, void* needle); \
|
||||
void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
(void* haystack, void* needle) \
|
||||
{ \
|
||||
UChar* h = (UChar*)haystack; \
|
||||
UChar* n = (UChar*)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 h; \
|
||||
\
|
||||
/* assert(nlen >= 1); */ \
|
||||
UChar n0 = n[0]; \
|
||||
\
|
||||
while (1) { \
|
||||
UChar 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 h; \
|
||||
\
|
||||
h++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRSTR(VG_Z_LIBC_SONAME, strstr)
|
||||
#endif
|
||||
|
||||
|
||||
#define STRPBRK(soname, fnname) \
|
||||
void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
(void* sV, void* acceptV); \
|
||||
void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
(void* sV, void* acceptV) \
|
||||
{ \
|
||||
UChar* s = (UChar*)sV; \
|
||||
UChar* accept = (UChar*)acceptV; \
|
||||
\
|
||||
/* find the length of 'accept', not including terminating zero */ \
|
||||
UWord nacc = 0; \
|
||||
while (accept[nacc]) nacc++; \
|
||||
\
|
||||
/* if n is the empty string, fail immediately. */ \
|
||||
if (nacc == 0) return NULL; \
|
||||
\
|
||||
/* assert(nacc >= 1); */ \
|
||||
while (1) { \
|
||||
UWord i; \
|
||||
UChar sc = *s; \
|
||||
if (sc == 0) \
|
||||
break; \
|
||||
for (i = 0; i < nacc; i++) { \
|
||||
if (sc == accept[i]) \
|
||||
return s; \
|
||||
} \
|
||||
s++; \
|
||||
} \
|
||||
\
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRPBRK(VG_Z_LIBC_SONAME, strpbrk)
|
||||
#endif
|
||||
|
||||
|
||||
#define STRCSPN(soname, fnname) \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
(void* sV, void* rejectV); \
|
||||
SizeT VG_REPLACE_FUNCTION_ZU(soname,fnname) \
|
||||
(void* sV, void* rejectV) \
|
||||
{ \
|
||||
UChar* s = (UChar*)sV; \
|
||||
UChar* reject = (UChar*)rejectV; \
|
||||
\
|
||||
/* find the length of 'reject', not including terminating zero */ \
|
||||
UWord nrej = 0; \
|
||||
while (reject[nrej]) nrej++; \
|
||||
\
|
||||
UWord len = 0; \
|
||||
while (1) { \
|
||||
UWord i; \
|
||||
UChar sc = *s; \
|
||||
if (sc == 0) \
|
||||
break; \
|
||||
for (i = 0; i < nrej; i++) { \
|
||||
if (sc == reject[i]) \
|
||||
break; \
|
||||
} \
|
||||
/* assert(i >= 0 && i <= nrej); */ \
|
||||
if (i < nrej) \
|
||||
break; \
|
||||
s++; \
|
||||
len++; \
|
||||
} \
|
||||
\
|
||||
return len; \
|
||||
}
|
||||
|
||||
#if defined(VGO_linux)
|
||||
STRCSPN(VG_Z_LIBC_SONAME, strcspn)
|
||||
#endif
|
||||
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
/*--- Improve definedness checking of process environment ---*/
|
||||
/*------------------------------------------------------------*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user