]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
elf: Add l_soname accessor function for DT_SONAME values
authorFlorian Weimer <fweimer@redhat.com>
Sun, 2 Feb 2025 19:10:09 +0000 (20:10 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Sun, 2 Feb 2025 19:10:09 +0000 (20:10 +0100)
It's not necessary to introduce temporaries because the compiler
is able to evaluate l_soname just once in constracts like:

  l_soname (l) != NULL && strcmp (l_soname (l), LIBC_SO) != 0

elf/dl-load.c
elf/dl-open.c
elf/rtld.c
elf/setup-vdso.h
elf/sprof.c
sysdeps/generic/ldsodefs.h

index deb1b32a273f71a716433663b8f225a7116bbfdb..4998652adff36568d517d402ffc198e87b3d22fa 100644 (file)
@@ -1421,10 +1421,8 @@ cannot enable executable stack as shared object requires");
 
   /* When we profile the SONAME might be needed for something else but
      loading.  Add it right away.  */
-  if (__glibc_unlikely (GLRO(dl_profile) != NULL)
-      && l->l_info[DT_SONAME] != NULL)
-    add_name_to_object (l, ((const char *) D_PTR (l, l_info[DT_STRTAB])
-                           + l->l_info[DT_SONAME]->d_un.d_val));
+  if (__glibc_unlikely (GLRO(dl_profile) != NULL) && l_soname (l) != NULL)
+    add_name_to_object (l, l_soname (l));
 #else
   /* Audit modules only exist when linking is dynamic so ORIGNAME
      cannot be non-NULL.  */
@@ -1434,9 +1432,7 @@ cannot enable executable stack as shared object requires");
   /* If we have newly loaded libc.so, update the namespace
      description.  */
   if (GL(dl_ns)[nsid].libc_map == NULL
-      && l->l_info[DT_SONAME] != NULL
-      && strcmp (((const char *) D_PTR (l, l_info[DT_STRTAB])
-                 + l->l_info[DT_SONAME]->d_un.d_val), LIBC_SO) == 0)
+      && l_soname (l) != NULL && strcmp (l_soname(l), LIBC_SO) == 0)
     GL(dl_ns)[nsid].libc_map = l;
 
   /* _dl_close can only eventually undo the module ID assignment (via
@@ -1903,19 +1899,12 @@ _dl_lookup_map (Lmid_t nsid, const char *name)
        continue;
       if (!_dl_name_match_p (name, l))
        {
-         const char *soname;
-
-         if (__glibc_likely (l->l_soname_added)
-             || l->l_info[DT_SONAME] == NULL)
-           continue;
-
-         soname = ((const char *) D_PTR (l, l_info[DT_STRTAB])
-                   + l->l_info[DT_SONAME]->d_un.d_val);
-         if (strcmp (name, soname) != 0)
+         if (__glibc_likely (l->l_soname_added) || l_soname (l) == NULL
+             || strcmp (name, l_soname (l)) != 0)
            continue;
 
          /* We have a match on a new name -- cache it.  */
-         add_name_to_object (l, soname);
+         add_name_to_object (l, l_soname (l));
          l->l_soname_added = 1;
        }
 
index 4c12ddec5968165fb31baf909c4eeb559e07cda2..a94e4c237605de4bf90f997a24d50b2976ff88a8 100644 (file)
@@ -617,9 +617,7 @@ dl_open_worker_begin (void *a)
           Perform partial initialization in this case.  This must
           come after the symbol versioning initialization in
           _dl_check_map_versions.  */
-       if (map->l_info[DT_SONAME] != NULL
-           && strcmp (((const char *) D_PTR (map, l_info[DT_STRTAB])
-                       + map->l_info[DT_SONAME]->d_un.d_val), LD_SO) == 0)
+       if (l_soname (map) != NULL && strcmp (l_soname (map), LD_SO) == 0)
          __rtld_static_init (map);
 #endif
       }
