Home | History | Annotate | Download | only in scripts
      1 #!/bin/bash -e
      2 #===- lib/asan/scripts/asan_device_setup -----------------------------------===#
      3 #
      4 #                     The LLVM Compiler Infrastructure
      5 #
      6 # This file is distributed under the University of Illinois Open Source
      7 # License. See LICENSE.TXT for details.
      8 #
      9 # Prepare Android device to run ASan applications.
     10 #
     11 #===------------------------------------------------------------------------===#
     12 
     13 
     14 HERE="$(cd "$(dirname "$0")" && pwd)"
     15 
     16 revert=no
     17 extra_options=
     18 device=
     19 lib=
     20 
     21 function usage {
     22     echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
     23     echo "  --revert: Uninstall ASan from the device."
     24     echo "  --lib: Path to ASan runtime library."
     25     echo "  --extra-options: Extra ASAN_OPTIONS."
     26     echo "  --device: Install to the given device. Use 'adb devices' to find"
     27     echo "            device-id."
     28     echo
     29     exit 1
     30 }
     31 
     32 while [[ $# > 0 ]]; do
     33   case $1 in
     34     --revert)
     35       revert=yes
     36       ;;
     37     --extra-options)
     38       shift
     39       if [[ $# == 0 ]]; then
     40         echo "--extra-options requires an argument."
     41         exit 1
     42       fi
     43       extra_options="$1"
     44       ;;
     45     --lib)
     46       shift
     47       if [[ $# == 0 ]]; then
     48         echo "--lib requires an argument."
     49         exit 1
     50       fi
     51       lib="$1"
     52       ;;
     53     --device)
     54       shift
     55       if [[ $# == 0 ]]; then
     56         echo "--device requires an argument."
     57         exit 1
     58       fi
     59       device="$1"
     60       ;;
     61     *)
     62       usage
     63       ;;
     64   esac
     65   shift
     66 done
     67 
     68 ADB=${ADB:-adb}
     69 if [[ x$device != x ]]; then
     70     ADB="$ADB -s $device"
     71 fi
     72 
     73 ASAN_RT="libclang_rt.asan-arm-android.so"
     74 
     75 if [[ x$revert == xyes ]]; then
     76     echo '>> Uninstalling ASan'
     77     $ADB root
     78     $ADB wait-for-device
     79     $ADB remount
     80     $ADB shell mv /system/bin/app_process.real /system/bin/app_process
     81     $ADB shell rm /system/bin/asanwrapper
     82     $ADB shell rm /system/lib/$ASAN_RT
     83 
     84     echo '>> Restarting shell'
     85     $ADB shell stop
     86     $ADB shell start
     87 
     88     echo '>> Done'
     89     exit 0
     90 fi
     91 
     92 if [[ -d "$lib" ]]; then
     93     ASAN_RT_PATH="$lib"
     94 elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
     95     ASAN_RT_PATH=$(dirname "$lib")
     96 elif [[ -f "$HERE/$ASAN_RT" ]]; then
     97     ASAN_RT_PATH="$HERE"
     98 elif [[ $(basename "$HERE") == "bin" ]]; then
     99     # We could be in the toolchain's base directory.
    100     # Consider ../lib, ../lib/asan and ../lib/clang/$VERSION/lib/linux.
    101     P=$(ls "$HERE"/../lib/"$ASAN_RT" "$HERE"/../lib/asan/"$ASAN_RT" "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
    102     if [[ -n "$P" ]]; then
    103         ASAN_RT_PATH="$(dirname "$P")"
    104     fi
    105 fi
    106 
    107 if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
    108     echo "ASan runtime library not found"
    109     exit 1
    110 fi
    111 
    112 TMPDIRBASE=$(mktemp -d)
    113 TMPDIROLD="$TMPDIRBASE/old"
    114 TMPDIR="$TMPDIRBASE/new"
    115 mkdir "$TMPDIROLD"
    116 
    117 echo '>> Remounting /system rw'
    118 $ADB root
    119 $ADB wait-for-device
    120 $ADB remount
    121 
    122 echo '>> Copying files from the device'
    123 $ADB pull /system/bin/app_process "$TMPDIROLD"
    124 $ADB pull /system/bin/app_process.real "$TMPDIROLD" || true
    125 $ADB pull /system/bin/asanwrapper "$TMPDIROLD" || true
    126 $ADB pull /system/lib/libclang_rt.asan-arm-android.so "$TMPDIROLD" || true
    127 cp -r "$TMPDIROLD" "$TMPDIR"
    128 
    129 if ! [[ -f "$TMPDIR/app_process" ]]; then
    130     echo "app_process missing???"
    131     exit 1
    132 fi
    133 
    134 if [[ -f "$TMPDIR/app_process.real" ]]; then
    135     echo "app_process.real exists, updating the wrapper"
    136 else
    137     echo "app_process.real missing, new installation"
    138     mv "$TMPDIR/app_process" "$TMPDIR/app_process.real"
    139 fi
    140 
    141 echo '>> Generating wrappers'
    142 
    143 cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
    144 
    145 # FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup,
    146 # which may or may not be a real bug (probably not).
    147 ASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0
    148 if [[ x$extra_options != x ]] ; then
    149     ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
    150 fi
    151 
    152 # Zygote wrapper.
    153 cat <<EOF >"$TMPDIR/app_process"
    154 #!/system/bin/sh
    155 ASAN_OPTIONS=$ASAN_OPTIONS \\
    156 LD_PRELOAD=libclang_rt.asan-arm-android.so \\
    157 exec /system/bin/app_process.real \$@
    158 
    159 EOF
    160 
    161 # General command-line tool wrapper (use for anything that's not started as
    162 # zygote).
    163 cat <<EOF >"$TMPDIR/asanwrapper"
    164 #!/system/bin/sh
    165 LD_PRELOAD=libclang_rt.asan-arm-android.so \\
    166 exec \$@
    167 
    168 EOF
    169 
    170 if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
    171     echo '>> Pushing files to the device'
    172     $ADB push "$TMPDIR/$ASAN_RT" /system/lib/
    173     $ADB push "$TMPDIR/app_process" /system/bin/app_process
    174     $ADB push "$TMPDIR/app_process.real" /system/bin/app_process.real
    175     $ADB push "$TMPDIR/asanwrapper" /system/bin/asanwrapper
    176     $ADB shell chown root.shell \
    177         /system/bin/app_process \
    178         /system/bin/app_process.real \
    179         /system/bin/asanwrapper
    180     $ADB shell chmod 755 \
    181         /system/bin/app_process \
    182         /system/bin/app_process.real \
    183         /system/bin/asanwrapper
    184 
    185     echo '>> Restarting shell (asynchronous)'
    186     $ADB shell stop
    187     $ADB shell start
    188 
    189     echo '>> Please wait until the device restarts'
    190 else
    191     echo '>> Device is up to date'
    192 fi
    193 
    194 rm -r "$TMPDIRBASE"
    195