Search code examples
linuxmmapmemory-mapping

Mapping multiple data arrays to arbitrary fixed memory addresses


I'm working on a program on a 64-bit Linux machine that needs to map multiple data arrays, of arbitrary length, to fixed memory addresses over which I have no control. I thought mmap() with MAP_FIXED and MAP_ANONYMOUS was the way to go, for example:

mmap((void *) 0x401000, 0x18e, PROT_NONE, MAP_ANONYMOUS | MAP_FIXED, -1, 0);

However, every time I call this function, it returns MAP_FAILED. I've set fd to -1, which I know is required by some systems, the address is a multiple of my page size (4096), and the length is non-negative, so I'm wondering if perhaps 0x401000 is already being used by my system; I've also tried 0x402000, 0x403000, and 0x404000 with the same result.

Is there something I'm missing about mmap(), or is there a way to find out what's already at this address? Even better, since I can't control which addresses I'll need, is there some better way to avoid running into existing mappings?

Edit: After checking errno, I found that the code I'm getting is an invalid argument, so, according to the man pages, "We don't like addr, length, or offset (e.g., they are too large, or not aligned on a page boundary)." I can't yet figure out which one is the problem, though.


Solution

  • Given that 0x400000 seems to be the .text address for processes on my amd64 Debian systems (x86 is different), I suspect you're getting the failure because you're trying to map over something existing, as you thought. Not sure the best way to (programatically) determine what segments are mapped/available, but you can start by examining /proc/<pid>/maps for a number of 'typical' processes to see how your system allocates address ranges to programs and libraries. Address space randomization throws some extra wrinkles in there, as well...