Subject: Re: Wine & NetBSD?
To: Chuck Silvers <chuq@chuq.com>
From: Chuck Cranor <chuck@research.att.com>
List: tech-kern
Date: 11/20/2001 11:26:41
hi-

    i'm in favor of getting wine to work, but it sounds like wine
is using the mmap() API in an incorrect way and just "lucking out" 
that it works on FreeBSD and linux.

    from what you've said, it seems clear that wine needs to mmap 
certain files at fixed addresses in order to use them properly.   
the way it is doing this is passing the address it wants to use for
the mapping as a "hint" to the kernel using the "addr" parameter 
(without using MAP_FIXED).

    the problem with this is that without MAP_FIXED the kernel has
a free hand and can adjust the virtual address used for the mapping
to suit its needs.   for example, we use this mechanism to avoid
virtual cache aliases on systems like the sparc.   in the case you 
posted, the VM system is adjusting the address to move it out of the 
area reserved for the process' heap (i.e. sbrk/malloc'd memory area).


    since wine is a special case application that needs to manage its
virtual address space itself, it seems clear to me that for it to
function properly it never wants the kernel to choose the address for 
its mappings and therefore should always use MAP_FIXED for its mappings.
it should also avoid functions like malloc() that independently use 
sbrk() or anonymous mmap() (MAP_ANON) to allocate memory because it has 
no control over where those mappings go.   to work in all cases, wine
needs complete control over its memory mappings.


    given that wine should be tracking and managing all its memory 
mappings itself, it isn't clear to me why you would ever have a case
where wine would try and mmap() something over top of a mapping that
it had already established (unless it was trying to make that mapping
go away?).

    regarding the semantics of MAP_FIXED: my guess is that the folks
who defined them figured that any application that needed to use MAP_FIXED
would track all its mappings itself, and thus would know in advance if
it was overwriting an existing mapping with a new one.



On Tue, Nov 20, 2001 at 04:56:59PM +0900, Bang Jun-Young wrote:
> Let's take a look at another one on NetBSD:
> 
> 	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);
> 
> Here I expected the second and the fourth mmap()'s would fail, since
> there was a mapping already done at 0x50000000 by the first mmap.

again, i believe the designers of the mmap MAP_FIXED API assume that
you are tracking mappings in your application and thus after the first
mmap() you are aware that the mapping at 0x50000000 is active.   thus,
the second call with MAP_FIXED indicates that you want to erase the old
mapping and establish the new one.   [if you knew there was already a
mapping at 0x50000000 and you didn't want to kill it, then you wouldn't
have bothered calling mmap again anyway, since the application already
knows this.]


> (I don't understand why it also says "If the specified address cannot
> be used, mmap will fail" even though it returns success for the address
> that can't be used as the above)

the failure occurs when you ask for a MAP_FIXED address outside the
address space of the process (e.g. in areas reserved for kernel [> KERNBASE]).



doesn't wine have some sort of list of active mappings that it maintains
so that it knows what is already mapped (and where the mappings are)?


chuck