#!/bin/sh # # Run the code in test.jar on the device. The jar should contain a top-level # class named Main to run. msg() { if [ "$QUIET" = "n" ]; then echo "$@" fi } ARCHITECTURES_32="(arm|x86|mips|none)" ARCHITECTURES_64="(arm64|x86_64|none)" ARCHITECTURES_PATTERN="${ARCHITECTURES_32}" RELOCATE="y" GDB="n" DEBUGGER="n" INTERPRETER="n" VERIFY="y" OPTIMIZE="y" ZYGOTE="" QUIET="n" DEV_MODE="n" INVOKE_WITH="" FLAGS="" TARGET_SUFFIX="32" GDB_TARGET_SUFFIX="" COMPILE_FLAGS="" FALSE_BIN="/system/bin/false" PATCHOAT="" DEX2OAT="" HAVE_IMAGE="y" while true; do if [ "x$1" = "x--quiet" ]; then QUIET="y" shift elif [ "x$1" = "x--lib" ]; then shift if [ "x$1" = "x" ]; then echo "$0 missing argument to --lib" 1>&2 exit 1 fi LIB="$1" shift elif [ "x$1" = "x-Xcompiler-option" ]; then shift option="$1" FLAGS="${FLAGS} -Xcompiler-option $option" COMPILE_FLAGS="${COMPILE_FLAGS} $option" shift elif [ "x$1" = "x--runtime-option" ]; then shift option="$1" FLAGS="${FLAGS} $option" shift elif [ "x$1" = "x--boot" ]; then shift BOOT_OPT="$1" BUILD_BOOT_OPT="--boot-image=${1#-Ximage:}" shift elif [ "x$1" = "x--no-dex2oat" ]; then DEX2OAT="-Xcompiler:${FALSE_BIN}" shift elif [ "x$1" = "x--no-patchoat" ]; then PATCHOAT="-Xpatchoat:${FALSE_BIN}" shift elif [ "x$1" = "x--relocate" ]; then RELOCATE="y" shift elif [ "x$1" = "x--no-relocate" ]; then RELOCATE="n" shift elif [ "x$1" = "x--no-image" ]; then HAVE_IMAGE="n" shift elif [ "x$1" = "x--debug" ]; then DEBUGGER="y" shift elif [ "x$1" = "x--gdb" ]; then GDB="y" DEV_MODE="y" shift elif [ "x$1" = "x--zygote" ]; then ZYGOTE="--zygote" msg "Spawning from zygote" shift elif [ "x$1" = "x--dev" ]; then DEV_MODE="y" shift elif [ "x$1" = "x--interpreter" ]; then INTERPRETER="y" shift elif [ "x$1" = "x--invoke-with" ]; then shift if [ "x$1" = "x" ]; then echo "$0 missing argument to --invoke-with" 1>&2 exit 1 fi if [ "x$INVOKE_WITH" = "x" ]; then INVOKE_WITH="$1" else INVOKE_WITH="$INVOKE_WITH $1" fi shift elif [ "x$1" = "x--no-verify" ]; then VERIFY="n" shift elif [ "x$1" = "x--no-optimize" ]; then OPTIMIZE="n" shift elif [ "x$1" = "x--" ]; then shift break elif [ "x$1" = "x--64" ]; then TARGET_SUFFIX="64" GDB_TARGET_SUFFIX="64" ARCHITECTURES_PATTERN="${ARCHITECTURES_64}" shift elif expr "x$1" : "x--" >/dev/null 2>&1; then echo "unknown $0 option: $1" 1>&2 exit 1 else break fi done if [ "$ZYGOTE" = "" ]; then if [ "$OPTIMIZE" = "y" ]; then if [ "$VERIFY" = "y" ]; then DEX_OPTIMIZE="-Xdexopt:verified" else DEX_OPTIMIZE="-Xdexopt:all" fi msg "Performing optimizations" else DEX_OPTIMIZE="-Xdexopt:none" msg "Skipping optimizations" fi if [ "$VERIFY" = "y" ]; then DEX_VERIFY="" msg "Performing verification" else DEX_VERIFY="-Xverify:none" msg "Skipping verification" fi fi msg "------------------------------" if [ "$HAVE_IMAGE" = "n" ]; then BOOT_OPT="-Ximage:/system/non-existant/boot.art" BOOT_OPT="${BOOT_OPT} -Xbootclasspath:/system/framework/core-libart.jar" fi ARCH=$(adb shell ls -F /data/dalvik-cache | grep -Ewo "${ARCHITECTURES_PATTERN}") if [ x"$ARCH" = "x" ]; then echo "Unable to determine architecture" exit 1 fi if [ "$QUIET" = "n" ]; then adb shell rm -r $DEX_LOCATION adb shell mkdir -p $DEX_LOCATION adb push $TEST_NAME.jar $DEX_LOCATION adb push $TEST_NAME-ex.jar $DEX_LOCATION else adb shell rm -r $DEX_LOCATION >/dev/null 2>&1 adb shell mkdir -p $DEX_LOCATION >/dev/null 2>&1 adb push $TEST_NAME.jar $DEX_LOCATION >/dev/null 2>&1 adb push $TEST_NAME-ex.jar $DEX_LOCATION >/dev/null 2>&1 fi if [ "$DEBUGGER" = "y" ]; then # Use this instead for ddms and connect by running 'ddms': # DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_android_adb,server=y,suspend=y" # TODO: add a separate --ddms option? PORT=12345 msg "Waiting for jdb to connect:" msg " adb forward tcp:$PORT tcp:$PORT" msg " jdb -attach localhost:$PORT" DEBUGGER_OPTS="-agentlib:jdwp=transport=dt_socket,address=$PORT,server=y,suspend=y" fi if [ "$GDB" = "y" ]; then gdb="gdbserver$GDB_TARGET_SUFFIX :5039" gdbargs="$exe" fi if [ "$INTERPRETER" = "y" ]; then INT_OPTS="-Xint" COMPILE_FLAGS="${COMPILE_FLAGS} --compiler-filter=interpret-only" fi JNI_OPTS="-Xjnigreflimit:512 -Xcheck:jni" if [ "$RELOCATE" = "y" ]; then RELOCATE_OPT="-Xrelocate" BUILD_RELOCATE_OPT="--runtime-arg -Xnorelocate" COMPILE_FLAGS="${COMPILE_FLAGS} --include-patch-information" FLAGS="${FLAGS} -Xcompiler-option --include-patch-information" else RELOCATE_OPT="-Xnorelocate" BUILD_RELOCATE_OPT="--runtime-arg -Xnorelocate" fi # This is due to the fact this cmdline can get longer than the longest allowed # adb command and there is no way to get the exit status from a adb shell # command. cmdline="cd $DEX_LOCATION && export ANDROID_DATA=$DEX_LOCATION && export DEX_LOCATION=$DEX_LOCATION && \ mkdir -p $DEX_LOCATION/dalvik-cache/$ARCH/ && \ $INVOKE_WITH /system/bin/dex2oatd $COMPILE_FLAGS $BUILD_BOOT_OPT $BUILD_RELOCATE_OPT --runtime-arg -classpath --runtime-arg $DEX_LOCATION/$TEST_NAME.jar --dex-file=$DEX_LOCATION/$TEST_NAME.jar --oat-file=$DEX_LOCATION/dalvik-cache/$ARCH/$(echo $DEX_LOCATION/$TEST_NAME.jar/classes.dex | cut -d/ -f 2- | sed "s:/:@:g") --instruction-set=$ARCH && \ $INVOKE_WITH $gdb /system/bin/dalvikvm$TARGET_SUFFIX $FLAGS $gdbargs -XXlib:$LIB $PATCHOAT $DEX2OAT $ZYGOTE $JNI_OPTS $RELOCATE_OPT $INT_OPTS $DEBUGGER_OPTS $BOOT_OPT -cp $DEX_LOCATION/$TEST_NAME.jar Main $@" cmdfile=$(tempfile -p "cmd-" -s "-$TEST_NAME") echo "$cmdline" > $cmdfile if [ "$DEV_MODE" = "y" ]; then echo $cmdline fi if [ "$QUIET" = "n" ]; then adb push $cmdfile $DEX_LOCATION/cmdline.sh else adb push $cmdfile $DEX_LOCATION/cmdline.sh > /dev/null 2>&1 fi adb shell sh $DEX_LOCATION/cmdline.sh rm -f $cmdfile