linker: the global group is added to all built-in namespaces
With ld.config.txt, we now have multiple built-in namespaces other than
the default namespace. Libs (and their dependents) listed in LD_PRELOAD
must be visible to those additional namespaces as well.
This also adds a debugging only feature: path to the linker config file
can be customized via LD_CONFIG_FILE environment variable. This works
only for debuggable builds.
Bug: 38114603
Bug: 62815515
Test: 1. ./external/compiler-rt/lib/asan/scripts/asan_device_setup --lib
prebuilts/clang/host/linux-x86/clang-stable/lib64/clang/5.0/lib/linux
2. enable talkback shortcut
3. in the home screen, hold vol-up/down together
4. device does not reboots and talkback shortcut is toggled
Test: bionic-unit-tests and linker-unit-tests successful
Change-Id: I9a03591053f4a9caea82f0dcb23e7a3d324bb9bd
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index bcb2281..54593e4 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -341,12 +341,19 @@
somain = si;
- init_default_namespace(executable_path);
+ std::vector<android_namespace_t*> namespaces = init_default_namespaces(executable_path);
if (!si->prelink_image()) __linker_cannot_link(g_argv[0]);
// add somain to global group
si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL);
+ // ... and add it to all other linked namespaces
+ for (auto linked_ns : namespaces) {
+ if (linked_ns != &g_default_namespace) {
+ linked_ns->add_soinfo(somain);
+ somain->add_secondary_namespace(linked_ns);
+ }
+ }
// Load ld_preloads and dependencies.
std::vector<const char*> needed_library_name_list;
@@ -364,6 +371,9 @@
const char** needed_library_names = &needed_library_name_list[0];
size_t needed_libraries_count = needed_library_name_list.size();
+ // readers_map is shared across recursive calls to find_libraries so that we
+ // don't need to re-load elf headers.
+ std::unordered_map<const soinfo*, ElfReader> readers_map;
if (needed_libraries_count > 0 &&
!find_libraries(&g_default_namespace,
si,
@@ -375,7 +385,9 @@
RTLD_GLOBAL,
nullptr,
true /* add_as_children */,
- true /* search_linked_namespaces */)) {
+ true /* search_linked_namespaces */,
+ readers_map,
+ &namespaces)) {
__linker_cannot_link(g_argv[0]);
} else if (needed_libraries_count == 0) {
if (!si->link_image(g_empty_list, soinfo_list_t::make_list(si), nullptr)) {