index 00bec1531638ea133f5a9c1445c81d18f5cdc8f1..115f1da37f364290bb2194d795299b1d57c3f033 100644 (file)
@@ -1055,13 +1055,9 @@ static void
 rtld_chain_load (struct link_map *main_map, char *argv0)
 {
   /* The dynamic loader run against itself.  */
-  const char *rtld_soname
-    = ((const char *) D_PTR (&_dl_rtld_map, l_info[DT_STRTAB])
-       + _dl_rtld_map.l_info[DT_SONAME]->d_un.d_val);
-  if (main_map->l_info[DT_SONAME] != NULL
-      && strcmp (rtld_soname,
-                ((const char *) D_PTR (main_map, l_info[DT_STRTAB])
-                 + main_map->l_info[DT_SONAME]->d_un.d_val)) == 0)
+  const char *rtld_soname = l_soname (&_dl_rtld_map);
+  if (l_soname (main_map) != NULL
+      && strcmp (rtld_soname, l_soname (main_map)) == 0)
     _dl_fatal_printf ("%s: loader cannot load itself\n", rtld_soname);
 
   /* With DT_NEEDED dependencies, the executable is dynamically
@@ -1632,20 +1628,20 @@ dl_main (const ElfW(Phdr) *phdr,
 
   /* If the current libname is different from the SONAME, add the
      latter as well.  */
-  if (_dl_rtld_map.l_info[DT_SONAME] != NULL
-      && strcmp (_dl_rtld_map.l_libname->name,
-                (const char *) D_PTR (&_dl_rtld_map, l_info[DT_STRTAB])
-                + _dl_rtld_map.l_info[DT_SONAME]->d_un.d_val) != 0)
-    {
-      static struct libname_list newname;
-      newname.name = ((char *) D_PTR (&_dl_rtld_map, l_info[DT_STRTAB])
-                     + _dl_rtld_map.l_info[DT_SONAME]->d_un.d_ptr);
-      newname.next = NULL;
-      newname.dont_free = 1;
-
-      assert (_dl_rtld_map.l_libname->next == NULL);
-      _dl_rtld_map.l_libname->next = &newname;
-    }
+  {
+    const char *soname = l_soname (&_dl_rtld_map);
+    if (soname != NULL
+       && strcmp (_dl_rtld_map.l_libname->name, soname) != 0)
+      {
+       static struct libname_list newname;
+       newname.name = soname;
+       newname.next = NULL;
+       newname.dont_free = 1;
+
+       assert (_dl_rtld_map.l_libname->next == NULL);
+       _dl_rtld_map.l_libname->next = &newname;
+      }
+  }
   /* The ld.so must be relocated since otherwise loading audit modules
      will fail since they reuse the very same ld.so.  */
   assert (_dl_rtld_map.l_relocated);
@@ -1658,10 +1654,8 @@ dl_main (const ElfW(Phdr) *phdr,
       /* If the main map is libc.so, update the base namespace to
         refer to this map.  If libc.so is loaded later, this happens
         in _dl_map_object_from_fd.  */
-      if (main_map->l_info[DT_SONAME] != NULL
-         && (strcmp (((const char *) D_PTR (main_map, l_info[DT_STRTAB])
-                     + main_map->l_info[DT_SONAME]->d_un.d_val), LIBC_SO)
-             == 0))
+      if (l_soname (main_map) != NULL
+         && strcmp (l_soname (main_map), LIBC_SO) == 0)
        GL(dl_ns)[LM_ID_BASE].libc_map = main_map;
 
       /* Set up our cache of pointers into the hash table.  */
index 6564557b5661eefeacadc31508a33ff8c6d9ab13..935d9e3baf2dc48e7b9760192a0cd9c83ade4db3 100644 (file)
@@ -76,13 +76,14 @@ setup_vdso (struct link_map *main_map __attribute__ ((unused)),
 
       /* Now that we have the info handy, use the DSO image's soname
         so this object can be looked up by name.  */
-      if (l->l_info[DT_SONAME] != NULL)
-       {
-         char *dsoname = ((char *) D_PTR (l, l_info[DT_STRTAB])
-                          + l->l_info[DT_SONAME]->d_un.d_val);
-         l->l_libname->name = dsoname;
-         l->l_name = dsoname;
-       }
+      {
+       const char *dsoname = l_soname (l);
+       if (dsoname != NULL)
+         {
+           l->l_libname->name = dsoname;
+           l->l_name = (char *) dsoname;
+         }
+      }
 
       /* Add the vDSO to the object list.  */
       _dl_add_to_namespace_list (l, LM_ID_BASE);
index 4baff86d2a7113867d5249c52ea277aa8c018a44..c82c7c9db66c3217ed575ecc1f179fa19386a385 100644 (file)
@@ -530,10 +530,7 @@ load_shobj (const char *name)
     printf ("string table: %p\n", result->dynstrtab);
 
   /* Determine the soname.  */
-  if (map->l_info[DT_SONAME] == NULL)
-    result->soname = NULL;
-  else
-    result->soname = result->dynstrtab + map->l_info[DT_SONAME]->d_un.d_val;
+  result->soname = l_soname (map);
   if (do_test && result->soname != NULL)
     printf ("soname: %s\n", result->soname);
 
index 6b4ed3d4dd04fc1c5e22bb0522597a14e4a71972..8465cbaa9b2aacf61838dc55a435d6cd7cffdf5a 100644 (file)
@@ -88,6 +88,18 @@ dl_relocate_ld (const struct link_map *l)
 #define D_PTR(map, i) \
   ((map)->i->d_un.d_ptr + (dl_relocate_ld (map) ? 0 : (map)->l_addr))
 
+/* Returns the soname string if the link map has a DT_SONAME tag, or
+   NULL if it does not.  */
+static inline const char *
+l_soname (const struct link_map *l)
+{
+  if (l->l_info[DT_SONAME] == NULL)
+    return NULL;
+  else
+    return ((const char *) D_PTR (l, l_info[DT_STRTAB])
+           + l->l_info[DT_SONAME]->d_un.d_val);
+}
+
 /* Result of the lookup functions and how to retrieve the base address.  */
 typedef struct link_map *lookup_t;
 #define LOOKUP_VALUE(map) map