diff options
| -rw-r--r-- | build/apex/Android.bp | 2 | ||||
| -rwxr-xr-x | build/apex/art_apex_test.py | 2 | ||||
| -rw-r--r-- | tools/Android.bp | 10 | ||||
| -rwxr-xr-x | tools/compile_bcp.sh | 178 |
4 files changed, 192 insertions, 0 deletions
diff --git a/build/apex/Android.bp b/build/apex/Android.bp index b99742b4a7..3639e13baf 100644 --- a/build/apex/Android.bp +++ b/build/apex/Android.bp @@ -118,12 +118,14 @@ art_tools_debug_binaries_both = [ // Tools exclusively for the device APEX derived from art-tools in art/Android.mk. art_tools_device_only_binaries = [ + "compile_bcp.sh", // oatdump cannot link with host linux_bionic due to not using clang lld; // TODO: Make it work with clang lld. "oatdump", ] // Same, but for only for debug packages. art_tools_debug_device_only_binaries = [ + "compile_bcp.sh", // oatdumpd cannot link with host linux_bionic due to not using clang lld; // TODO: Make it work with clang lld. "oatdumpd", diff --git a/build/apex/art_apex_test.py b/build/apex/art_apex_test.py index 2c40244b9a..d959d3f532 100755 --- a/build/apex/art_apex_test.py +++ b/build/apex/art_apex_test.py @@ -519,6 +519,7 @@ class ReleaseChecker: self._checker.check_file('apex_manifest.pb') # Check binaries for ART. + self._checker.check_executable("compile_bcp.sh") self._checker.check_first_executable('dex2oat') self._checker.check_executable('dexdump') self._checker.check_executable('dexlist') @@ -613,6 +614,7 @@ class ReleaseTargetChecker: # removed in Android R. # Check binaries for ART. + self._checker.check_executable("compile_bcp.sh") self._checker.check_executable('oatdump') self._checker.check_multilib_executable('dex2oat') diff --git a/tools/Android.bp b/tools/Android.bp index 042eb199d7..f6733ce185 100644 --- a/tools/Android.bp +++ b/tools/Android.bp @@ -74,3 +74,13 @@ sh_binary { }, }, } + +cc_prebuilt_binary { + name: "compile_bcp.sh", + host_supported: false, + srcs: ["compile_bcp.sh"], + apex_available: [ + "com.android.art.debug", + "com.android.art.release", + ], +} diff --git a/tools/compile_bcp.sh b/tools/compile_bcp.sh new file mode 100755 index 0000000000..397456bc1e --- /dev/null +++ b/tools/compile_bcp.sh @@ -0,0 +1,178 @@ +#!/system/bin/sh +# +# Copyright (C) 2020 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Script to recompile the non-APEX jars in the boot class path and +# system server jars for on-device signing following an ART Module +# update. +# +# For testing purposes, prepare Android device using: +# +# $ adb root +# $ adb shell setenforce 0 +# +# TODO: this is script is currently for proof-of-concept. It does not +# respect many of the available dalvik.vm properties, e.g. affinity, +# threads, etc nor dalvik.vm.dex2oat-resolve-startup-strings. +# +# TODO: some of the system server jars seem to be installed on device +# for 32-bit and 64-bit, but services.jar artifacts are just one arch. +# Not sure why both flavors are present. Does this script need to generate +# both? +# +# TODO: Logging failure / error handling. + +# Output directory for generated files. Real location is TBD. +output=$PWD/out + +function mkdir_clean() { + # mkdir_clean <dir_path> + local dir_path=$1 + rm -rf "${dir_path}" + mkdir -p "${dir_path}" +} + +# Determine candidate architectures for this device. +case `getprop ro.product.cpu.abi` in + arm*) + arch32=arm + arch64=arm64 + ;; + x86*) + arch32=x86 + arch64=x86_64 + ;; + *) + echo "Unknown abi" + exit -1 +esac + +# Determine architectures to use for Zygote. system_server runs under the primary +# architecture. Prefer dex2oat64 if device supports 64-bits. +case $(getprop ro.zygote) in + zygote32) + # The primary architecture is 32-bits. + archs="$arch32" + systemserver_arch="$arch32" + dex2oat=/apex/com.android.art/bin/dex2oat32 + ;; + zygote32_64) + # The primary architecture is 32-bits and the secondary is 64-bits. + archs="$arch32 $arch64" + systemserver_arch="$arch32" + dex2oat=/apex/com.android.art/bin/dex2oat64 + ;; + zygote64_32) + # The primary architecture is 64-bits and the secondary is 32-bits. + archs="$arch32 $arch64" + systemserver_arch="$arch64" + dex2oat=/apex/com.android.art/bin/dex2oat64 + ;; + zygote64) + # Primary architecture is 64-bits. + archs="$arch64" + systemserver_arch="$arch64" + dex2oat=/apex/com.android.art/bin/dex2oat64 + ;; + *) + echo "Unknown ro.zygote value" + exit -1 + ;; +esac + +# Determine which boot class path jars to compile. +device_bcp_list="" +device_bcp_dex_files="" +for jar in ${DEX2OATBOOTCLASSPATH//:/ }; do + if [[ ${jar} = *com.android.art* ]]; then + continue + fi + device_bcp_list="${device_bcp_list}${device_bcp_list:+:}${jar}" + device_bcp_dex_files="$device_bcp_dex_files --dex-file=${jar}" +done + +# Compile the boot class path elements that are present on device. +for arch in ${archs}; do + arch_output="${output}/$arch" + mkdir_clean "${arch_output}" + + invocation_dir="${output}/$arch" + mkdir_clean "${invocation_dir}" + + echo "Compiling ${device_bcp_list} ($arch)" + ${dex2oat} --avoid-storing-invocation \ + --compiler-filter=speed-profile \ + --profile-file=/system/etc/boot-image.prof \ + --dirty-image-objects=/system/etc/dirty-image-objects \ + --runtime-arg -Xbootclasspath:${DEX2OATBOOTCLASSPATH} \ + --boot-image=/apex/com.android.art/javalib/boot.art \ + ${device_bcp_dex_files} \ + --generate-debug-info \ + --image-format=lz4hc \ + --strip \ + --oat-file=${arch_output}/boot.oat \ + --image=${arch_output}/boot.art \ + --android-root=out/empty \ + --abort-on-hard-verifier-error \ + --instruction-set=$arch \ + --generate-mini-debug-info +done + +# Compile system_server and related jars. +classloader_context="" +for jar in ${SYSTEMSERVERCLASSPATH//:/ }; do + # Skip class path components in APEXes + if [[ ${jar} = "/apex"* ]]; then + continue + fi + + # Add profile if it exists. Only services.jar has a profile in AOSP. + stem=$(basename $jar .jar) + profile_file=/system/framework/${stem}.jar.prof + if [ -f "${profile_file}" ] ; then + profile_arg=--profile-file=${profile_file} + filter=speed-profile + else + profile_arg="" + filter=speed + fi + + # Add updatable boot class path packages file if there is a property for it. + updatable_bcp_file=$(getprop dalvik.vm.dex2oat-updatable-bcp-packages-file) + if [ "${updatable_bcp_file}" -a -f "${updatable_bcp_file}" ] ; then + updatable_bcp_file_arg="--updatable-bcp-packages-file=${updatable_bcp_file}" + fi + + echo "Compiling ${jar} (${systemserver_arch} ${filter} PCL[${classloader_context}])" + $dex2oat --avoid-storing-invocation \ + --runtime-arg -Xbootclasspath:${DEX2OATBOOTCLASSPATH} \ + --class-loader-context=PCL[${classloader_context}] \ + --boot-image=/apex/com.android.art/javalib/boot.art:${output}/boot-framework.art \ + --dex-file=${jar} \ + --oat-file=${arch_output}/${stem}.odex \ + --app-image-file=${oat_file_dir}/${stem}.art \ + --android-root=out/empty \ + --instruction-set=${systemserver_arch} \ + --abort-on-hard-verifier-error \ + --compiler-filter=$filter \ + --generate-mini-debug-info \ + --compilation-reason=prebuilt \ + --image-format=lz4 \ + --resolve-startup-const-strings=true \ + ${profile_arg} \ + ${updatable_bcp_file_arg} + + classloader_context=${classloader_context}${classloader_context:+:}${jar} +done |