From c49c393f73ac6d1dd35322415dd9e719325c2307 Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Tue, 15 Oct 2019 02:01:19 -0700 Subject: [PATCH] Repack libgcc.a to only include required objects Previous solution by using objcopy uses a quirky behaviour of the GNU objcopy and there is no equivalent option in llvm-objcopy. Instead of removing symbols, extract and repack libgcc to only include required objects. Bug: 142585047 Test: presubmit Change-Id: I58af74c18838f797e481da38c3265f0624fddf99 --- Android.bp | 91 ++------------------------------------- cc/builder.go | 25 +++++++++++ cc/toolchain_library.go | 11 +++++ scripts/archive_repack.sh | 87 +++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 87 deletions(-) create mode 100755 scripts/archive_repack.sh diff --git a/Android.bp b/Android.bp index 9962b6246..fa9a01763 100644 --- a/Android.bp +++ b/Android.bp @@ -579,104 +579,21 @@ toolchain_library { arch: { arm: { src: "prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a", - strip: { - keep_symbols_list: [ - // unwind-arm.o - "_Unwind_Complete", - "_Unwind_DeleteException", - "_Unwind_GetCFA", - "_Unwind_VRS_Get", - "_Unwind_VRS_Pop", - "_Unwind_VRS_Set", - "__aeabi_unwind_cpp_pr0", - "__aeabi_unwind_cpp_pr1", - "__aeabi_unwind_cpp_pr2", - "__gnu_Unwind_Backtrace", - "__gnu_Unwind_ForcedUnwind", - "__gnu_Unwind_RaiseException", - "__gnu_Unwind_Resume", - "__gnu_Unwind_Resume_or_Rethrow", - - // libunwind.o - "_Unwind_Backtrace", - "_Unwind_ForcedUnwind", - "_Unwind_RaiseException", - "_Unwind_Resume", - "_Unwind_Resume_or_Rethrow", - "___Unwind_Backtrace", - "___Unwind_ForcedUnwind", - "___Unwind_RaiseException", - "___Unwind_Resume", - "___Unwind_Resume_or_Rethrow", - "__gnu_Unwind_Restore_VFP", - "__gnu_Unwind_Restore_VFP_D", - "__gnu_Unwind_Restore_VFP_D_16_to_31", - "__gnu_Unwind_Restore_WMMXC", - "__gnu_Unwind_Restore_WMMXD", - "__gnu_Unwind_Save_VFP", - "__gnu_Unwind_Save_VFP_D", - "__gnu_Unwind_Save_VFP_D_16_to_31", - "__gnu_Unwind_Save_WMMXC", - "__gnu_Unwind_Save_WMMXD", - "__restore_core_regs", - "restore_core_regs", - - // pr-support.o - "_Unwind_GetDataRelBase", - "_Unwind_GetLanguageSpecificData", - "_Unwind_GetRegionStart", - "_Unwind_GetTextRelBase", - "__gnu_unwind_execute", - "__gnu_unwind_frame", - ], - }, + repack_objects_to_keep: ["unwind-arm.o", "libunwind.o", "pr-support.o"], }, arm64: { src: "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a", + repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"], }, x86: { src: "prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/lib/gcc/x86_64-linux-android/4.9.x/32/libgcc.a", - + repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"], }, x86_64: { src: "prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/lib/gcc/x86_64-linux-android/4.9.x/libgcc.a", + repack_objects_to_keep: ["unwind-dw2.o", "unwind-dw2-fde-dip.o"], }, }, - strip: { - keep_symbols_list: [ - // unwind-dw2.o - "_Unwind_Backtrace", - "_Unwind_DeleteException", - "_Unwind_FindEnclosingFunction", - "_Unwind_ForcedUnwind", - "_Unwind_GetCFA", - "_Unwind_GetDataRelBase", - "_Unwind_GetGR", - "_Unwind_GetIP", - "_Unwind_GetIPInfo", - "_Unwind_GetLanguageSpecificData", - "_Unwind_GetRegionStart", - "_Unwind_GetTextRelBase", - "_Unwind_RaiseException", - "_Unwind_Resume", - "_Unwind_Resume_or_Rethrow", - "_Unwind_SetGR", - "_Unwind_SetIP", - "__frame_state_for", - - // unwind-dw2-fde-dip.o - "_Unwind_Find_FDE", - "__deregister_frame", - "__deregister_frame_info", - "__deregister_frame_info_bases", - "__register_frame", - "__register_frame_info", - "__register_frame_info_bases", - "__register_frame_info_table", - "__register_frame_info_table_bases", - "__register_frame_table", - ], - }, } toolchain_library { diff --git a/cc/builder.go b/cc/builder.go index 0760dd490..491ebc59e 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -130,6 +130,17 @@ var ( }, "args", "crossCompile") + _ = pctx.SourcePathVariable("archiveRepackPath", "build/soong/scripts/archive_repack.sh") + + archiveRepack = pctx.AndroidStaticRule("archiveRepack", + blueprint.RuleParams{ + Depfile: "${out}.d", + Deps: blueprint.DepsGCC, + Command: "CLANG_BIN=${config.ClangBin} $archiveRepackPath -i ${in} -o ${out} -d ${out}.d ${objects}", + CommandDeps: []string{"$archiveRepackPath"}, + }, + "objects") + emptyFile = pctx.AndroidStaticRule("emptyFile", blueprint.RuleParams{ Command: "rm -f $out && touch $out", @@ -866,6 +877,20 @@ func TransformCoverageFilesToZip(ctx android.ModuleContext, return android.OptionalPath{} } +func TransformArchiveRepack(ctx android.ModuleContext, inputFile android.Path, + outputFile android.WritablePath, objects []string) { + + ctx.Build(pctx, android.BuildParams{ + Rule: archiveRepack, + Description: "Repack archive " + outputFile.Base(), + Output: outputFile, + Input: inputFile, + Args: map[string]string{ + "objects": strings.Join(objects, " "), + }, + }) +} + func gccCmd(toolchain config.Toolchain, cmd string) string { return filepath.Join(toolchain.GccRoot(), "bin", toolchain.GccTriple()+"-"+cmd) } diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go index fef4508f2..dfc6f7679 100644 --- a/cc/toolchain_library.go +++ b/cc/toolchain_library.go @@ -29,6 +29,9 @@ func init() { type toolchainLibraryProperties struct { // the prebuilt toolchain library, as a path from the top of the source tree Src *string `android:"arch_variant"` + + // Repack the archive with only the selected objects. + Repack_objects_to_keep []string `android:"arch_variant"` } type toolchainLibraryDecorator struct { @@ -90,6 +93,14 @@ func (library *toolchainLibraryDecorator) link(ctx ModuleContext, return outputFile } + if library.Properties.Repack_objects_to_keep != nil { + fileName := ctx.ModuleName() + staticLibraryExtension + outputFile := android.PathForModuleOut(ctx, fileName) + TransformArchiveRepack(ctx, srcPath, outputFile, library.Properties.Repack_objects_to_keep) + + return outputFile + } + return srcPath } diff --git a/scripts/archive_repack.sh b/scripts/archive_repack.sh new file mode 100755 index 000000000..f09372dd9 --- /dev/null +++ b/scripts/archive_repack.sh @@ -0,0 +1,87 @@ +#!/bin/bash -e + +# Copyright 2019 Google Inc. All rights reserved. +# +# 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 extract and repack an archive with specified object files. +# Inputs: +# Environment: +# CLANG_BIN: path to the clang bin directory +# Arguments: +# -i ${file}: input file +# -o ${file}: output file +# -d ${file}: deps file + +set -o pipefail + +OPTSTRING=d:i:o: + +usage() { + cat < + +OPTIONS: + -i : input file + -o : output file + -d : deps file +EOF + exit 1 +} + +while getopts $OPTSTRING opt; do + case "$opt" in + d) depsfile="${OPTARG}" ;; + i) infile="${OPTARG}" ;; + o) outfile="${OPTARG}" ;; + ?) usage ;; + esac +done +shift "$(($OPTIND -1))" + +if [ -z "${infile}" ]; then + echo "-i argument is required" + usage +fi + +if [ -z "${outfile}" ]; then + echo "-o argument is required" + usage +fi + +# Produce deps file +if [ ! -z "${depsfile}" ]; then + cat < "${depsfile}" +${outfile}: ${infile} ${CLANG_BIN}/llvm-ar +EOF +fi + +# Get absolute path for outfile and llvm-ar. +LLVM_AR="${PWD}/${CLANG_BIN}/llvm-ar" +if [[ "$outfile" != /* ]]; then + outfile="${PWD}/${outfile}" +fi + +tempdir="${outfile}.tmp" + +# Clean up any previous temporary files. +rm -f "${outfile}" +rm -rf "${tempdir}" + +# Do repack +# We have to change working directory since ar only allows extracting to CWD. +mkdir "${tempdir}" +cp "${infile}" "${tempdir}/archive" +cd "${tempdir}" +"${LLVM_AR}" x "archive" +"${LLVM_AR}" --format=gnu qc "${outfile}" "$@"