aboutsummaryrefslogtreecommitdiff
path: root/elf/dl-close.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-05-20 10:50:03 +0000
committerUlrich Drepper <drepper@redhat.com>1998-05-20 10:50:03 +0000
commita709dd439a010a88e6e8ae94583e71296008b89e (patch)
treea0c3fe9835f3a05c1ed61ba01d98ee90bbe858f5 /elf/dl-close.c
parentb0a01055eb0ff324fd5e2b44fa9687035e5f3204 (diff)
downloadglibc-a709dd439a010a88e6e8ae94583e71296008b89e.zip
glibc-a709dd439a010a88e6e8ae94583e71296008b89e.tar.gz
glibc-a709dd439a010a88e6e8ae94583e71296008b89e.tar.bz2
Update.
1998-05-20 Andreas Jaeger <aj@arthur.rhein-neckar.de> * Makeconfig (rpath-link): Add resolvobjdir. (resolvobjdir): New variable. Reported by Peter Breitenlohner <peb@mppmu.mpg.de> [fixes PR libc/633]. 1998-05-20 09:36 Ulrich Drepper <drepper@cygnus.com> * elf/dl-close.c: Call shared object terminators at the right time. Patch by Philippe Troin <phil@fifi.org>. 1998-05-20 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Make-dist (+tsrcs): Also add *.map for every member of $(extra-libs). * Makefile (distribute): Don't distribute scripts/printsources and scripts/=__ify. Distribute FAQ.in. (rpm/%): Don't pass subdirs to sub-make. * timezone/Makefile: Protect inclusion of z.* by $(avoid-generated) instead of $(no_deps). 1998-05-19 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * sysdeps/generic/setenv.c: Protect against GNU C extension. (KNOWN_VALUE, STORE_VALUE): Do it right. (setenv): Remove unused variable. 1998-05-18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * timezone/Makefile (tz-cflags): Define TM_GMTOFF and TM_ZONE. (CFLAGS-zdump.c): Add $(tz-cflags). * timezone/zdump.c (abbr): Use TM_ZONE if defined. Add const to return type. 1998-05-18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * time/tzfile.c (__tzfile_compute): Undo last change. Instead take struct tm parameter and set tm_isdst, tm_zone and tm_offset if use_localtime. * time/tzset.c: Update prototype of __tzfile_compute. (__tz_convert): Pass tp to __tzfile_compute. Don't set tm_isdst, tm_zone and tm_offset here if __use_tzfile. 1998-05-19 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makerules: Install libc.a even if there are no object file. 1998-05-18 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makerules (do-makelib): Don't force creating library from scratch, to avoid wasting time and space and to get correct behaviour if $(subdirs) is incomplete. 1998-05-19 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> * Makerules (do-stamp): Make it work when building in source directory.
Diffstat (limited to 'elf/dl-close.c')
-rw-r--r--elf/dl-close.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 70b2e60..49deb96 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -47,30 +47,39 @@ _dl_close (struct link_map *map)
__libc_lock_lock (_dl_load_lock);
/* Decrement the reference count. */
- if (--map->l_opencount > 0 || map->l_type != lt_loaded)
+ if (map->l_opencount > 1 || map->l_type != lt_loaded)
{
/* There are still references to this object. Do nothing more. */
+ --map->l_opencount;
__libc_lock_unlock (_dl_load_lock);
return;
}
+ list = map->l_searchlist;
+
+ /* Call all termination functions at once. */
+ for (i = 0; i < map->l_nsearchlist; ++i)
+ {
+ struct link_map *imap = list[i];
+ if (imap->l_opencount == 1 && imap->l_type == lt_loaded)
+ {
+ if (imap->l_info[DT_FINI])
+ /* Call its termination function. */
+ (*(void (*) (void)) ((void *) imap->l_addr
+ + imap->l_info[DT_FINI]->d_un.d_ptr)) ();
+ }
+ }
+
/* Notify the debugger we are about to remove some loaded objects. */
_r_debug.r_state = RT_DELETE;
_dl_debug_state ();
- list = map->l_searchlist;
-
/* The search list contains a counted reference to each object it
points to, the 0th elt being MAP itself. Decrement the reference
counts on all the objects MAP depends on. */
- for (i = 1; i < map->l_nsearchlist; ++i)
+ for (i = 0; i < map->l_nsearchlist; ++i)
--list[i]->l_opencount;
- /* Clear the search list so it doesn't get freed while we are still
- using it. We have cached it in LIST and will free it when
- finished. */
- map->l_searchlist = NULL;
-
/* Check each element of the search list to see if all references to
it are gone. */
for (i = 0; i < map->l_nsearchlist; ++i)
@@ -84,11 +93,6 @@ _dl_close (struct link_map *map)
const ElfW(Phdr) *first, *last;
ElfW(Addr) mapstart, mapend;
- if (imap->l_info[DT_FINI])
- /* Call its termination function. */
- (*(void (*) (void)) ((void *) imap->l_addr +
- imap->l_info[DT_FINI]->d_un.d_ptr)) ();
-
if (imap->l_global)
{
/* This object is in the global scope list. Remove it. */
@@ -126,7 +130,7 @@ _dl_close (struct link_map *map)
imap->l_prev->l_next = imap->l_next;
if (imap->l_next)
imap->l_next->l_prev = imap->l_prev;
- if (imap->l_searchlist)
+ if (imap->l_searchlist && imap->l_searchlist != list)
free (imap->l_searchlist);
free (imap);
}