Bug 324181 - mmap does not handle MAP_32BIT
Summary: mmap does not handle MAP_32BIT
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: 3.8.0
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Julian Seward
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-08-28 19:40 UTC by Mattias Engdegård
Modified: 2015-11-02 21:56 UTC (History)
6 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
(somewhat) support MAP_32BIT (4.90 KB, text/plain)
2015-06-16 20:55 UTC, Philippe Waroquiers
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Mattias Engdegård 2013-08-28 19:40:33 UTC
The mmap MAP_32BIT flag, specific to x86-64 on Linux, seems to be ignored. Correct behaviour is to return a block entirely within the lowest 2 GiB or MAP_FAILED (ENOMEM) if such a request could not be satisfied.

This is a problem because some software rely on MAP_32BIT to work properly, and misbehave if a block beyond 2**31 is returned (which never happens when running outside Valgrind).

Strictly speaking, it would even in some sense be correct to always fail mmap with MAP_32BIT; at least that would not violate the specification as openly. However, without knowing details about how things are implemented, supporting the flag should be easy work (just fail and munmap if we got a mapping in the wrong place).


Reproducible: Always

Steps to Reproduce:
1. mmap(NULL, somesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_32BIT, -1, 0)
2. repeat point 1 until it returns something beyond 0x80000000

Actual Results:  
mmap(MAP_32BIT) eventually returns a block beyond 2**31.

Expected Results:  
mmap(MAP_32BIT) should never return a block beyond 2**31 but MAP_FAILED instead.
Comment 1 Julian Seward 2013-10-14 14:54:39 UTC
Yes, we shouldn't silently ignore this flag.  r13644 makes any such call
always fail.  Seems like the simplest solution considering that this flag
is totally unportable.
Comment 2 David Reid 2013-11-24 09:05:05 UTC
Having mmap() always fail breaks LuaJIT, which is fairly widely used. Is it not possible to only return an ENOMEM error if the mapping goes beyond the allowed range? I reckon it would work successfully for the most part (LuaJIT works fine in practice with previous versions of Valgrind) - I feel like that's better than it never working.
Comment 3 Stas Sergeev 2015-06-16 12:38:09 UTC
MAP_32BIT is used by dosemu for creating a
32bit segments. It is likely also used in wine
for the same reason.
While this flag is non-portable, it has its valid
use: for legacy system emulators, which are
non-portable themselves. There is simply no
way such emulators can work without this flag.
No work-around (other than to emulate this
flag by looking into /proc/self/maps).
Is this flag really that difficult to implement?
Comment 4 Philippe Waroquiers 2015-06-16 20:55:23 UTC
Created attachment 93202 [details]
(somewhat) support MAP_32BIT

Can you try the attached patch ?
(based on revision Revision: 15339)
Thanks

The patch should allow to properly support MAP_32BIT, at least as long as there is
some free space in the first 2GB.
Note that Valgrind aspacemgr does no effort to keep the first 2GB free
(to the contrary: it starts mmap-ing in this area, with or without MAP_32BITS).
So, the first 2GB might be exhausted a lot more quickly under VAlgridn than with a native run
for which it seems the kernel tries to keep the lower address space free.
Comment 5 Stas Sergeev 2015-06-16 21:36:47 UTC
Great patch, thanks!
Note that the solution you propose, is perfectly
fine for the real life: the emulators I mentioned, can work
on 32bit systems too (obviously), so they will never exhaust
the 2GB of address space.

I made sure dosemu goes much further with your
patch, which is a big step forward.
Unfortunately, its not enough.
To get either wine or dosemu to work with valgrind,
someone have to re-visit this ticket:
https://bugs.kde.org/show_bug.cgi?id=253657
Comment 6 Philippe Waroquiers 2015-06-17 20:28:24 UTC
Fixed in Revision: 15341
Thanks for the testing.
Comment 7 Philippe Waroquiers 2015-06-20 17:00:06 UTC
(In reply to Stas Sergeev from comment #5)
> To get either wine or dosemu to work with valgrind,
> someone have to re-visit this ticket:
> https://bugs.kde.org/show_bug.cgi?id=253657
See comments I will add in 253657
Comment 8 Stas Sergeev 2015-06-20 17:06:33 UTC
(In reply to Philippe Waroquiers from comment #7)
> See comments I will add in 253657
Subscribed now. :)
Comment 9 Dennis Schridde 2015-10-30 15:23:57 UTC
(In reply to Philippe Waroquiers from comment #6)
> Fixed in Revision: 15341

Has this been released already?
Comment 10 Philippe Waroquiers 2015-11-02 21:56:53 UTC
(In reply to Dennis Schridde from comment #9)
> (In reply to Philippe Waroquiers from comment #6)
> > Fixed in Revision: 15341
> 
> Has this been released already?
Yes. This is in Valgrind 3.11.0, released the 22 September 2015
Note: the NEWS file indicates the svn revision used for the TEST and final releases.