From c4efddf601f496d3f4781f0af4c5ee3e7ecfc6bf Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 11 Jan 2001 12:33:12 +0000 Subject: [PATCH] * fhandler.h (fhandler_base): New method `fixup_mmap_after_fork'. (fhandler_disk_file: Ditto. (fhandler_dev_mem): Ditto. * fhandler_mem.cc (fhandler_dev_mem::open): Set OBJ_INHERIT attribute for device\physicalmemory handle. (fhandler_dev_mem::mmap): Ditto. * fhandler_mem.cc (fhandler_dev_mem::fixup_mmap_after_fork): New method. * mmap.cc (mmap_record): Add private `fdesc_' member. Change constructor accordingly. (get_fd): New method. (mmap): Use new mmap_record constructor. (fhandler_base::fixup_mmap_after_fork): New method. (fhandler_disk_file::fixup_mmap_after_fork): Ditto. (fixup_mmaps_after_fork): Call `fixup_mmap_after_fork' of appropriate fhandler class. --- winsup/cygwin/ChangeLog | 18 ++++++++++++ winsup/cygwin/fhandler.h | 6 ++++ winsup/cygwin/fhandler_mem.cc | 45 ++++++++++++++++++++++++++-- winsup/cygwin/mmap.cc | 55 ++++++++++++++++++++++++++--------- 4 files changed, 108 insertions(+), 16 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 4908cceb8..a44049f91 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,21 @@ +Thu Jan 11 13:17:00 2001 Corinna Vinschen + + * fhandler.h (fhandler_base): New method `fixup_mmap_after_fork'. + (fhandler_disk_file: Ditto. + (fhandler_dev_mem): Ditto. + * fhandler_mem.cc (fhandler_dev_mem::open): Set OBJ_INHERIT attribute + for device\physicalmemory handle. + (fhandler_dev_mem::mmap): Ditto. + * fhandler_mem.cc (fhandler_dev_mem::fixup_mmap_after_fork): New method. + * mmap.cc (mmap_record): Add private `fdesc_' member. Change constructor + accordingly. + (get_fd): New method. + (mmap): Use new mmap_record constructor. + (fhandler_base::fixup_mmap_after_fork): New method. + (fhandler_disk_file::fixup_mmap_after_fork): Ditto. + (fixup_mmaps_after_fork): Call `fixup_mmap_after_fork' of appropriate + fhandler class. + Wed Jan 10 22:08:30 2001 Kazuhiro Fujieda * sigproc.cc (wait_sig): Allow SIGCONT when stopped. diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 27a5cb942..356eb6beb 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -271,6 +271,8 @@ public: int flags, off_t off); virtual int munmap (HANDLE h, caddr_t addr, size_t len); virtual int msync (HANDLE h, caddr_t addr, size_t len, int flags); + virtual BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset, + DWORD size, void *address); void *operator new (size_t, void *p) {return p;} @@ -483,6 +485,8 @@ public: HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off); int munmap (HANDLE h, caddr_t addr, size_t len); int msync (HANDLE h, caddr_t addr, size_t len, int flags); + BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset, + DWORD size, void *address); }; class fhandler_serial: public fhandler_base @@ -806,6 +810,8 @@ public: HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, off_t off); int munmap (HANDLE h, caddr_t addr, size_t len); int msync (HANDLE h, caddr_t addr, size_t len, int flags); + BOOL fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset, + DWORD size, void *address); void dump (); } ; diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc index 9c41dda0b..81bfdc66b 100644 --- a/winsup/cygwin/fhandler_mem.cc +++ b/winsup/cygwin/fhandler_mem.cc @@ -94,7 +94,9 @@ fhandler_dev_mem::open (const char *, int flags, mode_t) RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory"); OBJECT_ATTRIBUTES attr; - InitializeObjectAttributes(&attr, &memstr, OBJ_CASE_INSENSITIVE, NULL, NULL); + InitializeObjectAttributes(&attr, &memstr, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + NULL, NULL); ACCESS_MASK section_access; if ((flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDONLY) @@ -277,7 +279,9 @@ fhandler_dev_mem::mmap (caddr_t *addr, size_t len, DWORD access, RtlInitUnicodeString (&memstr, L"\\device\\physicalmemory"); OBJECT_ATTRIBUTES attr; - InitializeObjectAttributes(&attr, &memstr, OBJ_CASE_INSENSITIVE, NULL, NULL); + InitializeObjectAttributes(&attr, &memstr, + OBJ_CASE_INSENSITIVE | OBJ_INHERIT, + NULL, NULL); ACCESS_MASK section_access; ULONG protect; @@ -359,6 +363,43 @@ fhandler_dev_mem::msync (HANDLE h, caddr_t addr, size_t len, int flags) return 0; } +BOOL +fhandler_dev_mem::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset, + DWORD size, void *address) +{ + DWORD ret; + PHYSICAL_ADDRESS phys; + void *base = address; + DWORD dlen = size; + ULONG protect; + + if (access & FILE_MAP_COPY) + protect = PAGE_WRITECOPY; + else if (access & FILE_MAP_WRITE) + protect = PAGE_READWRITE; + else + protect = PAGE_READONLY; + + phys.QuadPart = (ULONGLONG) offset; + + if ((ret = NtMapViewOfSection (h, + INVALID_HANDLE_VALUE, + &base, + 0L, + dlen, + &phys, + &dlen, + ViewShare /*??*/, + 0, + protect)) != STATUS_SUCCESS) + { + __seterrno_from_win_error (RtlNtStatusToDosError (ret)); + syscall_printf ("-1 = fixup_mmap_after_fork(): NtMapViewOfSection failed with %E"); + return FALSE; + } + return base == address; +} + int fhandler_dev_mem::fstat (struct stat *buf) { diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc index 4de9eb245..edee6ed95 100644 --- a/winsup/cygwin/mmap.cc +++ b/winsup/cygwin/mmap.cc @@ -30,6 +30,7 @@ details. */ class mmap_record { private: + int fdesc_; HANDLE mapping_handle_; DWORD access_mode_; DWORD offset_; @@ -37,13 +38,14 @@ class mmap_record void *base_address_; public: - mmap_record (HANDLE h, DWORD ac, DWORD o, DWORD s, void *b) : - mapping_handle_ (h), access_mode_ (ac), offset_ (o), + mmap_record (int fd, HANDLE h, DWORD ac, DWORD o, DWORD s, void *b) : + fdesc_ (fd), mapping_handle_ (h), access_mode_ (ac), offset_ (o), size_to_map_ (s), base_address_ (b) { ; } /* Default Copy constructor/operator=/destructor are ok */ /* Simple accessors */ + int get_fd () const { return fdesc_; } HANDLE get_handle () const { return mapping_handle_; } DWORD get_access () const { return access_mode_; } DWORD get_offset () const { return offset_; } @@ -206,6 +208,8 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) { fh_paging_file.set_io_handle (INVALID_HANDLE_VALUE); fh = &fh_paging_file; + /* Ensure that fd is recorded as -1 */ + fd = -1; } else { @@ -231,7 +235,7 @@ mmap (caddr_t addr, size_t len, int prot, int flags, int fd, off_t off) /* Now we should have a successfully mmaped area. Need to save it so forked children can reproduce it. */ - mmap_record mmap_rec (h, access, off, len, base); + mmap_record mmap_rec (fd, h, access, off, len, base); /* Get list of mmapped areas for this fd, create a new one if one does not exist yet. @@ -434,6 +438,14 @@ fhandler_base::msync (HANDLE h, caddr_t addr, size_t len, int flags) return -1; } +BOOL +fhandler_base::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset, + DWORD size, void *address) +{ + set_errno (ENODEV); + return -1; +} + /* Implementation for disk files. */ HANDLE fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access, @@ -498,6 +510,15 @@ fhandler_disk_file::msync (HANDLE h, caddr_t addr, size_t len, int flags) return 0; } +BOOL +fhandler_disk_file::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset, + DWORD size, void *address) +{ + /* Re-create the MapViewOfFileEx call */ + void *base = MapViewOfFileEx (h, access, 0, offset, size, address); + return base == address; +} + /* Set memory protection */ extern "C" @@ -575,19 +596,25 @@ fixup_mmaps_after_fork () { mmap_record rec = l->recs[li]; - debug_printf ("h %x, access %x, offset %d, size %d, address %p", - rec.get_handle (), rec.get_access (), rec.get_offset (), - rec.get_size (), rec.get_address ()); + 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 ()); - /* Now re-create the MapViewOfFileEx call */ - void *base = MapViewOfFileEx (rec.get_handle (), - rec.get_access (), 0, - rec.get_offset (), - rec.get_size (), - rec.get_address ()); - if (base != rec.get_address ()) + BOOL ret; + fhandler_disk_file fh_paging_file (NULL); + fhandler_base *fh; + 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 ()); + if (!ret) { - system_printf ("base address %p fails to match requested address %p", + system_printf ("base address fails to match requested address %p", rec.get_address ()); return -1; }