]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
elf: Merge __dl_libc_freemem into __rtld_libc_freeres
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)
The functions serve very similar purposes.  The advantage of
__rtld_libc_freeres is that it is located within ld.so, so it is
more natural to poke at link map internals there.

This slightly regresses cleanup capabilities for statically linked
binaries.  If that becomes a problem, we should start calling
__rtld_libc_freeres from __libc_freeres (perhaps after renaming it).

elf/dl-libc.c
elf/dl-libc_freeres.c
include/set-freeres.h
malloc/set-freeres.c

index d55f94e40da9e7e7a2ab5056d3552328746a2148..760cb955f77e0d0d90ccaffd582a51d6eff6df38 100644 (file)
@@ -226,110 +226,3 @@ __libc_dlclose (void *map)
 #endif
   return dlerror_run (do_dlclose, map);
 }
-
-
-static bool
-free_slotinfo (struct dtv_slotinfo_list **elemp)
-{
-  size_t cnt;
-
-  if (*elemp == NULL)
-    /* Nothing here, all is removed (or there never was anything).  */
-    return true;
-
-  if (!free_slotinfo (&(*elemp)->next))
-    /* We cannot free the entry.  */
-    return false;
-
-  /* That cleared our next pointer for us.  */
-
-  for (cnt = 0; cnt < (*elemp)->len; ++cnt)
-    if ((*elemp)->slotinfo[cnt].map != NULL)
-      /* Still used.  */
-      return false;
-
-  /* We can remove the list element.  */
-  free (*elemp);
-  *elemp = NULL;
-
-  return true;
-}
-
-
-void
-__dl_libc_freemem (void)
-{
-  struct link_map *l;
-  struct r_search_path_elem *d;
-
-  /* Remove all search directories.  */
-  d = GL(dl_all_dirs);
-  while (d != GLRO(dl_init_all_dirs))
-    {
-      struct r_search_path_elem *old = d;
-      d = d->next;
-      free (old);
-    }
-
-  for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
-    {
-      for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
-       {
-         struct libname_list *lnp = l->l_libname->next;
-
-         l->l_libname->next = NULL;
-
-         /* Remove all additional names added to the objects.  */
-         while (lnp != NULL)
-           {
-             struct libname_list *old = lnp;
-             lnp = lnp->next;
-             if (! old->dont_free)
-               free (old);
-           }
-
-         /* Free the initfini dependency list.  */
-         if (l->l_free_initfini)
-           free (l->l_initfini);
-         l->l_initfini = NULL;
-       }
-
-      if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
-         && (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
-             // XXX Check whether we need NS-specific initial_searchlist
-             == GLRO(dl_initial_searchlist).r_nlist))
-       {
-         /* All object dynamically loaded by the program are unloaded.  Free
-            the memory allocated for the global scope variable.  */
-         struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
-
-         /* Put the old map in.  */
-         GL(dl_ns)[ns]._ns_main_searchlist->r_list
-           // XXX Check whether we need NS-specific initial_searchlist
-           = GLRO(dl_initial_searchlist).r_list;
-         /* Signal that the original map is used.  */
-         GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
-
-         /* Now free the old map.  */
-         free (old);
-       }
-    }
-
-  /* Free the memory allocated for the dtv slotinfo array.  We can do
-     this only if all modules which used this memory are unloaded.  */
-#ifdef SHARED
-  if (GL(dl_initial_dtv) == NULL)
-    /* There was no initial TLS setup, it was set up later when
-       it used the normal malloc.  */
-    free_slotinfo (&GL(dl_tls_dtv_slotinfo_list));
-  else
-#endif
-    /* The first element of the list does not have to be deallocated.
-       It was allocated in the dynamic linker (i.e., with a different
-       malloc), and in the static library it's in .bss space.  */
-    free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next);
-
-  void *scope_free_list = GL(dl_scope_free_list);
-  GL(dl_scope_free_list) = NULL;
-  free (scope_free_list);
-}
index 0231e0fef21b5fed1021e8340aba5deccdf60bcf..e8bd7a4b98f180fe8739885ad0c027bfe89607af 100644 (file)
 #include <ldsodefs.h>
 #include <dl-find_object.h>
 
