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:
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:
+
+ 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
-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 arm64 (aarch64) you need the android-ndk-r10c NDK, from
+ http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin
-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:
+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.
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.
--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:
# 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.
# 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:
} 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)) {
/* 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
/* 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
+ 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)
{
# 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
}
dump_one_thread(¬elist, 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(¬elist, "CORE", NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo));
# endif
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);
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) {
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
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;
(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)
__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)
/* 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);
// 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";
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
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
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. */
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)
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
}
#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
}
#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
}
#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