4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-01-19 04:49:25 +08:00

* 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.
This commit is contained in:
Corinna Vinschen 2001-02-05 12:36:41 +00:00
parent d4eaf28eb5
commit cada03f92f
2 changed files with 83 additions and 45 deletions

View File

@ -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.

View File

@ -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,6 +472,7 @@ 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.
*/
if (fd == -1)
gran_len = PAGE_CNT (gran_len) * getpagesize ();
mmap_record mmap_rec (fd, h, access, gran_off, gran_len, base);
@ -504,17 +533,10 @@ 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)
{
off_t li = -1;
while ((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);
@ -527,6 +549,13 @@ munmap (caddr_t addr, size_t len)
}
else
fh = fdtab[fd];
off_t li = -1;
if ((li = l->match(addr, len, li)) >= 0)
{
mmap_record *rec = l->recs + li;
if (rec->unmap_map (addr, len))
{
fh->munmap (rec->get_handle (), addr, len);
/* Delete the entry. */
@ -577,17 +606,10 @@ 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)
{
mmap_record rec = l->recs[li];
if (rec.get_address () == addr)
{
int fd = l->fd;
fhandler_disk_file fh_paging_file (NULL);
@ -601,7 +623,12 @@ msync (caddr_t addr, size_t len, int flags)
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 ();
}
}
}