A patch for dl-close.c
H . J . Lu
hjl@valinux.com
Thu Oct 19 15:00:00 GMT 2000
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;
More information about the Libc-hacker
mailing list