diff options
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 55 |
1 files changed, 27 insertions, 28 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index c240c5639..3488f5cc7 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1242,7 +1242,7 @@ static bool load_library(android_namespace_t* ns, return false; } - // find and set DT_RUNPATH and dt_soname + // Find and set DT_RUNPATH, DT_SONAME, and DT_FLAGS_1. // Note that these field values are temporary and are // going to be overwritten on soinfo::prelink_image // with values from PT_LOAD segments. @@ -1254,6 +1254,10 @@ static bool load_library(android_namespace_t* ns, if (d->d_tag == DT_SONAME) { si->set_soname(elf_reader.get_string(d->d_un.d_val)); } + // We need to identify a DF_1_GLOBAL library early so we can link it to namespaces. + if (d->d_tag == DT_FLAGS_1) { + si->set_dt_flags_1(d->d_un.d_val); + } } #if !defined(__ANDROID__) @@ -1552,6 +1556,7 @@ bool find_libraries(android_namespace_t* ns, }); ZipArchiveCache zip_archive_cache; + soinfo_list_t new_global_group_members; // Step 1: expand the list of load_tasks to include // all DT_NEEDED libraries (do not load them just yet) @@ -1586,13 +1591,31 @@ bool find_libraries(android_namespace_t* ns, // When ld_preloads is not null, the first // ld_preloads_count libs are in fact ld_preloads. + bool is_ld_preload = false; if (ld_preloads != nullptr && soinfos_count < ld_preloads_count) { ld_preloads->push_back(si); + is_ld_preload = true; } if (soinfos_count < library_names_count) { soinfos[soinfos_count++] = si; } + + // Add the new global group members to all initial namespaces. Do this secondary namespace setup + // at the same time that libraries are added to their primary namespace so that the order of + // global group members is the same in the every namespace. Only add a library to a namespace + // once, even if it appears multiple times in the dependency graph. + if (is_ld_preload || (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) { + if (!si->is_linked() && namespaces != nullptr && !new_global_group_members.contains(si)) { + new_global_group_members.push_back(si); + for (auto linked_ns : *namespaces) { + if (si->get_primary_namespace() != linked_ns) { + linked_ns->add_soinfo(si); + si->add_secondary_namespace(linked_ns); + } + } + } + } } // Step 2: Load libraries in random order (see b/24047022) @@ -1649,39 +1672,15 @@ bool find_libraries(android_namespace_t* ns, register_soinfo_tls(si); } - // Step 4: Construct the global group. Note: DF_1_GLOBAL bit of a library is - // determined at step 3. - - // Step 4-1: DF_1_GLOBAL bit is force set for LD_PRELOADed libs because they - // must be added to the global group + // Step 4: Construct the global group. DF_1_GLOBAL bit is force set for LD_PRELOADed libs because + // they must be added to the global group. Note: The DF_1_GLOBAL bit for a library is normally set + // in step 3. if (ld_preloads != nullptr) { for (auto&& si : *ld_preloads) { si->set_dt_flags_1(si->get_dt_flags_1() | DF_1_GLOBAL); } } - // Step 4-2: Gather all DF_1_GLOBAL libs which were newly loaded during this - // run. These will be the new member of the global group - soinfo_list_t new_global_group_members; - for (auto&& task : load_tasks) { - soinfo* si = task->get_soinfo(); - if (!si->is_linked() && (si->get_dt_flags_1() & DF_1_GLOBAL) != 0) { - new_global_group_members.push_back(si); - } - } - - // Step 4-3: Add the new global group members to all the linked namespaces - if (namespaces != nullptr) { - for (auto linked_ns : *namespaces) { - for (auto si : new_global_group_members) { - if (si->get_primary_namespace() != linked_ns) { - linked_ns->add_soinfo(si); - si->add_secondary_namespace(linked_ns); - } - } - } - } - // Step 5: Collect roots of local_groups. // Whenever needed_by->si link crosses a namespace boundary it forms its own local_group. // Here we collect new roots to link them separately later on. Note that we need to avoid |