[Clang][SME2] Enable multi-vector loads & stores for SME2 (#75821)
[llvm-project.git] / compiler-rt / lib / asan / scripts / asan_device_setup
blob494867917fdb1d322b9ba1f60cc2f49c15940b3a
1 #!/usr/bin/env bash
2 #===- lib/asan/scripts/asan_device_setup -----------------------------------===#
4 # Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 # See https://llvm.org/LICENSE.txt for license information.
6 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 # Prepare Android device to run ASan applications.
10 #===------------------------------------------------------------------------===#
12 set -e
14 HERE="$(cd "$(dirname "$0")" && pwd)"
16 revert=no
17 extra_options=
18 device=
19 lib=
20 use_su=0
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 " --use-su: Use 'su -c' prefix for every adb command instead of using"
30 echo " 'adb root' once."
31 echo
32 exit 1
35 function adb_push {
36 if [ $use_su -eq 0 ]; then
37 $ADB push "$1" "$2"
38 else
39 local FILENAME=$(basename $1)
40 $ADB push "$1" "/data/local/tmp/$FILENAME"
41 $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null
42 $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
43 $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\""
47 function adb_remount {
48 if [ $use_su -eq 0 ]; then
49 $ADB remount
50 else
51 local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`
52 if [ "$STORAGE" != "" ]; then
53 echo Remounting $STORAGE at /system
54 $ADB shell su -c "mount -o rw,remount $STORAGE /system"
55 else
56 echo Failed to get storage device name for "/system" mount point
61 function adb_shell {
62 if [ $use_su -eq 0 ]; then
63 $ADB shell $@
64 else
65 $ADB shell su -c "$*"
69 function adb_root {
70 if [ $use_su -eq 0 ]; then
71 $ADB root
75 function adb_wait_for_device {
76 $ADB wait-for-device
79 function adb_pull {
80 if [ $use_su -eq 0 ]; then
81 $ADB pull "$1" "$2"
82 else
83 local FILENAME=$(basename $1)
84 $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null
85 $ADB shell su -c "[ -f \\\"$1\\\" ] && cat \\\"$1\\\" > \\\"/data/local/tmp/$FILENAME\\\" && chown root.shell \\\"/data/local/tmp/$FILENAME\\\" && chmod 755 \\\"/data/local/tmp/$FILENAME\\\"" &&
86 $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\""
90 function get_device_arch { # OUT OUT64
91 local _outvar=$1
92 local _outvar64=$2
93 local _ABI=$(adb_shell getprop ro.product.cpu.abi)
94 local _ARCH=
95 local _ARCH64=
96 if [[ $_ABI == x86* ]]; then
97 _ARCH=i686
98 elif [[ $_ABI == armeabi* ]]; then
99 _ARCH=arm
100 elif [[ $_ABI == arm64-v8a* ]]; then
101 _ARCH=arm
102 _ARCH64=aarch64
103 else
104 echo "Unrecognized device ABI: $_ABI"
105 exit 1
107 eval $_outvar=\$_ARCH
108 eval $_outvar64=\$_ARCH64
111 while [[ $# > 0 ]]; do
112 case $1 in
113 --revert)
114 revert=yes
116 --extra-options)
117 shift
118 if [[ $# == 0 ]]; then
119 echo "--extra-options requires an argument."
120 exit 1
122 extra_options="$1"
124 --lib)
125 shift
126 if [[ $# == 0 ]]; then
127 echo "--lib requires an argument."
128 exit 1
130 lib="$1"
132 --device)
133 shift
134 if [[ $# == 0 ]]; then
135 echo "--device requires an argument."
136 exit 1
138 device="$1"
140 --use-su)
141 use_su=1
144 usage
146 esac
147 shift
148 done
150 ADB=${ADB:-adb}
151 if [[ x$device != x ]]; then
152 ADB="$ADB -s $device"
155 if [ $use_su -eq 1 ]; then
156 # Test if 'su' is present on the device
157 SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
158 if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then
159 echo "ERROR: Cannot use 'su -c':"
160 echo "$ adb shell su -c \"echo foo\""
161 echo $SU_TEST_OUT
162 echo "Check that 'su' binary is correctly installed on the device or omit"
163 echo " --use-su flag"
164 exit 1
168 echo '>> Remounting /system rw'
169 adb_wait_for_device
170 adb_root
171 adb_wait_for_device
172 adb_remount
173 adb_wait_for_device
175 get_device_arch ARCH ARCH64
176 echo "Target architecture: $ARCH"
177 ASAN_RT="libclang_rt.asan-$ARCH-android.so"
178 if [[ -n $ARCH64 ]]; then
179 echo "Target architecture: $ARCH64"
180 ASAN_RT64="libclang_rt.asan-$ARCH64-android.so"
183 RELEASE=$(adb_shell getprop ro.build.version.release)
184 PRE_L=0
185 if echo "$RELEASE" | grep '^4\.' >&/dev/null; then
186 PRE_L=1
188 ANDROID_O=0
189 if echo "$RELEASE" | grep '^8\.0\.' >&/dev/null; then
190 # 8.0.x is for Android O
191 ANDROID_O=1
194 if [[ x$revert == xyes ]]; then
195 echo '>> Uninstalling ASan'
197 if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
198 echo '>> Pre-L device detected.'
199 adb_shell mv /system/bin/app_process.real /system/bin/app_process
200 adb_shell rm /system/bin/asanwrapper
201 elif ! adb_shell ls -l /system/bin/app_process64.real | grep -o 'No such file or directory' >&/dev/null; then
202 # 64-bit installation.
203 adb_shell mv /system/bin/app_process32.real /system/bin/app_process32
204 adb_shell mv /system/bin/app_process64.real /system/bin/app_process64
205 adb_shell rm /system/bin/asanwrapper
206 adb_shell rm /system/bin/asanwrapper64
207 else
208 # 32-bit installation.
209 adb_shell rm /system/bin/app_process.wrap
210 adb_shell rm /system/bin/asanwrapper
211 adb_shell rm /system/bin/app_process
212 adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
215 if [[ ANDROID_O -eq 1 ]]; then
216 adb_shell mv /system/etc/ld.config.txt.saved /system/etc/ld.config.txt
219 echo '>> Restarting shell'
220 adb_shell stop
221 adb_shell start
223 # Remove the library on the last step to give a chance to the 'su' binary to
224 # be executed without problem.
225 adb_shell rm /system/lib/$ASAN_RT
227 echo '>> Done'
228 exit 0
231 if [[ -d "$lib" ]]; then
232 ASAN_RT_PATH="$lib"
233 elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
234 ASAN_RT_PATH=$(dirname "$lib")
235 elif [[ -f "$HERE/$ASAN_RT" ]]; then
236 ASAN_RT_PATH="$HERE"
237 elif [[ $(basename "$HERE") == "bin" ]]; then
238 # We could be in the toolchain's base directory.
239 # Consider ../lib, ../lib/asan, ../lib/linux,
240 # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.
241 P=$(ls "$HERE"/../lib/"$ASAN_RT" \
242 "$HERE"/../lib/asan/"$ASAN_RT" \
243 "$HERE"/../lib/linux/"$ASAN_RT" \
244 "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" \
245 "$HERE"/../lib64/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
246 if [[ -n "$P" ]]; then
247 ASAN_RT_PATH="$(dirname "$P")"
251 if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
252 echo ">> ASan runtime library not found"
253 exit 1
256 if [[ -n "$ASAN_RT64" ]]; then
257 if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT64" ]]; then
258 echo ">> ASan runtime library not found"
259 exit 1
263 TMPDIRBASE=$(mktemp -d)
264 TMPDIROLD="$TMPDIRBASE/old"
265 TMPDIR="$TMPDIRBASE/new"
266 mkdir "$TMPDIROLD"
268 if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
270 if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then
271 echo '>> Old-style ASan installation detected. Reverting.'
272 adb_shell mv /system/bin/app_process.real /system/bin/app_process
275 echo '>> Pre-L device detected. Setting up app_process symlink.'
276 adb_shell mv /system/bin/app_process /system/bin/app_process32
277 adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
280 echo '>> Copying files from the device'
281 if [[ -n "$ASAN_RT64" ]]; then
282 adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
283 adb_pull /system/lib64/"$ASAN_RT64" "$TMPDIROLD" || true
284 adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
285 adb_pull /system/bin/app_process32.real "$TMPDIROLD" || true
286 adb_pull /system/bin/app_process64 "$TMPDIROLD" || true
287 adb_pull /system/bin/app_process64.real "$TMPDIROLD" || true
288 adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
289 adb_pull /system/bin/asanwrapper64 "$TMPDIROLD" || true
290 else
291 adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
292 adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
293 adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true
294 adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
296 cp -r "$TMPDIROLD" "$TMPDIR"
298 if [[ -f "$TMPDIR/app_process.wrap" || -f "$TMPDIR/app_process64.real" ]]; then
299 echo ">> Previous installation detected"
300 else
301 echo ">> New installation"
304 echo '>> Generating wrappers'
306 cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
307 if [[ -n "$ASAN_RT64" ]]; then
308 cp "$ASAN_RT_PATH/$ASAN_RT64" "$TMPDIR/"
311 ASAN_OPTIONS=start_deactivated=1
313 # The name of a symlink to libclang_rt.asan-$ARCH-android.so used in LD_PRELOAD.
314 # The idea is to have the same name in lib and lib64 to keep it from falling
315 # apart when a 64-bit process spawns a 32-bit one, inheriting the environment.
316 ASAN_RT_SYMLINK=symlink-to-libclang_rt.asan
318 function generate_zygote_wrapper { # from, to
319 local _from=$1
320 local _to=$2
321 if [[ PRE_L -eq 0 ]]; then
322 # LD_PRELOAD parsing is broken in N if it starts with ":". Luckily, it is
323 # unset in the system environment since L.
324 local _ld_preload=$ASAN_RT_SYMLINK
325 else
326 local _ld_preload=\$LD_PRELOAD:$ASAN_RT_SYMLINK
328 cat <<EOF >"$TMPDIR/$_from"
329 #!/system/bin/sh-from-zygote
330 ASAN_OPTIONS=$ASAN_OPTIONS \\
331 ASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\
332 LD_PRELOAD=$_ld_preload \\
333 exec $_to "\$@"
338 # On Android-L not allowing user segv handler breaks some applications.
339 # Since ~May 2017 this is the default setting; included for compatibility with
340 # older library versions.
341 if [[ PRE_L -eq 0 ]]; then
342 ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
345 if [[ x$extra_options != x ]] ; then
346 ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
349 # Zygote wrapper.
350 if [[ -f "$TMPDIR/app_process64" ]]; then
351 # A 64-bit device.
352 if [[ ! -f "$TMPDIR/app_process64.real" ]]; then
353 # New installation.
354 mv "$TMPDIR/app_process32" "$TMPDIR/app_process32.real"
355 mv "$TMPDIR/app_process64" "$TMPDIR/app_process64.real"
357 generate_zygote_wrapper "app_process32" "/system/bin/app_process32.real"
358 generate_zygote_wrapper "app_process64" "/system/bin/app_process64.real"
359 else
360 # A 32-bit device.
361 generate_zygote_wrapper "app_process.wrap" "/system/bin/app_process32"
364 # General command-line tool wrapper (use for anything that's not started as
365 # zygote).
366 cat <<EOF >"$TMPDIR/asanwrapper"
367 #!/system/bin/sh
368 LD_PRELOAD=$ASAN_RT_SYMLINK \\
369 exec \$@
373 if [[ -n "$ASAN_RT64" ]]; then
374 cat <<EOF >"$TMPDIR/asanwrapper64"
375 #!/system/bin/sh
376 LD_PRELOAD=$ASAN_RT_SYMLINK \\
377 exec \$@
382 function install { # from, to, chmod, chcon
383 local _from=$1
384 local _to=$2
385 local _mode=$3
386 local _context=$4
387 local _basename="$(basename "$_from")"
388 echo "Installing $_to/$_basename $_mode $_context"
389 adb_push "$_from" "$_to/$_basename"
390 adb_shell chown root.shell "$_to/$_basename"
391 if [[ -n "$_mode" ]]; then
392 adb_shell chmod "$_mode" "$_to/$_basename"
394 if [[ -n "$_context" ]]; then
395 adb_shell chcon "$_context" "$_to/$_basename"
399 if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
400 # Make SELinux happy by keeping app_process wrapper and the shell
401 # it runs on in zygote domain.
402 ENFORCING=0
403 if adb_shell getenforce | grep Enforcing >/dev/null; then
404 # Sometimes shell is not allowed to change file contexts.
405 # Temporarily switch to permissive.
406 ENFORCING=1
407 adb_shell setenforce 0
410 if [[ PRE_L -eq 1 ]]; then
411 CTX=u:object_r:system_file:s0
412 else
413 CTX=u:object_r:zygote_exec:s0
416 echo '>> Pushing files to the device'
418 if [[ -n "$ASAN_RT64" ]]; then
419 install "$TMPDIR/$ASAN_RT" /system/lib 644
420 install "$TMPDIR/$ASAN_RT64" /system/lib64 644
421 install "$TMPDIR/app_process32" /system/bin 755 $CTX
422 install "$TMPDIR/app_process32.real" /system/bin 755 $CTX
423 install "$TMPDIR/app_process64" /system/bin 755 $CTX
424 install "$TMPDIR/app_process64.real" /system/bin 755 $CTX
425 install "$TMPDIR/asanwrapper" /system/bin 755
426 install "$TMPDIR/asanwrapper64" /system/bin 755
428 adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
429 adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
430 adb_shell rm -f /system/lib64/$ASAN_RT_SYMLINK
431 adb_shell ln -s $ASAN_RT64 /system/lib64/$ASAN_RT_SYMLINK
432 else
433 install "$TMPDIR/$ASAN_RT" /system/lib 644
434 install "$TMPDIR/app_process32" /system/bin 755 $CTX
435 install "$TMPDIR/app_process.wrap" /system/bin 755 $CTX
436 install "$TMPDIR/asanwrapper" /system/bin 755 $CTX
438 adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
439 adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
441 adb_shell rm /system/bin/app_process
442 adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process
445 adb_shell cp /system/bin/sh /system/bin/sh-from-zygote
446 adb_shell chcon $CTX /system/bin/sh-from-zygote
448 if [[ ANDROID_O -eq 1 ]]; then
449 # For Android O, the linker namespace is temporarily disabled.
450 adb_shell mv /system/etc/ld.config.txt /system/etc/ld.config.txt.saved
453 if [ $ENFORCING == 1 ]; then
454 adb_shell setenforce 1
457 echo '>> Restarting shell (asynchronous)'
458 adb_shell stop
459 adb_shell start
461 echo '>> Please wait until the device restarts'
462 else
463 echo '>> Device is up to date'
466 rm -r "$TMPDIRBASE"