Fix up preload code so that on Android it doesn't try to call anything
else -- that seems to give a runtime link failure.  In particular,
avoid calling _exit, getpagesize or __libc_freeres.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11887 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index 26a4d01..647cdfd 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -83,8 +83,31 @@
    executable too.
 */
 
+
+
+/* Call here to exit if we can't continue.  On Android we can't call
+   _exit for some reason, so we have to blunt-instrument it. */
 __attribute__ ((__noreturn__))
-extern void _exit(int);
+static inline void my_exit ( int x )
+{
+#  if defined(VGPV_arm_linux_android)
+   __asm__ __volatile__(".word 0xFFFFFFFF");
+   while (1) {}
+#  else
+   extern void _exit(int status);
+   _exit(x)
+#  endif
+}
+
+/* Same problem with getpagesize. */
+static inline int my_getpagesize ( void ) {
+#  if defined(VGPV_arm_linux_android)
+   return 4096; /* kludge - link failure on Android, for some reason */
+#  else
+   extern int getpagesize (void);
+   return getpagesize();
+#  endif
+}
 
 
 /* Compute the high word of the double-length unsigned product of U
@@ -199,7 +222,7 @@
             "new/new[] failed and should throw an exception, but Valgrind\n"); \
          VALGRIND_PRINTF_BACKTRACE( \
             "   cannot throw exceptions and so is aborting instead.  Sorry.\n"); \
-            _exit(1); \
+            my_exit(1); \
       } \
       return v; \
    }
@@ -524,11 +547,6 @@
 
 /*---------------------- valloc ----------------------*/
 
-static int local__getpagesize ( void ) {
-   extern int getpagesize (void);
-   return getpagesize();
-}
-
 #define VALLOC(soname, fnname) \
    \
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( SizeT size ); \
@@ -536,7 +554,7 @@
    { \
       static int pszB = 0; \
       if (pszB == 0) \
-         pszB = local__getpagesize(); \
+         pszB = my_getpagesize(); \
       return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
                 ((SizeT)pszB, size); \
    }
@@ -547,9 +565,8 @@
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) ( void *zone, SizeT size )  \
    { \
       static int pszB = 0; \
-      extern int getpagesize (void); \
       if (pszB == 0) \
-         pszB = getpagesize(); \
+         pszB = my_getpagesize(); \
       return VG_REPLACE_FUNCTION_ZU(VG_Z_LIBC_SONAME,memalign) \
                 ((SizeT)pszB, size); \
    }
@@ -674,7 +691,7 @@
 static void panic(const char *str)
 {
    VALGRIND_PRINTF_BACKTRACE("Program aborting because of call to %s\n", str);
-   _exit(99);
+   my_exit(99);
    *(volatile int *)0 = 'x';
 }
 
diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c
index baee203..169bb72 100644
--- a/coregrind/vg_preloaded.c
+++ b/coregrind/vg_preloaded.c
@@ -56,10 +56,10 @@
 void VG_NOTIFY_ON_LOAD(freeres)( void );
 void VG_NOTIFY_ON_LOAD(freeres)( void )
 {
-#if !defined(__UCLIBC__)
+#  if !defined(__UCLIBC__) && !defined(VGPV_arm_linux_android)
    extern void __libc_freeres(void);
    __libc_freeres();
-#endif
+#  endif
    VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default */,
                                    VG_USERREQ__LIBC_FREERES_DONE, 
                                    0, 0, 0, 0, 0);
diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c
index 17ea205..250d2de 100644
--- a/memcheck/mc_replace_strmem.c
+++ b/memcheck/mc_replace_strmem.c
@@ -53,6 +53,7 @@
    THEY RUN ON THE SIMD CPU!
    ------------------------------------------------------------------ */
 
+
 /* Figure out if [dst .. dst+dstlen-1] overlaps with 
                  [src .. src+srclen-1].
    We assume that the address ranges do not wrap around
@@ -60,7 +61,7 @@
    are not accessible and the program will segfault in this
    circumstance, presumably).
 */
