Adds initial support for AArch64 (arm64) on Android.  Small programs
(/system/bin/ls, /system/bin/date) run.  Still to do:

* enable more malloc/free intercepts

* enable wrappers for ashmem and binder syscalls

* check to see if any special ioctl support is required for ARM Mali GPUs



git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14690 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/README.android b/README.android
index 891dcb3..01cd2fa 100644
--- a/README.android
+++ b/README.android
@@ -3,8 +3,8 @@
 since there are important details further down regarding crash
 avoidance and GPU support.
 
-These notes were last updated on 3 Sept 2014, for Valgrind SVN
-revision 14439/2941.
+These notes were last updated on 4 Nov 2014, for Valgrind SVN
+revision 14689/2987.
 
 These instructions are known to work, or have worked at some time in
 the past, for:
@@ -25,29 +25,37 @@
   Android 4.3   running on android mips emulator.
   Android 4.0.4 running on BROADCOM bcm7425
 
+arm64:
+  Android 4.5 (?) running on ARM Juno
+
 On android-arm, GDBserver might insert breaks at wrong addresses.
 Feedback on this welcome.
 
 Other configurations and toolchains might work, but haven't been tested.
 Feedback is welcome.
 
+Toolchain:
 
-You need the android-ndk-r6 native development kit.  r6b and r7
-give a non-completely-working build; see
-http://code.google.com/p/android/issues/detail?id=23203
-For the android emulator, the versions needed and how to
-install them are described in README.android_emulator.
+  For arm32, x86 and mips32 you need the android-ndk-r6 native
+    development kit.  r6b and r7 give a non-completely-working build;
+    see http://code.google.com/p/android/issues/detail?id=23203
+    For the android emulator, the versions needed and how to install
+    them are described in README.android_emulator.
 
-You can get android-ndk-r6 from
-http://dl.google.com/android/ndk/android-ndk-r6-linux-x86.tar.bz2
-Install it somewhere.  Doesn't matter where.  Then:
+    You can get android-ndk-r6 from
+    http://dl.google.com/android/ndk/android-ndk-r6-linux-x86.tar.bz2
+
+  For arm64 (aarch64) you need the android-ndk-r10c NDK, from
+    http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin
+
+Install the NDK somewhere.  Doesn't matter where.  Then:
 
 
 # Modify this (obviously).  Note, this "export" command is only done
 # so as to reduce the amount of typing required.  None of the commands
 # below read it as part of their operation.
 #
-export NDKROOT=/path/to/android-ndk-r6
+export NDKROOT=/path/to/android-ndk-r<version>
 
 
 # Then cd to the root of your Valgrind source tree.
@@ -76,6 +84,11 @@
 export LD=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin/mipsel-linux-android-ld
 export CC=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin/mipsel-linux-android-gcc
 
+# For ARM64 (AArch64)
+export AR=$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar 
+export LD=$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-ld
+export CC=$NDKROOT/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-gcc
+
 
 # Do configuration stuff.  Don't mess with the --prefix in the
 # configure command below, even if you think it's wrong.
@@ -110,6 +123,13 @@
    --host=mipsel-linux-android --target=mipsel-linux-android \
    --with-tmpdir=/sdcard
 
+# for ARM64 (AArch64)
+CPPFLAGS="--sysroot=$NDKROOT/platforms/android-21/arch-arm64" \
+   CFLAGS="--sysroot=$NDKROOT/platforms/android-21/arch-arm64" \
+   ./configure --prefix=/data/local/Inst \
+   --host=aarch64-unknown-linux --target=aarch64-unknown-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:
@@ -126,6 +146,10 @@
 #          Platform variant: android
 #     Primary -DVGPV string: -DVGPV_mips32_linux_android=1
 #
+# For ARM64 (AArch64):
+#          Platform variant: android
+#     Primary -DVGPV string: -DVGPV_arm64_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
 # which won't work.
