prelink-rtld may report an "error while loading shared libraries" for the wrong library.
If some set of DT_NEEDED DSOs are not in the default search path, they may have a dso_list entry added, but no matching entry is added to the needed_list. This causes the linker to miscalculate the max number of dsos during build_local_scope(), which later causes find_needed() to not search the entire l_local_scope[0]->r_list during _dl_check_map_versions() (since the max from build_local_scope() becomes l_local_scope[0]->r_nlist). Since find_needed() searches through the r_list, which would have the dso_list entries for the libraries that weren't found earlier, this cuts the search short, meaning libraries near the end of the local scope don't get included in the map version search. As the comment in _dl_check_map_versions() suggests, if needed is NULL, that means a dependency was not found and no stub entry created, which should never happen. Signed-off-by: Kyle Russell <bkyleruss...@gmail.com> --- src/rtld/rtld.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/rtld/rtld.c b/src/rtld/rtld.c index 8d7d760..d9a0862 100644 --- a/src/rtld/rtld.c +++ b/src/rtld/rtld.c @@ -686,6 +686,25 @@ find_lib_by_soname (const char *soname, struct dso_list *loader, return NULL; } +static void +add_dso_to_needed (struct dso_list *cur_dso_ent, struct dso_list *new_dso_ent) +{ + if (!cur_dso_ent->needed) + { + cur_dso_ent->needed = malloc (sizeof (struct needed_list)); + cur_dso_ent->needed_tail = cur_dso_ent->needed; + cur_dso_ent->needed_tail->ent = new_dso_ent; + cur_dso_ent->needed_tail->next = NULL; + } + else if (!in_needed_list (cur_dso_ent->needed, new_dso_ent->name)) + { + cur_dso_ent->needed_tail->next = malloc (sizeof (struct needed_list)); + cur_dso_ent->needed_tail = cur_dso_ent->needed_tail->next; + cur_dso_ent->needed_tail->ent = new_dso_ent; + cur_dso_ent->needed_tail->next = NULL; + } +} + static struct dso_list * load_dsos (DSO *dso, int host_paths) { @@ -812,6 +831,8 @@ load_dsos (DSO *dso, int host_paths) dso_list_tail->canon_filename = strdup(soname); dso_list_tail->err_no = errno; + add_dso_to_needed(cur_dso_ent, new_dso_ent); + continue; } @@ -854,20 +875,7 @@ load_dsos (DSO *dso, int host_paths) dso_list_tail->name = new_dso->soname; } - if (!cur_dso_ent->needed) - { - cur_dso_ent->needed = malloc (sizeof (struct needed_list)); - cur_dso_ent->needed_tail = cur_dso_ent->needed; - cur_dso_ent->needed_tail->ent = new_dso_ent; - cur_dso_ent->needed_tail->next = NULL; - } - else if (!in_needed_list (cur_dso_ent->needed, soname)) - { - cur_dso_ent->needed_tail->next = malloc (sizeof (struct needed_list)); - cur_dso_ent->needed_tail = cur_dso_ent->needed_tail->next; - cur_dso_ent->needed_tail->ent = new_dso_ent; - cur_dso_ent->needed_tail->next = NULL; - } + add_dso_to_needed(cur_dso_ent, new_dso_ent); continue; } -- 2.7.4 -- _______________________________________________ yocto mailing list yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/yocto