[PATCH v4 05/14] elf: Eliminate second loop in find_version in dl-version.c
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Mon Mar 17 14:03:48 GMT 2025
On 02/02/25 18:13, Florian Weimer wrote:
> The first loop iterates through all objects in the namespace
> because _dl_check_map_versions is called after the loaded
> objects have been added to the list. (This list is not limited
> by symbol search scope.)
>
> Turn the assert in _dl_check_map_versions into a proper error
> because it can be triggered by inconsistent variants of shared
> objects. This assert could fail if the soname in the vn_file field
> of the verneed structure for a version is not among the DT_NEEDED
> dependencies of an object. With such a discrepancy, the no matching
> object might be loaded, hence the assertion failure. Current
> binutils ld does not seem to produce such objects, preferring to
> create unversioned symbols instead of lifting symbol versions from
> indirect dependencies of the objects listed on the command line.
> This is why there is no test case for this error.
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> elf/dl-version.c | 18 +++++-------------
> 1 file changed, 5 insertions(+), 13 deletions(-)
>
> diff --git a/elf/dl-version.c b/elf/dl-version.c
> index d414bd1e18..0fae561e55 100644
> --- a/elf/dl-version.c
> +++ b/elf/dl-version.c
> @@ -31,21 +31,17 @@ __attribute ((always_inline))
> find_needed (const char *name, struct link_map *map)
> {
> struct link_map *tmap;
> - unsigned int n;
>
> for (tmap = GL(dl_ns)[map->l_ns]._ns_loaded; tmap != NULL;
> tmap = tmap->l_next)
> if (_dl_name_match_p (name, tmap))
> return tmap;
>
> - /* The required object is not in the global scope, look to see if it is
> - a dependency of the current object. */
> - for (n = 0; n < map->l_searchlist.r_nlist; n++)
> - if (_dl_name_match_p (name, map->l_searchlist.r_list[n]))
> - return map->l_searchlist.r_list[n];
> -
> - /* Should never happen. */
> - return NULL;
> + struct dl_exception exception;
> + _dl_exception_create_format
> + (&exception, DSO_FILENAME (map->l_name),
> + "missing soname %s in version dependency", name);
> + _dl_signal_exception (0, &exception, NULL);
> }
>
>
> @@ -199,10 +195,6 @@ _dl_check_map_versions (struct link_map *map, int verbose, int trace_mode)
> ElfW(Vernaux) *aux;
> struct link_map *needed = find_needed (strtab + ent->vn_file, map);
>
> - /* If NEEDED is NULL this means a dependency was not found
> - and no stub entry was created. This should never happen. */
> - assert (needed != NULL);
> -
> /* Make sure this is no stub we created because of a missing
> dependency. */
> if (__builtin_expect (! trace_mode, 1)
More information about the Libc-alpha
mailing list