301265 - add x86 support to Android build 

Patch by Dragos Tatulea.



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12835 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/Makefile.all.am b/Makefile.all.am
index bcca5ff..66bd414 100644
--- a/Makefile.all.am
+++ b/Makefile.all.am
@@ -198,6 +198,13 @@
 PRELOAD_LDFLAGS_COMMON_LINUX  = -nodefaultlibs -shared -Wl,-z,interpose,-z,initfirst
 PRELOAD_LDFLAGS_COMMON_DARWIN = -dynamic -dynamiclib -all_load
 
+if VGCONF_PLATVARIANT_IS_ANDROID
+# The Android toolchain includes all kinds of stdlib helpers present in
+# bionic which is bad because we are not linking with it and the Android
+# linker will panic.
+PRELOAD_LDFLAGS_COMMON_LINUX += -nostdlib
+endif
+
 PRELOAD_LDFLAGS_X86_LINUX    = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@
 PRELOAD_LDFLAGS_AMD64_LINUX  = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M64@
 PRELOAD_LDFLAGS_PPC32_LINUX  = $(PRELOAD_LDFLAGS_COMMON_LINUX) @FLAG_M32@
diff --git a/NEWS b/NEWS
index 136afc9..be48dea 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,8 @@
   Memcheck, massif, lackey, callgrind and none are tools that have been
   tested and are known to work well. See README.mips for more details.
 
+* Preliminary support for x86 platform running Android.
+
 * ==================== TOOL CHANGES ====================
 
 * Massif
@@ -261,6 +263,7 @@
 300414  FCOM and FCOMP unimplemented for amd64 guest
 301204  infinite loop in canonicaliseSymtab with ifunc symbol
 301229  dup of 203877, see above.
+301265  add x86 support to Android build 
 301984  configure script doesn't detect certain versions of clang
 302205  Fix compiler warnings for POWER VEX code and POWER test cases
 302287  Unhandled movbe instruction on Atom processors
diff --git a/README.android b/README.android
index 397a01d..fd06c59 100644
--- a/README.android
+++ b/README.android
@@ -3,13 +3,18 @@
 17 Feb 2012, for Valgrind SVN revision 12390/2257.
 
 This is known to work at least for :
+ARM:
+####
   Android 4.0.3 running on a (rooted, AOSP build) Nexus S.
   Android 4.0.3 running on Motorola Xoom.
-  Android 4.0.3 running on android emulator.
+  Android 4.0.3 running on android arm emulator.
   Android 4.1   running on android emulator.
-
 Android 2.3.4 on Nexus S worked at some time in the past.
 
+x86:
+####
+  Android 4.0.3 running on android x86 emulator.
+
 On android, GDBserver might insert breaks at wrong addresses.
 Feedback on this welcome.
 
@@ -43,7 +48,7 @@
 # So choose one of the below:
 #
 export HWKIND=nexus_s         # Samsung Nexus S; also Xoom (for now)
-export HWKIND=pandaboard      # Pandaboard running Linaro Android
+export HWKIND=generic         # A generic Android device. eg, Pandaboard
 export HWKIND=emulator        # Android emulator
 
 # Then cd to the root of your Valgrind source tree.
@@ -57,10 +62,18 @@
 
 # Set up toolchain paths.
 #
+For ARM
+#######
 export AR=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar
 export LD=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ld
 export CC=$NDKROOT/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-gcc
 
+For x86
+#######
+export AR=$NDKROOT/toolchains/x86-4.4.3/prebuilt/linux-x86/bin/i686-android-linux-ar
+export LD=$NDKROOT/toolchains/x86-4.4.3/prebuilt/linux-x86/bin/i686-android-linux-ld
+export CC=$NDKROOT/toolchains/x86-4.4.3/prebuilt/linux-x86/bin/i686-android-linux-gcc
+
 
 # Do configuration stuff.  Don't mess with the --prefix in the
 # configure command below, even if you think it's wrong.
@@ -70,6 +83,7 @@
 
 ./autogen.sh
 
