]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
drd: Add strchr(), strcpy(), strcmp() and memcpy() intercepts (#326436)
authorBart Van Assche <bvanassche@acm.org>
Wed, 23 Oct 2013 12:19:30 +0000 (12:19 +0000)
committerBart Van Assche <bvanassche@acm.org>
Wed, 23 Oct 2013 12:19:30 +0000 (12:19 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@13679

drd/drd_strmem_intercepts.c

index 3d4a64f7784099ca41abd8b208df8996d1deaa1d..ad57c6d0fb44a891dd3f35026acfec29aaf40a11 100644 (file)
 #include "pub_tool_clreq.h"
 
 
+#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
+
+
 #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 ) \
  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
+
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/