#include <sys/mman.h>(executable NetRun link)
int foo(void) {
long len=1024*1024;
void *addr=mmap((void *)0,len, /* address and data size (bytes) */
PROT_READ+PROT_WRITE,MAP_ANONYMOUS+MAP_SHARED, /* access flags */
-1,0); /* <- file descriptor (none needed) and file offset */
if (addr==MAP_FAILED) {perror("mmap"); exit(1);}
int *buf=(int *)addr; /* <- make mmap'd region into an int pointer */
buf[3]=7;
buf[2]=buf[3];
printf("mmap returned %p, which seems readable and writable\n",addr);
munmap(addr,len);
return 0;
}
Purpose |
Code |
You just want some memory from the OS. | void *mem=mmap(0,length, PROT_READ+PROT_WRITE, MAP_ANONYMOUS+MAP_SHARED, -1,0); |
You want to put some memory at a given location, for example to service a page fault, or operate with old code, so you pass in an address. | mmap((void *)0xabcde000,length, PROT_READ+PROT_WRITE, MAP_ANONYMOUS+MAP_SHARED, -1,0); |
You want to mark a given
location as unreadable, for example to cause pagefaults when
people try to access there. |
mmap((void *)0xabcde000,length, PROT_NONE, MAP_ANONYMOUS+MAP_SHARED, -1,0); |
You want to create some
executable memory, for example to write some machine code
there and have it be runnable. |
void *mem=mmap(0,length, PROT_READ+PROT_WRITE+PROT_EXEC, MAP_ANONYMOUS+MAP_SHARED, -1,0); |
You want to bring in the file
"fd" for reading. This is useful because I can mmap a
100GB file and use pointer arithmetic to read parts of it,
and the OS will only bring in the parts I use. |
void *mem=mmap(0,length, PROT_READ, MAP_ANONYMOUS+MAP_SHARED, fd,0); |
You want to bring in the file
"fd" for reading and writing. |
void *mem=mmap(0,length, PROT_READ+PROT_WRITE, MAP_ANONYMOUS+MAP_SHARED, fd,0); |
Flags |
What |
Why |
Weirdness |
PROT_NONE |
Disable all access to the memory. | Basically requesting a page
fault when accessed. Used by debug tools like "electric fence"
to find memory access errors. |
! |
PROT_READ |
Read only area. | Useful for input files, or
big read-only tables. |
normal |
PROT_WRITE |
Write only area. | Can't be read, though.
Secure shared drop box? |
!! |
PROT_EXEC |
Execute only area. | Theoretically, secure code? Not supported on x86 though. |
!! |
PROT_READ+PROT_WRITE |
Read-write access. | Most ordinary memory on the stack, or from
"new" or "malloc" is allocated like this. You can't execute code
here, as a security feature. |
normal |
PROT_READ+PROT_EXEC |
Readable (for constants) and
executable (for code). |
Most programs are mapped this
way. |
normal |
PROT_WRITE+PROT_EXEC |
Write and execute, but not read? | Maybe for a dynamically
generated program, plus security? |
!!! |
PROT_READ+PROT_WRITE+PROT_EXEC |
Allow all access: do what
thou wilt. |
Long ago, this access was used for
everything. Good for dynamically created code, but also handy for malware. |
! |
Threads actually share the page table, but the OS sets up a
separate stack for each thread. Print a local variable (or
rsp) from several threads, and you'll see they get stored in
different locations.
CUDA can use mmap to allow the CPU and GPU to share data, called
"Unified
Memory". (At the moment, it's definitely slower than
manual cudaMalloc and cudaMemcpy, but they're working on improving
that.)
SSE accesses to 4 floats are 16-byte aligned. Pages are
4096-byte aligned (!).