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
This commit is contained in:
Peter Collingbourne 2019-12-10 18:37:45 -08:00
parent 11e1ae025f
commit e5ba28648f
6 changed files with 15 additions and 7 deletions

View file

@ -595,6 +595,7 @@ toolchain_library {
vendor_available: true,
recovery_available: true,
native_bridge_supported: true,
sdk_version: "current",
arch: {
arm: {

View file

@ -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 {

View file

@ -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),

View file

@ -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

View file

@ -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))

View file

@ -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,
}