From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25982 invoked by alias); 17 Sep 2010 09:09:29 -0000 Received: (qmail 25963 invoked by uid 22791); 17 Sep 2010 09:09:28 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 17 Sep 2010 09:09:21 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o8H99KeH029946 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 17 Sep 2010 05:09:20 -0400 Received: from hase.home (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o8H99IXG022675 for ; Fri, 17 Sep 2010 05:09:19 -0400 From: Andreas Schwab To: libc-hacker@sourceware.org Subject: [PATCH] Move freeres function from ld.so to libc.so X-Yow: I am having FUN... I wonder if it's NET FUN or GROSS FUN? Date: Fri, 17 Sep 2010 09:09:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact libc-hacker-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sourceware.org X-SW-Source: 2010-09/txt/msg00006.txt.bz2 dl-close.c isn't included in libc.so, so the freeres function is never executed. Andreas. 2010-09-16 Andreas Schwab * elf/dl-close.c (free_slotinfo, free_mem): Move to... * elf/dl-libc.c (free_slotinfo, free_mem): ... here. --- elf/dl-close.c | 74 ---------------------------------------- elf/dl-libc.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 87 insertions(+), 90 deletions(-) diff --git a/elf/dl-close.c b/elf/dl-close.c index 5b54e9f..9bd91e3 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -755,77 +755,3 @@ _dl_close (void *_map) __rtld_lock_unlock_recursive (GL(dl_load_lock)); } - - -static bool __libc_freeres_fn_section -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; -} - - -libc_freeres_fn (free_mem) -{ - for (Lmid_t nsid = 0; nsid < GL(dl_nns); ++nsid) - if (__builtin_expect (GL(dl_ns)[nsid]._ns_global_scope_alloc, 0) != 0 - && (GL(dl_ns)[nsid]._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)[nsid]._ns_main_searchlist->r_list; - - /* Put the old map in. */ - GL(dl_ns)[nsid]._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)[nsid]._ns_global_scope_alloc = 0; - - /* Now free the old map. */ - free (old); - } - - if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL) - { - /* 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.c b/elf/dl-libc.c index 5e303f2..771c9c1 100644 --- a/elf/dl-libc.c +++ b/elf/dl-libc.c @@ -1,5 +1,5 @@ /* Handle loading and unloading shared objects for internal libc purposes. - Copyright (C) 1999-2002,2004,2005,2006,2009 Free Software Foundation, Inc. + Copyright (C) 1999-2002,2004-2006,2009,2010 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Zack Weinberg , 1999. @@ -221,6 +221,34 @@ __libc_dlclose (void *map) libc_hidden_def (__libc_dlclose) +static bool __libc_freeres_fn_section +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; +} + + libc_freeres_fn (free_mem) { struct link_map *l; @@ -235,20 +263,63 @@ libc_freeres_fn (free_mem) free (old); } - /* Remove all additional names added to the objects. */ 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; - - while (lnp != NULL) - { - struct libname_list *old = lnp; - lnp = lnp->next; - if (! old->dont_free) - free (old); - } - } + { + /* Remove all additional names added to the objects. */ + 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; + + while (lnp != NULL) + { + struct libname_list *old = lnp; + lnp = lnp->next; + if (! old->dont_free) + free (old); + } + } + + 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); + } + } + + if (USE___THREAD || GL(dl_tls_dtv_slotinfo_list) != NULL) + { + /* 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); } -- 1.7.2.3 -- Andreas Schwab, schwab@redhat.com GPG Key fingerprint = D4E8 DBE3 3813 BB5D FA84 5EC7 45C6 250E 6F00 984E "And now for something completely different."