]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
(_dl_close): Correct and simplify unmapping.
authorUlrich Drepper <drepper@redhat.com>
Tue, 17 Mar 1998 10:19:53 +0000 (10:19 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 17 Mar 1998 10:19:53 +0000 (10:19 +0000)
elf/dl-close.c

index b1bc9ecf0f0ddb1d3b9c4c550d1ee0efe25289ed..ca02eaae4e591f5bd1de3380458b75d7b3e24c38 100644 (file)
@@ -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;