Subject: Re: mmap() and gcc precompiled headers
From: Earl Chew <[email-masked]>
To: [email-masked]
Date: Thu, 03 Jul 2003 11:33:02 -0700

Corinna Vinschen wrote:
> On Thu, Jul 03, 2003 at 10:19:42AM -0400, Christopher Faylor wrote:
>> On Thu, Jul 03, 2003 at 11:47:28AM +0200, Corinna Vinschen wrote:
>> >Do you mean something like this:
>> >
>> >  If addr is given, check if it's 64K aligned.  If not, align and
>> >  raise the memory requirement accordingly.  Call MapViewOfFileEx
>> >  with the aligned address.  If it works, return the addr given as
>> >  parameter, otherwise return MapViewOfFileEx(NULL).
>> 
>> How about, instead, just use the address and if it fails and is not
>> MAP_FIXED, use MapViewOfFileEx without the address?
> 
> Yep, that's the simple approach.  I dropped this suggestion from my
> original reply since it requires addr to be on a 64k boundary.  
> Unfortunately I have no idea if the chance to succeed might be better
> or worse than using the more complex approach.
> 
> Either way, it's not us but gcc being on the wrong track.  If gcc relies
> on getting the same address it should use MAP_FIXED at least on hosts
> known to support MAP_FIXED correctly.

Patching gcc to use MAP_FIXED is possible, but I'm not sure that
it's really necessary, and there's another complication.

The application (gcc) is told to use 4k alignment, and does so.
Internally, Cygwin contains address arithmetic to add padding
to have an internal 64k alignment. The address returned from
MapViewOfFileEx() is modified so that the application sees no
difference.

Suppose we use MAP_FIXED to force the mapping to be restored as
before. Consider:

    preferred_base = mmap (NULL, size,
                           PROT_READ | PROT_WRITE, MAP_PRIVATE,
                           f, offset);

    munmap(preferred_base, size);

    newbase = mmap (preferred_base, size,
                    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
                    f, offset);

There's a good chance that this fails because preferred_base
is the fudged value from MapViewOfFileEx() and is no longer 64k
aligned (only 4k aligned), and MAP_FIXED contains a check
to ensure that the address is 64k aligned :-(

So a patch to gcc to use MAP_FIXED would also require somehow
making gcc aware of the 64k alignment.

I think fixing mmap() to support the BSD behaviour expected by gcc
would address the gcc issues whilst retaining compliance with SUSv3.

If addr is given, perform the 64k fixup. Essentially this means
undoing the mmap64() fudge that might have been done previously:

   caddr_t ret = rec->get_address () + (off - gran_off);

(Adjust the size appropriately too.)

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.

Earl

--
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/