about summary refs log tree commit diff
path: root/elf/dl-lookup.c
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2019-06-28 10:12:50 +0200
committerFlorian Weimer <fweimer@redhat.com>2019-06-28 10:15:38 +0200
commitf0b2132b35248c1f4a80f62a2c38cddcc802aa8c (patch)
tree32e3b30bba3d07b48c40035d8a4011ed39a212ef /elf/dl-lookup.c
parent17432d7150bdab3bce2ea66c70ad6c920f54077a (diff)
downloadglibc-f0b2132b35248c1f4a80f62a2c38cddcc802aa8c.tar.gz
glibc-f0b2132b35248c1f4a80f62a2c38cddcc802aa8c.tar.xz
glibc-f0b2132b35248c1f4a80f62a2c38cddcc802aa8c.zip
ld.so: Support moving versioned symbols between sonames [BZ #24741]
This change should be fully backwards-compatible because the old
code aborted the load if a soname mismatch was encountered
(instead of searching further for a matching symbol).  This means
that no different symbols are found.

The soname check was explicitly disabled for the skip_map != NULL
case.  However, this only happens with dl(v)sym and RTLD_NEXT,
and those lookups do not come with a verneed entry that could be used
for the check.

The error check was already explicitly disabled for the skip_map !=
NULL case, that is, when dl(v)sym was called with RTLD_NEXT.  But
_dl_vsym always sets filename in the struct r_found_version argument
to NULL, so the check was not active anyway.  This means that
symbol lookup results for the skip_map != NULL case do not change,
either.
Diffstat (limited to 'elf/dl-lookup.c')
-rw-r--r--elf/dl-lookup.c38
1 files changed, 5 insertions, 33 deletions
diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index e3f42a1efb..eb23cca4e3 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -536,11 +536,7 @@ do_lookup_x (const char *undef_name, uint_fast32_t new_hash,
 	}
 
 skip:
-      /* If this current map is the one mentioned in the verneed entry
-	 and we have not found a weak entry, it is a bug.  */
-      if (symidx == STN_UNDEF && version != NULL && version->filename != NULL
-	  && __glibc_unlikely (_dl_name_match_p (version->filename, map)))
-	return -1;
+      ;
     }
   while (++i < n);
 
@@ -810,34 +806,10 @@ _dl_lookup_symbol_x (const char *undef_name, struct link_map *undef_map,
 
   /* Search the relevant loaded objects for a definition.  */
   for (size_t start = i; *scope != NULL; start = 0, ++scope)
-    {
-      int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref,
-			     &current_value, *scope, start, version, flags,
-			     skip_map, type_class, undef_map);
-      if (res > 0)
-	break;
-
-      if (__glibc_unlikely (res < 0) && skip_map == NULL)
-	{
-	  /* Oh, oh.  The file named in the relocation entry does not
-	     contain the needed symbol.  This code is never reached
-	     for unversioned lookups.  */
-	  assert (version != NULL);
-	  const char *reference_name = undef_map ? undef_map->l_name : "";
-	  struct dl_exception exception;
-	  /* XXX We cannot translate the message.  */
-	  _dl_exception_create_format
-	    (&exception, DSO_FILENAME (reference_name),
-	     "symbol %s version %s not defined in file %s"
-	     " with link time reference%s",
-	     undef_name, version->name, version->filename,
-	     res == -2 ? " (no version symbols)" : "");
-	  _dl_signal_cexception (0, &exception, N_("relocation error"));
-	  _dl_exception_free (&exception);
-	  *ref = NULL;
-	  return 0;
-	}
-    }
+    if (do_lookup_x (undef_name, new_hash, &old_hash, *ref,
+		     &current_value, *scope, start, version, flags,
+		     skip_map, type_class, undef_map) != 0)
+      break;
 
   if (__glibc_unlikely (current_value.s == NULL))
     {