In other words, addr -= (off - gran_off). This address should now be 64k aligned. Error if it isn't.
Use this address when calling MapViewOfFileEx(). If the call fails and MAP_FIXED is not set, then try again with addr = 0.
Yes, that's what I mentioned in my first reply. I think it's worth a try. I've checked in a patch. I've tested it and it looks pretty good.
I've had a look at your patch and working with the code I've discovered some minor issues. I've included a revised patch for you to review.
o The if (addr) test is redundant (it will always succeed -- I think you meant to write *addr, but I think it's better to simply do away with the test since it doesn't buy anything).
o I think there is a problem with the address arithmetic in the match() method used by munmap(). Compare the code in list::match (__off64_t off, DWORD len) with list::match (caddr_t addr, DWORD len, __off32_t start).
I believe the address relationships are:
get_offset() get_size() <-------------> <-----------------------------------> +----------------------------------------------------+ | : | +----------------------------------------------------+ ^ ^ <-----------------------------> | | len get_address() | addr
Earl
--
--- mmap.cc.original 2003-07-03 13:24:58.000000000 -0700
+++ mmap.cc 2003-07-03 18:14:10.000000000 -0700
@@ -328,7 +328,7 @@
{
for (int i = start + 1; i < nrecs; ++i)
if (addr >= recs[i].get_address ()
- && addr + len <= recs[i].get_address ()
+ && addr + len <= recs[i].get_address () + recs[i].get_offset ()
+ (PAGE_CNT (recs[i].get_size ()) * getpagesize ()))
return i;
return -1;
@@ -439,7 +439,7 @@
if (off % getpagesize ()
|| (!(flags & MAP_SHARED) && !(flags & MAP_PRIVATE))
|| ((flags & MAP_SHARED) && (flags & MAP_PRIVATE))
- || ((flags & MAP_FIXED) && ((DWORD)addr % granularity))
+ || ((flags & MAP_FIXED) && ((DWORD)addr % getpagesize ()))
|| !len)
{
set_errno (EINVAL);
@@ -470,8 +470,6 @@
DWORD gran_len = howmany (off + len, granularity) * granularity - gran_off;
fhandler_base *fh; - caddr_t base = addr; - HANDLE h;
if (fd != -1) { @@ -541,7 +539,13 @@ && (wincap.has_working_copy_on_write () || fd != -1)) access = FILE_MAP_COPY;
- h = fh->mmap (&base, gran_len, access, flags, gran_off); + caddr_t base = addr; + /* This shifts the base address to the next lower 64K boundary. + The offset is re-added when evaluating the return value. */ + if (base) + base -= off - gran_off; + + HANDLE h = fh->mmap (&base, gran_len, access, flags, gran_off);
if (h == INVALID_HANDLE_VALUE) { @@ -814,9 +818,13 @@ }
DWORD high = off >> 32, low = off & 0xffffffff;
- void *base = MapViewOfFileEx (h, access, high, low, len,
- (flags & MAP_FIXED) ? *addr : NULL);
- debug_printf ("%x = MapViewOfFileEx (h:%x, access:%x, 0, off:%D, len:%d, addr:%x)", base, h, access, off, len, (flags & MAP_FIXED) ? *addr : 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. */
+ void *base = MapViewOfFileEx (h, access, high, low, len, *addr);
+ if (!base && !(flags & MAP_FIXED))
+ base = MapViewOfFileEx (h, access, high, low, len, NULL);
+ debug_printf ("%x = MapViewOfFileEx (h:%x, access:%x, 0, off:%D, "
+ "len:%d, addr:%x)", base, h, access, off, len, *addr);
if (!base || ((flags & MAP_FIXED) && base != *addr))
{
if (!base)
-- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/