diff options
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 363 |
1 files changed, 186 insertions, 177 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index f24167722..3488f5cc7 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -186,10 +186,10 @@ static bool maybe_accessible_via_namespace_links(android_namespace_t* ns, const return false; } -// TODO(dimitry): The grey-list is a workaround for http://b/26394120 --- +// TODO(dimitry): The exempt-list is a workaround for http://b/26394120 --- // gradually remove libraries from this list until it is gone. -static bool is_greylisted(android_namespace_t* ns, const char* name, const soinfo* needed_by) { - static const char* const kLibraryGreyList[] = { +static bool is_exempt_lib(android_namespace_t* ns, const char* name, const soinfo* needed_by) { + static const char* const kLibraryExemptList[] = { "libandroid_runtime.so", "libbinder.so", "libcrypto.so", @@ -206,13 +206,13 @@ static bool is_greylisted(android_namespace_t* ns, const char* name, const soinf nullptr }; - // If you're targeting N, you don't get the greylist. - if (g_greylist_disabled || get_application_target_sdk_version() >= 24) { + // If you're targeting N, you don't get the exempt-list. + if (get_application_target_sdk_version() >= 24) { return false; } // if the library needed by a system library - implicitly assume it - // is greylisted unless it is in the list of shared libraries for one or + // is exempt unless it is in the list of shared libraries for one or // more linked namespaces if (needed_by != nullptr && is_system_library(needed_by->get_realpath())) { return !maybe_accessible_via_namespace_links(ns, name); @@ -224,8 +224,8 @@ static bool is_greylisted(android_namespace_t* ns, const char* name, const soinf name = basename(name); } - for (size_t i = 0; kLibraryGreyList[i] != nullptr; ++i) { - if (strcmp(name, kLibraryGreyList[i]) == 0) { + for (size_t i = 0; kLibraryExemptList[i] != nullptr; ++i) { + if (strcmp(name, kLibraryExemptList[i]) == 0) { return true; } } @@ -311,6 +311,10 @@ static void soinfo_free(soinfo* si) { } } + if (si->has_min_version(6) && si->get_gap_size()) { + munmap(reinterpret_cast<void*>(si->get_gap_start()), si->get_gap_size()); + } + TRACE("name %s: freeing soinfo @ %p", si->get_realpath(), si); if (!solist_remove_soinfo(si)) { @@ -498,10 +502,10 @@ class LoadTask { static deleter_t deleter; - static LoadTask* create(const char* name, - soinfo* needed_by, - android_namespace_t* start_from, - std::unordered_map<const soinfo*, ElfReader>* readers_map) { + // needed_by is NULL iff dlopen is called from memory that isn't part of any known soinfo. + static LoadTask* create(const char* _Nonnull name, soinfo* _Nullable needed_by, + android_namespace_t* _Nonnull start_from, + std::unordered_map<const soinfo*, ElfReader>* _Nonnull readers_map) { LoadTask* ptr = TypeBasedAllocator<LoadTask>::alloc(); return new (ptr) LoadTask(name, needed_by, start_from, readers_map); } @@ -563,6 +567,11 @@ class LoadTask { return start_from_; } + void remove_cached_elf_reader() { + CHECK(si_ != nullptr); + (*elf_readers_map_).erase(si_); + } + const ElfReader& get_elf_reader() const { CHECK(si_ != nullptr); return (*elf_readers_map_)[si_]; @@ -594,6 +603,8 @@ class LoadTask { si_->load_bias = elf_reader.load_bias(); si_->phnum = elf_reader.phdr_count(); si_->phdr = elf_reader.loaded_phdr(); + si_->set_gap_start(elf_reader.gap_start()); + si_->set_gap_size(elf_reader.gap_size()); return true; } @@ -621,7 +632,7 @@ class LoadTask { bool close_fd_; off64_t file_offset_; std::unordered_map<const soinfo*, ElfReader>* elf_readers_map_; - // TODO(dimitry): needed by workaround for http://b/26394120 (the grey-list) + // TODO(dimitry): needed by workaround for http://b/26394120 (the exempt-list) bool is_dt_needed_; // END OF WORKAROUND const android_namespace_t* const start_from_; @@ -1001,47 +1012,24 @@ static int open_library(android_namespace_t* ns, // If the name contains a slash, we should attempt to open it directly and not search the paths. if (strchr(name, '/') != nullptr) { - int fd = -1; - - if (strstr(name, kZipFileSeparator) != nullptr) { - fd = open_library_in_zipfile(zip_archive_cache, name, file_offset, realpath); - } - - if (fd == -1) { - fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_CLOEXEC)); - if (fd != -1) { - *file_offset = 0; - if (!realpath_fd(fd, realpath)) { - if (!is_first_stage_init()) { - PRINT("warning: unable to get realpath for the library \"%s\". Will use given path.", - name); - } - *realpath = name; - } - } - } - - return fd; + return open_library_at_path(zip_archive_cache, name, file_offset, realpath); } - // Otherwise we try LD_LIBRARY_PATH first, and fall back to the default library path + // LD_LIBRARY_PATH has the highest priority. We don't have to check accessibility when searching + // the namespace's path lists, because anything found on a namespace path list should always be + // accessible. int fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_ld_library_paths(), realpath); + + // Try the DT_RUNPATH, and verify that the library is accessible. if (fd == -1 && needed_by != nullptr) { fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath); - // Check if the library is accessible if (fd != -1 && !ns->is_accessible(*realpath)) { close(fd); fd = -1; } } -#if !defined(__ANDROID_APEX__) - if (fd == -1) { - std::vector<std::string> bootstrap_paths = { std::string(kSystemLibDir) + "/bootstrap" }; - fd = open_library_on_paths(zip_archive_cache, name, file_offset, bootstrap_paths, realpath); - } -#endif - + // Finally search the namespace's main search path list. if (fd == -1) { fd = open_library_on_paths(zip_archive_cache, name, file_offset, ns->get_default_library_paths(), realpath); } @@ -1199,12 +1187,12 @@ static bool load_library(android_namespace_t* ns, // do not check accessibility using realpath if fd is located on tmpfs // this enables use of memfd_create() for apps if ((fs_stat.f_type != TMPFS_MAGIC) && (!ns->is_accessible(realpath))) { - // TODO(dimitry): workaround for http://b/26394120 - the grey-list + // TODO(dimitry): workaround for http://b/26394120 - the exempt-list // TODO(dimitry) before O release: add a namespace attribute to have this enabled // only for classloader-namespaces const soinfo* needed_by = task->is_dt_needed() ? task->get_needed_by() : nullptr; - if (is_greylisted(ns, name, needed_by)) { + if (is_exempt_lib(ns, name, needed_by)) { // print warning only if needed by non-system library if (needed_by == nullptr || !is_system_library(needed_by->get_realpath())) { const soinfo* needed_or_dlopened_by = task->get_needed_by(); @@ -1243,20 +1231,18 @@ static bool load_library(android_namespace_t* ns, } soinfo* si = soinfo_alloc(ns, realpath.c_str(), &file_stat, file_offset, rtld_flags); - if (si == nullptr) { - return false; - } task->set_soinfo(si); // Read the ELF header and some of the segments. if (!task->read(realpath.c_str(), file_stat.st_size)) { - soinfo_free(si); + task->remove_cached_elf_reader(); task->set_soinfo(nullptr); + soinfo_free(si); 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. @@ -1268,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__) @@ -1298,14 +1288,13 @@ static bool load_library(android_namespace_t* ns, soinfo* needed_by = task->get_needed_by(); const android_dlextinfo* extinfo = task->get_extinfo(); - off64_t file_offset; - std::string realpath; if (extinfo != nullptr && (extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD) != 0) { - file_offset = 0; + off64_t file_offset = 0; if ((extinfo->flags & ANDROID_DLEXT_USE_LIBRARY_FD_OFFSET) != 0) { file_offset = extinfo->library_fd_offset; } + std::string realpath; if (!realpath_fd(extinfo->library_fd, &realpath)) { if (!is_first_stage_init()) { PRINT( @@ -1323,10 +1312,12 @@ static bool load_library(android_namespace_t* ns, LD_LOG(kLogDlopen, "load_library(ns=%s, task=%s, flags=0x%x, search_linked_namespaces=%d): calling " - "open_library with realpath=%s", - ns->get_name(), name, rtld_flags, search_linked_namespaces, realpath.c_str()); + "open_library", + ns->get_name(), name, rtld_flags, search_linked_namespaces); // Open the file. + off64_t file_offset; + std::string realpath; int fd = open_library(ns, zip_archive_cache, name, needed_by, &file_offset, &realpath); if (fd == -1) { if (task->is_dt_needed()) { @@ -1352,8 +1343,7 @@ static bool find_loaded_library_by_soname(android_namespace_t* ns, const char* name, soinfo** candidate) { return !ns->soinfo_list().visit([&](soinfo* si) { - const char* soname = si->get_soname(); - if (soname != nullptr && (strcmp(name, soname) == 0)) { + if (strcmp(name, si->get_soname()) == 0) { *candidate = si; return false; } @@ -1437,11 +1427,11 @@ static bool find_library_internal(android_namespace_t* ns, LoadTask* task, ZipArchiveCache* zip_archive_cache, LoadTaskList* load_tasks, - int rtld_flags, - bool search_linked_namespaces) { + int rtld_flags) { soinfo* candidate; - if (find_loaded_library_by_soname(ns, task->get_name(), search_linked_namespaces, &candidate)) { + if (find_loaded_library_by_soname(ns, task->get_name(), true /* search_linked_namespaces */, + &candidate)) { LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Already loaded (by soname): %s", ns->get_name(), task->get_name(), candidate->get_realpath()); @@ -1454,54 +1444,49 @@ static bool find_library_internal(android_namespace_t* ns, TRACE("[ \"%s\" find_loaded_library_by_soname failed (*candidate=%s@%p). Trying harder... ]", task->get_name(), candidate == nullptr ? "n/a" : candidate->get_realpath(), candidate); - if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, search_linked_namespaces)) { + if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, + true /* search_linked_namespaces */)) { return true; } - // TODO(dimitry): workaround for http://b/26394120 (the grey-list) - if (ns->is_greylist_enabled() && is_greylisted(ns, task->get_name(), task->get_needed_by())) { - // For the libs in the greylist, switch to the default namespace and then + // TODO(dimitry): workaround for http://b/26394120 (the exempt-list) + if (ns->is_exempt_list_enabled() && is_exempt_lib(ns, task->get_name(), task->get_needed_by())) { + // For the libs in the exempt-list, switch to the default namespace and then // try the load again from there. The library could be loaded from the // default namespace or from another namespace (e.g. runtime) that is linked // from the default namespace. LD_LOG(kLogDlopen, - "find_library_internal(ns=%s, task=%s): Greylisted library - trying namespace %s", + "find_library_internal(ns=%s, task=%s): Exempt system library - trying namespace %s", ns->get_name(), task->get_name(), g_default_namespace.get_name()); ns = &g_default_namespace; if (load_library(ns, task, zip_archive_cache, load_tasks, rtld_flags, - search_linked_namespaces)) { + true /* search_linked_namespaces */)) { return true; } } // END OF WORKAROUND - if (search_linked_namespaces) { - // if a library was not found - look into linked namespaces - // preserve current dlerror in the case it fails. - DlErrorRestorer dlerror_restorer; - LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Trying %zu linked namespaces", - ns->get_name(), task->get_name(), ns->linked_namespaces().size()); - for (auto& linked_namespace : ns->linked_namespaces()) { - if (find_library_in_linked_namespace(linked_namespace, task)) { - if (task->get_soinfo() == nullptr) { - // try to load the library - once namespace boundary is crossed - // we need to load a library within separate load_group - // to avoid using symbols from foreign namespace while. - // - // However, actual linking is deferred until when the global group - // is fully identified and is applied to all namespaces. - // Otherwise, the libs in the linked namespace won't get symbols from - // the global group. - if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, rtld_flags, false)) { - LD_LOG( - kLogDlopen, "find_library_internal(ns=%s, task=%s): Found in linked namespace %s", - ns->get_name(), task->get_name(), linked_namespace.linked_namespace()->get_name()); - return true; - } - } else { - // lib is already loaded - return true; - } + // if a library was not found - look into linked namespaces + // preserve current dlerror in the case it fails. + DlErrorRestorer dlerror_restorer; + LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Trying %zu linked namespaces", + ns->get_name(), task->get_name(), ns->linked_namespaces().size()); + for (auto& linked_namespace : ns->linked_namespaces()) { + if (find_library_in_linked_namespace(linked_namespace, task)) { + // Library is already loaded. + if (task->get_soinfo() != nullptr) { + // n.b. This code path runs when find_library_in_linked_namespace found an already-loaded + // library by soname. That should only be possible with a exempt-list lookup, where we + // switch the namespace, because otherwise, find_library_in_linked_namespace is duplicating + // the soname scan done in this function's first call to find_loaded_library_by_soname. + return true; + } + + if (load_library(linked_namespace.linked_namespace(), task, zip_archive_cache, load_tasks, + rtld_flags, false /* search_linked_namespaces */)) { + LD_LOG(kLogDlopen, "find_library_internal(ns=%s, task=%s): Found in linked namespace %s", + ns->get_name(), task->get_name(), linked_namespace.linked_namespace()->get_name()); + return true; } } } @@ -1538,7 +1523,6 @@ bool find_libraries(android_namespace_t* ns, int rtld_flags, const android_dlextinfo* extinfo, bool add_as_children, - bool search_linked_namespaces, std::vector<android_namespace_t*>* namespaces) { // Step 0: prepare. std::unordered_map<const soinfo*, ElfReader> readers_map; @@ -1572,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) @@ -1594,8 +1579,7 @@ bool find_libraries(android_namespace_t* ns, task, &zip_archive_cache, &load_tasks, - rtld_flags, - search_linked_namespaces || is_dt_needed)) { + rtld_flags)) { return false; } @@ -1607,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) @@ -1670,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 @@ -1837,8 +1815,7 @@ static soinfo* find_library(android_namespace_t* ns, 0, rtld_flags, extinfo, - false /* add_as_children */, - true /* search_linked_namespaces */)) { + false /* add_as_children */)) { if (si != nullptr) { soinfo_unload(si); } @@ -2404,6 +2381,21 @@ static void add_soinfos_to_namespace(const soinfo_list_t& soinfos, android_names } } +std::vector<std::string> fix_lib_paths(std::vector<std::string> paths) { + // For the bootstrap linker, insert /system/${LIB}/bootstrap in front of /system/${LIB} in any + // namespace search path. The bootstrap linker should prefer to use the bootstrap bionic libraries + // (e.g. libc.so). +#if !defined(__ANDROID_APEX__) + for (size_t i = 0; i < paths.size(); ++i) { + if (paths[i] == kSystemLibDir) { + paths.insert(paths.begin() + i, std::string(kSystemLibDir) + "/bootstrap"); + ++i; + } + } +#endif + return paths; +} + android_namespace_t* create_namespace(const void* caller_addr, const char* name, const char* ld_library_path, @@ -2432,7 +2424,7 @@ android_namespace_t* create_namespace(const void* caller_addr, android_namespace_t* ns = new (g_namespace_allocator.alloc()) android_namespace_t(); ns->set_name(name); ns->set_isolated((type & ANDROID_NAMESPACE_TYPE_ISOLATED) != 0); - ns->set_greylist_enabled((type & ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED) != 0); + ns->set_exempt_list_enabled((type & ANDROID_NAMESPACE_TYPE_EXEMPT_LIST_ENABLED) != 0); ns->set_also_used_as_anonymous((type & ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS) != 0); if ((type & ANDROID_NAMESPACE_TYPE_SHARED) != 0) { @@ -2577,9 +2569,8 @@ bool VersionTracker::init_verneed(const soinfo* si_from) { const char* target_soname = si_from->get_string(verneed->vn_file); // find it in dependencies - soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) { - return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0; - }); + soinfo* target_si = si_from->get_children().find_if( + [&](const soinfo* si) { return strcmp(si->get_soname(), target_soname) == 0; }); if (target_si == nullptr) { DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"", @@ -3147,6 +3138,14 @@ bool soinfo::prelink_image() { // resolves everything eagerly, so these can be ignored. break; +#if defined(__aarch64__) + case DT_AARCH64_BTI_PLT: + case DT_AARCH64_PAC_PLT: + case DT_AARCH64_VARIANT_PCS: + // Ignored: AArch64 processor-specific dynamic array tags. + break; +#endif + default: if (!relocating_linker) { const char* tag_name; @@ -3174,7 +3173,7 @@ bool soinfo::prelink_image() { DEBUG("si->base = %p, si->strtab = %p, si->symtab = %p", reinterpret_cast<void*>(base), strtab_, symtab_); - // Sanity checks. + // Validity checks. if (relocating_linker && needed_count != 0) { DL_ERR("linker cannot have DT_NEEDED dependencies on other libraries"); return false; @@ -3193,34 +3192,32 @@ bool soinfo::prelink_image() { return false; } - // second pass - parse entries relying on strtab - for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) { - switch (d->d_tag) { - case DT_SONAME: - set_soname(get_string(d->d_un.d_val)); - break; - case DT_RUNPATH: - set_dt_runpath(get_string(d->d_un.d_val)); - break; + // Second pass - parse entries relying on strtab. Skip this while relocating the linker so as to + // avoid doing heap allocations until later in the linker's initialization. + if (!relocating_linker) { + for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) { + switch (d->d_tag) { + case DT_SONAME: + set_soname(get_string(d->d_un.d_val)); + break; + case DT_RUNPATH: + set_dt_runpath(get_string(d->d_un.d_val)); + break; + } } } - // Before M release linker was using basename in place of soname. - // In the case when dt_soname is absent some apps stop working - // because they can't find dt_needed library by soname. - // This workaround should keep them working. (Applies only - // for apps targeting sdk version < M.) Make an exception for - // the main executable and linker; they do not need to have dt_soname. - // TODO: >= O the linker doesn't need this workaround. - if (soname_ == nullptr && - this != solist_get_somain() && - (flags_ & FLAG_LINKER) == 0 && + // Before M release, linker was using basename in place of soname. In the case when DT_SONAME is + // absent some apps stop working because they can't find DT_NEEDED library by soname. This + // workaround should keep them working. (Applies only for apps targeting sdk version < M.) Make + // an exception for the main executable, which does not need to have DT_SONAME. The linker has an + // DT_SONAME but the soname_ field is initialized later on. + if (soname_.empty() && this != solist_get_somain() && !relocating_linker && get_application_target_sdk_version() < 23) { soname_ = basename(realpath_.c_str()); - DL_WARN_documented_change(23, - "missing-soname-enforced-for-api-level-23", - "\"%s\" has no DT_SONAME (will use %s instead)", - get_realpath(), soname_); + DL_WARN_documented_change(23, "missing-soname-enforced-for-api-level-23", + "\"%s\" has no DT_SONAME (will use %s instead)", get_realpath(), + soname_.c_str()); // Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI } @@ -3259,9 +3256,8 @@ bool soinfo::link_image(const SymbolLookupList& lookup_list, soinfo* local_group // Fail if app is targeting M or above. int app_target_api_level = get_application_target_sdk_version(); if (app_target_api_level >= 23) { - DL_ERR_AND_LOG("\"%s\" has text relocations (https://android.googlesource.com/platform/" - "bionic/+/master/android-changes-for-ndk-developers.md#Text-Relocations-" - "Enforced-for-API-level-23)", get_realpath()); + DL_ERR_AND_LOG("\"%s\" has text relocations (%s#Text-Relocations-Enforced-for-API-level-23)", + get_realpath(), kBionicChangesUrl); return false; } // Make segments writable to allow text relocations to work properly. We will later call @@ -3385,6 +3381,22 @@ static std::string get_ld_config_file_vndk_path() { return ld_config_file_vndk; } +bool is_linker_config_expected(const char* executable_path) { + // Do not raise message from a host environment which is expected to miss generated linker + // configuration. +#if !defined(__ANDROID__) + return false; +#endif + + if (strcmp(executable_path, "/system/bin/init") == 0) { + // Generated linker configuration can be missed from processes executed + // with init binary + return false; + } + + return true; +} + static std::string get_ld_config_file_path(const char* executable_path) { #ifdef USE_LD_CONFIG_FILE // This is a debugging/testing only feature. Must not be available on @@ -3411,10 +3423,11 @@ static std::string get_ld_config_file_path(const char* executable_path) { if (file_exists(kLdGeneratedConfigFilePath)) { return kLdGeneratedConfigFilePath; - } else { - // TODO(b/146386369) : Adjust log level and add more condition to log only when necessary - INFO("Warning: failed to find generated linker configuration from \"%s\"", - kLdGeneratedConfigFilePath); + } + + if (is_linker_config_expected(executable_path)) { + DL_WARN("Warning: failed to find generated linker configuration from \"%s\"", + kLdGeneratedConfigFilePath); } path = get_ld_config_file_vndk_path(); @@ -3440,23 +3453,19 @@ std::vector<android_namespace_t*> init_default_namespaces(const char* executable const Config* config = nullptr; - std::string error_msg; - - std::string ld_config_file_path = get_ld_config_file_path(executable_path); - - INFO("[ Reading linker config \"%s\" ]", ld_config_file_path.c_str()); - if (!Config::read_binary_config(ld_config_file_path.c_str(), - executable_path, - g_is_asan, - &config, - &error_msg)) { - if (!error_msg.empty()) { - DL_WARN("Warning: couldn't read \"%s\" for \"%s\" (using default configuration instead): %s", - ld_config_file_path.c_str(), - executable_path, - error_msg.c_str()); + { + std::string ld_config_file_path = get_ld_config_file_path(executable_path); + INFO("[ Reading linker config \"%s\" ]", ld_config_file_path.c_str()); + ScopedTrace trace(("linker config " + ld_config_file_path).c_str()); + std::string error_msg; + if (!Config::read_binary_config(ld_config_file_path.c_str(), executable_path, g_is_asan, + &config, &error_msg)) { + if (!error_msg.empty()) { + DL_WARN("Warning: couldn't read '%s' for '%s' (using default configuration instead): %s", + ld_config_file_path.c_str(), executable_path, error_msg.c_str()); + } + config = nullptr; } - config = nullptr; } if (config == nullptr) { @@ -3490,7 +3499,7 @@ std::vector<android_namespace_t*> init_default_namespaces(const char* executable ns->set_isolated(ns_config->isolated()); ns->set_default_library_paths(ns_config->search_paths()); ns->set_permitted_paths(ns_config->permitted_paths()); - ns->set_whitelisted_libs(ns_config->whitelisted_libs()); + ns->set_allowed_libs(ns_config->allowed_libs()); namespaces[ns_config->name()] = ns; if (ns_config->visible()) { |