[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
mmap: MAP_FIXED semantics
- To: tech_(_at_)_openbsd_(_dot_)_org
- Subject: mmap: MAP_FIXED semantics
- From: Constantine Sapuntzakis <csapuntz_(_at_)_lcs_(_dot_)_mit_(_dot_)_edu>
- Date: Tue, 28 Jul 1998 23:39:13 -0400 (EDT)
pa = mmap (addr, len, prot, flags, fd, offset);
Wine needs to load in certain executables (like MS Word) at fixed locations in
the address space because Word is not PIC code. This would suggest the use of
the MAP_FIXED call. However, the Single UNIX spec by the Open Group suggests
that MAP_FIXED clobbers any previous mapping:
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).
Now we can interpret the second sentence as meaning that we can return
MAP_FAILED and EINVAL whenever the mmap would clobber a current region.
However, the third sentence seems to imply that the process might be able to
use MAP_FIXED to overwrite a current mapping it knows about. The spec isn't
clear enough to allow programs to count on either semantics (no-clobber or
clobber) from an OS. I prefer no-clobber semantics because they are safer.
Also, according to the spec, mmap can feel free to clobber any previous mapping
any time (not just when MAP_FIXED is set). The words from the spec are:
The mapping established by mmap() replaces any previous mappings for those
whole pages containing any part of the address space of the process
starting at pa and continuing for len bytes.
I can't imagine that an OS would replace an arbitrary previous mapping when
MAP_FIXED wasn't set because that would require programs to detect the behavior
and modify the number of times they call munmap (i.e. ref count). So, it seems
the spec is too liberal in its wording.
Going back to the question of how to fix Wine. OpenBSD/i386 doesn't like
to mmap stuff under 1GB without the MAP_FIXED flag, but Wine needs mmap
MS Word there. We can co-erce OpenBSD/i386 to map stuff under the 1GB line
by using MAP_FIXED, but then we have probably lost safety. We can regain
safety in one of two ways:
- Changes semantics of MAP_FIXED mmap
- Provide some way to enumerate the mapped regions of an address space
so app can check for conflicts itself.
Finally, it looks like under certain conditions, if MAP_FIXED fails and
returns an error, it still unmaps the old region (see vm/vm_mmap.c).
Visit your host, monkey.org