diff --git a/Android.bp b/Android.bp index 910fe4bc5..56fa89469 100644 --- a/Android.bp +++ b/Android.bp @@ -479,6 +479,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, diff --git a/apex/apex_test.go b/apex/apex_test.go index c771ae45e..a07a89b8c 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -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: "", diff --git a/cc/builder.go b/cc/builder.go index c64243f62..c42f56cc5 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -255,6 +255,7 @@ type builderFlags struct { groupStaticLibs bool stripKeepSymbols bool + stripKeepSymbolsList string stripKeepMiniDebugInfo bool stripAddGnuDebuglink bool stripUseGnuStrip bool @@ -823,6 +824,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" } diff --git a/cc/cc_test.go b/cc/cc_test.go index 05d74b995..f3d5e60d5 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -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 { diff --git a/cc/linker.go b/cc/linker.go index b279c0654..e063e441b 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -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") } diff --git a/cc/strip.go b/cc/strip.go index 02397f4e1..7122585e3 100644 --- a/cc/strip.go +++ b/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 } diff --git a/cc/testing.go b/cc/testing.go index 2f41de1aa..8d76c2f5a 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -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, diff --git a/cc/toolchain_library.go b/cc/toolchain_library.go index ae08b1c71..8ab8bc946 100644 --- a/cc/toolchain_library.go +++ b/cc/toolchain_library.go @@ -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) } func ToolchainLibraryFactory() android.Module { @@ -75,7 +77,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 { diff --git a/scripts/strip.sh b/scripts/strip.sh index d53690716..0f77da8a9 100755 --- a/scripts/strip.sh +++ b/scripts/strip.sh @@ -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 < "${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