Strip libgcc to only keep fallback symbols
We use libgcc as fallback for symbols not present in libclang_rt builtins, however we didn't know what exact symbols were being used, some may not be intended to fallback. Create libgcc_stripped, which only contains unwind symbols from libgcc. Bug: 29275768 Test: bionic-unit-tests Change-Id: I5b349fa6138e51663bf3b67109b880b4356da8e8
This commit is contained in:
parent
feef2ef4d7
commit
acee27cd72
9 changed files with 201 additions and 27 deletions
111
Android.bp
111
Android.bp
|
@ -482,6 +482,117 @@ toolchain_library {
|
|||
},
|
||||
}
|
||||
|
||||
toolchain_library {
|
||||
name: "libgcc_stripped",
|
||||
defaults: ["linux_bionic_supported"],
|
||||
vendor_available: true,
|
||||
recovery_available: true,
|
||||
|
||||
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",
|
||||
],
|
||||
use_gnu_strip: true,
|
||||
},
|
||||
},
|
||||
arm64: {
|
||||
src: "prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/lib/gcc/aarch64-linux-android/4.9.x/libgcc.a",
|
||||
},
|
||||
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",
|
||||
|
||||
},
|
||||
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",
|
||||
},
|
||||
},
|
||||
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",
|
||||
],
|
||||
use_gnu_strip: true,
|
||||
},
|
||||
}
|
||||
|
||||
toolchain_library {
|
||||
name: "libwinpthread",
|
||||
host_supported: true,
|
||||
|
|
|
@ -92,6 +92,13 @@ func testApex(t *testing.T, bp string) *android.TestContext {
|
|||
recovery_available: true,
|
||||
}
|
||||
|
||||
toolchain_library {
|
||||
name: "libgcc_stripped",
|
||||
src: "",
|
||||
vendor_available: true,
|
||||
recovery_available: true,
|
||||
}
|
||||
|
||||
toolchain_library {
|
||||
name: "libclang_rt.builtins-aarch64-android",
|
||||
src: "",
|
||||
|
|
|
@ -255,6 +255,7 @@ type builderFlags struct {
|
|||
groupStaticLibs bool
|
||||
|
||||
stripKeepSymbols bool
|
||||
stripKeepSymbolsList string
|
||||
stripKeepMiniDebugInfo bool
|
||||
stripAddGnuDebuglink bool
|
||||
stripUseGnuStrip bool
|
||||
|
@ -835,6 +836,9 @@ func TransformStrip(ctx android.ModuleContext, inputFile android.Path,
|
|||
if flags.stripKeepSymbols {
|
||||
args += " --keep-symbols"
|
||||
}
|
||||
if flags.stripKeepSymbolsList != "" {
|
||||
args += " -k" + flags.stripKeepSymbolsList
|
||||
}
|
||||
if flags.stripUseGnuStrip {
|
||||
args += " --use-gnu-strip"
|
||||
}
|
||||
|
|
|
@ -1833,13 +1833,13 @@ func TestStaticLibDepExport(t *testing.T) {
|
|||
// Check the shared version of lib2.
|
||||
variant := "android_arm64_armv8-a_core_shared"
|
||||
module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
|
||||
checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
|
||||
checkStaticLibs(t, []string{"lib1", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
|
||||
|
||||
// Check the static version of lib2.
|
||||
variant = "android_arm64_armv8-a_core_static"
|
||||
module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
|
||||
// libc++_static is linked additionally.
|
||||
checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc"}, module)
|
||||
checkStaticLibs(t, []string{"lib1", "libc++_static", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module)
|
||||
}
|
||||
|
||||
var compilerFlagsTestCases = []struct {
|
||||
|
|
|
@ -228,10 +228,10 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||
// libclang_rt.builtins, libgcc and libatomic have to be last on the command line
|
||||
if !Bool(linker.Properties.No_libcrt) {
|
||||
deps.LateStaticLibs = append(deps.LateStaticLibs, config.BuiltinsRuntimeLibrary(ctx.toolchain()))
|
||||
}
|
||||
|
||||
deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
|
||||
if !Bool(linker.Properties.No_libgcc) {
|
||||
deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
|
||||
deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc_stripped")
|
||||
} else if !Bool(linker.Properties.No_libgcc) {
|
||||
deps.LateStaticLibs = append(deps.LateStaticLibs, "libatomic")
|
||||
deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc")
|
||||
}
|
||||
|
||||
|
|
17
cc/strip.go
17
cc/strip.go
|
@ -15,15 +15,19 @@
|
|||
package cc
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"android/soong/android"
|
||||
)
|
||||
|
||||
type StripProperties struct {
|
||||
Strip struct {
|
||||
None *bool
|
||||
All *bool
|
||||
Keep_symbols *bool
|
||||
}
|
||||
None *bool `android:"arch_variant"`
|
||||
All *bool `android:"arch_variant"`
|
||||
Keep_symbols *bool `android:"arch_variant"`
|
||||
Keep_symbols_list []string `android:"arch_variant"`
|
||||
Use_gnu_strip *bool `android:"arch_variant"`
|
||||
} `android:"arch_variant"`
|
||||
}
|
||||
|
||||
type stripper struct {
|
||||
|
@ -42,9 +46,14 @@ func (stripper *stripper) strip(ctx ModuleContext, in android.Path, out android.
|
|||
} else {
|
||||
if Bool(stripper.StripProperties.Strip.Keep_symbols) {
|
||||
flags.stripKeepSymbols = true
|
||||
} else if len(stripper.StripProperties.Strip.Keep_symbols_list) > 0 {
|
||||
flags.stripKeepSymbolsList = strings.Join(stripper.StripProperties.Strip.Keep_symbols_list, ",")
|
||||
} else if !Bool(stripper.StripProperties.Strip.All) {
|
||||
flags.stripKeepMiniDebugInfo = true
|
||||
}
|
||||
if Bool(stripper.StripProperties.Strip.Use_gnu_strip) {
|
||||
flags.stripUseGnuStrip = true
|
||||
}
|
||||
if ctx.Config().Debuggable() && !flags.stripKeepMiniDebugInfo {
|
||||
flags.stripAddGnuDebuglink = true
|
||||
}
|
||||
|
|
|
@ -69,6 +69,13 @@ func GatherRequiredDepsForTest(os android.OsType) string {
|
|||
src: "",
|
||||
}
|
||||
|
||||
toolchain_library {
|
||||
name: "libgcc_stripped",
|
||||
vendor_available: true,
|
||||
recovery_available: true,
|
||||
src: "",
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libc",
|
||||
no_libgcc: true,
|
||||
|
|
|
@ -34,6 +34,8 @@ type toolchainLibraryProperties struct {
|
|||
type toolchainLibraryDecorator struct {
|
||||
*libraryDecorator
|
||||
|
||||
stripper
|
||||
|
||||
Properties toolchainLibraryProperties
|
||||
}
|
||||
|
||||
|
@ -45,7 +47,7 @@ func (*toolchainLibraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
|||
func (library *toolchainLibraryDecorator) linkerProps() []interface{} {
|
||||
var props []interface{}
|
||||
props = append(props, library.libraryDecorator.linkerProps()...)
|
||||
return append(props, &library.Properties)
|
||||
return append(props, &library.Properties, &library.stripper.StripProperties)
|
||||
}
|
||||
|
||||
// toolchain_library is used internally by the build tool to link the specified
|
||||
|
@ -78,7 +80,17 @@ func (library *toolchainLibraryDecorator) link(ctx ModuleContext,
|
|||
return android.PathForSource(ctx, "")
|
||||
}
|
||||
|
||||
return android.PathForSource(ctx, *library.Properties.Src)
|
||||
srcPath := android.PathForSource(ctx, *library.Properties.Src)
|
||||
|
||||
if library.stripper.StripProperties.Strip.Keep_symbols_list != nil {
|
||||
fileName := ctx.ModuleName() + staticLibraryExtension
|
||||
outputFile := android.PathForModuleOut(ctx, fileName)
|
||||
buildFlags := flagsToBuilderFlags(flags)
|
||||
library.stripper.strip(ctx, srcPath, outputFile, buildFlags)
|
||||
return outputFile
|
||||
}
|
||||
|
||||
return srcPath
|
||||
}
|
||||
|
||||
func (library *toolchainLibraryDecorator) nativeCoverage() bool {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
# -i ${file}: input file (required)
|
||||
# -o ${file}: output file (required)
|
||||
# -d ${file}: deps file (required)
|
||||
# -k symbols: Symbols to keep (optional)
|
||||
# --add-gnu-debuglink
|
||||
# --keep-mini-debug-info
|
||||
# --keep-symbols
|
||||
|
@ -32,11 +33,11 @@
|
|||
|
||||
set -o pipefail
|
||||
|
||||
OPTSTRING=d:i:o:-:
|
||||
OPTSTRING=d:i:o:k:-:
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: strip.sh [options] -i in-file -o out-file -d deps-file
|
||||
Usage: strip.sh [options] -k symbols -i in-file -o out-file -d deps-file
|
||||
Options:
|
||||
--add-gnu-debuglink Add a gnu-debuglink section to out-file
|
||||
--keep-mini-debug-info Keep compressed debug info in out-file
|
||||
|
@ -71,6 +72,20 @@ do_strip_keep_symbols() {
|
|||
fi
|
||||
}
|
||||
|
||||
do_strip_keep_symbol_list() {
|
||||
if [ -z "${use_gnu_strip}" ]; then
|
||||
echo "do_strip_keep_symbol_list does not work with llvm-objcopy"
|
||||
echo "http://b/131631155"
|
||||
usage
|
||||
fi
|
||||
|
||||
echo "${symbols_to_keep}" | tr ',' '\n' > "${outfile}.symbolList"
|
||||
KEEP_SYMBOLS="-w --strip-unneeded-symbol=* --keep-symbols="
|
||||
KEEP_SYMBOLS+="${outfile}.symbolList"
|
||||
|
||||
"${CROSS_COMPILE}objcopy" "${infile}" "${outfile}.tmp" ${KEEP_SYMBOLS}
|
||||
}
|
||||
|
||||
do_strip_keep_mini_debug_info() {
|
||||
rm -f "${outfile}.dynsyms" "${outfile}.funcsyms" "${outfile}.keep_symbols" "${outfile}.debug" "${outfile}.mini_debuginfo" "${outfile}.mini_debuginfo.xz"
|
||||
local fail=
|
||||
|
@ -124,19 +139,21 @@ do_remove_build_id() {
|
|||
|
||||
while getopts $OPTSTRING opt; do
|
||||
case "$opt" in
|
||||
d) depsfile="${OPTARG}" ;;
|
||||
i) infile="${OPTARG}" ;;
|
||||
o) outfile="${OPTARG}" ;;
|
||||
-)
|
||||
case "${OPTARG}" in
|
||||
add-gnu-debuglink) add_gnu_debuglink=true ;;
|
||||
keep-mini-debug-info) keep_mini_debug_info=true ;;
|
||||
keep-symbols) keep_symbols=true ;;
|
||||
remove-build-id) remove_build_id=true ;;
|
||||
*) echo "Unknown option --${OPTARG}"; usage ;;
|
||||
esac;;
|
||||
?) usage ;;
|
||||
*) echo "'${opt}' '${OPTARG}'"
|
||||
d) depsfile="${OPTARG}" ;;
|
||||
i) infile="${OPTARG}" ;;
|
||||
o) outfile="${OPTARG}" ;;
|
||||
k) symbols_to_keep="${OPTARG}" ;;
|
||||
-)
|
||||
case "${OPTARG}" in
|
||||
add-gnu-debuglink) add_gnu_debuglink=true ;;
|
||||
keep-mini-debug-info) keep_mini_debug_info=true ;;
|
||||
keep-symbols) keep_symbols=true ;;
|
||||
remove-build-id) remove_build_id=true ;;
|
||||
use-gnu-strip) use_gnu_strip=true ;;
|
||||
*) echo "Unknown option --${OPTARG}"; usage ;;
|
||||
esac;;
|
||||
?) usage ;;
|
||||
*) echo "'${opt}' '${OPTARG}'"
|
||||
esac
|
||||
done
|
||||
|
||||
|
@ -160,6 +177,11 @@ if [ ! -z "${keep_symbols}" -a ! -z "${keep_mini_debug_info}" ]; then
|
|||
usage
|
||||
fi
|
||||
|
||||
if [ ! -z "${symbols_to_keep}" -a ! -z "${keep_symbols}" ]; then
|
||||
echo "--keep-symbols and -k cannot be used together"
|
||||
usage
|
||||
fi
|
||||
|
||||
if [ ! -z "${add_gnu_debuglink}" -a ! -z "${keep_mini_debug_info}" ]; then
|
||||
echo "--add-gnu-debuglink cannot be used with --keep-mini-debug-info"
|
||||
usage
|
||||
|
@ -169,6 +191,8 @@ rm -f "${outfile}.tmp"
|
|||
|
||||
if [ ! -z "${keep_symbols}" ]; then
|
||||
do_strip_keep_symbols
|
||||
elif [ ! -z "${symbols_to_keep}" ]; then
|
||||
do_strip_keep_symbol_list
|
||||
elif [ ! -z "${keep_mini_debug_info}" ]; then
|
||||
do_strip_keep_mini_debug_info
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue