Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Message-ID: <3F04D70E.6000604@agilent.com> Date: Thu, 03 Jul 2003 18:23:26 -0700 From: Earl Chew Organization: Agilent Technologies User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.2) Gecko/20030208 Netscape/7.02 X-Accept-Language: en-us, en MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: mmap() and gcc precompiled headers Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Corinna Vinschen wrote: >> 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/