@@ -133,8 +157,8 @@
 
 # Build, and park the install tree in `pwd`/Inst
 #
-make -j2
-make -j2 install DESTDIR=`pwd`/Inst
+make -j4
+make -j4 install DESTDIR=`pwd`/Inst
 
 
 # To get the install tree onto the device:
diff --git a/coregrind/launcher-linux.c b/coregrind/launcher-linux.c
index 64e799c..c7f4869 100644
--- a/coregrind/launcher-linux.c
+++ b/coregrind/launcher-linux.c
@@ -239,7 +239,8 @@
          } else if (header[EI_DATA] == ELFDATA2MSB) {
 #           if !defined(VGPV_arm_linux_android) \
                && !defined(VGPV_x86_linux_android) \
-               && !defined(VGPV_mips32_linux_android)
+               && !defined(VGPV_mips32_linux_android) \
+               && !defined(VGPV_arm64_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_aspacemgr/aspacemgr-linux.c b/coregrind/m_aspacemgr/aspacemgr-linux.c
index 36f6e37..17f4ab0 100644
--- a/coregrind/m_aspacemgr/aspacemgr-linux.c
+++ b/coregrind/m_aspacemgr/aspacemgr-linux.c
@@ -270,7 +270,10 @@
 /* Max number of segments we can track.  On Android, virtual address
    space is limited, so keep a low limit -- 5000 x sizef(NSegment) is
    360KB. */
-#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
+#if defined(VGPV_arm_linux_android) \
+    || defined(VGPV_x86_linux_android) \
+    || defined(VGPV_mips32_linux_android) \
+    || defined(VGPV_arm64_linux_android)
 # define VG_N_SEGMENTS 5000
 #else
 # define VG_N_SEGMENTS 30000
@@ -278,7 +281,10 @@
 
 /* Max number of segment file names we can track.  These are big (1002
    bytes) so on Android limit the space usage to ~1MB. */
-#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
+#if defined(VGPV_arm_linux_android) \
+    || defined(VGPV_x86_linux_android) \
+    || defined(VGPV_mips32_linux_android) \
+    || defined(VGPV_arm64_linux_android)
 # define VG_N_SEGNAMES 1000
 #else
 # define VG_N_SEGNAMES 6000
diff --git a/coregrind/m_coredump/coredump-elf.c b/coregrind/m_coredump/coredump-elf.c
index a40369b..1f9ebed 100644
--- a/coregrind/m_coredump/coredump-elf.c
+++ b/coregrind/m_coredump/coredump-elf.c
@@ -160,8 +160,10 @@
                             + VG_ROUNDUP(n->note.n_descsz, 4);
 }
 
-#if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-    && !defined(VGPV_mips32_linux_android)
+#if !defined(VGPV_arm_linux_android) \
+    && !defined(VGPV_x86_linux_android) \
+    && !defined(VGPV_mips32_linux_android) \
+    && !defined(VGPV_arm64_linux_android)
 static void add_note(struct note **list, const HChar *name, UInt type,
                      const void *data, UInt datasz)
 {
@@ -559,14 +561,18 @@
 #     endif
 
       fill_fpu(&VG_(threads)[tid], &fpu);
-#     if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-         && !defined(VGPV_mips32_linux_android)
+#     if !defined(VGPV_arm_linux_android) \
+         && !defined(VGPV_x86_linux_android) \
+         && !defined(VGPV_mips32_linux_android) \
+         && !defined(VGPV_arm64_linux_android)
       add_note(notelist, "CORE", NT_FPREGSET, &fpu, sizeof(fpu));
 #     endif
 
       fill_prstatus(&VG_(threads)[tid], &prstatus, si);
-#     if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-         && !defined(VGPV_mips32_linux_android)
+#     if !defined(VGPV_arm_linux_android) \
+         && !defined(VGPV_x86_linux_android) \
+         && !defined(VGPV_mips32_linux_android) \
+         && !defined(VGPV_arm64_linux_android)
       add_note(notelist, "CORE", NT_PRSTATUS, &prstatus, sizeof(prstatus));
 #     endif
 }
@@ -668,8 +674,10 @@
    dump_one_thread(&notelist, si, tid);
 
    fill_prpsinfo(&VG_(threads)[tid], &prpsinfo);
-#  if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-      && !defined(VGPV_mips32_linux_android)
+#  if !defined(VGPV_arm_linux_android) \
+      && !defined(VGPV_x86_linux_android) \
+      && !defined(VGPV_mips32_linux_android) \
+      && !defined(VGPV_arm64_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 a891e57..09cd033 100644
--- a/coregrind/m_debuginfo/readelf.c
+++ b/coregrind/m_debuginfo/readelf.c
@@ -185,8 +185,8 @@
    HChar* sym_name = NULL;
    if (sym->st_name)
       sym_name = ML_(img_strdup)(strtab_img, "di.sres.1", sym_name_ioff);
-   VG_(printf)(": svma %#010lx, %ssz %4ld  %s\n",
-               sym_svma, space, sym->st_size + 0UL,
+   VG_(printf)(": svma %#010lx, %ssz %4llu  %s\n",
+               sym_svma, space, (ULong)(sym->st_size + 0UL),
                (sym_name ? sym_name : "NONAME") ); 
    if (sym_name)
       ML_(dinfo_free)(sym_name);
@@ -420,7 +420,10 @@
       in /system/bin/linker:  __dl_strcmp __dl_strlen
    */
    if (*sym_size_out == 0) {
-#     if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
+#     if defined(VGPV_arm_linux_android) \
+         || defined(VGPV_x86_linux_android) \
+         || defined(VGPV_mips32_linux_android) \
+         || defined(VGPV_arm64_linux_android)
       *sym_size_out = 2048;
 #     else
       if (TRACE_SYMTAB_ENABLED) {
diff --git a/coregrind/m_initimg/initimg-linux.c b/coregrind/m_initimg/initimg-linux.c
index 238ab57..964e355 100644
--- a/coregrind/m_initimg/initimg-linux.c
+++ b/coregrind/m_initimg/initimg-linux.c
@@ -635,7 +635,8 @@
          case AT_CLKTCK:
 #        if !defined(VGPV_arm_linux_android) \
             && !defined(VGPV_x86_linux_android) \
-            && !defined(VGPV_mips32_linux_android)
+            && !defined(VGPV_mips32_linux_android) \
+            && !defined(VGPV_arm64_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 5765ba5..6c1d1bf 100644
--- a/coregrind/m_options.c
+++ b/coregrind/m_options.c
@@ -47,8 +47,10 @@
 Bool   VG_(clo_error_limit)    = True;
 Int    VG_(clo_error_exitcode) = 0;
 
-#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
-    || defined(VGPV_mips32_linux_android)
+#if defined(VGPV_arm_linux_android) \
+    || defined(VGPV_x86_linux_android) \
+    || defined(VGPV_mips32_linux_android) \
+    || defined(VGPV_arm64_linux_android)
 VgVgdb VG_(clo_vgdb)           = Vg_VgdbNo; // currently disabled on Android
 #else
 VgVgdb VG_(clo_vgdb)           = Vg_VgdbYes;
diff --git a/coregrind/m_redir.c b/coregrind/m_redir.c
index 2d403ce..8f7a4e0 100644
--- a/coregrind/m_redir.c
+++ b/coregrind/m_redir.c
@@ -1409,11 +1409,13 @@
          (Addr)&VG_(arm64_linux_REDIR_FOR_strcmp),
          NULL 
       );
-      //add_hardwired_spec(
-      //   "ld-linux.so.3", "memcpy",
-      //   (Addr)&VG_(arm_linux_REDIR_FOR_memcpy),
-      //   complain_about_stripped_glibc_ldso
-      //);
+#     if defined(VGPV_arm64_linux_android)
+      add_hardwired_spec(
+         "NONE", "__dl_strlen", // in /system/bin/linker64
+         (Addr)&VG_(arm64_linux_REDIR_FOR_strlen),
+         NULL
+      );
+#     endif
    }
 
 #  elif defined(VGP_x86_darwin)
diff --git a/coregrind/m_replacemalloc/vg_replace_malloc.c b/coregrind/m_replacemalloc/vg_replace_malloc.c
index 37eeb12..060cb15 100644
--- a/coregrind/m_replacemalloc/vg_replace_malloc.c
+++ b/coregrind/m_replacemalloc/vg_replace_malloc.c
@@ -122,7 +122,8 @@
 __attribute__ ((__noreturn__))
 static inline void my_exit ( int x )
 {
-#  if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android)
+#  if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
+      || defined(VGPV_arm64_linux_android)
    __asm__ __volatile__(".word 0xFFFFFFFF");
    while (1) {}
 #  elif defined(VGPV_x86_linux_android)
@@ -137,8 +138,10 @@
 /* Same problem with getpagesize. */
 static inline int my_getpagesize ( void )
 {
-#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
-      || defined(VGPV_mips32_linux_android)
+#  if defined(VGPV_arm_linux_android) \
+      || defined(VGPV_x86_linux_android) \
+      || defined(VGPV_mips32_linux_android) \
+      || defined(VGPV_arm64_linux_android)
    return 4096; /* kludge - link failure on Android, for some reason */
 #  else
    extern int getpagesize (void);
diff --git a/coregrind/m_ume/main.c b/coregrind/m_ume/main.c
index dc17d27..40556af 100644
--- a/coregrind/m_ume/main.c
+++ b/coregrind/m_ume/main.c
@@ -199,8 +199,10 @@
 // will refuse to (eg. scripts lacking a "#!" prefix).
 static Int do_exec_shell_followup(Int ret, const HChar* exe_name, ExeInfo* info)
 {
-#  if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
-      || defined(VGPV_mips32_linux_android)
+#  if defined(VGPV_arm_linux_android) \
+      || defined(VGPV_x86_linux_android) \
+      || defined(VGPV_mips32_linux_android) \
+      || defined(VGPV_arm64_linux_android)
    const HChar*  default_interp_name = "/system/bin/sh";
 #  else
    const HChar*  default_interp_name = "/bin/sh";
diff --git a/coregrind/pub_core_transtab.h b/coregrind/pub_core_transtab.h
index e9e3233..2c91cfa 100644
--- a/coregrind/pub_core_transtab.h
+++ b/coregrind/pub_core_transtab.h
@@ -71,7 +71,10 @@
    On other platforms we can go to town.  16 sectors gives theoretical
    capacity of about 440MB of JITted code in 1.05 million translations
    (realistically, about 2/3 of that) for Memcheck. */
-#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
+#if defined(VGPV_arm_linux_android) \
+    || defined(VGPV_x86_linux_android) \
+    || defined(VGPV_mips32_linux_android) \
+    || defined(VGPV_arm64_linux_android)
 # define N_SECTORS_DEFAULT 6
 #else
 # define N_SECTORS_DEFAULT 16
diff --git a/coregrind/vg_preloaded.c b/coregrind/vg_preloaded.c
index 775f8b2..fbb2e28 100644
--- a/coregrind/vg_preloaded.c
+++ b/coregrind/vg_preloaded.c
@@ -57,8 +57,10 @@
 void VG_NOTIFY_ON_LOAD(freeres)( void )
 {
 #  if !defined(__UCLIBC__) \
-   && !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-   && !defined(VGPV_mips32_linux_android)
+      && !defined(VGPV_arm_linux_android) \
+      && !defined(VGPV_x86_linux_android) \
+      && !defined(VGPV_mips32_linux_android) \
+      && !defined(VGPV_arm64_linux_android)
    extern void __libc_freeres(void);
    __libc_freeres();
 #  endif
diff --git a/coregrind/vgdb.c b/coregrind/vgdb.c
index 160e6ee..8aa70f6 100644
--- a/coregrind/vgdb.c
+++ b/coregrind/vgdb.c
@@ -687,8 +687,10 @@
       sigpipe++;
    } else if (signum == SIGALRM) {
       sigalrm++;
-#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
-    || defined(VGPV_mips32_linux_android)
+#if defined(VGPV_arm_linux_android) \
+    || defined(VGPV_x86_linux_android) \
+    || defined(VGPV_mips32_linux_android) \
+    || defined(VGPV_arm64_linux_android)
       /* Android has no pthread_cancel. As it also does not have
          an invoker implementation, there is no need for cleanup action.
          So, we just do nothing. */
diff --git a/shared/vg_replace_strmem.c b/shared/vg_replace_strmem.c
index 4ef6286..8f699db 100644
--- a/shared/vg_replace_strmem.c
+++ b/shared/vg_replace_strmem.c
@@ -145,7 +145,7 @@
 static inline void my_exit ( int x )
 {
 #  if defined(VGPV_arm_linux_android) || defined(VGPV_mips32_linux_android) \
-      || defined(VGPV_mips32_linux_android)
+      || defined(VGPV_arm64_linux_android)
    __asm__ __volatile__(".word 0xFFFFFFFF");
    while (1) {}
 #  elif defined(VGPV_x86_linux_android)
@@ -419,7 +419,8 @@
  STRLEN(VG_Z_LIBC_SONAME,          __strlen_sse42)
  STRLEN(VG_Z_LD_LINUX_SO_2,        strlen)
  STRLEN(VG_Z_LD_LINUX_X86_64_SO_2, strlen)
-# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
+# if defined(VGPV_arm_linux_android) \
+     || defined(VGPV_x86_linux_android) \
      || defined(VGPV_mips32_linux_android)
   STRLEN(NONE, __dl_strlen); /* in /system/bin/linker */
 # endif
@@ -610,8 +611,10 @@
    }
 
 #if defined(VGO_linux)
-# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-     && !defined(VGPV_mips32_linux_android)
+# if !defined(VGPV_arm_linux_android) \
+     && !defined(VGPV_x86_linux_android) \
+     && !defined(VGPV_mips32_linux_android) \
+     && !defined(VGPV_arm64_linux_android)
   STRCASECMP(VG_Z_LIBC_SONAME, strcasecmp)
   STRCASECMP(VG_Z_LIBC_SONAME, __GI_strcasecmp)
 # endif
@@ -648,8 +651,10 @@
    }
 
 #if defined(VGO_linux)
-# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-     && !defined(VGPV_mips32_linux_android)
+# if !defined(VGPV_arm_linux_android) \
+     && !defined(VGPV_x86_linux_android) \
+     && !defined(VGPV_mips32_linux_android) \
+     && !defined(VGPV_arm64_linux_android)
   STRNCASECMP(VG_Z_LIBC_SONAME, strncasecmp)
   STRNCASECMP(VG_Z_LIBC_SONAME, __GI_strncasecmp)
 # endif
@@ -1632,8 +1637,10 @@
    }
 
 #if defined(VGO_linux)
-# if !defined(VGPV_arm_linux_android) && !defined(VGPV_x86_linux_android) \
-     && !defined(VGPV_mips32_linux_android)
+# if !defined(VGPV_arm_linux_android) \
+     && !defined(VGPV_x86_linux_android) \
+     && !defined(VGPV_mips32_linux_android) \
+     && !defined(VGPV_arm64_linux_android)
   STRCASESTR(VG_Z_LIBC_SONAME,      strcasestr)
 # endif