I was trying to do a little late-night hacking last night on SuperGameHerm, the Game Boy emulator my friends and I are writing, and I hit an error in the memory mapper. Specifically, certain OSes that used to be named after cats don’t like calling mmap on /dev/zero (neither does Android). I thought it was odd that it was falling back to that code in the first place, though, because Apple’s Mac OS X — I mean, a certain cat themed OS — has always supported
MAP_ANON, and I confirmed that by going to
man mmap on a Mac.
What was going on? I dug deeper and saw
MAP_ANON was guarded in sys/mman.h, so CMake wasn’t finding it and it was instead compiling our fallback code. And so I started digging up other issues related to big endian machines and realised that I had only tested OS X and FreeBSD on big endian, and never tested OS X or FreeBSD on little endian. So was my big mistake.
This is a comprehensive guide to How to Make
MAP_ANON(YMOUS) Visible, for every OS I could find information on:
Mac OS X
On 10.3 and below, this is easy; it’s always there! It is not guarded by any #ifdef.
On 10.5 and above, it is slighly harder; you must define
_DARWIN_C_SOURCE to cause
MAP_ANON to be visible in a public scope.
On 10.4 only, it’s much harder! It is only protected by
#ifndef _POSIX_C_SOURCE, so to use
MAP_ANON against the 10.4 SDK, you must completely undefine
_POSIX_C_SOURCE. You don’t have any other choice.
I suppose that means my overall advice then is to use the 10.5 SDK no matter what, if you have a Leopard computer handy, because it can target as low as 10.0. Otherwise, use the Panther SDK included with Tiger’s Xcode Tools. Don’t ever use Tiger’s SDK if you want
Before 5.0, it’s always visible, just as in OS X 10.3. There are no preprocessor options to show or hide
On 5.0 or above, the only way to cause MAP_ANON to be visible is to define
__BSD_VISIBLE somewhere. Undefining
_POSIX_C_SOURCE won’t save you here.
Other BSDs (NetBSD, OpenBSD, DragonFly BSD)
It’s never guarded.
MAP_ANON is always available.
I could only get my hands on OpenSolaris, but considering the header having a copyright date of 1989 (by AT&T), I can’t imagine it’s any different on Real Solaris (or Oracle Solaris). There are no guards here, either; that’s to be expected since they invented the damn thing.
glibc: I don’t understand /usr/include/bits in the slightest. It seems to be always available no matter what options I toss to
clang, but it is guarded by..
__USE_MISC? I presume this is some sort of feature macro buried deep in glibc that I don’t care about or understand.
musl: It’s always available, at least on 1.1.11 which is what I have on my test box.
Android: After searching through their spaghetti of includes to get to the actual file that defines constants, it appears they are all completely unguarded, though that isn’t surprising since it is Linux and embedded.
Perhaps it’s best to avoid anonymous
mmap(2) in applications that you want to actually be portable.