Merge "Delay setting linker soname until post-reloc and post-ctor"
This commit is contained in:
commit
caf32c7697
3 changed files with 26 additions and 18 deletions
|
@ -328,7 +328,7 @@ soinfo* get_libdl_info(const soinfo& linker_si) {
|
|||
__libdl_info->ref_count_ = 1;
|
||||
__libdl_info->strtab_size_ = linker_si.strtab_size_;
|
||||
__libdl_info->local_group_root_ = __libdl_info;
|
||||
__libdl_info->soname_ = linker_si.soname_.c_str();
|
||||
__libdl_info->soname_ = linker_si.soname_;
|
||||
__libdl_info->target_sdk_version_ = __ANDROID_API__;
|
||||
__libdl_info->generate_handle();
|
||||
#if defined(__work_around_b_24465209__)
|
||||
|
|
|
@ -3193,26 +3193,27 @@ 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_.empty() && 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",
|
||||
|
|
|
@ -725,6 +725,13 @@ __linker_init_post_relocation(KernelArgumentBlock& args, soinfo& tmp_linker_so)
|
|||
// Initialize the linker's own global variables
|
||||
tmp_linker_so.call_constructors();
|
||||
|
||||
// Setting the linker soinfo's soname can allocate heap memory, so delay it until here.
|
||||
for (const ElfW(Dyn)* d = tmp_linker_so.dynamic; d->d_tag != DT_NULL; ++d) {
|
||||
if (d->d_tag == DT_SONAME) {
|
||||
tmp_linker_so.set_soname(tmp_linker_so.get_string(d->d_un.d_val));
|
||||
}
|
||||
}
|
||||
|
||||
// When the linker is run directly rather than acting as PT_INTERP, parse
|
||||
// arguments and determine the executable to load. When it's instead acting
|
||||
// as PT_INTERP, AT_ENTRY will refer to the loaded executable rather than the
|
||||
|
|
Loading…
Reference in a new issue