| Index: tools/android/asan/third_party/asan_device_setup.sh
|
| diff --git a/tools/android/asan/third_party/asan_device_setup.sh b/tools/android/asan/third_party/asan_device_setup.sh
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..eb50ea4ed1fce89b6cb37fe35b895ef85a4bac58
|
| --- /dev/null
|
| +++ b/tools/android/asan/third_party/asan_device_setup.sh
|
| @@ -0,0 +1,267 @@
|
| +#!/bin/bash
|
| +#===- lib/asan/scripts/asan_device_setup -----------------------------------===#
|
| +#
|
| +# The LLVM Compiler Infrastructure
|
| +#
|
| +# This file is distributed under the University of Illinois Open Source
|
| +# License. See LICENSE.TXT for details.
|
| +#
|
| +# Prepare Android device to run ASan applications.
|
| +#
|
| +#===------------------------------------------------------------------------===#
|
| +
|
| +set -e
|
| +
|
| +HERE="$(cd "$(dirname "$0")" && pwd)"
|
| +
|
| +revert=no
|
| +extra_options=
|
| +device=
|
| +lib=
|
| +
|
| +function usage {
|
| + echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
|
| + echo " --revert: Uninstall ASan from the device."
|
| + echo " --lib: Path to ASan runtime library."
|
| + echo " --extra-options: Extra ASAN_OPTIONS."
|
| + echo " --device: Install to the given device. Use 'adb devices' to find"
|
| + echo " device-id."
|
| + echo
|
| + exit 1
|
| +}
|
| +
|
| +function get_device_arch { # OUTVAR
|
| + local _outvar=$1
|
| + local _ABI=$($ADB shell getprop ro.product.cpu.abi)
|
| + local _ARCH=
|
| + if [[ $_ABI == x86* ]]; then
|
| + _ARCH=i686
|
| + elif [[ $_ABI == armeabi* ]]; then
|
| + _ARCH=arm
|
| + else
|
| + echo "Unrecognized device ABI: $_ABI"
|
| + exit 1
|
| + fi
|
| + eval $_outvar=\$_ARCH
|
| +}
|
| +
|
| +while [[ $# > 0 ]]; do
|
| + case $1 in
|
| + --revert)
|
| + revert=yes
|
| + ;;
|
| + --extra-options)
|
| + shift
|
| + if [[ $# == 0 ]]; then
|
| + echo "--extra-options requires an argument."
|
| + exit 1
|
| + fi
|
| + extra_options="$1"
|
| + ;;
|
| + --lib)
|
| + shift
|
| + if [[ $# == 0 ]]; then
|
| + echo "--lib requires an argument."
|
| + exit 1
|
| + fi
|
| + lib="$1"
|
| + ;;
|
| + --device)
|
| + shift
|
| + if [[ $# == 0 ]]; then
|
| + echo "--device requires an argument."
|
| + exit 1
|
| + fi
|
| + device="$1"
|
| + ;;
|
| + *)
|
| + usage
|
| + ;;
|
| + esac
|
| + shift
|
| +done
|
| +
|
| +ADB=${ADB:-adb}
|
| +if [[ x$device != x ]]; then
|
| + ADB="$ADB -s $device"
|
| +fi
|
| +
|
| +echo '>> Remounting /system rw'
|
| +$ADB root
|
| +$ADB wait-for-device
|
| +$ADB remount
|
| +$ADB wait-for-device
|
| +
|
| +get_device_arch ARCH
|
| +echo "Target architecture: $ARCH"
|
| +ASAN_RT="libclang_rt.asan-$ARCH-android.so"
|
| +
|
| +if [[ x$revert == xyes ]]; then
|
| + echo '>> Uninstalling ASan'
|
| +
|
| + if ! $ADB shell readlink /system/bin/app_process | grep 'app_process' >&/dev/null; then
|
| + echo '>> Pre-L device detected.'
|
| + $ADB shell mv /system/bin/app_process.real /system/bin/app_process
|
| + $ADB shell rm /system/bin/asanwrapper
|
| + $ADB shell rm /system/lib/$ASAN_RT
|
| + else
|
| + $ADB shell rm /system/bin/app_process.wrap
|
| + $ADB shell rm /system/bin/asanwrapper
|
| + $ADB shell rm /system/lib/$ASAN_RT
|
| + $ADB shell rm /system/bin/app_process
|
| + $ADB shell ln -s /system/bin/app_process32 /system/bin/app_process
|
| + fi
|
| +
|
| + echo '>> Restarting shell'
|
| + $ADB shell stop
|
| + $ADB shell start
|
| +
|
| + echo '>> Done'
|
| + exit 0
|
| +fi
|
| +
|
| +if [[ -d "$lib" ]]; then
|
| + ASAN_RT_PATH="$lib"
|
| +elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
|
| + ASAN_RT_PATH=$(dirname "$lib")
|
| +elif [[ -f "$HERE/$ASAN_RT" ]]; then
|
| + ASAN_RT_PATH="$HERE"
|
| +elif [[ $(basename "$HERE") == "bin" ]]; then
|
| + # We could be in the toolchain's base directory.
|
| + # Consider ../lib, ../lib/asan, ../lib/linux and ../lib/clang/$VERSION/lib/linux.
|
| + P=$(ls "$HERE"/../lib/"$ASAN_RT" "$HERE"/../lib/asan/"$ASAN_RT" "$HERE"/../lib/linux/"$ASAN_RT" "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
|
| + if [[ -n "$P" ]]; then
|
| + ASAN_RT_PATH="$(dirname "$P")"
|
| + fi
|
| +fi
|
| +
|
| +if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
|
| + echo ">> ASan runtime library not found"
|
| + exit 1
|
| +fi
|
| +
|
| +TMPDIRBASE=$(mktemp -d)
|
| +TMPDIROLD="$TMPDIRBASE/old"
|
| +TMPDIR="$TMPDIRBASE/new"
|
| +mkdir "$TMPDIROLD"
|
| +
|
| +RELEASE=$($ADB shell getprop ro.build.version.release)
|
| +PRE_L=0
|
| +if echo "$RELEASE" | grep '^4\.' >&/dev/null; then
|
| + PRE_L=1
|
| +fi
|
| +
|
| +if ! $ADB shell readlink /system/bin/app_process | grep 'app_process' >&/dev/null; then
|
| +
|
| + if $ADB pull /system/bin/app_process.real /dev/null >&/dev/null; then
|
| + echo '>> Old-style ASan installation detected. Reverting.'
|
| + $ADB shell mv /system/bin/app_process.real /system/bin/app_process
|
| + fi
|
| +
|
| + echo '>> Pre-L device detected. Setting up app_process symlink.'
|
| + $ADB shell mv /system/bin/app_process /system/bin/app_process32
|
| + $ADB shell ln -s /system/bin/app_process32 /system/bin/app_process
|
| +fi
|
| +
|
| +echo '>> Copying files from the device'
|
| +$ADB pull /system/bin/app_process.wrap "$TMPDIROLD" || true
|
| +$ADB pull /system/bin/asanwrapper "$TMPDIROLD" || true
|
| +$ADB pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
|
| +cp -r "$TMPDIROLD" "$TMPDIR"
|
| +
|
| +if [[ -f "$TMPDIR/app_process.wrap" ]]; then
|
| + echo ">> Previous installation detected"
|
| +else
|
| + echo ">> New installation"
|
| +fi
|
| +
|
| +echo '>> Generating wrappers'
|
| +
|
| +cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
|
| +
|
| +# FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup,
|
| +# which may or may not be a real bug (probably not).
|
| +ASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0
|
| +
|
| +# On Android-L not allowing user segv handler breaks some applications.
|
| +if [[ PRE_L -eq 0 ]]; then
|
| + ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
|
| +fi
|
| +
|
| +if [[ x$extra_options != x ]] ; then
|
| + ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
|
| +fi
|
| +
|
| +# Zygote wrapper.
|
| +cat <<EOF >"$TMPDIR/app_process.wrap"
|
| +#!/system/bin/sh-from-zygote
|
| +ASAN_OPTIONS=$ASAN_OPTIONS \\
|
| +LD_PRELOAD=\$LD_PRELOAD:$ASAN_RT \\
|
| +exec /system/bin/app_process32 \$@
|
| +
|
| +EOF
|
| +
|
| +# General command-line tool wrapper (use for anything that's not started as
|
| +# zygote).
|
| +cat <<EOF >"$TMPDIR/asanwrapper"
|
| +#!/system/bin/sh
|
| +LD_PRELOAD=$ASAN_RT \\
|
| +exec \$@
|
| +
|
| +EOF
|
| +
|
| +if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
|
| + echo '>> Pushing files to the device'
|
| + $ADB push "$TMPDIR/$ASAN_RT" /system/lib/
|
| + $ADB push "$TMPDIR/app_process.wrap" /system/bin/app_process.wrap
|
| + $ADB push "$TMPDIR/asanwrapper" /system/bin/asanwrapper
|
| +
|
| + $ADB shell rm /system/bin/app_process
|
| + $ADB shell ln -s /system/bin/app_process.wrap /system/bin/app_process
|
| +
|
| + $ADB shell chown root.shell \
|
| + /system/lib/"$ASAN_RT" \
|
| + /system/bin/app_process.wrap \
|
| + /system/bin/asanwrapper
|
| + $ADB shell chmod 644 \
|
| + /system/lib/"$ASAN_RT"
|
| + $ADB shell chmod 755 \
|
| + /system/bin/app_process.wrap \
|
| + /system/bin/asanwrapper
|
| +
|
| + # Make SELinux happy by keeping app_process wrapper and the shell
|
| + # it runs on in zygote domain.
|
| + ENFORCING=0
|
| + if $ADB shell getenforce | grep Enforcing >/dev/null; then
|
| + # Sometimes shell is not allowed to change file contexts.
|
| + # Temporarily switch to permissive.
|
| + ENFORCING=1
|
| + $ADB shell setenforce 0
|
| + fi
|
| +
|
| + $ADB shell cp /system/bin/sh /system/bin/sh-from-zygote
|
| +
|
| + if [[ PRE_L -eq 1 ]]; then
|
| + CTX=u:object_r:system_file:s0
|
| + else
|
| + CTX=u:object_r:zygote_exec:s0
|
| + fi
|
| + $ADB shell chcon $CTX \
|
| + /system/bin/sh-from-zygote \
|
| + /system/bin/app_process.wrap \
|
| + /system/bin/app_process32
|
| +
|
| + if [ $ENFORCING == 1 ]; then
|
| + $ADB shell setenforce 1
|
| + fi
|
| +
|
| + echo '>> Restarting shell (asynchronous)'
|
| + $ADB shell stop
|
| + $ADB shell start
|
| +
|
| + echo '>> Please wait until the device restarts'
|
| +else
|
| + echo '>> Device is up to date'
|
| +fi
|
| +
|
| +rm -r "$TMPDIRBASE"
|
|
|