From: Julian Seward Date: Tue, 4 Nov 2014 17:44:21 +0000 (+0000) Subject: Adds initial support for AArch64 (arm64) on Android. Small programs X-Git-Tag: svn/VALGRIND_3_11_0~858 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b519f733071e9f6f991fbcd0162f0f7e2da77a43;p=thirdparty%2Fvalgrind.git 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 --- diff --git a/README.android b/README.android index 891dcb3078..01cd2fa217 100644 --- a/README.android +++ b/README.android @@ -3,8 +3,8 @@ How to cross-compile and run on Android. Please read to the end, 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 @@ mips32: 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 # Then cd to the root of your Valgrind source tree. @@ -76,6 +84,11 @@ export AR=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin 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 @@ CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips" \ --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 @@ CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips" \ # 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 @@ CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips" \ # 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 64e799c766..c7f486917f 100644 --- a/coregrind/launcher-linux.c +++ b/coregrind/launcher-linux.c @@ -239,7 +239,8 @@ static const char *select_platform(const char *clientname) } 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 36f6e37da0..17f4ab0db6 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 a40369b3c2..1f9ebed4a2 100644 --- a/coregrind/m_coredump/coredump-elf.c +++ b/coregrind/m_coredump/coredump-elf.c @@ -160,8 +160,10 @@ static UInt note_size(const struct note *n) + 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 @@ void dump_one_thread(struct note **notelist, const vki_siginfo_t *si, ThreadId t # 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 @@ void make_elf_coredump(ThreadId tid, const vki_siginfo_t *si, ULong max_size) 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 diff --git a/coregrind/m_debuginfo/readelf.c b/coregrind/m_debuginfo/readelf.c index a891e5749f..09cd033396 100644 --- a/coregrind/m_debuginfo/readelf.c +++ b/coregrind/m_debuginfo/readelf.c @@ -185,8 +185,8 @@ void show_raw_elf_symbol ( DiImage* strtab_img, 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 @@ Bool get_elf_symbol_info ( 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 238ab5779c..964e355bb7 100644 --- a/coregrind/m_initimg/initimg-linux.c +++ b/coregrind/m_initimg/initimg-linux.c @@ -635,7 +635,8 @@ Addr setup_client_stack( void* init_sp, 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 5765ba59e9..6c1d1bfa1c 100644 --- a/coregrind/m_options.c +++ b/coregrind/m_options.c @@ -47,8 +47,10 @@ VexControl VG_(clo_vex_control); 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 2d403ce8d1..8f7a4e0e84 100644 --- a/coregrind/m_redir.c +++ b/coregrind/m_redir.c @@ -1409,11 +1409,13 @@ void VG_(redir_initialise) ( void ) (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 37eeb12b71..060cb15a61 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 @@ static inline void my_exit ( int x ) /* 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 dc17d27cd2..40556afe2e 100644 --- a/coregrind/m_ume/main.c +++ b/coregrind/m_ume/main.c @@ -199,8 +199,10 @@ static Bool is_binary_file(const HChar* f) // 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 e9e3233d07..2c91cfabd4 100644 --- a/coregrind/pub_core_transtab.h +++ b/coregrind/pub_core_transtab.h @@ -71,7 +71,10 @@ extern void VG_(init_tt_tc) ( void ); 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 775f8b2c15..fbb2e285f9 100644 --- a/coregrind/vg_preloaded.c +++ b/coregrind/vg_preloaded.c @@ -57,8 +57,10 @@ void VG_NOTIFY_ON_LOAD(freeres)( void ); 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 160e6eebab..8aa70f6440 100644 --- a/coregrind/vgdb.c +++ b/coregrind/vgdb.c @@ -687,8 +687,10 @@ void received_signal (int signum) 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 4ef6286f5b..8f699db14d 100644 --- a/shared/vg_replace_strmem.c +++ b/shared/vg_replace_strmem.c @@ -145,7 +145,7 @@ __attribute__ ((__noreturn__)) 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 @@ static inline void my_exit ( int x ) 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 @@ static inline void my_exit ( int x ) } #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 @@ static inline void my_exit ( int x ) } #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 @@ static inline void my_exit ( int x ) } #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