11188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker#!/bin/bash 21188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker#===- lib/asan/scripts/asan_device_setup -----------------------------------===# 31188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# 41188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# The LLVM Compiler Infrastructure 51188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# 61188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# This file is distributed under the University of Illinois Open Source 71188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# License. See LICENSE.TXT for details. 81188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# 91188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# Prepare Android device to run ASan applications. 101188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# 111188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker#===------------------------------------------------------------------------===# 121188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 131188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerset -e 141188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 151188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerHERE="$(cd "$(dirname "$0")" && pwd)" 161188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 171188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerrevert=no 181188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerextra_options= 191188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerdevice= 201188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerlib= 211188dcf30923cb444143ffa4b83dc951037e76agitbuildkickeruse_su=0 221188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 231188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction usage { 241188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]" 251188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " --revert: Uninstall ASan from the device." 261188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " --lib: Path to ASan runtime library." 271188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " --extra-options: Extra ASAN_OPTIONS." 281188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " --device: Install to the given device. Use 'adb devices' to find" 291188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " device-id." 301188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " --use-su: Use 'su -c' prefix for every adb command instead of using" 311188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " 'adb root' once." 321188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo 331188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 341188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 351188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 361188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction adb_push { 371188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $use_su -eq 0 ]; then 381188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB push "$1" "$2" 391188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 401188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local FILENAME=$(basename $1) 411188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB push "$1" "/data/local/tmp/$FILENAME" 421188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null 431188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\"" 441188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\"" 451188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 461188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 471188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 481188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction adb_remount { 491188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $use_su -eq 0 ]; then 501188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB remount 511188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 521188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1` 531188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ "$STORAGE" != "" ]; then 541188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo Remounting $STORAGE at /system 551188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell su -c "mount -o remount,rw $STORAGE /system" 561188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 571188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo Failed to get storage device name for "/system" mount point 581188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 591188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 601188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 611188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 621188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction adb_shell { 631188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $use_su -eq 0 ]; then 641188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell $@ 651188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 661188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell su -c "$*" 671188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 681188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 691188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 701188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction adb_root { 711188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $use_su -eq 0 ]; then 721188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB root 731188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 741188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 751188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 761188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction adb_wait_for_device { 771188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB wait-for-device 781188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 791188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 801188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction adb_pull { 811188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $use_su -eq 0 ]; then 821188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB pull "$1" "$2" 831188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 841188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local FILENAME=$(basename $1) 851188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null 861188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $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\\\"" && 871188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\"" 881188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 891188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 901188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 911188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction get_device_arch { # OUT OUT64 921188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _outvar=$1 931188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _outvar64=$2 941188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _ABI=$(adb_shell getprop ro.product.cpu.abi) 951188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _ARCH= 961188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _ARCH64= 971188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ $_ABI == x86* ]]; then 981188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker _ARCH=i686 991188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker elif [[ $_ABI == armeabi* ]]; then 1001188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker _ARCH=arm 1011188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker elif [[ $_ABI == arm64-v8a* ]]; then 1021188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker _ARCH=arm 1031188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker _ARCH64=aarch64 1041188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 1051188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "Unrecognized device ABI: $_ABI" 1061188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 1071188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 1081188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker eval $_outvar=\$_ARCH 1091188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker eval $_outvar64=\$_ARCH64 1101188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 1111188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1121188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerwhile [[ $# > 0 ]]; do 1131188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker case $1 in 1141188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker --revert) 1151188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker revert=yes 1161188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ;; 1171188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker --extra-options) 1181188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker shift 1191188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ $# == 0 ]]; then 1201188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "--extra-options requires an argument." 1211188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 1221188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 1231188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker extra_options="$1" 1241188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ;; 1251188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker --lib) 1261188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker shift 1271188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ $# == 0 ]]; then 1281188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "--lib requires an argument." 1291188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 1301188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 1311188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker lib="$1" 1321188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ;; 1331188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker --device) 1341188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker shift 1351188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ $# == 0 ]]; then 1361188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "--device requires an argument." 1371188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 1381188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 1391188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker device="$1" 1401188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ;; 1411188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker --use-su) 1421188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker use_su=1 1431188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ;; 1441188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker *) 1451188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker usage 1461188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ;; 1471188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker esac 1481188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker shift 1491188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerdone 1501188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1511188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerADB=${ADB:-adb} 1521188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ x$device != x ]]; then 1531188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ADB="$ADB -s $device" 1541188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 1551188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1561188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [ $use_su -eq 1 ]; then 1571188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # Test if 'su' is present on the device 1581188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'` 1591188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then 1601188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "ERROR: Cannot use 'su -c':" 1611188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "$ adb shell su -c \"echo foo\"" 1621188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo $SU_TEST_OUT 1631188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "Check that 'su' binary is correctly installed on the device or omit" 1641188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo " --use-su flag" 1651188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 1661188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 1671188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 1681188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1691188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerecho '>> Remounting /system rw' 1701188dcf30923cb444143ffa4b83dc951037e76agitbuildkickeradb_wait_for_device 1711188dcf30923cb444143ffa4b83dc951037e76agitbuildkickeradb_root 1721188dcf30923cb444143ffa4b83dc951037e76agitbuildkickeradb_wait_for_device 1731188dcf30923cb444143ffa4b83dc951037e76agitbuildkickeradb_remount 1741188dcf30923cb444143ffa4b83dc951037e76agitbuildkickeradb_wait_for_device 1751188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1761188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerget_device_arch ARCH ARCH64 1771188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerecho "Target architecture: $ARCH" 1781188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerASAN_RT="libclang_rt.asan-$ARCH-android.so" 1791188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -n $ARCH64 ]]; then 1801188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "Target architecture: $ARCH64" 1811188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_RT64="libclang_rt.asan-$ARCH64-android.so" 1821188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 1831188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1841188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ x$revert == xyes ]]; then 1851188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Uninstalling ASan' 1861188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 1871188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then 1881188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Pre-L device detected.' 1891188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell mv /system/bin/app_process.real /system/bin/app_process 1901188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/asanwrapper 1911188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker elif ! adb_shell ls -l /system/bin/app_process64.real | grep -o 'No such file or directory' >&/dev/null; then 1921188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # 64-bit installation. 1931188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell mv /system/bin/app_process32.real /system/bin/app_process32 1941188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell mv /system/bin/app_process64.real /system/bin/app_process64 1951188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/asanwrapper 1961188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/asanwrapper64 1971188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 1981188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # 32-bit installation. 1991188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/app_process.wrap 2001188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/asanwrapper 2011188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/app_process 2021188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell ln -s /system/bin/app_process32 /system/bin/app_process 2031188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 2041188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2051188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Restarting shell' 2061188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell stop 2071188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell start 2081188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2091188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # Remove the library on the last step to give a chance to the 'su' binary to 2101188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # be executed without problem. 2111188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/lib/$ASAN_RT 2121188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2131188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Done' 2141188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 0 2151188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2161188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2171188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -d "$lib" ]]; then 2181188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_RT_PATH="$lib" 2191188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then 2201188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_RT_PATH=$(dirname "$lib") 2211188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelif [[ -f "$HERE/$ASAN_RT" ]]; then 2221188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_RT_PATH="$HERE" 2231188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelif [[ $(basename "$HERE") == "bin" ]]; then 2241188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # We could be in the toolchain's base directory. 2251188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # Consider ../lib, ../lib/asan, ../lib/linux, 2261188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux. 2271188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker P=$(ls "$HERE"/../lib/"$ASAN_RT" \ 2281188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker "$HERE"/../lib/asan/"$ASAN_RT" \ 2291188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker "$HERE"/../lib/linux/"$ASAN_RT" \ 2301188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" \ 2311188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker "$HERE"/../lib64/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1) 2321188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ -n "$P" ]]; then 2331188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_RT_PATH="$(dirname "$P")" 2341188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 2351188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2361188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2371188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then 2381188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo ">> ASan runtime library not found" 2391188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 2401188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2411188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2421188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -n "$ASAN_RT64" ]]; then 2431188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT64" ]]; then 2441188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo ">> ASan runtime library not found" 2451188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker exit 1 2461188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 2471188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2481188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2491188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerTMPDIRBASE=$(mktemp -d) 2501188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerTMPDIROLD="$TMPDIRBASE/old" 2511188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerTMPDIR="$TMPDIRBASE/new" 2521188dcf30923cb444143ffa4b83dc951037e76agitbuildkickermkdir "$TMPDIROLD" 2531188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2541188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerRELEASE=$(adb_shell getprop ro.build.version.release) 2551188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerPRE_L=0 2561188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif echo "$RELEASE" | grep '^4\.' >&/dev/null; then 2571188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker PRE_L=1 2581188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2591188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2601188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then 2611188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2621188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then 2631188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Old-style ASan installation detected. Reverting.' 2641188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell mv /system/bin/app_process.real /system/bin/app_process 2651188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 2661188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2671188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Pre-L device detected. Setting up app_process symlink.' 2681188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell mv /system/bin/app_process /system/bin/app_process32 2691188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell ln -s /system/bin/app_process32 /system/bin/app_process 2701188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2711188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2721188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerecho '>> Copying files from the device' 2731188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -n "$ASAN_RT64" ]]; then 2741188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true 2751188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/lib64/"$ASAN_RT64" "$TMPDIROLD" || true 2761188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/app_process32 "$TMPDIROLD" || true 2771188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/app_process32.real "$TMPDIROLD" || true 2781188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/app_process64 "$TMPDIROLD" || true 2791188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/app_process64.real "$TMPDIROLD" || true 2801188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true 2811188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/asanwrapper64 "$TMPDIROLD" || true 2821188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelse 2831188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true 2841188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/app_process32 "$TMPDIROLD" || true 2851188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true 2861188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true 2871188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2881188dcf30923cb444143ffa4b83dc951037e76agitbuildkickercp -r "$TMPDIROLD" "$TMPDIR" 2891188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2901188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -f "$TMPDIR/app_process.wrap" || -f "$TMPDIR/app_process64.real" ]]; then 2911188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo ">> Previous installation detected" 2921188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelse 2931188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo ">> New installation" 2941188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 2951188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2961188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerecho '>> Generating wrappers' 2971188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 2981188dcf30923cb444143ffa4b83dc951037e76agitbuildkickercp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/" 2991188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -n "$ASAN_RT64" ]]; then 3001188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker cp "$ASAN_RT_PATH/$ASAN_RT64" "$TMPDIR/" 3011188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 3021188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3031188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# FIXME: alloc_dealloc_mismatch=0 prevents a failure in libdvm startup, 3041188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# which may or may not be a real bug (probably not). 3051188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerASAN_OPTIONS=start_deactivated=1,alloc_dealloc_mismatch=0,malloc_context_size=0 3061188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3071188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction generate_zygote_wrapper { # from, to, asan_rt 3081188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _from=$1 3091188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _to=$2 3101188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _asan_rt=$3 3111188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ PRE_L -eq 0 ]]; then 3121188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # LD_PRELOAD parsing is broken in N if it starts with ":". Luckily, it is 3131188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # unset in the system environment since L. 3141188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _ld_preload=$_asan_rt 3151188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 3161188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _ld_preload=\$LD_PRELOAD:$_asan_rt 3171188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 3181188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker cat <<EOF >"$TMPDIR/$_from" 3191188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker#!/system/bin/sh-from-zygote 3201188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerASAN_OPTIONS=$ASAN_OPTIONS \\ 3211188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\ 3221188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerLD_PRELOAD=$_ld_preload \\ 3231188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerexec $_to \$@ 3241188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3251188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerEOF 3261188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 3271188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3281188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# On Android-L not allowing user segv handler breaks some applications. 3291188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ PRE_L -eq 0 ]]; then 3301188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1" 3311188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 3321188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3331188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ x$extra_options != x ]] ; then 3341188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options" 3351188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 3361188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3371188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# Zygote wrapper. 3381188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -f "$TMPDIR/app_process64" ]]; then 3391188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # A 64-bit device. 3401188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ ! -f "$TMPDIR/app_process64.real" ]]; then 3411188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # New installation. 3421188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker mv "$TMPDIR/app_process32" "$TMPDIR/app_process32.real" 3431188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker mv "$TMPDIR/app_process64" "$TMPDIR/app_process64.real" 3441188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 3451188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker generate_zygote_wrapper "app_process32" "/system/bin/app_process32.real" "$ASAN_RT" 3461188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker generate_zygote_wrapper "app_process64" "/system/bin/app_process64.real" "$ASAN_RT64" 3471188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelse 3481188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # A 32-bit device. 3491188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker generate_zygote_wrapper "app_process.wrap" "/system/bin/app_process32" "$ASAN_RT" 3501188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 3511188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3521188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# General command-line tool wrapper (use for anything that's not started as 3531188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker# zygote). 3541188dcf30923cb444143ffa4b83dc951037e76agitbuildkickercat <<EOF >"$TMPDIR/asanwrapper" 3551188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker#!/system/bin/sh 3561188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerLD_PRELOAD=$ASAN_RT \\ 3571188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerexec \$@ 3581188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3591188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerEOF 3601188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3611188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif [[ -n "$ASAN_RT64" ]]; then 3621188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker cat <<EOF >"$TMPDIR/asanwrapper64" 3631188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker#!/system/bin/sh 3641188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerLD_PRELOAD=$ASAN_RT64 \\ 3651188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerexec \$@ 3661188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3671188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerEOF 3681188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 3691188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3701188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfunction install { # from, to, chmod, chcon 3711188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _from=$1 3721188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _to=$2 3731188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _mode=$3 3741188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _context=$4 3751188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker local _basename="$(basename "$_from")" 3761188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo "Installing $_to/$_basename $_mode $_context" 3771188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_push "$_from" "$_to/$_basename" 3781188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell chown root.shell "$_to/$_basename" 3791188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ -n "$_mode" ]]; then 3801188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell chmod "$_mode" "$_to/$_basename" 3811188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 3821188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ -n "$_context" ]]; then 3831188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell chcon "$_context" "$_to/$_basename" 3841188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 3851188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker} 3861188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3871188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerif ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then 3881188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # Make SELinux happy by keeping app_process wrapper and the shell 3891188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # it runs on in zygote domain. 3901188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ENFORCING=0 3911188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if adb_shell getenforce | grep Enforcing >/dev/null; then 3921188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # Sometimes shell is not allowed to change file contexts. 3931188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker # Temporarily switch to permissive. 3941188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker ENFORCING=1 3951188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell setenforce 0 3961188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 3971188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 3981188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ PRE_L -eq 1 ]]; then 3991188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker CTX=u:object_r:system_file:s0 4001188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 4011188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker CTX=u:object_r:zygote_exec:s0 4021188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 4031188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4041188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Pushing files to the device' 4051188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4061188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [[ -n "$ASAN_RT64" ]]; then 4071188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/$ASAN_RT" /system/lib 644 4081188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/$ASAN_RT64" /system/lib64 644 4091188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/app_process32" /system/bin 755 $CTX 4101188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/app_process32.real" /system/bin 755 $CTX 4111188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/app_process64" /system/bin 755 $CTX 4121188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/app_process64.real" /system/bin 755 $CTX 4131188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/asanwrapper" /system/bin 755 4141188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/asanwrapper64" /system/bin 755 4151188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker else 4161188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/$ASAN_RT" /system/lib 644 4171188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/app_process32" /system/bin 755 $CTX 4181188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/app_process.wrap" /system/bin 755 $CTX 4191188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker install "$TMPDIR/asanwrapper" /system/bin 755 $CTX 4201188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4211188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell rm /system/bin/app_process 4221188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process 4231188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 4241188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4251188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell cp /system/bin/sh /system/bin/sh-from-zygote 4261188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell chcon $CTX /system/bin/sh-from-zygote 4271188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4281188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker if [ $ENFORCING == 1 ]; then 4291188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell setenforce 1 4301188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker fi 4311188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4321188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Restarting shell (asynchronous)' 4331188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell stop 4341188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker adb_shell start 4351188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4361188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Please wait until the device restarts' 4371188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerelse 4381188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker echo '>> Device is up to date' 4391188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerfi 4401188dcf30923cb444143ffa4b83dc951037e76agitbuildkicker 4411188dcf30923cb444143ffa4b83dc951037e76agitbuildkickerrm -r "$TMPDIRBASE" 442