[yocto] [prelink-cross][PATCH] rtld: Add missing DT_NEEDED DSOs to needed_list

Mark Hatle mark.hatle at windriver.com
Thu Aug 25 10:03:18 PDT 2016


Thanks!  I'll try to get this included soon.

--Mark

On 8/25/16 10:39 AM, Kyle Russell wrote:
> 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 <bkylerussell at 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;
>  		}
> 




More information about the yocto mailing list