diff options
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | elf/dl-close.c | 35 |
2 files changed, 29 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog index eab19826c2..f5ef5bbf2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 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 list immediately when empty. Move code to... (free_mem): ...here. Called as part of __libc_subfreeres list. diff --git a/elf/dl-close.c b/elf/dl-close.c index 5f829223cc..c98a21d57d 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -43,11 +43,15 @@ void internal_function _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 **rellist; struct link_map *map = _map; unsigned int nsearchlist; - unsigned int nrellist; unsigned int i; unsigned int *new_opencount; @@ -119,9 +123,6 @@ _dl_close (void *_map) } assert (new_opencount[0] == 0); - rellist = map->l_reldeps; - nrellist = map->l_reldepsact; - /* Call all termination functions at once. */ for (i = 0; i < nsearchlist; ++i) { @@ -221,6 +222,20 @@ _dl_close (void *_map) if (imap->l_origin != NULL && imap->l_origin != (char *) -1) 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. */ free (imap->l_name); /* 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 dependencies because of symbol lookup. */ - if (__builtin_expect (rellist != NULL, 0)) + while (__builtin_expect (reldeps != NULL, 0)) { - while (nrellist-- > 0) - _dl_close (rellist[nrellist]); + while (reldeps->nrellist-- > 0) + _dl_close (reldeps->rellist[reldeps->nrellist]); + + free (reldeps->rellist); - free (rellist); + reldeps = reldeps->next; } free (list); |