From 4b4fcf99d16d881e33308c3e333ab32dbb9b999b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Tue, 24 Oct 2000 20:20:37 +0000 Subject: Update. * elf/dl-close.c (_dl_close): Handle relocation dependencies of the dependencies of the object currently unloaded. --- elf/dl-close.c | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) (limited to 'elf/dl-close.c') 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); -- cgit v1.2.3