diff --git a/cc/library.go b/cc/library.go index 7cbfdb534..2b7c9a135 100644 --- a/cc/library.go +++ b/cc/library.go @@ -110,6 +110,9 @@ type LibraryProperties struct { // Symbol tags that should be ignored from the symbol file Exclude_symbol_tags []string } + + // Order symbols in .bss section by their sizes. Only useful for shared libraries. + Sort_bss_symbols_by_size *bool } type LibraryMutatedProperties struct { @@ -758,6 +761,18 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext, linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...) linkerDeps = append(linkerDeps, objs.tidyFiles...) + if Bool(library.Properties.Sort_bss_symbols_by_size) { + unsortedOutputFile := android.PathForModuleOut(ctx, "unsorted", fileName) + TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, + deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, + linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, unsortedOutputFile, implicitOutputs) + + symbolOrderingFile := android.PathForModuleOut(ctx, "unsorted", fileName+".symbol_order") + symbolOrderingFlag := library.baseLinker.sortBssSymbolsBySize(ctx, unsortedOutputFile, symbolOrderingFile, builderFlags) + builderFlags.ldFlags += " " + symbolOrderingFlag + linkerDeps = append(linkerDeps, symbolOrderingFile) + } + TransformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs, deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, false, builderFlags, outputFile, implicitOutputs) diff --git a/cc/linker.go b/cc/linker.go index fa3b0a63d..daacec11b 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -147,9 +147,6 @@ type BaseLinkerProperties struct { // local file name to pass to the linker as --version_script Version_script *string `android:"path,arch_variant"` - - // Local file name to pass to the linker as --symbol-ordering-file - Symbol_ordering_file *string `android:"arch_variant"` } func NewBaseLinker(sanitize *sanitize) *baseLinker { @@ -442,16 +439,6 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { } } - if !linker.dynamicProperties.BuildStubs { - symbolOrderingFile := ctx.ExpandOptionalSource( - linker.Properties.Symbol_ordering_file, "Symbol_ordering_file") - if symbolOrderingFile.Valid() { - flags.LdFlags = append(flags.LdFlags, - "-Wl,--symbol-ordering-file,"+symbolOrderingFile.String()) - flags.LdFlagsDeps = append(flags.LdFlagsDeps, symbolOrderingFile.Path()) - } - } - return flags } @@ -487,3 +474,29 @@ func (linker *baseLinker) injectVersionSymbol(ctx ModuleContext, in android.Path }, }) } + +// Rule to generate .bss symbol ordering file. + +var ( + _ = pctx.SourcePathVariable("genSortedBssSymbolsPath", "build/soong/scripts/gen_sorted_bss_symbols.sh") + gen_sorted_bss_symbols = pctx.AndroidStaticRule("gen_sorted_bss_symbols", + blueprint.RuleParams{ + Command: "CROSS_COMPILE=$crossCompile $genSortedBssSymbolsPath ${in} ${out}", + CommandDeps: []string{"$genSortedBssSymbolsPath"}, + }, + "crossCompile") +) + +func (linker *baseLinker) sortBssSymbolsBySize(ctx ModuleContext, in android.Path, symbolOrderingFile android.ModuleOutPath, flags builderFlags) string { + crossCompile := gccCmd(flags.toolchain, "") + ctx.Build(pctx, android.BuildParams{ + Rule: gen_sorted_bss_symbols, + Description: "generate bss symbol order " + symbolOrderingFile.Base(), + Output: symbolOrderingFile, + Input: in, + Args: map[string]string{ + "crossCompile": crossCompile, + }, + }) + return "-Wl,--symbol-ordering-file," + symbolOrderingFile.String() +} diff --git a/scripts/gen_sorted_bss_symbols.sh b/scripts/gen_sorted_bss_symbols.sh new file mode 100755 index 000000000..244ed0dea --- /dev/null +++ b/scripts/gen_sorted_bss_symbols.sh @@ -0,0 +1,28 @@ +#!/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 generate a symbol ordering file that sorts bss section symbols by +# their sizes. +# Inputs: +# Environment: +# CROSS_COMPILE: prefix added to nm tools +# Arguments: +# $1: Input ELF file +# $2: Output symbol ordering file + +set -o pipefail + +${CROSS_COMPILE}nm --size-sort $1 | awk '{if ($2 == "b" || $2 == "B") print $3}' > $2