+# for ARM
 CPPFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm -DANDROID_HARDWARE_$HWKIND" \
    CFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm" \
    ./configure --prefix=/data/local/Inst \
@@ -78,11 +92,21 @@
 # note: on android emulator, android-14 platform was also tested and works.
 # It is not clear what this platform nr really is.
 
+# for x86
+CPPFLAGS="--sysroot=$NDKROOT/platforms/android-9/arch-x86 -DANDROID_HARDWARE_$HWKIND" \
+   CFLAGS="--sysroot=$NDKROOT/platforms/android-9/arch-x86 -fno-pic" \
+   ./configure --prefix=/data/local/Inst \
+   --host=i686-android-linux --target=i686-android-linux \
+   --with-tmpdir=/sdcard
+
 # At the end of the configure run, a few lines of details
 # are printed.  Make sure that you see these two lines:
-#
+# For ARM:
 #          Platform variant: android
 #     Primary -DVGPV string: -DVGPV_arm_linux_android=1
+# For x86:
+#          Platform variant: android
+#     Primary -DVGPV string: -DVGPV_x86_linux_android=1
 #
 # If you see anything else at this point, something is wrong, and
 # either the build will fail, or will succeed but you'll get something
diff --git a/auxprogs/Makefile.am b/auxprogs/Makefile.am
index c336b27..074d8f6 100644
--- a/auxprogs/Makefile.am
+++ b/auxprogs/Makefile.am
@@ -31,6 +31,9 @@
 valgrind_listener_CFLAGS    = $(AM_CFLAGS_PRI)
 valgrind_listener_CCASFLAGS = $(AM_CCASFLAGS_PRI)
 valgrind_listener_LDFLAGS   = $(AM_CFLAGS_PRI)
+if VGCONF_PLATVARIANT_IS_ANDROID
+valgrind_listener_CFLAGS    += -static
+endif
 if VGCONF_PLATFORMS_INCLUDE_X86_DARWIN
 valgrind_listener_LDFLAGS   += -Wl,-read_only_relocs -Wl,suppress
 endif
diff --git a/configure.in b/configure.in
index 2ba2b00..ed39ca4 100644
--- a/configure.in
+++ b/configure.in
@@ -944,10 +944,10 @@
 
 # Normally the PLAT = (ARCH, OS) characterisation of the platform is enough.
 # But there are times where we need a bit more control.  The motivating
-# and currently only case is Android: this is almost identical to arm-linux,
-# but not quite.  So this introduces the concept of platform variant tags,
-# which get passed in the compile as -DVGPV_<arch>_<os>_<variant> along
-# with the main -DVGP_<arch>_<os> definition.
+# and currently only case is Android: this is almost identical to
+# {x86,arm}-linux, but not quite.  So this introduces the concept of platform
+# variant tags, which get passed in the compile as -DVGPV_<arch>_<os>_<variant>
+# along with the main -DVGP_<arch>_<os> definition.
 #
 # In almost all cases, the <variant> bit is "vanilla".  But for Android
 # it is "android" instead.
@@ -960,15 +960,14 @@
 #
 #   -DVGP_arm_linux -DVGPV_arm_linux_android
 #
-# The setup of the platform variant is pushed relatively far down this
-# file in order that we can inspect any of the variables set above.
+# Same for x86. The setup of the platform variant is pushed relatively far
+# down this file in order that we can inspect any of the variables set above.
 
 # In the normal case ..
 VGCONF_PLATVARIANT="vanilla"
 
-# Android on ARM ?
-if test "$VGCONF_ARCH_PRI-$VGCONF_OS" = "arm-linux" \
-        -a "$GLIBC_VERSION" = "bionic";
+# Android ?
+if test "$GLIBC_VERSION" = "bionic";
 then
    VGCONF_PLATVARIANT="android"
 fi
diff --git a/coregrind/Makefile.am b/coregrind/Makefile.am
index 0d44da6..01015a7 100644
--- a/coregrind/Makefile.am
+++ b/coregrind/Makefile.am
@@ -53,17 +53,19 @@
 valgrind_LDFLAGS   += -Wl,-read_only_relocs -Wl,suppress
 endif
 # On Android we must ask for non-executable stack, not sure why.
