Subject: Re: Wine & NetBSD?
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 11/20/2001 22:29:06
In article <Pine.WNT.4.40.0111201112080.1148-100000@todd>,
Todd Vierling <tv@wasabisystems.com> wrote:
>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.
So is linux. Using the address as a hint should not be a problem, as long
as that address has no other mappings. I can see the two POV's clearly.
wine people: It works everywhere else, and it might break if we change it.
Or because of older broken versions of mmap on linux, we don't want to
make any changes.
netbsd people: Well, you depend on completely non portable behavior. If
you *have* to use that particular address, you should specify so. The
code is incorrect because it does not specify MAP_FIXED.
One side of me thinks that we should consider taking the passed address
as a hint, so that we don't have to deal with patching wine, the other
tells me that introducing this behavior will just serve to create more
obscure bugs in the future.
christos