mmap on MacOSX
Posted: Fri Sep 06, 2013 12:59 pm
Hello OSDev.org! I've been searching and asking all over the internet for a solution to this problem and I haven't found one yet.
I am trying to get access to a *very* specific memory address within the first 4GB of address space using a 64-bit application in MacOSX. Ideally, the first 64mb at least. On Windows and Linux, I've been able to accomplish this (Linux was easy, of course, but Windows took a bit more work), but absolutely cannot get this to work on MacOSX! I assumed that since MacOSX is a UNIX based OS, it would be as simple as this (which works fine on Linux btw):
Doesn't work on OSX. I heard that the first 4GB of address space was unused in 64-bit OSX. Is that wrong? My knowledge of MacOSX's memory map layout is minimal, and there isn't much documentation on how this OS works.
In order for this to work on Windows, I had to *trick* Windows into letting me have it by setting the base address of the .exe, declare a fixed array of bytes the length of the memory range I want to reserve, put all of my Win32 code into a .dll and *only* call the function from the .exe, set the permissions using VirtualProtect, back up the every byte that the .exe has taken up in that memory address range, and then do my dirty work until it's time to exit, in which I restore the .exe contents, and return from the .dll function.
You might be thinking "why on earth do you need to do this??". It's for a VM I'm writing, without the need for VMX (because VMX seems like a pain to use). If you need a more detailed description of what I'm trying to do, feel free to ask anything specific. Thanks.
- Shogun.
I am trying to get access to a *very* specific memory address within the first 4GB of address space using a 64-bit application in MacOSX. Ideally, the first 64mb at least. On Windows and Linux, I've been able to accomplish this (Linux was easy, of course, but Windows took a bit more work), but absolutely cannot get this to work on MacOSX! I assumed that since MacOSX is a UNIX based OS, it would be as simple as this (which works fine on Linux btw):
Code: Select all
#include <sys/mman.h>
#include <iostream>
namespace {
void * const MEMORY_ADDRESS = reinterpret_cast<void *>(0x10000);
size_t const MEMORY_SIZE = 1 << 20;
}
int main() {
void * p = mmap(MEMORY_ADDRESS, MEMORY_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
if (p != reinterpret_cast<void *>(-1)) {
std::cout << "Memory allocated" << std::endl;
munmap(p, MEMORY_SIZE);
} else {
std::cout << "Memory could not be allocated" << std::endl;
}
}
In order for this to work on Windows, I had to *trick* Windows into letting me have it by setting the base address of the .exe, declare a fixed array of bytes the length of the memory range I want to reserve, put all of my Win32 code into a .dll and *only* call the function from the .exe, set the permissions using VirtualProtect, back up the every byte that the .exe has taken up in that memory address range, and then do my dirty work until it's time to exit, in which I restore the .exe contents, and return from the .dll function.
You might be thinking "why on earth do you need to do this??". It's for a VM I'm writing, without the need for VMX (because VMX seems like a pain to use). If you need a more detailed description of what I'm trying to do, feel free to ask anything specific. Thanks.
- Shogun.