-if VGCONF_PLATFORMS_INCLUDE_ARM_LINUX
 if VGCONF_PLATVARIANT_IS_ANDROID
+valgrind_CFLAGS += -static
 valgrind_LDFLAGS   += -Wl,-z,noexecstack
 endif
-endif
 
 vgdb_SOURCES = vgdb.c
 vgdb_CPPFLAGS  = $(AM_CPPFLAGS_PRI)
 vgdb_CFLAGS    = $(AM_CFLAGS_PRI)
 vgdb_CCASFLAGS = $(AM_CCASFLAGS_PRI)
 vgdb_LDFLAGS   = $(AM_CFLAGS_PRI)
+if VGCONF_PLATVARIANT_IS_ANDROID
+vgdb_CFLAGS    += -static
+endif
 if !VGCONF_PLATVARIANT_IS_ANDROID
 vgdb_LDADD     = -lpthread
 endif
diff --git a/coregrind/launcher-linux.c b/coregrind/launcher-linux.c
index a9ad1e3..45fcf26 100644
--- a/coregrind/launcher-linux.c
+++ b/coregrind/launcher-linux.c
@@ -210,7 +210,7 @@
                platform = "amd64-linux";
             }
          } else if (header[EI_DATA] == ELFDATA2MSB) {
-#           if !defined(VGPV_arm_linux_android)
+#           if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
             if (ehdr->e_machine == EM_PPC64 &&
                 (ehdr->e_ident[EI_OSABI] == ELFOSABI_SYSV ||
                  ehdr->e_ident[EI_OSABI] == ELFOSABI_LINUX)) {
diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c
index ddfe2ba..8a329a6 100644
--- a/coregrind/m_coredump/coredump-elf.c
+++ b/coregrind/m_coredump/coredump-elf.c
@@ -136,7 +136,7 @@
    phdr->p_align = VKI_PAGE_SIZE;
 }
 
-#if defined(VGPV_arm_linux_android)
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
 /* Android's libc doesn't provide a definition for this.  Hence: */
 typedef
    struct {
@@ -159,7 +159,7 @@
                             + VG_ROUNDUP(n->note.n_descsz, 4);
 }
 
-#if !defined(VGPV_arm_linux_android)
+#if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
 static void add_note(struct note **list, const Char *name, UInt type,
                      const void *data, UInt datasz)
 {
@@ -181,7 +181,7 @@
    VG_(memcpy)(n->name, name, namelen);
    VG_(memcpy)(n->name+VG_ROUNDUP(namelen,4), data, datasz);
 }
-#endif /* !defined(VGPV_arm_linux_android) */
+#endif /* !defined(VGPV_*_linux_android) */
 
 static void write_note(Int fd, const struct note *n)
 {
@@ -476,7 +476,7 @@
 #endif
 }
 
-#if defined(VGP_x86_linux)
+#if defined(VGP_x86_linux) && !defined(VGPV_x86_linux_android)
 static void fill_xfpu(const ThreadState *tst, vki_elf_fpxregset_t *xfpu)
 {
    ThreadArchState* arch = (ThreadArchState*)&tst->arch;
@@ -589,26 +589,28 @@
 	 continue;
 
 #     if defined(VGP_x86_linux)
+#     if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
       {
          vki_elf_fpxregset_t xfpu;
          fill_xfpu(&VG_(threads)[i], &xfpu);
          add_note(&notelist, "LINUX", NT_PRXFPREG, &xfpu, sizeof(xfpu));
       }
 #     endif
+#     endif
 
       fill_fpu(&VG_(threads)[i], &fpu);
-#     if !defined(VGPV_arm_linux_android)
+#     if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
       add_note(&notelist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu));
 #     endif
 
       fill_prstatus(&VG_(threads)[i], &prstatus, si);
-#     if !defined(VGPV_arm_linux_android)
+#     if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
       add_note(&notelist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus));
 #     endif
    }
 
    fill_prpsinfo(&VG_(threads)[tid], &prpsinfo);
