Merge changes from topic "host_bionic"
* changes:
Use an embedded linker for host bionic
linker: Only link to debuggerd on Android
diff --git a/libc/Android.bp b/libc/Android.bp
index 8932be6..d126f2f 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -2130,6 +2130,14 @@
"crtbegin_dynamic1",
"crtbrand",
],
+ target: {
+ linux_bionic: {
+ generated_sources: ["host_bionic_linker_asm"],
+ objs: [
+ "linker_wrapper",
+ ],
+ },
+ },
defaults: ["crt_defaults"],
}
diff --git a/linker/Android.bp b/linker/Android.bp
index f96e038..9125fd6 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -13,6 +13,48 @@
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: [
@@ -136,7 +178,7 @@
"libbase",
"libz",
- "libdebuggerd_handler_fallback",
+ "libasync_safe",
"liblog",
"libc++_static",
@@ -156,7 +198,7 @@
},
target: {
android: {
- static_libs: ["libdebuggerd_client"],
+ static_libs: ["libdebuggerd_handler_fallback"],
},
android64: {
cflags: ["-DTARGET_IS_64_BIT"],
diff --git a/linker/linker.cpp b/linker/linker.cpp
index a843b7b..f6ca430 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3474,7 +3474,7 @@
const char *interp = phdr_table_get_interpreter_name(somain->phdr, somain->phnum,
somain->load_bias);
- const char* bname = basename(interp);
+ const char* bname = (interp != nullptr) ? basename(interp) : nullptr;
g_is_asan = bname != nullptr &&
(strcmp(bname, "linker_asan") == 0 ||
diff --git a/linker/linker_wrapper.cpp b/linker/linker_wrapper.cpp
new file mode 100644
index 0000000..571d3ab
--- /dev/null
+++ b/linker/linker_wrapper.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 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 "private/KernelArgumentBlock.h"
+
+extern const char linker_code_start;
+extern const char original_start;
+extern const char linker_entry;
+
+/*
+ * This is the entry point for the linker wrapper, which finds
+ * the real linker, then bootstraps into it.
+ */
+extern "C" ElfW(Addr) __linker_init(void* raw_args) {
+ KernelArgumentBlock args(raw_args);
+
+ static uintptr_t linker_offset = reinterpret_cast<uintptr_t>(&linker_code_start);
+ static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr);
+ ElfW(Addr) my_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr;
+
+ // Set AT_ENTRY to the proper entry point
+ for (ElfW(auxv_t)* v = args.auxv; v->a_type != AT_NULL; ++v) {
+ if (v->a_type == AT_BASE) {
+ v->a_un.a_val = my_addr + linker_offset;
+ }
+ if (v->a_type == AT_ENTRY) {
+ v->a_un.a_val = my_addr + reinterpret_cast<uintptr_t>(&original_start);
+ }
+ }
+
+ // Return address of linker entry point -- may need to ensure that raw_args
+ // was saved.
+ return my_addr + linker_offset + reinterpret_cast<uintptr_t>(&linker_entry);
+}