Intercept strstr, required on SSE4 capable Linux targets.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11271 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-ptrcheck/h_intercepts.c b/exp-ptrcheck/h_intercepts.c
index 0e23e07..caabcd3 100644
--- a/exp-ptrcheck/h_intercepts.c
+++ b/exp-ptrcheck/h_intercepts.c
@@ -314,6 +314,48 @@
 #endif
 
 
+#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
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                          pc_intercepts.c ---*/
 /*--------------------------------------------------------------------*/