+static bool
+free_slotinfo (struct dtv_slotinfo_list **elemp)
+{
+  size_t cnt;
+
+  if (*elemp == NULL)
+    /* Nothing here, all is removed (or there never was anything).  */
+    return true;
+
+  if (!free_slotinfo (&(*elemp)->next))
+    /* We cannot free the entry.  */
+    return false;
+
+  /* That cleared our next pointer for us.  */
+
+  for (cnt = 0; cnt < (*elemp)->len; ++cnt)
+    if ((*elemp)->slotinfo[cnt].map != NULL)
+      /* Still used.  */
+      return false;
+
+  /* We can remove the list element.  */
+  free (*elemp);
+  *elemp = NULL;
+
+  return true;
+}
+
 void
 __rtld_libc_freeres (void)
 {
+  struct link_map *l;
+  struct r_search_path_elem *d;
+
+  /* Remove all search directories.  */
+  d = GL(dl_all_dirs);
+  while (d != GLRO(dl_init_all_dirs))
+    {
+      struct r_search_path_elem *old = d;
+      d = d->next;
+      free (old);
+    }
+
+  for (Lmid_t ns = 0; ns < GL(dl_nns); ++ns)
+    {
+      for (l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
+       {
+         struct libname_list *lnp = l->l_libname->next;
+
+         l->l_libname->next = NULL;
+
+         /* Remove all additional names added to the objects.  */
+         while (lnp != NULL)
+           {
+             struct libname_list *old = lnp;
+             lnp = lnp->next;
+             if (! old->dont_free)
+               free (old);
+           }
+
+         /* Free the initfini dependency list.  */
+         if (l->l_free_initfini)
+           free (l->l_initfini);
+         l->l_initfini = NULL;
+       }
+
+      if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
+         && (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
+             // XXX Check whether we need NS-specific initial_searchlist
+             == GLRO(dl_initial_searchlist).r_nlist))
+       {
+         /* All object dynamically loaded by the program are unloaded.  Free
+            the memory allocated for the global scope variable.  */
+         struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
+
+         /* Put the old map in.  */
+         GL(dl_ns)[ns]._ns_main_searchlist->r_list
+           // XXX Check whether we need NS-specific initial_searchlist
+           = GLRO(dl_initial_searchlist).r_list;
+         /* Signal that the original map is used.  */
+         GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
+
+         /* Now free the old map.  */
+         free (old);
+       }
+    }
+
+  /* Free the memory allocated for the dtv slotinfo array.  We can do
+     this only if all modules which used this memory are unloaded.  */
+#ifdef SHARED
+  if (GL(dl_initial_dtv) == NULL)
+    /* There was no initial TLS setup, it was set up later when
+       it used the normal malloc.  */
+    free_slotinfo (&GL(dl_tls_dtv_slotinfo_list));
+  else
+#endif
+    /* The first element of the list does not have to be deallocated.
+       It was allocated in the dynamic linker (i.e., with a different
+       malloc), and in the static library it's in .bss space.  */
+    free_slotinfo (&GL(dl_tls_dtv_slotinfo_list)->next);
+
+  void *scope_free_list = GL(dl_scope_free_list);
+  GL(dl_scope_free_list) = NULL;
+  free (scope_free_list);
+
   _dl_find_object_freeres ();
 }
index bb1d0a8f72e1f50111c6f16860e12a91755aa268..0fb25827ec3e6f8351e0383ce917ae6902170e31 100644 (file)
@@ -38,7 +38,6 @@
    Each free routines must be explicit listed below.  */
 
 /* From libc.so.  */
-extern void __dl_libc_freemem (void) attribute_hidden;
 extern void __hdestroy (void) attribute_hidden;
 extern void __gconv_cache_freemem (void) attribute_hidden;
 extern void __gconv_conf_freemem (void) attribute_hidden;
index c1809d3af7077172a09dd66757c22c616d6d69b0..2ac1df3c1c53c95335bc0dd2ec297ed9c87cec79 100644 (file)
@@ -28,7 +28,6 @@
 # pragma weak __nss_module_freeres
 # pragma weak __nss_action_freeres
 # pragma weak __nss_database_freeres
-# pragma weak __dl_libc_freemem
 # pragma weak __hdestroy
 # pragma weak __gconv_cache_freemem
 # pragma weak __gconv_conf_freemem
@@ -136,7 +135,6 @@ __libc_freeres (void)
       _IO_cleanup ();
 
       /* We run the resource freeing after IO cleanup.  */
-      call_function_static_weak (__dl_libc_freemem);
       call_function_static_weak (__hdestroy);
       call_function_static_weak (__gconv_cache_freemem);
       call_function_static_weak (__gconv_conf_freemem);