Refactor linker/Android.bp for native-bridge

Define a "linker_bin_template" cc_defaults module that a native bridge
implementation can inherit to define a guest linker.

Break the debuggerd_init call off into separate
linker_debuggerd_{android,stub}.cpp files to allow opting in/out of the
debuggerd integration without needing to change how linker_main.cpp is
compiled. (This is necessary for a later commit that moves
linker_main.cpp into a new static library.)

Test: bionic unit tests
Bug: none
Change-Id: I7c5d79281bce1e69817b266dd91d43ea40f78522
This commit is contained in:
Ryan Prichard 2019-10-31 19:54:46 -07:00
parent 75d7488ab4
commit 5adf402ee9
5 changed files with 277 additions and 150 deletions

View file

@ -1,22 +1,6 @@
cc_library_static {
name: "liblinker_malloc",
defaults: ["linux_bionic_supported"],
recovery_available: true,
native_bridge_supported: true,
srcs: [
"linker_memory.cpp",
],
cflags: [
"-Wall",
"-Werror",
],
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
static_libs: ["libasync_safe", "libbase"],
}
// ========================================================
// linker_wrapper - Linux Bionic (on the host)
// ========================================================
// This is used for bionic on (host) Linux to bootstrap our linker embedded into
// a binary.
@ -66,6 +50,94 @@ cc_object {
include_dirs: ["bionic/libc"],
}
// ========================================================
// linker default configuration
// ========================================================
// Configuration for the linker binary and any of its static libraries.
cc_defaults {
name: "linker_defaults",
arch: {
arm: {
cflags: ["-D__work_around_b_24465209__"],
},
x86: {
cflags: ["-D__work_around_b_24465209__"],
},
},
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"],
static_libs: [
"libziparchive",
"libbase",
"libz",
"libasync_safe",
"liblog",
],
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
}
// ========================================================
// linker components
// ========================================================
// Enable a module on all targets the linker runs on (ordinary Android targets, Linux Bionic, and
// native bridge implementations).
cc_defaults {
name: "linker_all_targets",
defaults: ["linux_bionic_supported"],
recovery_available: true,
native_bridge_supported: true,
}
cc_library_static {
name: "liblinker_malloc",
defaults: ["linker_defaults", "linker_all_targets"],
srcs: ["linker_memory.cpp"],
}
cc_library_static {
name: "liblinker_debuggerd_stub",
defaults: ["linker_defaults", "linker_all_targets"],
srcs: ["linker_debuggerd_stub.cpp"],
}
// ========================================================
// template for the linker binary
// ========================================================
filegroup {
name: "linker_sources",
srcs: [
@ -137,30 +209,50 @@ filegroup {
],
}
filegroup {
name: "linker_version_script",
srcs: ["linker.generic.map"],
}
filegroup {
name: "linker_version_script_arm",
srcs: ["linker.arm.map"],
}
cc_defaults {
name: "linker_defaults",
name: "linker_version_script_overlay",
arch: {
arm: { version_script: "linker.arm.map" },
arm64: { version_script: "linker.generic.map" },
x86: { version_script: "linker.generic.map" },
x86_64: { version_script: "linker.generic.map" },
mips: { version_script: "linker.generic.map" },
mips64: { version_script: "linker.generic.map" },
},
}
// A template for the linker binary. May be inherited by native bridge implementations.
cc_defaults {
name: "linker_bin_template",
defaults: ["linker_defaults"],
srcs: [":linker_sources"],
arch: {
arm: {
cflags: ["-D__work_around_b_24465209__"],
srcs: [":linker_sources_arm"],
static_libs: ["libunwind_llvm"],
},
arm64: {
srcs: [":linker_sources_arm64"],
},
x86: {
cflags: ["-D__work_around_b_24465209__"],
srcs: [":linker_sources_x86"],
},
x86_64: {
srcs: [":linker_sources_x86_64"],
},
mips: {
srcs: [":linker_sources_mips"],
},
mips64: {
srcs: [":linker_sources_mips64"],
},
},
// -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.
// -shared is used to overwrite the -Bstatic and -static flags triggered by enabling
// static_executable. This dynamic linker is actually a shared object linked with static
// libraries.
ldflags: [
"-shared",
"-Wl,-Bsymbolic",
@ -168,35 +260,6 @@ cc_defaults {
"-Wl,-soname,ld-android.so",
],
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
@ -222,58 +285,13 @@ cc_defaults {
sanitize: {
hwaddress: false,
},
}
cc_binary {
defaults: ["linux_bionic_supported", "linker_defaults"],
srcs: [ ":linker_sources" ],
arch: {
arm: {
srcs: [ ":linker_sources_arm" ],
version_script: ":linker_version_script_arm",
static_libs: ["libunwind_llvm"],
},
arm64: {
srcs: [":linker_sources_arm64"],
version_script: ":linker_version_script",
},
x86: {
srcs: [":linker_sources_x86"],
version_script: ":linker_version_script",
},
x86_64: {
srcs: [":linker_sources_x86_64"],
version_script: ":linker_version_script",
},
mips: {
srcs: [":linker_sources_mips"],
version_script: ":linker_version_script",
},
mips64: {
srcs: [":linker_sources_mips64"],
version_script: ":linker_version_script",
},
},
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
static_libs: [
"liblinker_malloc",
"libc++_static",
"libc_nomalloc",
"libm",
"libziparchive",
"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",
],
// Ensure that if the linker needs __gnu_Unwind_Find_exidx, then the linker will have a
@ -287,9 +305,25 @@ cc_binary {
// linker stops linking against libgcc.a's arm32 unwinder.
whole_static_libs: ["libc_unwind_static"],
system_shared_libs: [],
// Opt out of native_coverage when opting out of system_shared_libs
native_coverage: false,
}
// ========================================================
// linker[_asan][64] binary
// ========================================================
cc_binary {
name: "linker",
defaults: [
"linker_bin_template",
"linux_bionic_supported",
"linker_version_script_overlay",
],
symlinks: ["linker_asan"],
recovery_available: true,
multilib: {
lib32: {
cflags: ["-DLIB_PATH=\"lib\""],
@ -299,28 +333,38 @@ cc_binary {
suffix: "64",
},
},
system_shared_libs: [],
// Opt out of native_coverage when opting out of system_shared_libs
native_coverage: false,
compile_multilib: "both",
xom: false,
recovery_available: true,
apex_available: [
"//apex_available:platform",
"com.android.runtime",
],
target: {
android: {
srcs: [
"linker_debuggerd_android.cpp",
],
static_libs: [
"libc++demangle",
"libdebuggerd_handler_fallback",
],
},
},
compile_multilib: "both",
xom: false,
apex_available: [
"//apex_available:platform",
"com.android.runtime",
linux_bionic: {
static_libs: [
"liblinker_debuggerd_stub",
],
}
},
}
// ========================================================
// assorted modules
// ========================================================
sh_binary {
name: "ldd",
src: "ldd",
@ -347,25 +391,11 @@ cc_library {
// for x86, exclude libgcc_eh.a for the same reasons as above
arch: {
arm: {
version_script: "linker.arm.map",
},
arm64: {
version_script: "linker.generic.map",
},
x86: {
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
version_script: "linker.generic.map",
},
x86_64: {
ldflags: ["-Wl,--exclude-libs=libgcc_eh.a"],
version_script: "linker.generic.map",
},
mips: {
version_script: "linker.generic.map",
},
mips64: {
version_script: "linker.generic.map",
},
},
@ -379,7 +409,7 @@ cc_library {
stl: "none",
name: "ld-android",
defaults: ["linux_bionic_supported"],
defaults: ["linux_bionic_supported", "linker_version_script_overlay"],
recovery_available: true,
native_bridge_supported: true,

31
linker/linker_debuggerd.h Normal file
View file

@ -0,0 +1,31 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#pragma once
void linker_debuggerd_init();

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "linker_debuggerd.h"
#include "debuggerd/handler.h"
#include "private/bionic_globals.h"
#include "linker_gdb_support.h"
void linker_debuggerd_init() {
debuggerd_callbacks_t callbacks = {
.get_abort_message = []() {
return __libc_shared_globals()->abort_msg;
},
.post_dump = &notify_gdb_of_libraries,
};
debuggerd_init(&callbacks);
}

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2019 The Android Open Source Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "linker_debuggerd.h"
void linker_debuggerd_init() {
}

View file

@ -32,6 +32,7 @@
#include <sys/auxv.h>
#include "linker_debug.h"
#include "linker_debuggerd.h"
#include "linker_cfi.h"
#include "linker_gdb_support.h"
#include "linker_globals.h"
@ -46,9 +47,6 @@
#include "android-base/unique_fd.h"
#include "android-base/strings.h"
#include "android-base/stringprintf.h"
#ifdef __ANDROID__
#include "debuggerd/handler.h"
#endif
#include <async_safe/log.h>
#include <bionic/libc_init_common.h>
@ -311,15 +309,7 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load
__system_properties_init(); // may use 'environ'
// Register the debuggerd signal handler.
#ifdef __ANDROID__
debuggerd_callbacks_t callbacks = {
.get_abort_message = []() {
return __libc_shared_globals()->abort_msg;
},
.post_dump = &notify_gdb_of_libraries,
};
debuggerd_init(&callbacks);
#endif
linker_debuggerd_init();
g_linker_logger.ResetState();