This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

A patch for dl-close.c


I don't think l_initfini is handled right. Why does it use nsearchlist as
the indexing limit? l_initfini is a NULL terminated array. We also should
decrement l_opencount on DSOs on l_initfini even if the main DSO is not
unloaded.

Here is a patch. Please ignore my previous one for dl-close.c.


-- 
H.J. Lu (hjl@gnu.org)
--
2000-10-19  H.J. Lu  <hjl@gnu.org>

	* elf/dl-close.c (_dl_close): Correctly handle l_initfini.

Index: elf/dl-close.c
===================================================================
RCS file: /work/cvs/gnu/glibc/elf/dl-close.c,v
retrieving revision 1.1.1.10
diff -u -p -r1.1.1.10 dl-close.c
--- elf/dl-close.c	2000/10/08 23:01:33	1.1.1.10
+++ elf/dl-close.c	2000/10/19 21:49:48
@@ -46,6 +46,7 @@ _dl_close (void *_map)
   struct link_map **list;
   struct link_map **rellist;
   struct link_map *map = _map;
+  struct link_map *imap;
   unsigned int nsearchlist;
   unsigned int nrellist;
   unsigned int i;
@@ -78,6 +79,15 @@ _dl_close (void *_map)
 			     "\n", NULL);
 	}
 
+      /* Even if we don't unload it now, we still need to decrement
+         l_opencount on l_initfini. Otherwise, they may not get
+	 unloaded later. */
+      if (map->l_initfini)
+	for (i = 0; (imap = map->l_initfini[i]); ++i)
+	  if (imap != map && imap->l_opencount > 1
+	      && imap->l_type == lt_loaded)
+	    imap->l_opencount--;
+
       --map->l_opencount;
       __libc_lock_unlock (_dl_load_lock);
       return;
@@ -90,9 +100,8 @@ _dl_close (void *_map)
   nrellist = map->l_reldepsact;
 
   /* Call all termination functions at once.  */
-  for (i = 0; i < nsearchlist; ++i)
-    {
-      struct link_map *imap = map->l_initfini[i];
+  if (map->l_initfini)
+    for (i = 0; (imap = map->l_initfini[i]); ++i)
       if (imap->l_opencount == 1 && imap->l_type == lt_loaded
 	  && (imap->l_info[DT_FINI] || imap->l_info[DT_FINI_ARRAY])
 	  && ! (imap->l_flags_1 & DF_1_NODELETE)
@@ -123,7 +132,6 @@ _dl_close (void *_map)
 	    (*(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;
@@ -140,7 +148,7 @@ _dl_close (void *_map)
      it are gone.  */
   for (i = 0; i < nsearchlist; ++i)
     {
-      struct link_map *imap = list[i];
+      imap = list[i];
       if (imap->l_opencount == 0 && imap->l_type == lt_loaded)
 	{
 	  struct libname_list *lnp;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]