From: Ulrich Drepper Date: Tue, 17 Mar 1998 10:19:53 +0000 (+0000) Subject: (_dl_close): Correct and simplify unmapping. X-Git-Tag: cvs/before-sparc-2_0_x-branch~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9989767ab921809eaef8d6c27fff522a027e291d;p=thirdparty%2Fglibc.git (_dl_close): Correct and simplify unmapping. --- diff --git a/elf/dl-close.c b/elf/dl-close.c index b1bc9ecf0f0..ca02eaae4e5 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -68,6 +68,8 @@ _dl_close (struct link_map *map) /* That was the last reference, and this was a dlopen-loaded object. We can unmap it. */ const ElfW(Phdr) *ph; + const ElfW(Phdr) *first, *last; + ElfW(Addr) mapstart, mapend; if (imap->l_info[DT_FINI]) /* Call its termination function. */ @@ -87,19 +89,23 @@ _dl_close (struct link_map *map) _dl_global_scope_end[1] = NULL; } - /* Unmap the segments. */ - for (ph = imap->l_phdr + (imap->l_phnum - 1); - ph >= imap->l_phdr; --ph) + /* We can unmap all the maps at once. We just have to determine + the length and the `munmap' call does the rest. */ + first = last = NULL; + for (ph = imap->l_phdr; ph < imap->l_phdr + imap->l_phnum; ++ph) if (ph->p_type == PT_LOAD) { - ElfW(Addr) mapstart = ph->p_vaddr & ~(ph->p_align - 1); - ElfW(Addr) mapend = ((ph->p_vaddr + ph->p_memsz - + ph->p_align - 1) - & ~(ph->p_align - 1)); - __munmap ((caddr_t) (imap->l_addr + mapstart), - mapend - mapstart); + if (first == NULL) + first = ph; + last = ph; } + /* Now we have all the information we need for the unmapping. + See the method used in `_dl_map_object_from_fd'. */ + mapstart = first->p_vaddr & ~(first->p_align - 1); + mapend = last->p_vaddr + last->p_memsz; + __munmap ((caddr_t) (imap->l_addr + mapstart), mapend - mapstart); + /* Finally, unlink the data structure and free it. */ if (imap->l_prev) imap->l_prev->l_next = imap->l_next;