diff options
author | Jiyong Park <jiyong@google.com> | 2017-05-20 01:01:24 +0900 |
---|---|---|
committer | Jiyong Park <jiyong@google.com> | 2017-08-03 01:02:07 +0900 |
commit | 02586a2a34e6acfccf359b94db840f422b6c0231 (patch) | |
tree | 9dde1a2bcf8a004b23fe41b9f3e497895d44e44d /linker/linker_main.cpp | |
parent | 5ac5a7c0839a123c2982b37b383a7691fd216e7e (diff) |
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
Diffstat (limited to 'linker/linker_main.cpp')
-rw-r--r-- | linker/linker_main.cpp | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index bcb22818a..54593e434 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -341,12 +341,19 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) { 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 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) { 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 @@ static ElfW(Addr) __linker_init_post_relocation(KernelArgumentBlock& args) { 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)) { |