-#  if !defined(VGPV_arm_linux_android)
+#  if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
    add_note(&notelist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
 #  endif
 
diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c
index dc0b21c..998e0fe 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -385,7 +385,7 @@
       in /system/bin/linker:  __dl_strcmp __dl_strlen
    */
    if (sym->st_size == 0) {
-#     if defined(VGPV_arm_linux_android)
+#     if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
       *sym_size_out = 2048;
 #     else
       TRACE_SYMTAB("    ignore -- size=0: %s\n", sym_name);
@@ -1120,7 +1120,7 @@
 {
    vg_assert(*dimage == 0 && *n_dimage == 0);
 
-#  if !defined(VGPV_arm_linux_android)
+#  if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
    return False; /* we don't know narfink */
 
 #  else /* android specific hacks; look away now. */
@@ -2659,7 +2659,8 @@
 #     if !defined(VGP_amd64_linux) \
          && !defined(VGP_s390x_linux) \
          && !defined(VGP_ppc64_linux) \
-         && !defined(VGPV_arm_linux_android)
+         && !defined(VGPV_arm_linux_android) \
+         && !defined(VGPV_x86_linux_android)
       if (stab_img && stabstr_img) {
          ML_(read_debuginfo_stabs) ( di, stab_img, stab_sz, 
                                          stabstr_img, stabstr_sz );
diff --git a/coregrind/m_debuginfo/readstabs.c b/coregrind/m_debuginfo/readstabs.c
index e62721b..d1d7440 100644
--- a/coregrind/m_debuginfo/readstabs.c
+++ b/coregrind/m_debuginfo/readstabs.c
@@ -35,8 +35,9 @@
 */
 
 /* "on Linux (except android), or on Darwin" */
-#if (defined(VGO_linux) && !defined(VGPV_arm_linux_android)) \
-    || defined(VGO_darwin)
+#if (defined(VGO_linux) && \
+    !(defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)) \
+    || defined(VGO_darwin))
 
 #include "pub_core_basics.h"
 #include "pub_core_debuginfo.h"
@@ -388,7 +389,7 @@
    }
 }
 
-#endif /* (defined(VGO_linux) && !defined(VGPV_arm_linux_android)) \
+#endif /* (defined(VGO_linux) && !defined(VGPV_*_linux_android)) \
           || defined(VGO_darwin) */
 
 /*--------------------------------------------------------------------*/
diff --git a/coregrind/m_debuglog.c b/coregrind/m_debuglog.c
index 8e1c032..88c3a64 100644
--- a/coregrind/m_debuglog.c
+++ b/coregrind/m_debuglog.c
@@ -76,12 +76,14 @@
    Int result;
 
    __asm__ volatile (
+      "pushl %%ebx\n"
       "movl  $"VG_STRINGIFY(__NR_write)", %%eax\n" /* %eax = __NR_write */
       "movl  $2, %%ebx\n"       /* %ebx = stderr */
       "int   $0x80\n"           /* write(stderr, buf, n) */
+      "popl %%ebx\n"
       : /*wr*/    "=a" (result)
       : /*rd*/    "c" (buf), "d" (n)
-      : /*trash*/ "ebx", "edi", "memory", "cc"
+      : /*trash*/ "edi", "memory", "cc"
    );
 
    return result >= 0 ? result : -1;
diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c
index dd68d6b..132bdd7 100644
--- a/coregrind/m_initimg/initimg-linux.c
+++ b/coregrind/m_initimg/initimg-linux.c
@@ -643,7 +643,7 @@
          case AT_GID:
          case AT_EGID:
          case AT_CLKTCK:
