diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-02-05 15:36:41 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-02-05 15:36:41 +0300 |
commit | cada03f92f6d9f2126ab8dd094a740bdeb673103 (patch) | |
tree | f02da22d4cc6106728321ea62c3a6e7e3e737716 /winsup/cygwin | |
parent | d4eaf28eb5b96c045e64815d07dd17a66e67ac8a (diff) |
* mmap.cc (mmap_record::fixup_map): New method to duplicate
the memory protection in a just forked child.
(mmap): Realign gran_len to page boundary only on anonymous
mapping before saving in the mmap_record.
(munmap): Cleanup code.
(msync): Ditto.
(fixup_mmaps_after_fork): Ditto. Call mmap_record::fixup_map now.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r-- | winsup/cygwin/ChangeLog | 10 | ||||
-rw-r--r-- | winsup/cygwin/mmap.cc | 118 |
2 files changed, 83 insertions, 45 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 98bfb224d..838f25372 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +Mon Feb 5 13:30:00 2001 Corinna Vinschen <corinna@vinschen.de> + + * mmap.cc (mmap_record::fixup_map): New method to duplicate + the memory protection in a just forked child. + (mmap): Realign gran_len to page boundary only on anonymous + mapping before saving in the mmap_record. + (munmap): Cleanup code. + (msync): Ditto. + (fixup_mmaps_after_fork): Ditto. Call mmap_record::fixup_map now. + Thu Feb 1 23:08:29 2001 Christopher Faylor <cgf@cygnus.com> * cygheap.cc (creturn): Correctly calculate cygheap_max. diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 5f07efd98..afb348e71 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -82,6 +82,7 @@ class mmap_record DWORD find_empty (DWORD pages); DWORD map_map (DWORD off, DWORD len); BOOL unmap_map (caddr_t addr, DWORD len); + void fixup_map (void); }; DWORD @@ -171,6 +172,33 @@ mmap_record::unmap_map (caddr_t addr, DWORD len) return TRUE; } +void +mmap_record::fixup_map () +{ + if (os_being_run != winNT) + return; + + DWORD prot, old_prot; + switch (access_mode_) + { + case FILE_MAP_WRITE: + prot = PAGE_READWRITE; + break; + case FILE_MAP_READ: + prot = PAGE_READONLY; + break; + default: + prot = PAGE_WRITECOPY; + break; + } + + for (DWORD off = PAGE_CNT (size_to_map_); off > 0; --off) + VirtualProtect (base_address_ + off * getpagesize (), + getpagesize (), + MAP_ISSET (off - 1) ? prot : PAGE_NOACCESS, + &old_prot); +} + class list { public: mmap_record *recs; @@ -444,7 +472,8 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) /* Now we should have a successfully mmapped area. Need to save it so forked children can reproduce it. */ - gran_len = PAGE_CNT (gran_len) * getpagesize (); + if (fd == -1) + gran_len = PAGE_CNT (gran_len) * getpagesize (); mmap_record mmap_rec (fd, h, access, gran_off, gran_len, base); /* Get list of mmapped areas for this fd, create a new one if @@ -504,29 +533,29 @@ munmap (caddr_t addr, size_t len) /* Iterate through the map, looking for the mmapped area. Error if not found. */ - int it; - for (it = 0; it < mmapped_areas->nlists; ++it) + for (int it = 0; it < mmapped_areas->nlists; ++it) { list *l = mmapped_areas->lists[it]; if (l != 0) { + int fd = l->fd; + fhandler_disk_file fh_paging_file (NULL); + fhandler_base *fh; + + if (fd == -1 || fdtab.not_open (fd)) + { + fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE); + fh = &fh_paging_file; + } + else + fh = fdtab[fd]; + off_t li = -1; - while ((li = l->match(addr, len, li)) >= 0) + if ((li = l->match(addr, len, li)) >= 0) { mmap_record *rec = l->recs + li; if (rec->unmap_map (addr, len)) { - int fd = l->fd; - fhandler_disk_file fh_paging_file (NULL); - fhandler_base *fh; - - if (fd == -1 || fdtab.not_open (fd)) - { - fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE); - fh = &fh_paging_file; - } - else - fh = fdtab[fd]; fh->munmap (rec->get_handle (), addr, len); /* Delete the entry. */ @@ -577,31 +606,29 @@ msync (caddr_t addr, size_t len, int flags) /* Iterate through the map, looking for the mmapped area. Error if not found. */ - int it; - for (it = 0; it < mmapped_areas->nlists; ++it) + for (int it = 0; it < mmapped_areas->nlists; ++it) { list *l = mmapped_areas->lists[it]; if (l != 0) { - int li; - for (li = 0; li < l->nrecs; ++li) + int fd = l->fd; + fhandler_disk_file fh_paging_file (NULL); + fhandler_base *fh; + + if (fd == -1 || fdtab.not_open (fd)) { - mmap_record rec = l->recs[li]; - if (rec.get_address () == addr) - { - int fd = l->fd; - fhandler_disk_file fh_paging_file (NULL); - fhandler_base *fh; - - if (fd == -1 || fdtab.not_open (fd)) - { - fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE); - fh = &fh_paging_file; - } - else - fh = fdtab[fd]; + fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE); + fh = &fh_paging_file; + } + else + fh = fdtab[fd]; - int ret = fh->msync (rec.get_handle (), addr, len, flags); + for (int li = 0; li < l->nrecs; ++li) + { + mmap_record *rec = l->recs + li; + if (rec->get_address () == addr) + { + int ret = fh->msync (rec->get_handle (), addr, len, flags); if (ret) syscall_printf ("%d = msync(): %E", ret); @@ -818,30 +845,31 @@ fixup_mmaps_after_fork () int li; for (li = 0; li < l->nrecs; ++li) { - mmap_record rec = l->recs[li]; + mmap_record *rec = l->recs + li; debug_printf ("fd %d, h %x, access %x, offset %d, size %d, address %p", - rec.get_fd (), rec.get_handle (), rec.get_access (), - rec.get_offset (), rec.get_size (), rec.get_address ()); + rec->get_fd (), rec->get_handle (), rec->get_access (), + rec->get_offset (), rec->get_size (), rec->get_address ()); BOOL ret; fhandler_disk_file fh_paging_file (NULL); fhandler_base *fh; - if (rec.get_fd () == -1) /* MAP_ANONYMOUS */ + if (rec->get_fd () == -1) /* MAP_ANONYMOUS */ fh = &fh_paging_file; else - fh = fdtab[rec.get_fd ()]; - ret = fh->fixup_mmap_after_fork (rec.get_handle (), - rec.get_access (), - rec.get_offset (), - rec.get_size (), - rec.get_address ()); + fh = fdtab[rec->get_fd ()]; + ret = fh->fixup_mmap_after_fork (rec->get_handle (), + rec->get_access (), + rec->get_offset (), + rec->get_size (), + rec->get_address ()); if (!ret) { system_printf ("base address fails to match requested address %p", - rec.get_address ()); + rec->get_address ()); return -1; } + rec->fixup_map (); } } } |