* elf/dl-close.c (_dl_close): Handle relocation dependencies of
	the dependencies of the object currently unloaded.
This commit is contained in:
Ulrich Drepper 2000-10-24 20:20:37 +00:00
parent e3e5f6725b
commit 4b4fcf99d1
2 changed files with 29 additions and 9 deletions

View File

@ -1,5 +1,8 @@
2000-10-24 Ulrich Drepper <drepper@redhat.com> 2000-10-24 Ulrich Drepper <drepper@redhat.com>
* elf/dl-close.c (_dl_close): Handle relocation dependencies of
the dependencies of the object currently unloaded.
* elf/dl-close.c (_dl_close): Don't free memory for global scope * elf/dl-close.c (_dl_close): Don't free memory for global scope
list immediately when empty. Move code to... list immediately when empty. Move code to...
(free_mem): ...here. Called as part of __libc_subfreeres list. (free_mem): ...here. Called as part of __libc_subfreeres list.

View File

@ -43,11 +43,15 @@ void
internal_function internal_function
_dl_close (void *_map) _dl_close (void *_map)
{ {
struct reldep_list
{
struct link_map **rellist;
unsigned int nrellist;
struct reldep_list *next;
} *reldeps = NULL;
struct link_map **list; struct link_map **list;
struct link_map **rellist;
struct link_map *map = _map; struct link_map *map = _map;
unsigned int nsearchlist; unsigned int nsearchlist;
unsigned int nrellist;
unsigned int i; unsigned int i;
unsigned int *new_opencount; unsigned int *new_opencount;
@ -119,9 +123,6 @@ _dl_close (void *_map)
} }
assert (new_opencount[0] == 0); assert (new_opencount[0] == 0);
rellist = map->l_reldeps;
nrellist = map->l_reldepsact;
/* Call all termination functions at once. */ /* Call all termination functions at once. */
for (i = 0; i < nsearchlist; ++i) for (i = 0; i < nsearchlist; ++i)
{ {
@ -221,6 +222,20 @@ _dl_close (void *_map)
if (imap->l_origin != NULL && imap->l_origin != (char *) -1) if (imap->l_origin != NULL && imap->l_origin != (char *) -1)
free ((char *) imap->l_origin); free ((char *) imap->l_origin);
/* If the object has relocation dependencies save this
information for latter. */
if (__builtin_expect (imap->l_reldeps != NULL, 0))
{
struct reldep_list *newrel;
newrel = (struct reldep_list *) alloca (sizeof (*reldeps));
newrel->rellist = map->l_reldeps;
newrel->nrellist = map->l_reldepsact;
newrel->next = reldeps;
reldeps = newrel;
}
/* This name always is allocated. */ /* This name always is allocated. */
free (imap->l_name); free (imap->l_name);
/* Remove the list with all the names of the shared object. */ /* Remove the list with all the names of the shared object. */
@ -255,12 +270,14 @@ _dl_close (void *_map)
/* Now we can perhaps also remove the modules for which we had /* Now we can perhaps also remove the modules for which we had
dependencies because of symbol lookup. */ dependencies because of symbol lookup. */
if (__builtin_expect (rellist != NULL, 0)) while (__builtin_expect (reldeps != NULL, 0))
{ {
while (nrellist-- > 0) while (reldeps->nrellist-- > 0)
_dl_close (rellist[nrellist]); _dl_close (reldeps->rellist[reldeps->nrellist]);
free (rellist); free (reldeps->rellist);
reldeps = reldeps->next;
} }
free (list); free (list);