-#        if !defined(VGPV_arm_linux_android)
+#        if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
          case AT_FPUCW: /* missing on android */
 #        endif
             /* All these are pointerless, so we don't need to do
diff --git a/coregrind/m_options.c b/coregrind/m_options.c
index 4c3282f..a19b4f7 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -47,7 +47,7 @@
 Bool   VG_(clo_error_limit)    = True;
 Int    VG_(clo_error_exitcode) = 0;
 
-#if defined(VGPV_arm_linux_android)
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
 VgVgdb VG_(clo_vgdb)           = Vg_VgdbNo; // currently disabled on Android
 #else
 VgVgdb VG_(clo_vgdb)           = Vg_VgdbYes;
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index bec413a..17d9a96 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -119,6 +119,9 @@
 #  if defined(VGPV_arm_linux_android)
    __asm__ __volatile__(".word 0xFFFFFFFF");
    while (1) {}
+#  elif defined(VGPV_x86_linux_android)
+   __asm__ __volatile__("ud2");
+   while (1) {}
 #  else
    extern __attribute__ ((__noreturn__)) void _exit(int status);
    _exit(x);
@@ -128,7 +131,7 @@
 /* Same problem with getpagesize. */
 static inline int my_getpagesize ( void )
 {
-#  if defined(VGPV_arm_linux_android)
+#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    return 4096; /* kludge - link failure on Android, for some reason */
 #  else
    extern int getpagesize (void);
@@ -904,7 +907,7 @@
  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_usable_size);
  MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, malloc_size);
  MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    malloc_size);
-# if defined(VGPV_arm_linux_android)
+# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
   MALLOC_USABLE_SIZE(VG_Z_LIBC_SONAME, dlmalloc_usable_size);
   MALLOC_USABLE_SIZE(SO_SYN_MALLOC,    dlmalloc_usable_size);
 # endif
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 64cacbe..eafbed4 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -223,13 +223,15 @@
          assembler. */
 #if defined(VGP_x86_linux)
       asm volatile (
+         "pushl %%ebx\n"
          "movl	%1, %0\n"	/* set tst->status = VgTs_Empty */
          "movl	%2, %%eax\n"    /* set %eax = __NR_exit */
          "movl	%3, %%ebx\n"    /* set %ebx = tst->os_state.exitcode */
          "int	$0x80\n"	/* exit(tst->os_state.exitcode) */
+	 "popl %%ebx\n"
          : "=m" (tst->status)
          : "n" (VgTs_Empty), "n" (__NR_exit), "m" (tst->os_state.exitcode)
-         : "eax", "ebx"
+         : "eax"
       );
 #elif defined(VGP_amd64_linux)
       asm volatile (
@@ -5379,7 +5381,7 @@
       /* These just take an int by value */
       break;
 
-#  if defined(VGPV_arm_linux_android)
+#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    /* ashmem */
    case VKI_ASHMEM_GET_SIZE:
    case VKI_ASHMEM_SET_SIZE:
@@ -5445,7 +5447,7 @@
            PRE_FIELD_WRITE("ioctl(BINDER_VERSION)", bv->protocol_version);
        }
        break;
-#  endif /* defined(VGPV_arm_linux_android) */
+#  endif /* defined(VGPV_*_linux_android) */
 
    case VKI_HCIINQUIRY:
       if (ARG3) {
@@ -5505,7 +5507,7 @@
 
    /* --- BEGIN special IOCTL handlers for specific Android hardware --- */
 
-#  if defined(VGPV_arm_linux_android)
+#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
 
 #  if defined(ANDROID_HARDWARE_nexus_s)
 
@@ -5567,18 +5569,11 @@
    /* END Nexus S specific ioctls */
 
 
-#  elif defined(ANDROID_HARDWARE_pandaboard)
+#  elif defined(ANDROID_HARDWARE_generic) || defined(ANDROID_HARDWARE_emulator)
 
-   /* BEGIN Pandaboard specific ioctls */
+   /* BEGIN generic/emulator specific ioctls */
    /* currently none are known */
-   /* END Pandaboard specific ioctls */
-
-
-#  elif defined(ANDROID_HARDWARE_emulator)
-
-   /* BEGIN emulator specific ioctls */
-   /* currently none are known */
-   /* END emulator specific ioctls */
+   /* END generic/emulator specific ioctls */
 
 
 #  else /* no ANDROID_HARDWARE_anything defined */
@@ -5589,7 +5584,8 @@
 #   warning "building for.  Currently known values are"
 #   warning ""
 #   warning "   ANDROID_HARDWARE_nexus_s       Samsung Nexus S"
-#   warning "   ANDROID_HARDWARE_pandaboard    Pandaboard running Linaro Android"
+#   warning "   ANDROID_HARDWARE_generic       Generic device (eg, Pandaboard)"
+#   warning "   ANDROID_HARDWARE_emulator      x86 or arm emulator"
 #   warning ""
 #   warning "Make sure you exactly follow the steps in README.android."
 #   warning ""
@@ -5597,7 +5593,7 @@
 
 #  endif /* cases for ANDROID_HARDWARE_blah */
 
-#  endif /* defined(VGPV_arm_linux_android) */
+#  endif /* defined(VGPV_*_linux_android) */
 
    /* --- END special IOCTL handlers for specific Android hardware --- */
 
@@ -6408,7 +6404,7 @@
       }
       break;
 
