From e5ba28648f8ea79764e06c854af595595b7c9e8e Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 10 Dec 2019 18:37:45 -0800 Subject: [PATCH] build: Link the unwinder dynamically into platform and vendor binaries. Instead of linking the unwinder statically into every binary, link it dynamically, by exporting the symbols from libc.so. This has a number of advantages: - Reduces image size (system.img size decreases by 1.7MB on walleye-userdebug, and 1.2MB on crosshatch-userdebug). - Allows us to easily change/upgrade the unwinder throughout the system, including vendor prebuilts. - Allows code outside of libc++ to define custom personality routines. Previously, personality routines would call the unwinder routines in the local binary, which would cause problems with unwinders with global state (such as the libgcc unwinder) if the copy of the unwinder used for unwinding (normally libc++'s copy) were different from the copy linked against the personality routine. Bug: 144430859 Change-Id: I3b2a4a3ee58c6777989f811e19a3aeb47c0945bd --- Android.bp | 1 + cc/cc_test.go | 4 ++-- cc/config/global.go | 1 + cc/linker.go | 3 +-- cc/stl.go | 10 +++++++--- cc/testing.go | 3 +++ 6 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Android.bp b/Android.bp index 9403b26f8..45180c38a 100644 --- a/Android.bp +++ b/Android.bp @@ -595,6 +595,7 @@ toolchain_library { vendor_available: true, recovery_available: true, native_bridge_supported: true, + sdk_version: "current", arch: { arm: { diff --git a/cc/cc_test.go b/cc/cc_test.go index 4d02f4f62..332cc45e7 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -2303,13 +2303,13 @@ func TestStaticLibDepExport(t *testing.T) { // Check the shared version of lib2. variant := "android_arm64_armv8-a_shared" module := ctx.ModuleForTests("lib2", variant).Module().(*Module) - checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module) + checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module) // Check the static version of lib2. variant = "android_arm64_armv8-a_static" module = ctx.ModuleForTests("lib2", variant).Module().(*Module) // libc++_static is linked additionally. - checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic", "libgcc_stripped"}, module) + checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module) } var compilerFlagsTestCases = []struct { diff --git a/cc/config/global.go b/cc/config/global.go index bae5555f9..87314dc1a 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -88,6 +88,7 @@ var ( "-Wl,--no-undefined-version", "-Wl,--exclude-libs,libgcc.a", "-Wl,--exclude-libs,libgcc_stripped.a", + "-Wl,--exclude-libs,libunwind_llvm.a", } deviceGlobalLldflags = append(ClangFilterUnknownLldflags(deviceGlobalLdflags), diff --git a/cc/linker.go b/cc/linker.go index 61ae7575a..6f2e5b7d0 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -224,11 +224,10 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { } if ctx.toolchain().Bionic() { - // libclang_rt.builtins, libgcc and libatomic have to be last on the command line + // libclang_rt.builtins 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") - deps.LateStaticLibs = append(deps.LateStaticLibs, "libgcc_stripped") } systemSharedLibs := linker.Properties.System_shared_libs diff --git a/cc/stl.go b/cc/stl.go index 5ccd44a4a..af015f91d 100644 --- a/cc/stl.go +++ b/cc/stl.go @@ -171,11 +171,13 @@ func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { deps.StaticLibs = append(deps.StaticLibs, "libc++demangle") } if ctx.toolchain().Bionic() { - if ctx.Arch().ArchType == android.Arm { - deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm") - } if ctx.staticBinary() { deps.StaticLibs = append(deps.StaticLibs, "libm", "libc") + if ctx.Arch().ArchType == android.Arm { + deps.StaticLibs = append(deps.StaticLibs, "libunwind_llvm") + } else { + deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped") + } } } case "": @@ -196,6 +198,8 @@ func (stl *stl) deps(ctx BaseModuleContext, deps Deps) Deps { } if ctx.Arch().ArchType == android.Arm { deps.StaticLibs = append(deps.StaticLibs, "ndk_libunwind") + } else { + deps.StaticLibs = append(deps.StaticLibs, "libgcc_stripped") } default: panic(fmt.Errorf("Unknown stl: %q", stl.Properties.SelectedStl)) diff --git a/cc/testing.go b/cc/testing.go index bc3107721..d6f23913a 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -135,6 +135,7 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libc", no_libcrt: true, nocrt: true, + stl: "none", system_shared_libs: [], recovery_available: true, } @@ -146,6 +147,7 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libm", no_libcrt: true, nocrt: true, + stl: "none", system_shared_libs: [], recovery_available: true, } @@ -157,6 +159,7 @@ func GatherRequiredDepsForTest(os android.OsType) string { name: "libdl", no_libcrt: true, nocrt: true, + stl: "none", system_shared_libs: [], recovery_available: true, }