diff options
Diffstat (limited to 'linker/linker.cpp')
-rw-r--r-- | linker/linker.cpp | 52 |
1 files changed, 24 insertions, 28 deletions
diff --git a/linker/linker.cpp b/linker/linker.cpp index 2481be4e4..c240c5639 100644 --- a/linker/linker.cpp +++ b/linker/linker.cpp @@ -1339,8 +1339,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; } @@ -2571,9 +2570,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\"", @@ -3195,34 +3193,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 } |