Files
clang-p2996/compiler-rt/lib/asan/scripts/asan_device_setup
2014-09-11 12:20:29 +00:00

214 lines
5.7 KiB
Bash
Executable File

#!/bin/bash -e
#===- 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.
#
#===------------------------------------------------------------------------===#
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
}
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
ASAN_RT="libclang_rt.asan-arm-android.so"
if [[ x$revert == xyes ]]; then
echo '>> Uninstalling ASan'
$ADB root
$ADB wait-for-device
$ADB remount
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 and ../lib/clang/$VERSION/lib/linux.
P=$(ls "$HERE"/../lib/"$ASAN_RT" "$HERE"/../lib/asan/"$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"
echo '>> Remounting /system rw'
$ADB root
$ADB wait-for-device
$ADB remount
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/libclang_rt.asan-arm-android.so "$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
if [[ x$extra_options != x ]] ; then
ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
fi
# Zygote wrapper.
cat <<EOF >"$TMPDIR/app_process.wrap"
#!/system/bin/sh
ASAN_OPTIONS=$ASAN_OPTIONS \\
LD_PRELOAD=\$LD_PRELOAD:libclang_rt.asan-arm-android.so \\
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=libclang_rt.asan-arm-android.so \\
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
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"