Implement internal_memmove.
authorAlexander Potapenko <glider@google.com>
Mon, 15 Oct 2012 15:34:41 +0000 (15:34 +0000)
committerAlexander Potapenko <glider@google.com>
Mon, 15 Oct 2012 15:34:41 +0000 (15:34 +0000)
Use internal_memmove() and internal_memcpy() in the memcpy() and memmove() wrappers
when building the dynamic runtime (OS X only), to work around a bug in resolver functions wrapping.
See also http://code.google.com/p/address-sanitizer/issues/detail?id=116

llvm-svn: 165939

compiler-rt/lib/asan/asan_interceptors.cc
compiler-rt/lib/sanitizer_common/sanitizer_libc.cc
compiler-rt/lib/sanitizer_common/sanitizer_libc.h

index 1c94cae..1fec3b6 100644 (file)
@@ -239,7 +239,13 @@ INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {
     ASAN_WRITE_RANGE(from, size);
     ASAN_READ_RANGE(to, size);
   }
+#if MAC_INTERPOSE_FUNCTIONS
+  // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8.
+  // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116.
+  return internal_memcpy(to, from, size);
+#else
   return REAL(memcpy)(to, from, size);
+#endif
 }
 
 INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
@@ -254,7 +260,13 @@ INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
     ASAN_WRITE_RANGE(from, size);
     ASAN_READ_RANGE(to, size);
   }
+#if MAC_INTERPOSE_FUNCTIONS
+  // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8.
+  // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116.
+  return internal_memmove(to, from, size);
+#else
   return REAL(memmove)(to, from, size);
+#endif
 }
 
 INTERCEPTOR(void*, memset, void *block, int c, uptr size) {
index 6fa05e4..a1d9528 100644 (file)
@@ -44,6 +44,22 @@ void *internal_memcpy(void *dest, const void *src, uptr n) {
   return dest;
 }
 
+void *internal_memmove(void *dest, const void *src, uptr n) {
+  char *d = (char*)dest;
+  char *s = (char*)src;
+  uptr i;
+  if (d < s) {
+    for (i = 0; i < n; ++i)
+      d[i] = s[i];
+  } else {
+    if (d > s && n > 0)
+      for (i = n - 1; i > 0 ; --i) {
+       d[i] = s[i];
+      }
+  }
+  return dest;
+}
+
 void *internal_memset(void* s, int c, uptr n) {
   // The next line prevents Clang from making a call to memset() instead of the
   // loop below.
index b1bac7b..ec0b061 100644 (file)
@@ -29,6 +29,7 @@ s64 internal_atoll(const char *nptr);
 void *internal_memchr(const void *s, int c, uptr n);
 int internal_memcmp(const void* s1, const void* s2, uptr n);
 void *internal_memcpy(void *dest, const void *src, uptr n);
+void *internal_memmove(void *dest, const void *src, uptr n);
 // Should not be used in performance-critical places.
 void *internal_memset(void *s, int c, uptr n);
 char* internal_strchr(const char *s, int c);