Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / android / asan / third_party / asan_device_setup.sh
blobeb50ea4ed1fce89b6cb37fe35b895ef85a4bac58
1 #!/bin/bash
2 #===- lib/asan/scripts/asan_device_setup -----------------------------------===#
4 # The LLVM Compiler Infrastructure
6 # This file is distributed under the University of Illinois Open Source
7 # License. See LICENSE.TXT for details.
9 # Prepare Android device to run ASan applications.
11 #===------------------------------------------------------------------------===#
13 set -e
15 HERE="$(cd "$(dirname "$0")" && pwd)"
17 revert=no
18 extra_options=
19 device=
20 lib=
22 function usage {
23 echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
24 echo " --revert: Uninstall ASan from the device."
25 echo " --lib: Path to ASan runtime library."
26 echo " --extra-options: Extra ASAN_OPTIONS."
27 echo " --device: Install to the given device. Use 'adb devices' to find"
28 echo " device-id."
29 echo
30 exit 1
33 function get_device_arch { # OUTVAR
34 local _outvar=$1
35 local _ABI=$($ADB shell getprop ro.product.cpu.abi)
36 local _ARCH=
37 if [[ $_ABI == x86* ]]; then
38 _ARCH=i686
39 elif [[ $_ABI == armeabi* ]]; then
40 _ARCH=arm
41 else
42 echo "Unrecognized device ABI: $_ABI"
43 exit 1
45 eval $_outvar=\$_ARCH
48 while [[ $# > 0 ]]; do
49 case $1 in
50 --revert)
51 revert=yes
53 --extra-options)
54 shift
55 if [[ $# == 0 ]]; then
56 echo "--extra-options requires an argument."
57 exit 1
59 extra_options="$1"
61 --lib)
62 shift
63 if [[ $# == 0 ]]; then
64 echo "--lib requires an argument."
65 exit 1
67 lib="$1"
69 --device)
70 shift
71 if [[ $# == 0 ]]; then
72 echo "--device requires an argument."
73 exit 1
75 device="$1"
78 usage
80 esac
81 shift
82 done
84 ADB=${ADB:-adb}
85 if [[ x$device != x ]]; then
86 ADB="$ADB -s $device"
89 echo '>> Remounting /system rw'
90 $ADB root
91 $ADB wait-for-device
92 $ADB remount
93 $ADB wait-for-device
95 get_device_arch ARCH
96 echo "Target architecture: $ARCH"
97 ASAN_RT="libclang_rt.asan-$ARCH-android.so"
99 if [[ x$revert == xyes ]]; then
100 echo '>> Uninstalling ASan'
102 if ! $ADB shell readlink /system/bin/app_process | grep 'app_process' >&/dev/null; then
103 echo '>> Pre-L device detected.'
104 $ADB shell mv /system/bin/app_process.real /system/bin/app_process
105 $ADB shell rm /system/bin/asanwrapper
106 $ADB shell rm /system/lib/$ASAN_RT
107 else
108 $ADB shell rm /system/bin/app_process.wrap
109 $ADB shell rm /system/bin/asanwrapper
110 $ADB shell rm /system/lib/$ASAN_RT
111 $ADB shell rm /system/bin/app_process
112 $ADB shell ln -s /system/bin/app_process32 /system/bin/app_process
115 echo '>> Restarting shell'
116 $ADB shell stop
117 $ADB shell start
119 echo '>> Done'
120 exit 0
123 if [[ -d "$lib" ]]; then
124 ASAN_RT_PATH="$lib"
125 elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
126 ASAN_RT_PATH=$(dirname "$lib")
127 elif [[ -f "$HERE/$ASAN_RT" ]]; then
128 ASAN_RT_PATH="$HERE"
129 elif [[ $(basename "$HERE") == "bin" ]]; then
130 # We could be in the toolchain's base directory.
131 # Consider ../lib, ../lib/asan, ../lib/linux and ../lib/clang/$VERSION/lib/linux.
132 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)
133 if [[ -n "$P" ]]; then
134 ASAN_RT_PATH="$(dirname "$P")"
138 if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
139 echo ">> ASan runtime library not found"
140 exit 1
143 TMPDIRBASE=$(mktemp -d)
144 TMPDIROLD="$TMPDIRBASE/old"
145 TMPDIR="$TMPDIRBASE/new"
146 mkdir "$TMPDIROLD"
148 RELEASE=$($ADB shell getprop ro.build.version.release)
149 PRE_L=0
150 if echo "$RELEASE" | grep '^4\.' >&/dev/null; then
151 PRE_L=1
154 if ! $ADB shell readlink /system/bin/app_process | grep 'app_process' >&/dev/null; then
156 if $ADB pull /system/bin/app_process.real /dev/null >&/dev/null; then
157 echo '>> Old-style ASan installation detected. Reverting.'
158 $ADB shell mv /system/bin/app_process.real /system/bin/app_process
161 echo '>> Pre-L device detected. Setting up app_process symlink.'
162 $ADB shell mv /system/bin/app_process /system/bin/app_process32
163 $ADB shell ln -s /system/bin/app_process32 /system/bin/app_process
166 echo '>> Copying files from the device'
167 $ADB pull /system/bin/app_process.wrap "$TMPDIROLD" || true
168 $ADB pull /system/bin/asanwrapper "$TMPDIROLD" || true
169 $ADB pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
170 cp -r "$TMPDIROLD" "$TMPDIR"
172 if [[ -f "$TMPDIR/app_process.wrap" ]]; then
173 echo ">> Previous installation detected"
174 else
175 echo ">> New installation"
178 echo '>> Generating wrappers'
180 cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
182 # FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup,
183 # which may or may not be a real bug (probably not).
184 ASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0
186 # On Android-L not allowing user segv handler breaks some applications.
187 if [[ PRE_L -eq 0 ]]; then
188 ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
191 if [[ x$extra_options != x ]] ; then
192 ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
195 # Zygote wrapper.
196 cat <<EOF >"$TMPDIR/app_process.wrap"
197 #!/system/bin/sh-from-zygote
198 ASAN_OPTIONS=$ASAN_OPTIONS \\
199 LD_PRELOAD=\$LD_PRELOAD:$ASAN_RT \\
200 exec /system/bin/app_process32 \$@
204 # General command-line tool wrapper (use for anything that's not started as
205 # zygote).
206 cat <<EOF >"$TMPDIR/asanwrapper"
207 #!/system/bin/sh
208 LD_PRELOAD=$ASAN_RT \\
209 exec \$@
213 if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
214 echo '>> Pushing files to the device'
215 $ADB push "$TMPDIR/$ASAN_RT" /system/lib/
216 $ADB push "$TMPDIR/app_process.wrap" /system/bin/app_process.wrap
217 $ADB push "$TMPDIR/asanwrapper" /system/bin/asanwrapper
219 $ADB shell rm /system/bin/app_process
220 $ADB shell ln -s /system/bin/app_process.wrap /system/bin/app_process
222 $ADB shell chown root.shell \
223 /system/lib/"$ASAN_RT" \
224 /system/bin/app_process.wrap \
225 /system/bin/asanwrapper
226 $ADB shell chmod 644 \
227 /system/lib/"$ASAN_RT"
228 $ADB shell chmod 755 \
229 /system/bin/app_process.wrap \
230 /system/bin/asanwrapper
232 # Make SELinux happy by keeping app_process wrapper and the shell
233 # it runs on in zygote domain.
234 ENFORCING=0
235 if $ADB shell getenforce | grep Enforcing >/dev/null; then
236 # Sometimes shell is not allowed to change file contexts.
237 # Temporarily switch to permissive.
238 ENFORCING=1
239 $ADB shell setenforce 0
242 $ADB shell cp /system/bin/sh /system/bin/sh-from-zygote
244 if [[ PRE_L -eq 1 ]]; then
245 CTX=u:object_r:system_file:s0
246 else
247 CTX=u:object_r:zygote_exec:s0
249 $ADB shell chcon $CTX \
250 /system/bin/sh-from-zygote \
251 /system/bin/app_process.wrap \
252 /system/bin/app_process32
254 if [ $ENFORCING == 1 ]; then
255 $ADB shell setenforce 1
258 echo '>> Restarting shell (asynchronous)'
259 $ADB shell stop
260 $ADB shell start
262 echo '>> Please wait until the device restarts'
263 else
264 echo '>> Device is up to date'
267 rm -r "$TMPDIRBASE"