Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2005-02-26 00:23:15 +0300
committerCorinna Vinschen <corinna@vinschen.de>2005-02-26 00:23:15 +0300
commit6d11044c633bc7aca545c5409327ef023646205b (patch)
tree36cafdc3745b15ae7f1945dac569ff8e3015ce29
parent99e281eb1939d42ef14a03bbe8847da6cdd003ee (diff)
* fhandler.h (class fhandler_base): Declare fixup_mmap_after_fork
with additional flags parameter. Change offset parameter to _off64_t. (class fhandler_disk_file): Ditto. (class fhandler_dev_mem): Ditto. * fhandler_mem.cc (fhandler_dev_mem::fixup_mmap_after_fork): Accomodate new parameters. * mmap.cc: Include ntdll.h. (class mmap_record): Add flags member. (mmap_record::mmap_record): Add flags parameter. (mmap_record::get_flags): New method. (class map): Add next_anon_addr member to store next anonymous mapping address suggestion. (map::get_next_anon_addr): New method. (map::set_next_anon_addr): New method. (mmap64): Don't align offset and length to granularity in case of MAP_ANONYMOUS on NT. Check for already existing mapping only on 9x. Call mmap_record::mmap_record with additional flags argument. (fhandler_base::fixup_mmap_after_fork): Accomodate new parameters. (fhandler_disk_file::mmap): Use NtMapViewOfSection with AT_ROUND_TO_PAGE flag for anonymous mappings on NT. If addr is NULL, try to map adjacent to previous mapping. (fhandler_disk_file::fixup_mmap_after_fork): Add flags argument. Change offset parameter to _off64_t. Use NtMapViewOfSection to re-create anonymous mappings on NT. (fixup_mmaps_after_fork): Accomodate new parameters when calling fhandler's fixup_mmaps_after_fork function. * ntdll.h (AT_ROUND_TO_PAGE): New define.
-rw-r--r--winsup/cygwin/ChangeLog30
-rw-r--r--winsup/cygwin/fhandler.h13
-rw-r--r--winsup/cygwin/fhandler_mem.cc5
-rw-r--r--winsup/cygwin/mmap.cc194
-rw-r--r--winsup/cygwin/ntdll.h2
5 files changed, 176 insertions, 68 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 003a185ba..9a5de4d70 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,35 @@
2005-02-25 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler.h (class fhandler_base): Declare fixup_mmap_after_fork
+ with additional flags parameter. Change offset parameter to _off64_t.
+ (class fhandler_disk_file): Ditto.
+ (class fhandler_dev_mem): Ditto.
+ * fhandler_mem.cc (fhandler_dev_mem::fixup_mmap_after_fork):
+ Accomodate new parameters.
+ * mmap.cc: Include ntdll.h.
+ (class mmap_record): Add flags member.
+ (mmap_record::mmap_record): Add flags parameter.
+ (mmap_record::get_flags): New method.
+ (class map): Add next_anon_addr member to store next anonymous mapping
+ address suggestion.
+ (map::get_next_anon_addr): New method.
+ (map::set_next_anon_addr): New method.
+ (mmap64): Don't align offset and length to granularity in case of
+ MAP_ANONYMOUS on NT. Check for already existing mapping only on 9x.
+ Call mmap_record::mmap_record with additional flags argument.
+ (fhandler_base::fixup_mmap_after_fork): Accomodate new parameters.
+ (fhandler_disk_file::mmap): Use NtMapViewOfSection with
+ AT_ROUND_TO_PAGE flag for anonymous mappings on NT. If addr is NULL,
+ try to map adjacent to previous mapping.
+ (fhandler_disk_file::fixup_mmap_after_fork): Add flags argument.
+ Change offset parameter to _off64_t. Use NtMapViewOfSection to
+ re-create anonymous mappings on NT.
+ (fixup_mmaps_after_fork): Accomodate new parameters when calling
+ fhandler's fixup_mmaps_after_fork function.
+ * ntdll.h (AT_ROUND_TO_PAGE): New define.
+
+2005-02-25 Corinna Vinschen <corinna@vinschen.de>
+
* mmap.cc (mmap64): Handle anonymous MAP_FIXED request on
non-granulation boundary.
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index d3250d1b2..2d9aa5f7f 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -285,8 +285,9 @@ class fhandler_base
int flags, _off64_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);
+ virtual bool fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
+ _off64_t offset, DWORD size,
+ void *address);
void *operator new (size_t, void *p) {return p;}
@@ -633,8 +634,8 @@ class fhandler_disk_file: public fhandler_base
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_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);
+ bool fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
+ _off64_t offset, DWORD size, void *address);
DIR *opendir ();
struct dirent *readdir (DIR *);
_off64_t telldir (DIR *);
@@ -1055,8 +1056,8 @@ class fhandler_dev_mem: public fhandler_base
HANDLE mmap (caddr_t *addr, size_t len, DWORD access, int flags, _off64_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);
+ bool fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
+ _off64_t offset, DWORD size, void *address);
void dump ();
} ;
diff --git a/winsup/cygwin/fhandler_mem.cc b/winsup/cygwin/fhandler_mem.cc
index 68532c6dd..4c873d758 100644
--- a/winsup/cygwin/fhandler_mem.cc
+++ b/winsup/cygwin/fhandler_mem.cc
@@ -361,8 +361,9 @@ fhandler_dev_mem::msync (HANDLE h, caddr_t addr, size_t len, int flags)
}
bool
-fhandler_dev_mem::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
- DWORD size, void *address)
+fhandler_dev_mem::fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
+ _off64_t offset, DWORD size,
+ void *address)
{
DWORD ret;
PHYSICAL_ADDRESS phys;
diff --git a/winsup/cygwin/mmap.cc b/winsup/cygwin/mmap.cc
index 1a8f15338..36db16ce6 100644
--- a/winsup/cygwin/mmap.cc
+++ b/winsup/cygwin/mmap.cc
@@ -22,6 +22,7 @@ details. */
#include "cygheap.h"
#include "pinfo.h"
#include "sys/cygwin.h"
+#include "ntdll.h"
#define PAGE_CNT(bytes) howmany((bytes),getpagesize())
@@ -58,6 +59,7 @@ class mmap_record
int fdesc_;
HANDLE mapping_handle_;
DWORD access_mode_;
+ int flags_;
_off64_t offset_;
DWORD size_to_map_;
caddr_t base_address_;
@@ -65,10 +67,12 @@ class mmap_record
device dev;
public:
- mmap_record (int fd, HANDLE h, DWORD ac, _off64_t o, DWORD s, caddr_t b) :
+ mmap_record (int fd, HANDLE h, DWORD ac, int f, _off64_t o, DWORD s,
+ caddr_t b) :
fdesc_ (fd),
mapping_handle_ (h),
access_mode_ (ac),
+ flags_ (f),
offset_ (o),
size_to_map_ (s),
base_address_ (b),
@@ -83,6 +87,7 @@ class mmap_record
HANDLE get_handle () const { return mapping_handle_; }
device& get_device () { return dev; }
DWORD get_access () const { return access_mode_; }
+ DWORD get_flags () const { return flags_; }
_off64_t get_offset () const { return offset_; }
DWORD get_size () const { return size_to_map_; }
caddr_t get_address () const { return base_address_; }
@@ -128,12 +133,15 @@ class map
private:
list *lists;
int nlists, maxlists;
+ caddr_t next_anon_addr;
public:
list *get_list (int i) { return i >= nlists ? NULL : lists + i; }
list *get_list_by_fd (int fd);
list *add_list (int fd);
void del_list (int i);
+ caddr_t get_next_anon_addr () { return next_anon_addr; }
+ void set_next_anon_addr (caddr_t addr) { next_anon_addr = addr; }
};
/* This is the global map structure pointer. It's allocated once on the
@@ -530,13 +538,21 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
if (flags & MAP_ANONYMOUS)
fd = -1;
- /* If MAP_FIXED is requested on a non-granularity boundary, change request
- so that this looks like a request with offset addr % granularity. */
- if (fd == -1 && (flags & MAP_FIXED) && ((DWORD)addr % granularity) && !off)
+ /* 9x only: If MAP_FIXED is requested on a non-granularity boundary,
+ change request so that this looks like a request with offset
+ addr % granularity. */
+ if (wincap.share_mmaps_only_by_name () && fd == -1 && (flags & MAP_FIXED)
+ && ((DWORD)addr % granularity) && !off)
off = (DWORD)addr % granularity;
- /* Map always in multipliers of `granularity'-sized chunks. */
- _off64_t gran_off = off & ~(granularity - 1);
- DWORD gran_len = howmany (off + len, granularity) * granularity - gran_off;
+ /* Map always in multipliers of `granularity'-sized chunks.
+ Not necessary for anonymous maps on NT. */
+ _off64_t gran_off = off;
+ DWORD gran_len = len;
+ if (wincap.share_mmaps_only_by_name () || fd != -1)
+ {
+ gran_off = off & ~(granularity - 1);
+ gran_len = howmany (off + len, granularity) * granularity - gran_off;
+ }
fhandler_base *fh;
@@ -571,8 +587,11 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
gran_len = fsiz;
}
else if (fh->get_device () == FH_ZERO)
- /* mmap /dev/zero is like MAP_ANONYMOUS. */
- fd = -1;
+ {
+ /* mmap /dev/zero is like MAP_ANONYMOUS. */
+ fd = -1;
+ flags |= MAP_ANONYMOUS;
+ }
}
if (fd == -1)
{
@@ -597,60 +616,67 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
list *map_list = mmapped_areas->get_list_by_fd (fd);
- /* First check if this mapping matches into the chunk of another
- already performed mapping. Only valid for MAP_ANON in a special
- case of MAP_PRIVATE. */
- if (map_list && fd == -1 && off == 0 && !(flags & MAP_FIXED))
- {
- mmap_record *rec;
- if ((rec = map_list->search_record (off, len)) != NULL
- && rec->get_access () == access)
- {
- if ((off = rec->map_pages (off, len)) == (_off64_t)-1)
- {
- syscall_printf ("-1 = mmap()");
- ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK|WRITE_LOCK,
- "mmap");
- return MAP_FAILED;
- }
- caddr_t ret = rec->get_address () + off;
- syscall_printf ("%x = mmap() succeeded", ret);
- ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, "mmap");
- return ret;
- }
- }
- if (map_list && fd == -1 && (flags & MAP_FIXED))
+ /* A bit of memory munging on 9x. */
+ if (map_list && fd == -1 && wincap.share_mmaps_only_by_name ())
{
- caddr_t u_addr;
- DWORD u_len;
- long record_idx = -1;
- if ((record_idx = map_list->search_record ((caddr_t)addr, len, u_addr,
- u_len, record_idx)) >= 0)
+ /* First check if this mapping matches into the chunk of another
+ already performed mapping. Only valid for MAP_ANON in a special
+ case of MAP_PRIVATE. */
+ if (off == 0 && !(flags & MAP_FIXED))
{
- mmap_record *rec = map_list->get_record (record_idx);
- if (u_addr > (caddr_t)addr || u_addr + len < (caddr_t)addr + len
- || rec->get_access () != access)
+ mmap_record *rec;
+ if ((rec = map_list->search_record (off, len)) != NULL
+ && rec->get_access () == access)
{
- /* Partial match only, or access mode doesn't match. */
- /* FIXME: Handle partial mappings gracefully if adjacent
- memory is available. */
- set_errno (EINVAL);
- syscall_printf ("-1 = mmap()");
+ if ((off = rec->map_pages (off, len)) == (_off64_t)-1)
+ {
+ syscall_printf ("-1 = mmap()");
+ ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK|WRITE_LOCK,
+ "mmap");
+ return MAP_FAILED;
+ }
+ caddr_t ret = rec->get_address () + off;
+ syscall_printf ("%x = mmap() succeeded", ret);
ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
"mmap");
- return MAP_FAILED;
+ return ret;
}
- if (!rec->map_pages ((caddr_t)addr, len))
+ }
+ if ((flags & MAP_FIXED))
+ {
+ caddr_t u_addr;
+ DWORD u_len;
+ long record_idx = -1;
+ if ((record_idx = map_list->search_record ((caddr_t)addr, len,
+ u_addr, u_len,
+ record_idx)) >= 0)
{
- syscall_printf ("-1 = mmap()");
+ mmap_record *rec = map_list->get_record (record_idx);
+ if (u_addr > (caddr_t)addr || u_addr + len < (caddr_t)addr + len
+ || rec->get_access () != access)
+ {
+ /* Partial match only, or access mode doesn't match. */
+ /* FIXME: Handle partial mappings gracefully if adjacent
+ memory is available. */
+ set_errno (EINVAL);
+ syscall_printf ("-1 = mmap()");
+ ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
+ "mmap");
+ return MAP_FAILED;
+ }
+ if (!rec->map_pages ((caddr_t)addr, len))
+ {
+ syscall_printf ("-1 = mmap()");
+ ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
+ "mmap");
+ return MAP_FAILED;
+ }
+ caddr_t ret = (caddr_t)addr;
+ syscall_printf ("%x = mmap() succeeded", ret);
ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK,
"mmap");
- return MAP_FAILED;
+ return ret;
}
- caddr_t ret = (caddr_t)addr;
- syscall_printf ("%x = mmap() succeeded", ret);
- ReleaseResourceLock (LOCK_MMAP_LIST, READ_LOCK | WRITE_LOCK, "mmap");
- return ret;
}
}
@@ -672,7 +698,7 @@ mmap64 (void *addr, size_t len, int prot, int flags, int fd, _off64_t off)
Now it's time for bookkeeping stuff. */
if (fd == -1)
gran_len = PAGE_CNT (gran_len) * getpagesize ();
- mmap_record mmap_rec (fd, h, access, gran_off, gran_len, base);
+ mmap_record mmap_rec (fd, h, access, flags, gran_off, gran_len, base);
/* Get list of mmapped areas for this fd, create a new one if
one does not exist yet.
@@ -959,8 +985,9 @@ fhandler_base::msync (HANDLE h, caddr_t addr, size_t len, int flags)
}
bool
-fhandler_base::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
- DWORD size, void *address)
+fhandler_base::fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
+ _off64_t offset, DWORD size,
+ void *address)
{
set_errno (ENODEV);
return -1;
@@ -1022,7 +1049,25 @@ fhandler_disk_file::mmap (caddr_t *addr, size_t len, DWORD access,
void *base = NULL;
/* If a non-zero address is given, try mapping using the given address first.
If it fails and flags is not MAP_FIXED, try again with NULL address. */
- if (*addr)
+ if (!wincap.share_mmaps_only_by_name ()
+ && get_handle () == INVALID_HANDLE_VALUE)
+ {
+ PHYSICAL_ADDRESS phys;
+ phys.QuadPart = (ULONGLONG) off;
+ ULONG ulen = len;
+ base = *addr ?: (void *) mmapped_areas->get_next_anon_addr ();
+ NTSTATUS ret = NtMapViewOfSection (h, INVALID_HANDLE_VALUE, &base, 0L,
+ ulen, &phys, &ulen, ViewShare,
+ base ? AT_ROUND_TO_PAGE : 0, protect);
+ if (ret != STATUS_SUCCESS)
+ {
+ __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+ base = NULL;
+ }
+ else
+ mmapped_areas->set_next_anon_addr ((caddr_t) base + len);
+ }
+ else if (*addr)
base = MapViewOfFileEx (h, access, high, low, len, *addr);
if (!base && !(flags & MAP_FIXED))
base = MapViewOfFileEx (h, access, high, low, len, NULL);
@@ -1068,11 +1113,39 @@ fhandler_disk_file::msync (HANDLE h, caddr_t addr, size_t len, int flags)
}
bool
-fhandler_disk_file::fixup_mmap_after_fork (HANDLE h, DWORD access, DWORD offset,
- DWORD size, void *address)
+fhandler_disk_file::fixup_mmap_after_fork (HANDLE h, DWORD access, int flags,
+ _off64_t offset, DWORD size,
+ void *address)
{
/* Re-create the MapViewOfFileEx call */
- void *base = MapViewOfFileEx (h, access, 0, offset, size, address);
+ void *base;
+ if (!wincap.share_mmaps_only_by_name () && (flags & MAP_ANONYMOUS))
+ {
+ PHYSICAL_ADDRESS phys;
+ phys.QuadPart = (ULONGLONG) offset;
+ ULONG ulen = size;
+ base = address;
+ DWORD protect;
+ switch (access)
+ {
+ case FILE_MAP_WRITE:
+ protect = PAGE_READWRITE;
+ break;
+ case FILE_MAP_READ:
+ protect = PAGE_READONLY;
+ break;
+ default:
+ protect = PAGE_WRITECOPY;
+ break;
+ }
+ NTSTATUS ret = NtMapViewOfSection (h, INVALID_HANDLE_VALUE, &base, 0L,
+ ulen, &phys, &ulen, ViewShare,
+ AT_ROUND_TO_PAGE, protect);
+ if (ret != STATUS_SUCCESS)
+ __seterrno_from_win_error (RtlNtStatusToDosError (ret));
+ }
+ else
+ base = MapViewOfFileEx (h, access, 0, offset, size, address);
if (base != address)
{
MEMORY_BASIC_INFORMATION m;
@@ -1121,6 +1194,7 @@ fixup_mmaps_after_fork (HANDLE parent)
fhandler_base *fh = rec->alloc_fh ();
bool ret = fh->fixup_mmap_after_fork (rec->get_handle (),
rec->get_access (),
+ rec->get_flags (),
rec->get_offset (),
rec->get_size (),
rec->get_address ());
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 23ce468cd..844a131b5 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -23,6 +23,8 @@
#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
#define WSLE_PAGE_SHAREABLE 0x100
+#define AT_ROUND_TO_PAGE 0x40000000
+
typedef ULONG KAFFINITY;
typedef enum _SYSTEM_INFORMATION_CLASS