public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Florian Weimer <fweimer@redhat.com>
To: libc-alpha@sourceware.org
Subject: [PATCH 14/33] elf: Merge __dl_libc_freemem into __rtld_libc_freeres
Date: Tue, 04 Jul 2023 22:03:16 +0200	[thread overview]
Message-ID: <a4e20e7814a3d35fe0a12893576328ff58a84821.1688499219.git.fweimer@redhat.com> (raw)
In-Reply-To: <cover.1688499219.git.fweimer@redhat.com>

The functions serve very similar purposes.  The advantage of
__rtld_libc_freeres is that it is locate 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         | 107 ------------------------------------------
 elf/dl-libc_freeres.c | 101 +++++++++++++++++++++++++++++++++++++++
 include/set-freeres.h |   1 -
 malloc/set-freeres.c  |   2 -
 4 files changed, 101 insertions(+), 110 deletions(-)

diff --git a/elf/dl-libc.c b/elf/dl-libc.c
index c12e52f330..1d0ebd4793 100644
--- a/elf/dl-libc.c
+++ b/elf/dl-libc.c
@@ -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);
-}
diff --git a/elf/dl-libc_freeres.c b/elf/dl-libc_freeres.c
index d6d824acb5..d60c18d359 100644
--- a/elf/dl-libc_freeres.c
+++ b/elf/dl-libc_freeres.c
@@ -19,8 +19,109 @@
 #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 ();
 }
diff --git a/include/set-freeres.h b/include/set-freeres.h
index 866d0e3717..4286710df9 100644
--- a/include/set-freeres.h
+++ b/include/set-freeres.h
@@ -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;
diff --git a/malloc/set-freeres.c b/malloc/set-freeres.c
index 1aab34b586..d2ef073c75 100644
--- a/malloc/set-freeres.c
+++ b/malloc/set-freeres.c
@@ -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
@@ -90,7 +89,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);
-- 
2.41.0



  parent reply	other threads:[~2023-07-04 20:03 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-04 20:02 [PATCH 00/33] RFC: RELRO link maps Florian Weimer
2023-07-04 20:02 ` [PATCH 01/33] support: Add <support/memprobe.h> for protection flags probing Florian Weimer
2023-07-04 20:02 ` [PATCH 02/33] misc: Enable internal use of memory protection keys Florian Weimer
2023-07-04 20:02 ` [PATCH 03/33] elf: Remove _dl_sysdep_open_object hook function Florian Weimer
2023-07-04 20:02 ` [PATCH 04/33] elf: Eliminate second loop in find_version in dl-version.c Florian Weimer
2023-07-04 20:02 ` [PATCH 05/33] elf: In rtld_setup_main_map, assume ld.so has a DYNAMIC segment Florian Weimer
2023-07-04 20:02 ` [PATCH 06/33] elf: Remove version assert in check_match in elf/dl-lookup.c Florian Weimer
2023-07-04 20:02 ` [PATCH 07/33] elf: Disambiguate some failures in _dl_load_cache_lookup Florian Weimer
2023-07-04 20:02 ` [PATCH 08/33] elf: Eliminate alloca in open_verify Florian Weimer
2023-07-04 20:02 ` [PATCH 09/33] Do not export <alloc_buffer.h> functions from libc Florian Weimer
2023-07-04 20:02 ` [PATCH 10/33] elf: Make <alloc_buffer.h> usable in ld.so Florian Weimer
2023-07-04 20:03 ` [PATCH 11/33] elf: Merge the three implementations of _dl_dst_substitute Florian Weimer
2023-07-04 20:03 ` [PATCH 12/33] elf: _dl_find_object may return 1 during early startup (bug 30515) Florian Weimer
2023-07-04 20:03 ` [PATCH 13/33] elf: Move __rtld_malloc_init_stubs call into _dl_start_final Florian Weimer
2023-07-04 20:03 ` Florian Weimer [this message]
2023-07-04 20:03 ` [PATCH 15/33] elf: Use struct link_map_private for the internal link map Florian Weimer
2023-07-04 20:03 ` [PATCH 16/33] elf: Remove run-time-writable fields from struct link_map_private Florian Weimer
2023-07-04 20:03 ` [PATCH 17/33] elf: Move l_tls_offset into read-write part of link map Florian Weimer
2023-07-04 20:03 ` [PATCH 18/33] elf: Allocate auditor state after read-write " Florian Weimer
2023-07-04 20:03 ` [PATCH 19/33] elf: Move link map fields used by dependency sorting to writable part Florian Weimer
2023-07-04 20:03 ` [PATCH 20/33] elf: Split _dl_lookup_map, _dl_map_new_object from _dl_map_object Florian Weimer
2023-07-04 20:03 ` [PATCH 21/33] elf: Add l_soname accessor function for DT_SONAME values Florian Weimer
2023-07-04 20:03 ` [PATCH 22/33] elf: _dl_rtld_map should not exist in static builds Florian Weimer
2023-07-04 20:03 ` [PATCH 23/33] elf: Introduce GLPM accessor for the protected memory area Florian Weimer
2023-07-04 20:04 ` [PATCH 24/33] elf: Bootstrap allocation for future protected memory allocator Florian Weimer
2023-07-04 20:04 ` [PATCH 25/33] elf: Implement a basic " Florian Weimer
2023-07-04 20:04 ` [PATCH 26/33] elf: Move most of the _dl_find_object data to the protected heap Florian Weimer
2023-07-04 20:04 ` [PATCH 27/33] elf: Switch to a region-based protected memory allocator Florian Weimer
2023-07-04 20:04 ` [PATCH 28/33] elf: Determine the caller link map in _dl_open Florian Weimer
2023-07-04 20:04 ` [PATCH 29/33] elf: Add fast path to dlopen for fully-opened maps Florian Weimer
2023-07-04 20:04 ` [PATCH 30/33] elf: Use _dl_find_object instead of _dl_find_dso_for_object in dlopen Florian Weimer
2023-07-04 20:04 ` [PATCH 31/33] elf: Put critical _dl_find_object pointers into protected memory area Florian Weimer
2023-07-04 20:04 ` [PATCH 32/33] elf: Add hash tables to speed up DT_NEEDED, dlopen lookups Florian Weimer
2023-07-04 20:04 ` [PATCH 33/33] elf: Use memory protection keys for the protected memory allocator Florian Weimer
2023-07-04 20:07 ` [PATCH 00/33] RFC: RELRO link maps Florian Weimer
2023-07-05 15:54   ` Carlos O'Donell
2023-07-05 15:57     ` Florian Weimer
2023-07-05 17:48       ` Carlos O'Donell
2023-07-05 17:58         ` Adhemerval Zanella Netto
2023-07-07 11:10           ` Florian Weimer
2023-07-07 12:42             ` Florian Weimer
2023-07-07 12:48               ` Adhemerval Zanella Netto
2023-07-07 13:18                 ` Florian Weimer
2023-07-07 13:58                   ` Adhemerval Zanella Netto
2023-07-07 14:55                     ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a4e20e7814a3d35fe0a12893576328ff58a84821.1688499219.git.fweimer@redhat.com \
    --to=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).