-#  if defined(VGPV_arm_linux_android)
+#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    /* ashmem */
    case VKI_ASHMEM_GET_SIZE:
    case VKI_ASHMEM_SET_SIZE:
@@ -6449,7 +6445,7 @@
            POST_FIELD_WRITE(bv->protocol_version);
        }
        break;
-#  endif /* defined(VGPV_arm_linux_android) */
+#  endif /* defined(VGPV_*_linux_android) */
 
    case VKI_HCIINQUIRY:
       if (ARG3) {
diff --git a/coregrind/m_ume/main.c b/coregrind/m_ume/main.c
index 1250182..6eca0a7 100644
--- a/coregrind/m_ume/main.c
+++ b/coregrind/m_ume/main.c
@@ -199,7 +199,7 @@
 // will refuse to (eg. scripts lacking a "#!" prefix).
 static Int do_exec_shell_followup(Int ret, HChar* exe_name, ExeInfo* info)
 {
-#  if defined(VGPV_arm_linux_android)
+#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
    Char*  default_interp_name = "/system/bin/sh";
 #  else
    Char*  default_interp_name = "/bin/sh";
diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c
index 03038ac..1973291 100644
--- a/coregrind/vg_preloaded.c
+++ b/coregrind/vg_preloaded.c
@@ -56,7 +56,8 @@
 void VG_NOTIFY_ON_LOAD(freeres)( void );
 void VG_NOTIFY_ON_LOAD(freeres)( void )
 {
-#  if !defined(__UCLIBC__) && !defined(VGPV_arm_linux_android)
+#  if !defined(__UCLIBC__) \
+   && !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
    extern void __libc_freeres(void);
    __libc_freeres();
 #  endif
@@ -89,27 +90,6 @@
     return (void*)result;
 }
 
-#if defined(ANDROID_HARDWARE_emulator)
-/* When running on android emulator, we get the following error when doing
-     ./valgrind date
-
-   link_image[1921]:   494 could not load needed library
-   '/data/local/Inst/lib/valgrind/vgpreload_core-arm-linux.so' for 'date'
-   (reloc_library[1285]:   494 cannot locate '__cxa_finalize'...
-   )CANNOT LINK EXECUTABLE
-
-   This problem is bypassed by adding the below function.
-   Do not ask me to explain neither the problem nor the solution.
-*/
-extern void __cxa_finalize(void);
-void __cxa_finalize(void)
-{
-   // ??? what should we do here ? Silently do nothing looks not sane.
-   // So, try to crash:
-   *(volatile int *)0 = 'x';
-}
-#endif
-
 #elif defined(VGO_darwin)
 
 #include "config.h" /* VERSION */
diff --git a/coregrind/vgdb.c b/coregrind/vgdb.c
index 8a4f58a..9ed59a5 100644
--- a/coregrind/vgdb.c
+++ b/coregrind/vgdb.c
@@ -94,7 +94,7 @@
 #undef PTRACEINVOKER
 #endif
 
-#if defined(VGPV_arm_linux_android)
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
 #undef PTRACEINVOKER
 #endif
 
@@ -1634,7 +1634,7 @@
       sigpipe++;
    } else if (signum == SIGALRM) {
       sigalrm++;
-#if defined(VGPV_arm_linux_android)
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
       /* Android has no pthread_cancel. As it also does not have
          PTRACE_INVOKER, there is no need for cleanup action.
          So, we just do nothing. */
diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h
index 0a54db0..ccf0635 100644
--- a/include/vki/vki-linux.h
+++ b/include/vki/vki-linux.h
@@ -2844,7 +2844,7 @@
 // From kernel/common/include/linux/ashmem.h
 //----------------------------------------------------------------------
 
-#if defined(VGPV_arm_linux_android)
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
 
 #define VKI_ASHMEM_NAME_LEN 256
 
@@ -2899,7 +2899,7 @@
 #define VKI_BINDER_THREAD_EXIT _VKI_IOW('b', 8, int)
 #define VKI_BINDER_VERSION _VKI_IOWR('b', 9, struct vki_binder_version)
 
-#endif /* defined(VGPV_arm_linux_android) */
+#endif /* defined(VGPV_*_linux_android) */
 
 //----------------------------------------------------------------------
 // From linux-3.0.4/include/net/bluetooth/bluetooth.h
diff --git a/memcheck/mc_replace_strmem.c b/memcheck/mc_replace_strmem.c
index 649c7e9..485ec49 100644
--- a/memcheck/mc_replace_strmem.c
+++ b/memcheck/mc_replace_strmem.c
@@ -142,6 +142,9 @@
 #  if defined(VGPV_arm_linux_android)
    __asm__ __volatile__(".word 0xFFFFFFFF");
    while (1) {}
+#  elif defined(VGPV_x86_linux_android)
+   __asm__ __volatile__("ud2");
+   while (1) {}
 #  else
    extern __attribute__ ((__noreturn__)) void _exit(int status);
    _exit(x);
@@ -179,6 +182,9 @@
  STRRCHR(VG_Z_LIBC_SONAME,   rindex)
  STRRCHR(VG_Z_LIBC_SONAME,   __GI_strrchr)
  STRRCHR(VG_Z_LD_LINUX_SO_2, rindex)
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
+  STRRCHR(NONE, __dl_strrchr); /* in /system/bin/linker */
+#endif
 
 #elif defined(VGO_darwin)
  //STRRCHR(VG_Z_LIBC_SONAME,   strrchr)
@@ -391,7 +397,7 @@
 #if defined(VGO_linux)
  STRLEN(VG_Z_LIBC_SONAME,          strlen)
  STRLEN(VG_Z_LIBC_SONAME,          __GI_strlen)
-# if defined(VGPV_arm_linux_android)
+# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
   STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
 # endif
 
@@ -502,6 +508,10 @@
 
 #if defined(VGO_linux)
 
+#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
+ STRLCPY(VG_Z_LIBC_SONAME, strlcpy);
+#endif
+
 #elif defined(VGO_darwin)
  //STRLCPY(VG_Z_LIBC_SONAME, strlcpy)
  //STRLCPY(VG_Z_DYLD,        strlcpy)
@@ -568,7 +578,7 @@
    }
 
 #if defined(VGO_linux)
-# if !defined(VGPV_arm_linux_android)
+# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
   STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
   STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
 # endif
@@ -605,7 +615,7 @@
    }
 
 #if defined(VGO_linux)
-# if !defined(VGPV_arm_linux_android)
+# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
   STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
   STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
 # endif
@@ -715,7 +725,7 @@
  STRCMP(VG_Z_LIBC_SONAME,          __GI_strcmp)
  STRCMP(VG_Z_LD_LINUX_X86_64_SO_2, strcmp)
  STRCMP(VG_Z_LD64_SO_1,            strcmp)
-# if defined(VGPV_arm_linux_android)
+# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
   STRCMP(NONE, __dl_strcmp); /* in /system/bin/linker */
 # endif
 
@@ -1524,7 +1534,7 @@
    }
 
 #if defined(VGO_linux)
-# if !defined(VGPV_arm_linux_android)
+# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android)
   STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
 # endif