From: Julian Seward Date: Wed, 3 Sep 2014 15:19:25 +0000 (+0000) Subject: Improvements for Android: X-Git-Tag: svn/VALGRIND_3_10_0~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7e3f04874a74015a3ca3b804996cfa9897f556d1;p=thirdparty%2Fvalgrind.git Improvements for Android: * All Linux targets: add minimal ioctl support for the ION_IOC family * Android targets: change proprietary-ioctl support for GPUs from being a build-time #define kludge to being controlled by --kernel-variant, as it should be. Update documentation accordingly. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@14440 --- diff --git a/NEWS b/NEWS index 1cadd24d16..8cf94130b9 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,9 @@ significantly improved relative to the 3.9.0 release. * Both 32- and 64-bit executables are supported on MacOSX 10.8 and 10.9. +* Configuration for and running on Android targets has changed. + See README.android in the source tree for details. + * ================== DEPRECATED FEATURES ================= * --db-attach is now deprecated and will be removed in the next diff --git a/README.android b/README.android index cebe2cd9ba..891dcb3078 100644 --- a/README.android +++ b/README.android @@ -1,9 +1,15 @@ -How to cross-compile for Android. These notes were last updated on -17 Feb 2012, for Valgrind SVN revision 12390/2257. +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. -This is known to work at least for : -ARM: +These notes were last updated on 3 Sept 2014, for Valgrind SVN +revision 14439/2941. + +These instructions are known to work, or have worked at some time in +the past, 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 arm emulator. @@ -34,7 +40,7 @@ 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 do this: +Install it somewhere. Doesn't matter where. Then: # Modify this (obviously). Note, this "export" command is only done @@ -44,25 +50,12 @@ Install it somewhere. Doesn't matter where. Then do this: export NDKROOT=/path/to/android-ndk-r6 -# Modify this too. Tell the build system which Android hardware you -# are building for. It needs to know this so it can compile in -# support for the right Android-hw-specific ioctls. (sigh.) As with -# NDKROOT above, this is merely to avoid repeated typing; none of the -# commands read it. -# -# Currently the supported values are: nexus_s pandaboard -# So choose one of the below: -# -export HWKIND=nexus_s # Samsung Nexus S; also Xoom (for now) -export HWKIND=generic # A generic Android device. eg, Pandaboard -export HWKIND=emulator # Android emulator - # Then cd to the root of your Valgrind source tree. # cd /path/to/valgrind/source/tree -# After this point, you don't need to modify anything; just copy and +# After this point, you don't need to modify anything. Just copy and # paste the commands below. @@ -83,6 +76,7 @@ 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 + # Do configuration stuff. Don't mess with the --prefix in the # configure command below, even if you think it's wrong. # You may need to set the --with-tmpdir path to something @@ -94,7 +88,7 @@ export CC=$NDKROOT/toolchains/mipsel-linux-android-4.8/prebuilt/linux-x86_64/bin ./autogen.sh # for ARM -CPPFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm -DANDROID_HARDWARE_$HWKIND" \ +CPPFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm" \ CFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm" \ ./configure --prefix=/data/local/Inst \ --host=armv7-unknown-linux --target=armv7-unknown-linux \ @@ -103,19 +97,20 @@ CPPFLAGS="--sysroot=$NDKROOT/platforms/android-3/arch-arm -DANDROID_HARDWARE_$HW # It is not clear what this platform nr really is. # for x86 -CPPFLAGS="--sysroot=$NDKROOT/platforms/android-9/arch-x86 -DANDROID_HARDWARE_$HWKIND" \ +CPPFLAGS="--sysroot=$NDKROOT/platforms/android-9/arch-x86" \ 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 # for MIPS32 -CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips -DANDROID_HARDWARE_$HWKIND" \ +CPPFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips" \ CFLAGS="--sysroot=$NDKROOT/platforms/android-18/arch-mips" \ ./configure --prefix=/data/local/Inst \ --host=mipsel-linux-android --target=mipsel-linux-android \ --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: # @@ -148,8 +143,26 @@ make -j2 install DESTDIR=`pwd`/Inst # adb push Inst / -# To run (on the device) -/data/local/Inst/bin/valgrind [the usual args etc] + +# To run (on the device). There are two things you need to consider: +# +# (1) if you are running on the Android emulator, Valgrind may crash +# at startup. This is because the emulator (for ARM) may not be +# simulating a hardware TLS register. To get around this, run +# Valgrind with: +# --kernel-variant=android-emulator-no-hw-tls +# +# (2) if you are running a real device, you need to tell Valgrind +# what GPU it has, so Valgrind knows how to handle custom GPU +# ioctls. You can choose one of the following: +# --kernel-variant=android-gpu-sgx5xx # PowerVR SGX 5XX series +# --kernel-variant=android-gpu-adreno3xx # Qualcomm Adreno 3XX series +# If you don't choose one, the program will still run, but Memcheck +# may report false errors after the program performs GPU-specific ioctls. +# +# Anyway: to run on the device: +# +/data/local/Inst/bin/valgrind [kernel variant args] [the usual args etc] # Once you're up and running, a handy modify-V-rebuild-reinstall diff --git a/README.android_emulator b/README.android_emulator index 754895965d..f2ed598736 100644 --- a/README.android_emulator +++ b/README.android_emulator @@ -61,6 +61,14 @@ adb shell adb push Inst / +# IMPORTANT: when running Valgrind, you may need give it the flag +# +# --kernel-variant=android-emulator-no-hw-tls +# +# since otherwise it may crash at startup. +# See README.android for details. + + # if you need to debug: # You have on the android side a gdbserver # on the device side: diff --git a/coregrind/m_main.c b/coregrind/m_main.c index a15d55fe8a..7aa8746252 100644 --- a/coregrind/m_main.c +++ b/coregrind/m_main.c @@ -179,9 +179,11 @@ static void usage_NORETURN ( Bool debug_help ) " where hint is one of lax-ioctls fuse-compatible enable-outer\n" " no-inner-prefix no-nptl-pthread-stackcache none\n" " --fair-sched=no|yes|try schedule threads fairly on multicore systems [no]\n" -" --kernel-variant=variant1,variant2,... handle non-standard kernel" - " variants [none]\n" -" where variant is one of bproc none\n" +" --kernel-variant=variant1,variant2,...\n" +" handle non-standard kernel variants [none]\n" +" where variant is one of:\n" +" bproc android-emulator-no-hw-tls\n" +" android-gpu-sgx5xx android-gpu-adreno3xx none\n" " --merge-recursive-frames= merge frames between identical\n" " program counters in max frames) [0]\n" " --num-transtab-sectors= size of translated code cache [%d]\n" @@ -627,7 +629,11 @@ void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd, VG_(clo_smc_check), Vg_SmcAllNonFile); - else if VG_USETX_CLO (arg, "--kernel-variant", "bproc", + else if VG_USETX_CLO (arg, "--kernel-variant", + "bproc," + "android-emulator-no-hw-tls," + "android-gpu-sgx5xx," + "android-gpu-adreno3xx", VG_(clo_kernel_variant)) {} else if VG_BOOL_CLO(arg, "--dsymutil", VG_(clo_dsymutil)) {} diff --git a/coregrind/m_syswrap/syswrap-arm-linux.c b/coregrind/m_syswrap/syswrap-arm-linux.c index b91edcc2c0..18c86676d2 100644 --- a/coregrind/m_syswrap/syswrap-arm-linux.c +++ b/coregrind/m_syswrap/syswrap-arm-linux.c @@ -280,41 +280,43 @@ static void assign_guest_tls(ThreadId tid, Addr tlsptr) static SysRes sys_set_tls ( ThreadId tid, Addr tlsptr ) { assign_guest_tls(tid, tlsptr); -#if defined(ANDROID_HARDWARE_emulator) - /* Android emulator does not provide an hw tls register. - So, the tls register is emulated by the kernel. - This emulated value is set by the __NR_ARM_set_tls syscall. - The emulated value must be read by the kernel helper function - located at 0xffff0fe0. + + if (KernelVariantiS(KernelVariant_android_emulator_no_hw_tls, + VG_(clo_kernel_variant))) { + /* Android emulator does not provide an hw tls register. + So, the tls register is emulated by the kernel. + This emulated value is set by the __NR_ARM_set_tls syscall. + The emulated value must be read by the kernel helper function + located at 0xffff0fe0. - The emulated tlsptr is located at 0xffff0ff0 - (so slightly after the kernel helper function). - Note that applications are not supposed to read this directly. + The emulated tlsptr is located at 0xffff0ff0 + (so slightly after the kernel helper function). + Note that applications are not supposed to read this directly. - For compatibility : if there is a hw tls register, the kernel - will put at 0xffff0fe0 the instructions to read it, so - as to have old applications calling the kernel helper - working properly. - - For having emulated guest TLS working correctly with - Valgrind, it is needed to execute the syscall to set - the emulated TLS value in addition to the assignment - of TPIDRURO. - - Note: the below means that if we need thread local storage - for Valgrind host, then there will be a conflict between - the need of the guest tls and of the host tls. - If all the guest code would cleanly call 0xffff0fe0, - then we might maybe intercept this. However, at least - __libc_preinit reads directly 0xffff0ff0. - */ - /* ??? might call the below if auxv->u.a_val & VKI_HWCAP_TLS ??? - Unclear if real hardware having tls hw register sets - VKI_HWCAP_TLS. */ - return VG_(do_syscall1) (__NR_ARM_set_tls, tlsptr); -#else - return VG_(mk_SysRes_Success)( 0 ); -#endif + For compatibility : if there is a hw tls register, the kernel + will put at 0xffff0fe0 the instructions to read it, so + as to have old applications calling the kernel helper + working properly. + + For having emulated guest TLS working correctly with + Valgrind, it is needed to execute the syscall to set + the emulated TLS value in addition to the assignment + of TPIDRURO. + + Note: the below means that if we need thread local storage + for Valgrind host, then there will be a conflict between + the need of the guest tls and of the host tls. + If all the guest code would cleanly call 0xffff0fe0, + then we might maybe intercept this. However, at least + __libc_preinit reads directly 0xffff0ff0. + */ + /* ??? might call the below if auxv->u.a_val & VKI_HWCAP_TLS ??? + Unclear if real hardware having tls hw register sets + VKI_HWCAP_TLS. */ + return VG_(do_syscall1) (__NR_ARM_set_tls, tlsptr); + } else { + return VG_(mk_SysRes_Success)( 0 ); + } } /* --------------------------------------------------------------------- diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c index 3b3218d518..a4b64a8572 100644 --- a/coregrind/m_syswrap/syswrap-linux.c +++ b/coregrind/m_syswrap/syswrap-linux.c @@ -7149,99 +7149,95 @@ POST(sys_ioctl) /* --- BEGIN special IOCTL handlers for specific Android hardware --- */ -# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \ - || defined(VGPV_mips32_linux_android) - -# if defined(ANDROID_HARDWARE_nexus_s) - - /* BEGIN undocumented ioctls for the graphics hardware (??) - (libpvr) on Nexus S */ - if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) { - /* What's going on here: there appear to be a bunch of ioctls of - the form 0xC01C67xx which are undocumented, and if unhandled - give rise to a vast number of false positives in Memcheck. - - The "normal" intrepretation of an ioctl of this form would be - that the 3rd arg is a pointer to an area of size 0x1C (28 - bytes) which is filled in by the kernel. Hence you might - think that "POST_MEM_WRITE(ARG3, 28)" would fix it. But it - doesn't. - - It requires POST_MEM_WRITE(ARG3, 256) to silence them. One - interpretation of this is that ARG3 really does point to a 28 - byte struct, but inside that are pointers to other areas also - filled in by the kernel. If these happen to be allocated - just back up the stack then the 256 byte paint might cover - them too, somewhat indiscriminately. - - By printing out ARG3 and also the 28 bytes that it points at, - it's possible to guess that the 7 word structure has this form - - 0 1 2 3 4 5 6 - ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask - - Unfortunately that doesn't seem to work for some reason, so - stay with the blunt-instrument approach for the time being. - */ - if (1) { - /* blunt-instrument approach */ - if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned" - " (%08lx, %08lx)\n", ARG2, ARG3); - POST_MEM_WRITE(ARG3, 256); - } else { - /* be a bit more sophisticated */ - if (0) VG_(printf)("QQQQQQQQQQ c01c quick hack actioned" - " (%08lx, %08lx) (fancy)\n", ARG2, ARG3); - POST_MEM_WRITE(ARG3, 28); - UInt* word = (UInt*)ARG3; - if (word && word[2] && word[3] < 0x200/*stay sane*/) - POST_MEM_WRITE(word[2], word[3]); // "ptr1" - if (word && word[4] && word[5] < 0x200/*stay sane*/) - POST_MEM_WRITE(word[4], word[5]); // "ptr2" - } - if (0) { - Int i; - VG_(printf)("QQQQQQQQQQ "); - for (i = 0; i < (0x1C/4); i++) { - VG_(printf)("%08x ", ((UInt*)(ARG3))[i]); + /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */ + if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx, + VG_(clo_kernel_variant))) { + + if (ARG2 >= 0xC01C6700 && ARG2 <= 0xC01C67FF && ARG3 >= 0x1000) { + /* What's going on here: there appear to be a bunch of ioctls + of the form 0xC01C67xx which are undocumented, and if + unhandled give rise to a vast number of false positives in + Memcheck. + + The "normal" interpretation of an ioctl of this form would + be that the 3rd arg is a pointer to an area of size 0x1C + (28 bytes) which is filled in by the kernel. Hence you + might think that "POST_MEM_WRITE(ARG3, 28)" would fix it. + But it doesn't. + + It requires POST_MEM_WRITE(ARG3, 256) to silence them. + One interpretation of this is that ARG3 really does point + to a 28 byte struct, but inside that are pointers to other + areas also filled in by the kernel. If these happen to be + allocated just back up the stack then the 256 byte paint + might cover them too, somewhat indiscriminately. + + By printing out ARG3 and also the 28 bytes that it points + at, it's possible to guess that the 7 word structure has + this form + + 0 1 2 3 4 5 6 + ioctl-number 0x1C ptr1 ptr1size ptr2 ptr2size aBitMask + + Unfortunately that doesn't seem to work for some reason, + so stay with the blunt-instrument approach for the time + being. + */ + if (1) { + /* blunt-instrument approach */ + POST_MEM_WRITE(ARG3, 256); + } else { + /* be a bit more sophisticated */ + POST_MEM_WRITE(ARG3, 28); + UInt* word = (UInt*)ARG3; + if (word && word[2] && word[3] < 0x200/*stay sane*/) + POST_MEM_WRITE(word[2], word[3]); // "ptr1" + if (word && word[4] && word[5] < 0x200/*stay sane*/) + POST_MEM_WRITE(word[4], word[5]); // "ptr2" } - VG_(printf)("\n"); + goto post_sys_ioctl__out; } - return; } - /* END Nexus S specific ioctls */ - - -# elif defined(ANDROID_HARDWARE_generic) || defined(ANDROID_HARDWARE_emulator) - - /* BEGIN generic/emulator specific ioctls */ - /* currently none are known */ - /* END generic/emulator specific ioctls */ + /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */ - -# else /* no ANDROID_HARDWARE_anything defined */ - -# warning "" -# warning "You need to define one the CPP symbols ANDROID_HARDWARE_blah" -# warning "at configure time, to tell Valgrind what hardware you are" -# warning "building for. Currently known values are" -# warning "" -# warning " ANDROID_HARDWARE_nexus_s Samsung Nexus S" -# 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 "" -# error "No CPP symbol ANDROID_HARDWARE_blah defined. Giving up." - -# endif /* cases for ANDROID_HARDWARE_blah */ - -# endif /* defined(VGPV_*_linux_android) */ + /* BEGIN undocumented ioctls for Qualcomm Adreno 3xx */ + if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx, + VG_(clo_kernel_variant))) { + if (ARG2 == 0xC00C0902) { + POST_MEM_WRITE(ARG3, 24); // 16 is not enough + goto post_sys_ioctl__out; + } + } + /* END undocumented ioctls for Qualcomm Adreno 3xx */ /* --- END special IOCTL handlers for specific Android hardware --- */ /* --- normal handling --- */ switch (ARG2 /* request */) { + + /* The Linux kernel "ion" memory allocator, used on Android. Note: + this is pretty poor given that there's no pre-handling to check + that writable areas are addressable. */ + case VKI_ION_IOC_ALLOC: + POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_allocation_data)); + break; + case VKI_ION_IOC_MAP: + POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_fd_data)); + break; + case VKI_ION_IOC_FREE: // is this necessary? + POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_handle_data)); + break; + case VKI_ION_IOC_SHARE: + break; + case VKI_ION_IOC_IMPORT: // is this necessary? + POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_fd_data)); + break; + case VKI_ION_IOC_SYNC: + break; + case VKI_ION_IOC_CUSTOM: // is this necessary? + POST_MEM_WRITE(ARG3, sizeof(struct vki_ion_custom_data)); + break; + case VKI_TCSETS: case VKI_TCSETSW: case VKI_TCSETSF: @@ -8448,6 +8444,9 @@ POST(sys_ioctl) } break; } + + post_sys_ioctl__out: + {} /* keep C compilers happy */ } /* --------------------------------------------------------------------- diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h index 9bf2d04f10..876d112f31 100644 --- a/coregrind/pub_core_options.h +++ b/coregrind/pub_core_options.h @@ -338,8 +338,12 @@ extern VgSmc VG_(clo_smc_check); /* A set of minor kernel variants, so they can be properly handled by m_syswrap. */ -typedef enum { - KernelVariant_bproc +typedef + enum { + KernelVariant_bproc, + KernelVariant_android_emulator_no_hw_tls, + KernelVariant_android_gpu_sgx5xx, + KernelVariant_android_gpu_adreno3xx } KernelVariant; // Build mask to check or set KernelVariant a membership diff --git a/include/vki/vki-linux.h b/include/vki/vki-linux.h index e00960c50c..3828c33414 100644 --- a/include/vki/vki-linux.h +++ b/include/vki/vki-linux.h @@ -3446,6 +3446,57 @@ struct vki_ethtool_ts_info { #define VKI_ETHTOOL_SCHANNELS 0x0000003d /* Set no of channels */ #define VKI_ETHTOOL_GET_TS_INFO 0x00000041 /* Get time stamping and PHC info */ +//---------------------------------------------------------------------- +// From linux-3.15.8/drivers/staging/android/uapi/ion.h +//---------------------------------------------------------------------- + +typedef int vki_ion_user_handle_t; + +struct vki_ion_allocation_data { + vki_size_t len; + vki_size_t align; + unsigned int heap_id_mask; + unsigned int flags; + vki_ion_user_handle_t handle; +}; + +struct vki_ion_fd_data { + vki_ion_user_handle_t handle; + int fd; +}; + +struct vki_ion_handle_data { + vki_ion_user_handle_t handle; +}; + +struct vki_ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +#define VKI_ION_IOC_MAGIC 'I' + +#define VKI_ION_IOC_ALLOC \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 0, struct vki_ion_allocation_data) + +#define VKI_ION_IOC_FREE \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 1, struct vki_ion_handle_data) + +#define VKI_ION_IOC_MAP \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 2, struct vki_ion_fd_data) + +#define VKI_ION_IOC_SHARE \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 4, struct vki_ion_fd_data) + +#define VKI_ION_IOC_IMPORT \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 5, struct vki_ion_fd_data) + +#define VKI_ION_IOC_SYNC \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 7, struct vki_ion_fd_data) + +#define VKI_ION_IOC_CUSTOM \ + _VKI_IOWR(VKI_ION_IOC_MAGIC, 6, struct vki_ion_custom_data) + //---------------------------------------------------------------------- // From drivers/staging/lustre/lustre/include/lustre/lustre_user.h //---------------------------------------------------------------------- diff --git a/none/tests/cmdline1.stdout.exp b/none/tests/cmdline1.stdout.exp index cf5794fd7b..8d10737c61 100644 --- a/none/tests/cmdline1.stdout.exp +++ b/none/tests/cmdline1.stdout.exp @@ -92,8 +92,11 @@ usage: valgrind [options] prog-and-args where hint is one of lax-ioctls fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache none --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] - --kernel-variant=variant1,variant2,... handle non-standard kernel variants [none] - where variant is one of bproc none + --kernel-variant=variant1,variant2,... + handle non-standard kernel variants [none] + where variant is one of: + bproc android-emulator-no-hw-tls + android-gpu-sgx5xx android-gpu-adreno3xx none --merge-recursive-frames= merge frames between identical program counters in max frames) [0] --num-transtab-sectors= size of translated code cache [16] diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp index 315d0d657d..2049ec5d76 100644 --- a/none/tests/cmdline2.stdout.exp +++ b/none/tests/cmdline2.stdout.exp @@ -92,8 +92,11 @@ usage: valgrind [options] prog-and-args where hint is one of lax-ioctls fuse-compatible enable-outer no-inner-prefix no-nptl-pthread-stackcache none --fair-sched=no|yes|try schedule threads fairly on multicore systems [no] - --kernel-variant=variant1,variant2,... handle non-standard kernel variants [none] - where variant is one of bproc none + --kernel-variant=variant1,variant2,... + handle non-standard kernel variants [none] + where variant is one of: + bproc android-emulator-no-hw-tls + android-gpu-sgx5xx android-gpu-adreno3xx none --merge-recursive-frames= merge frames between identical program counters in max frames) [0] --num-transtab-sectors= size of translated code cache [16]