diff --git a/cc/binary.go b/cc/binary.go index 3aa3fdf01..48f70d9b8 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -146,16 +146,17 @@ func (binary *binaryDecorator) getStem(ctx BaseModuleContext) string { // modules common to most binaries, such as bionic libraries. func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { deps = binary.baseLinker.linkerDeps(ctx, deps) - if ctx.toolchain().Bionic() { - if !Bool(binary.baseLinker.Properties.Nocrt) { - if binary.static() { - deps.CrtBegin = []string{"crtbegin_static"} - } else { - deps.CrtBegin = []string{"crtbegin_dynamic"} - } - deps.CrtEnd = []string{"crtend_android"} + if !Bool(binary.baseLinker.Properties.Nocrt) { + if binary.static() { + deps.CrtBegin = ctx.toolchain().CrtBeginStaticBinary() + deps.CrtEnd = ctx.toolchain().CrtEndStaticBinary() + } else { + deps.CrtBegin = ctx.toolchain().CrtBeginSharedBinary() + deps.CrtEnd = ctx.toolchain().CrtEndSharedBinary() } + } + if ctx.toolchain().Bionic() { if binary.static() { if ctx.selectedStl() == "libc++_static" { deps.StaticLibs = append(deps.StaticLibs, "libm", "libc") @@ -169,16 +170,8 @@ func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...) } - // Embed the linker into host bionic binaries. This is needed to support host bionic, - // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be - // either an absolute path, or relative from CWD. To work around this, we extract - // the load sections from the runtime linker ELF binary and embed them into each host - // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static - // binary, and then we use a special entry point to fix up the arguments passed by - // the kernel before jumping to the embedded linker. if ctx.Os() == android.LinuxBionic && !binary.static() { deps.DynamicLinker = "linker" - deps.CrtBegin = append(deps.CrtBegin, "host_bionic_linker_script") } } diff --git a/cc/config/Android.bp b/cc/config/Android.bp index e4a8b6203..c1d4f1755 100644 --- a/cc/config/Android.bp +++ b/cc/config/Android.bp @@ -17,6 +17,8 @@ bootstrap_go_package { "toolchain.go", "vndk.go", + "bionic.go", + "arm_device.go", "arm64_device.go", "arm64_fuchsia_device.go", diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go index 864fba100..af6361bff 100644 --- a/cc/config/arm64_device.go +++ b/cc/config/arm64_device.go @@ -149,6 +149,7 @@ var ( ) type toolchainArm64 struct { + toolchainBionic toolchain64Bit ldflags string diff --git a/cc/config/arm64_fuchsia_device.go b/cc/config/arm64_fuchsia_device.go index 02c0c14d7..a6b5e8c67 100644 --- a/cc/config/arm64_fuchsia_device.go +++ b/cc/config/arm64_fuchsia_device.go @@ -82,10 +82,6 @@ func (t *toolchainFuchsiaArm64) ClangCflags() string { return "--target=arm64-fuchsia --sysroot=" + fuchsiaArm64SysRoot + " -I" + fuchsiaArm64SysRoot + "/include" } -func (t *toolchainFuchsiaArm64) Bionic() bool { - return false -} - func (t *toolchainFuchsiaArm64) ToolchainClangCflags() string { return "-march=armv8-a" } diff --git a/cc/config/arm64_linux_host.go b/cc/config/arm64_linux_host.go index 59c52d162..83bd7997b 100644 --- a/cc/config/arm64_linux_host.go +++ b/cc/config/arm64_linux_host.go @@ -45,6 +45,16 @@ var ( "-Wl,--hash-style=gnu", "-Wl,--no-undefined-version", }) + + // Embed the linker into host bionic binaries. This is needed to support host bionic, + // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be + // either an absolute path, or relative from CWD. To work around this, we extract + // the load sections from the runtime linker ELF binary and embed them into each host + // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static + // binary, and then we use a special entry point to fix up the arguments passed by + // the kernel before jumping to the embedded linker. + linuxArm64CrtBeginSharedBinary = append(android.CopyOf(bionicCrtBeginSharedBinary), + "host_bionic_linker_script") ) func init() { @@ -68,6 +78,10 @@ func (toolchainLinuxArm64) ClangCflags() string { return "${config.Arm64ClangCflags} ${config.LinuxBionicArm64Cflags}" } +func (toolchainLinuxArm64) CrtBeginSharedBinary() []string { + return linuxArm64CrtBeginSharedBinary +} + func linuxArm64ToolchainFactory(arch android.Arch) Toolchain { archVariant := "armv8-a" // for host, default to armv8-a toolchainClangCflags := []string{arm64ClangArchVariantCflagsVar[archVariant]} diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go index 439084e3b..3c2773021 100644 --- a/cc/config/arm_device.go +++ b/cc/config/arm_device.go @@ -237,6 +237,7 @@ var ( ) type toolchainArm struct { + toolchainBionic toolchain32Bit ldflags string lldflags string diff --git a/cc/config/bionic.go b/cc/config/bionic.go new file mode 100644 index 000000000..e87f5712b --- /dev/null +++ b/cc/config/bionic.go @@ -0,0 +1,37 @@ +// Copyright 2015 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. + +package config + +type toolchainBionic struct { +} + +var ( + bionicDefaultSharedLibraries = []string{"libc", "libm", "libdl"} + + bionicCrtBeginStaticBinary, bionicCrtEndStaticBinary = []string{"crtbegin_static"}, []string{"crtend_android"} + bionicCrtBeginSharedBinary, bionicCrtEndSharedBinary = []string{"crtbegin_dynamic"}, []string{"crtend_android"} + bionicCrtBeginSharedLibrary, bionicCrtEndSharedLibrary = []string{"crtbegin_so"}, []string{"crtend_so"} +) + +func (toolchainBionic) Bionic() bool { return true } + +func (toolchainBionic) DefaultSharedLibraries() []string { return bionicDefaultSharedLibraries } + +func (toolchainBionic) CrtBeginStaticBinary() []string { return bionicCrtBeginStaticBinary } +func (toolchainBionic) CrtBeginSharedBinary() []string { return bionicCrtBeginSharedBinary } +func (toolchainBionic) CrtBeginSharedLibrary() []string { return bionicCrtBeginSharedLibrary } +func (toolchainBionic) CrtEndStaticBinary() []string { return bionicCrtEndStaticBinary } +func (toolchainBionic) CrtEndSharedBinary() []string { return bionicCrtEndSharedBinary } +func (toolchainBionic) CrtEndSharedLibrary() []string { return bionicCrtEndSharedLibrary } diff --git a/cc/config/toolchain.go b/cc/config/toolchain.go index fce28c1ee..ab09751ac 100644 --- a/cc/config/toolchain.go +++ b/cc/config/toolchain.go @@ -106,6 +106,17 @@ type Toolchain interface { AvailableLibraries() []string + CrtBeginStaticBinary() []string + CrtBeginSharedBinary() []string + CrtBeginSharedLibrary() []string + CrtEndStaticBinary() []string + CrtEndSharedBinary() []string + CrtEndSharedLibrary() []string + + // DefaultSharedLibraries returns the list of shared libraries that will be added to all + // targets unless they explicitly specify system_shared_libs. + DefaultSharedLibraries() []string + Bionic() bool } @@ -165,11 +176,22 @@ func (toolchainBase) LibclangRuntimeLibraryArch() string { } func (toolchainBase) AvailableLibraries() []string { - return []string{} + return nil +} + +func (toolchainBase) CrtBeginStaticBinary() []string { return nil } +func (toolchainBase) CrtBeginSharedBinary() []string { return nil } +func (toolchainBase) CrtBeginSharedLibrary() []string { return nil } +func (toolchainBase) CrtEndStaticBinary() []string { return nil } +func (toolchainBase) CrtEndSharedBinary() []string { return nil } +func (toolchainBase) CrtEndSharedLibrary() []string { return nil } + +func (toolchainBase) DefaultSharedLibraries() []string { + return nil } func (toolchainBase) Bionic() bool { - return true + return false } func (t toolchainBase) ToolPath() string { diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go index 1e25a3b8f..54dc6d523 100644 --- a/cc/config/x86_64_device.go +++ b/cc/config/x86_64_device.go @@ -123,6 +123,7 @@ func init() { } type toolchainX86_64 struct { + toolchainBionic toolchain64Bit toolchainClangCflags string } diff --git a/cc/config/x86_64_fuchsia_device.go b/cc/config/x86_64_fuchsia_device.go index 0f2013b54..d6837c8b4 100644 --- a/cc/config/x86_64_fuchsia_device.go +++ b/cc/config/x86_64_fuchsia_device.go @@ -83,10 +83,6 @@ func (t *toolchainFuchsiaX8664) ClangCflags() string { return "--target=x86_64-fuchsia --sysroot=" + fuchsiaSysRoot + " -I" + fuchsiaSysRoot + "/include" } -func (t *toolchainFuchsiaX8664) Bionic() bool { - return false -} - func (t *toolchainFuchsiaX8664) YasmFlags() string { return "-f elf64 -m amd64" } diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go index b0344af84..4e3e2a69d 100644 --- a/cc/config/x86_darwin_host.go +++ b/cc/config/x86_darwin_host.go @@ -241,10 +241,6 @@ func (t *toolchainDarwin) AvailableLibraries() []string { return darwinAvailableLibraries } -func (t *toolchainDarwin) Bionic() bool { - return false -} - func (t *toolchainDarwin) ToolPath() string { return "${config.MacToolPath}" } diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go index fe830982f..1507d9813 100644 --- a/cc/config/x86_device.go +++ b/cc/config/x86_device.go @@ -134,6 +134,7 @@ func init() { } type toolchainX86 struct { + toolchainBionic toolchain32Bit toolchainClangCflags string } diff --git a/cc/config/x86_linux_bionic_host.go b/cc/config/x86_linux_bionic_host.go index fa625e34a..e7e5f2dab 100644 --- a/cc/config/x86_linux_bionic_host.go +++ b/cc/config/x86_linux_bionic_host.go @@ -63,6 +63,16 @@ var ( }) linuxBionicLldflags = ClangFilterUnknownLldflags(linuxBionicLdflags) + + // Embed the linker into host bionic binaries. This is needed to support host bionic, + // as the linux kernel requires that the ELF interpreter referenced by PT_INTERP be + // either an absolute path, or relative from CWD. To work around this, we extract + // the load sections from the runtime linker ELF binary and embed them into each host + // bionic binary, omitting the PT_INTERP declaration. The kernel will treat it as a static + // binary, and then we use a special entry point to fix up the arguments passed by + // the kernel before jumping to the embedded linker. + linuxBionicCrtBeginSharedBinary = append(android.CopyOf(bionicCrtBeginSharedBinary), + "host_bionic_linker_script") ) func init() { @@ -76,6 +86,7 @@ func init() { type toolchainLinuxBionic struct { toolchain64Bit + toolchainBionic } func (t *toolchainLinuxBionic) Name() string { @@ -133,14 +144,14 @@ func (t *toolchainLinuxBionic) AvailableLibraries() []string { return nil } -func (t *toolchainLinuxBionic) Bionic() bool { - return true -} - func (toolchainLinuxBionic) LibclangRuntimeLibraryArch() string { return "x86_64" } +func (toolchainLinuxBionic) CrtBeginSharedBinary() []string { + return linuxBionicCrtBeginSharedBinary +} + var toolchainLinuxBionicSingleton Toolchain = &toolchainLinuxBionic{} func linuxBionicToolchainFactory(arch android.Arch) Toolchain { diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go index 13b55112a..c406c885f 100644 --- a/cc/config/x86_linux_host.go +++ b/cc/config/x86_linux_host.go @@ -245,10 +245,6 @@ func (t *toolchainLinux) AvailableLibraries() []string { return linuxAvailableLibraries } -func (t *toolchainLinux) Bionic() bool { - return false -} - var toolchainLinuxX86Singleton Toolchain = &toolchainLinuxX86{} var toolchainLinuxX8664Singleton Toolchain = &toolchainLinuxX8664{} diff --git a/cc/library.go b/cc/library.go index 5b6c6236d..95f9b0a09 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1174,9 +1174,9 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.StaticProperties.Static.Export_shared_lib_headers...) deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.StaticProperties.Static.Export_static_lib_headers...) } else if library.shared() { - if ctx.toolchain().Bionic() && !Bool(library.baseLinker.Properties.Nocrt) { - deps.CrtBegin = []string{"crtbegin_so"} - deps.CrtEnd = []string{"crtend_so"} + if !Bool(library.baseLinker.Properties.Nocrt) { + deps.CrtBegin = append(deps.CrtBegin, ctx.toolchain().CrtBeginSharedLibrary()...) + deps.CrtEnd = append(deps.CrtEnd, ctx.toolchain().CrtEndSharedLibrary()...) } deps.WholeStaticLibs = append(deps.WholeStaticLibs, library.SharedProperties.Shared.Whole_static_libs...) deps.StaticLibs = append(deps.StaticLibs, library.SharedProperties.Shared.Static_libs...) diff --git a/cc/linker.go b/cc/linker.go index d9ee0cfde..7b16b4097 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -344,7 +344,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { // Provide a default system_shared_libs if it is unspecified. Note: If an // empty list [] is specified, it implies that the module declines the // default system_shared_libs. - deps.SystemSharedLibs = []string{"libc", "libm", "libdl"} + deps.SystemSharedLibs = append(deps.SystemSharedLibs, ctx.toolchain().DefaultSharedLibraries()...) } if inList("libdl", deps.SharedLibs) { @@ -365,10 +365,10 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { indexList("libdl", deps.SystemSharedLibs) < indexList("libc", deps.SystemSharedLibs) { ctx.PropertyErrorf("system_shared_libs", "libdl must be after libc") } - - deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) } + deps.LateSharedLibs = append(deps.LateSharedLibs, deps.SystemSharedLibs...) + if ctx.Fuchsia() { if ctx.ModuleName() != "libbioniccompat" && ctx.ModuleName() != "libcompiler_rt-extras" &&