-static __inline__
+static inline
 Bool is_overlap ( void* dst, const void* src, SizeT dstlen, SizeT srclen )
 {
    Addr loS, hiS, loD, hiD;
@@ -87,6 +88,22 @@
    }
 }
 
+
+/* Call here to exit if we can't continue.  On Android we can't call
+   _exit for some reason, so we have to blunt-instrument it. */
+__attribute__ ((__noreturn__))
+static inline void my_exit ( int x )
+{
+#  if defined(VGPV_arm_linux_android)
+   __asm__ __volatile__(".word 0xFFFFFFFF");
+   while (1) {}
+#  else
+   extern void _exit(int status);
+   _exit(x)
+#  endif
+}
+
+
 // This is a macro rather than a function because we don't want to have an
 // extra function in the stack trace.
 #define RECORD_OVERLAP_ERROR(s, src, dst, len)                  \
@@ -421,8 +438,10 @@
       return 0; \
    }
 
+#if !defined(VGPV_arm_linux_android)
 STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
-#if defined(VGO_linux)
+#endif
+#if defined(VGO_linux) && !defined(VGPV_arm_linux_android)
 STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
 #endif
 
@@ -448,8 +467,10 @@
       } \
    }
 
+#if !defined(VGPV_arm_linux_android)
 STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
-#if defined(VGO_linux)
+#endif
+#if defined(VGO_linux) && !defined(VGPV_arm_linux_android)
 STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
 #elif defined(VGO_darwin)
 STRNCASECMP(VG_Z_DYLD,        strncasecmp)
@@ -799,7 +820,6 @@
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
             (void *dstV, const void *srcV, SizeT n, SizeT destlen) \
    { \
-      extern void _exit(int status); \
       SizeT i; \
       Char* dst = (Char*)dstV; \
       Char* src = (Char*)srcV; \
@@ -819,7 +839,7 @@
       VALGRIND_PRINTF_BACKTRACE( \
          "*** memmove_chk: buffer overflow detected ***: " \
          "program terminated\n"); \
-     _exit(127); \
+     my_exit(127); \
      /*NOTREACHED*/ \
      return NULL; \
    }
@@ -870,7 +890,6 @@
    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
                                (char* dst, const char* src, SizeT len) \
    { \
-      extern void _exit(int status); \
       char* ret = dst; \
       if (! len) \
          goto badness; \
@@ -882,7 +901,7 @@
       VALGRIND_PRINTF_BACKTRACE( \
          "*** strcpy_chk: buffer overflow detected ***: " \
          "program terminated\n"); \
-     _exit(127); \
+     my_exit(127); \
      /*NOTREACHED*/ \
      return NULL; \
    }
@@ -898,7 +917,6 @@
    char* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
                                (char* dst, const char* src, SizeT len) \
    { \
-      extern void _exit(int status); \
       if (! len) \
          goto badness; \
       while ((*dst++ = *src++) != '\0') \
@@ -909,7 +927,7 @@
       VALGRIND_PRINTF_BACKTRACE( \
          "*** stpcpy_chk: buffer overflow detected ***: " \
          "program terminated\n"); \
-     _exit(127); \
+     my_exit(127); \
      /*NOTREACHED*/ \
      return NULL; \
    }
@@ -962,7 +980,6 @@
    void* VG_REPLACE_FUNCTION_ZU(soname,fnname) \
             (void* dst, const void* src, SizeT len, SizeT dstlen ) \
    { \
-      extern void _exit(int status); \
       register char *d; \
       register char *s; \
       \
@@ -992,7 +1009,7 @@
       VALGRIND_PRINTF_BACKTRACE( \
          "*** memcpy_chk: buffer overflow detected ***: " \
          "program terminated\n"); \
-     _exit(127); \
+     my_exit(127); \
      /*NOTREACHED*/ \
      return NULL; \
    }