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 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/NEWS b/NEWS
index 1cadd24..8cf9413 100644
--- a/NEWS
+++ b/NEWS
@@ -27,6 +27,9 @@
* 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 cebe2cd..891dcb3 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 @@
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 @@
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 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 @@
./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 @@
# 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 @@
#
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 7548959..f2ed598 100644
--- a/README.android_emulator
+++ b/README.android_emulator
@@ -61,6 +61,14 @@
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 a15d55f..7aa8746 100644
--- a/coregrind/m_main.c
+++ b/coregrind/m_main.c
@@ -179,9 +179,11 @@
" 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=<number> merge frames between identical\n"
" program counters in max <number> frames) [0]\n"
" --num-transtab-sectors=<number> size of translated code cache [%d]\n"
@@ -627,7 +629,11 @@
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 b91edcc..18c8667 100644
--- a/coregrind/m_syswrap/syswrap-arm-linux.c
+++ b/coregrind/m_syswrap/syswrap-arm-linux.c
@@ -280,41 +280,43 @@
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.
-
- 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.
+ 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.
+
+ 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.
- 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 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 3b3218d..a4b64a8 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -7149,99 +7149,95 @@
/* --- BEGIN special IOCTL handlers for specific Android hardware --- */
-# if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
- || defined(VGPV_mips32_linux_android)
+ /* BEGIN undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
+ if (KernelVariantiS(KernelVariant_android_gpu_sgx5xx,
+ VG_(clo_kernel_variant))) {
-# if defined(ANDROID_HARDWARE_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.
- /* 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" 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.
- 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.
- 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
- 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
- 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]);
+ 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 */
+ /* END undocumented ioctls for PowerVR SGX 540 (the GPU on Nexus S) */
-
-# elif defined(ANDROID_HARDWARE_generic) || defined(ANDROID_HARDWARE_emulator)
-
- /* BEGIN generic/emulator specific ioctls */
- /* currently none are known */
- /* END generic/emulator specific ioctls */
-
-
-# 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 @@
}
break;
}
+
+ post_sys_ioctl__out:
+ {} /* keep C compilers happy */
}
/* ---------------------------------------------------------------------
diff --git a/coregrind/pub_core_options.h b/coregrind/pub_core_options.h
index 9bf2d04..876d112 100644
--- a/coregrind/pub_core_options.h
+++ b/coregrind/pub_core_options.h
@@ -338,8 +338,12 @@
/* 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 e00960c..3828c33 100644
--- a/include/vki/vki-linux.h
+++ b/include/vki/vki-linux.h
@@ -3447,6 +3447,57 @@
#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 cf5794f..8d10737 100644
--- a/none/tests/cmdline1.stdout.exp
+++ b/none/tests/cmdline1.stdout.exp
@@ -92,8 +92,11 @@
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=<number> merge frames between identical
program counters in max <number> frames) [0]
--num-transtab-sectors=<number> size of translated code cache [16]
diff --git a/none/tests/cmdline2.stdout.exp b/none/tests/cmdline2.stdout.exp
index 315d0d6..2049ec5 100644
--- a/none/tests/cmdline2.stdout.exp
+++ b/none/tests/cmdline2.stdout.exp
@@ -92,8 +92,11 @@
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=<number> merge frames between identical
program counters in max <number> frames) [0]
--num-transtab-sectors=<number> size of translated code cache [16]