]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Add intercepts for strstr, strpbrk, strcspn. These are needed for
authorJulian Seward <jseward@acm.org>
Thu, 19 Aug 2010 13:22:34 +0000 (13:22 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 19 Aug 2010 13:22:34 +0000 (13:22 +0000)
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

memcheck/mc_replace_strmem.c

index e7cae0494e2f36ec960337371f378fa86a09a1c7..f928769dfba477e7c83f4a1ba34c6a1f4df703f7 100644 (file)
@@ -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  ---*/
 /*------------------------------------------------------------*/