Add some intercepts to make Ptrcheck usable-ish on Ubuntu 9.10 (amd64).


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11042 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-ptrcheck/h_intercepts.c b/exp-ptrcheck/h_intercepts.c
index 2b2cc19..1c5059c 100644
--- a/exp-ptrcheck/h_intercepts.c
+++ b/exp-ptrcheck/h_intercepts.c
@@ -45,6 +45,60 @@
    them in the same order as in mc_replace_strmem.c. */
 
 
+#define STRRCHR(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 ) \
+   { \
+      UChar  ch   = (UChar)((UInt)c); \
+      UChar* p    = (UChar*)s; \
+      UChar* last = NULL; \
+      while (True) { \
+         if (*p == ch) last = p; \
+         if (*p == 0) return last; \
+         p++; \
+      } \
+   }
+
+// Apparently rindex() is the same thing as strrchr()
+STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
+STRRCHR(VG_Z_LIBC_SONAME,   rindex)
+#if defined(VGO_linux)
+STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
+STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
+#elif defined(VGO_darwin)
+STRRCHR(VG_Z_DYLD,          strrchr)
+STRRCHR(VG_Z_DYLD,          rindex)
+#endif
+
+
+#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 ) \
+   { \
+      UChar  ch = (UChar)((UInt)c); \
+      UChar* p  = (UChar*)s; \
+      while (True) { \
+         if (*p == ch) return p; \
+         if (*p == 0) return NULL; \
+         p++; \
+      } \
+   }
+
+// Apparently index() is the same thing as strchr()
+STRCHR(VG_Z_LIBC_SONAME,          strchr)
+STRCHR(VG_Z_LIBC_SONAME,          index)
+#if defined(VGO_linux)
+STRCHR(VG_Z_LIBC_SONAME,          __GI_strchr)
+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_DYLD,                 strchr)
+STRCHR(VG_Z_DYLD,                 index)
+#endif
+
+
 #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 ) \
@@ -105,6 +159,24 @@
 #endif
 
 
+#define MEMCHR(soname, fnname) \
+   void* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const void *s, int c, SizeT n); \
+   void* VG_REPLACE_FUNCTION_ZU(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; \
+   }
+
+MEMCHR(VG_Z_LIBC_SONAME, memchr)
+#if defined(VGO_darwin)
+MEMCHR(VG_Z_DYLD,        memchr)
+#endif
+
+
 #define MEMCPY(soname, fnname) \
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
             ( void *dst, const void *src, SizeT sz ); \
@@ -173,6 +245,25 @@
 #endif
 
 
+/* Find the first occurrence of C in S.  */
+#define GLIBC232_RAWMEMCHR(soname, fnname) \
+   char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in); \
+   char* VG_REPLACE_FUNCTION_ZU(soname,fnname) (const char* s, int c_in) \
+   { \
+      unsigned char  c        = (unsigned char) c_in; \
+      unsigned char* char_ptr = (unsigned char *)s; \
+      while (1) { \
+         if (*char_ptr == c) return char_ptr; \
+         char_ptr++; \
+      } \
+   }
+
+GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, rawmemchr)
+#if defined (VGO_linux)
+GLIBC232_RAWMEMCHR(VG_Z_LIBC_SONAME, __GI___rawmemchr)
+#endif
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                          pc_intercepts.c ---*/
 /*--------------------------------------------------------------------*/