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