Subject: Re: Wine & NetBSD?
To: Bang Jun-Young <bjy@mogua.org>
From: Todd Vierling <tv@wasabisystems.com>
List: tech-kern
Date: 11/20/2001 11:23:00
On Tue, 20 Nov 2001, Bang Jun-Young wrote:

: > > 	mmap((void *)0x50000000, 4096, PROT_READ, 0, fd, 0);
: > > 	mmap((void *)0x50000000, 4096, PROT_READ, MAP_FIXED, fd, 0);
: > > 	mmap((void *)0x50000000, 4096, PROT_READ, 0, fd, 0);
: > > 	mmap((void *)0x50000000, 4096, PROT_READ, MAP_FIXED, fd, 0);

: > A successful
: > .Fa mmap
: > deletes any previous mapping in the allocated address range.

: At first I expected that, but the result shows that mmap(2) doesn't
: act like that: the third mmap call returned 0x50001000, not 0x50000000.

This is because the third mmap call did not specify MAP_FIXED, and as such,
mmap went to a new location that was not already in use.  There is no
guaranteed relationship between the first argument to mmap and mmap's result
if MAP_FIXED is not specified.

Note that some mmap implementations ignore the first argument *completely*
if MAP_FIXED is not supplied; thus, you should not rely on that first
argument being heeded at all if MAP_FIXED is not set.  It'd be a perfectly
valid result, even if suboptimal, for the first mmap call above to return
0x01234000 rather than 0x50000000.

The Wine people are probably relying on a nonportable Loonixism.  To quote
the Single Unix Specification, Version 2:

   The format of the call is as follows:

   pa=mmap(addr, len, prot, flags, fildes, off);
   [...]

   When MAP_FIXED is set in the flags argument, the implementation is
   informed that the value of pa must be addr, exactly. If MAP_FIXED is set,
   mmap() may return MAP_FAILED and set errno to [EINVAL]. If a MAP_FIXED
   request is successful, the mapping established by mmap() replaces any
   previous mappings for the process' pages in the range [pa, pa + len).

   When MAP_FIXED is not set, the implementation uses addr in an unspecified
   manner to arrive at pa. The pa so chosen will be an area of the address
   space that the implementation deems suitable for a mapping of len bytes
   to the file. All implementations interpret an addr value of 0 as granting
   the implementation complete freedom in selecting pa, subject to
   constraints described below. A non-zero value of addr is taken to be a
   suggestion of a process address near which the mapping should be placed.

   When the implementation selects a value for pa, it never places a mapping
   at address 0, nor does it replace any extant mapping.

According to this citation, NetBSD is 100% correct in its implementation of
MAP_FIXED vs. non-MAP_FIXED.

-- 
-- Todd Vierling <tv@wasabisystems.com>  *  Wasabi & NetBSD:  Run with it.
-- CDs, Integration, Embedding, Support -- http://www.wasabisystems.com/