platform_bionic/linker/Android.bp
Dan Willemsen 7ccc50d2e4 Use an embedded linker for host bionic
The linux kernel requires that the ELF interpreter (runtime linker)
that's referenced by PT_INTERP be either an absolute path, or a relative
path from the current working directory. We'd prefer a relative path
from the binary, similarly to how we handle looking up shared libraries,
but that's not supported.

Instead, extract the LOAD segments 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 we'll use
a special entry point (linker_wrapper) to fix up the arguments passed by
the kernel before jumping to the embedded linker. From the linker's
point of view, it looks like the kernel loaded the linker like normal.

Bug: 31559095
Test: Enable host bionic, build and run libdemangle_test
Change-Id: I1753401ef91eecbf0ae3376faca31eec1c53842b
2017-09-20 13:59:13 -07:00

221 lines
5.5 KiB
Text

cc_library_static {
name: "liblinker_malloc",
defaults: ["linux_bionic_supported"],
srcs: [
"linker_allocator.cpp",
"linker_memory.cpp",
],
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
static_libs: ["libasync_safe"],
}
// This is used for bionic on (host) Linux to bootstrap our linker embedded into
// a binary.
//
// Host bionic binaries do not have a PT_INTERP section, instead this gets
// embedded as the entry point, and the linker is embedded as ELF sections in
// each binary. There's a linker script that sets all of that up (generated by
// extract_linker), and defines the extern symbols used in this file.
cc_object {
name: "linker_wrapper",
host_supported: true,
device_supported: false,
target: {
linux_bionic: { enabled: true },
linux: { enabled: false },
darwin: { enabled: false },
},
cflags: [
"-fno-stack-protector",
"-Wstrict-overflow=5",
"-fvisibility=hidden",
"-Wall",
"-Wextra",
"-Wno-unused",
"-Werror",
],
srcs: [
"linker_wrapper.cpp",
],
arch: {
x86_64: {
srcs: ["arch/x86_64/begin.S"],
},
},
prefix_symbols: "__dlwrap_",
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
}
cc_binary {
defaults: ["linux_bionic_supported"],
srcs: [
"dlfcn.cpp",
"linker.cpp",
"linker_block_allocator.cpp",
"linker_dlwarning.cpp",
"linker_cfi.cpp",
"linker_config.cpp",
"linker_gdb_support.cpp",
"linker_globals.cpp",
"linker_libc_support.c",
"linker_libcxx_support.cpp",
"linker_main.cpp",
"linker_namespaces.cpp",
"linker_logger.cpp",
"linker_mapped_file_fragment.cpp",
"linker_phdr.cpp",
"linker_sdk_versions.cpp",
"linker_soinfo.cpp",
"linker_utils.cpp",
"rt.cpp",
],
arch: {
arm: {
srcs: [
"arch/arm/begin.S",
"linker_exidx_static.c",
],
cflags: ["-D__work_around_b_24465209__"],
version_script: "linker.arm.map",
},
arm64: {
srcs: ["arch/arm64/begin.S"],
version_script: "linker.generic.map",
},
x86: {
srcs: ["arch/x86/begin.c"],
cflags: ["-D__work_around_b_24465209__"],
version_script: "linker.generic.map",
},
x86_64: {
srcs: ["arch/x86_64/begin.S"],
version_script: "linker.generic.map",
},
mips: {
srcs: [
"arch/mips/begin.S",
"linker_mips.cpp",
],
version_script: "linker.generic.map",
},
mips64: {
srcs: [
"arch/mips64/begin.S",
"linker_mips.cpp",
],
version_script: "linker.generic.map",
},
},
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
// -shared is used to overwrite the -Bstatic and -static
// flags triggered by LOCAL_FORCE_STATIC_EXECUTABLE.
// This dynamic linker is actually a shared object linked with static libraries.
ldflags: [
"-shared",
"-Wl,-Bsymbolic",
"-Wl,--exclude-libs,ALL",
],
cflags: [
"-fno-stack-protector",
"-Wstrict-overflow=5",
"-fvisibility=hidden",
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
],
// TODO: split out the asflags.
asflags: [
"-fno-stack-protector",
"-Wstrict-overflow=5",
"-fvisibility=hidden",
"-Wall",
"-Wextra",
"-Wunused",
"-Werror",
],
product_variables: {
debuggable: {
cppflags: ["-DUSE_LD_CONFIG_FILE"],
},
},
cppflags: ["-Wold-style-cast"],
// we are going to link libc++_static manually because
// when stl is not set to "none" build system adds libdl
// to the list of static libraries which needs to be
// avoided in the case of building loader.
stl: "none",
// we don't want crtbegin.o (because we have begin.o), so unset it
// just for this module
nocrt: true,
static_libs: [
"libc_nomalloc",
"libm",
"libziparchive",
"libutils",
"libbase",
"libz",
"libasync_safe",
"liblog",
"libc++_static",
// Important: The liblinker_malloc should be the last library in the list
// to overwrite any other malloc implementations by other static libraries.
"liblinker_malloc"
],
static_executable: true,
name: "linker",
symlinks: ["linker_asan"],
multilib: {
lib64: {
suffix: "64",
},
},
target: {
android: {
static_libs: ["libdebuggerd_handler_fallback"],
},
android64: {
cflags: ["-DTARGET_IS_64_BIT"],
},
linux_bionic: {
cflags: ["-DTARGET_IS_64_BIT"],
},
},
compile_multilib: "both",
// Leave the symbols in the shared library so that stack unwinders can produce
// meaningful name resolution.
strip: {
keep_symbols: true,
},
// Insert an extra objcopy step to add prefix to symbols. This is needed to prevent gdb
// looking up symbols in the linker by mistake.
prefix_symbols: "__dl_",
}