Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

mmap(2)

FieldValue
Numbers (x64 / i386 / arm64-generic / arm32)9 / 90 / 222 / -
Since (kernel)1.0
Man pageman2/mmap.2 (cached, dated 2021-03-22; companion man2/mmap2.2 is indexed under descriptors-io)
glibc wrapperyes, in libc; on 32-bit the wrapper calls mmap2(2) with the offset adjusted (man “C library/kernel differences”)
Aliases coverednone (munmap has its own page munmap)
Ledger IDSC-mmap

Purpose

mmap() creates a new mapping in the calling process’s virtual address space, backed by a file (length bytes at offset of the file on fd) or, with MAP_ANONYMOUS, by zero-filled memory: the kernel’s universal interface for memory-mapped file I/O, shared memory, allocators, loaders, and stacks. addr is a hint unless MAP_FIXED is given.

Synopsis

#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
           int fd, off_t offset);

Arguments and behavior

addr = NULL lets the kernel choose a page-aligned address (the portable form); non-NULL is a hint, rounded down since 2.6.24. With MAP_FIXED the address is enforced and overlapping mappings are discarded. length must be > 0 (EINVAL when 0, since 2.6.12); offset must be a page-size multiple (huge-page size for hugetlb). fd may be closed right after a successful call; prot must not conflict with the file’s open mode; mappings survive fork(2) unchanged.

Return value and errors

Returns the mapped address; on failure MAP_FAILED ((void *) -1) with errno: EACCES, EAGAIN, EBADF, EEXIST (MAP_FIXED_NOREPLACE collision), EINVAL (bad arguments; no MAP_PRIVATE/MAP_SHARED/ MAP_SHARED_VALIDATE), ENFILE, ENODEV, ENOMEM (no memory; mapping count; RLIMIT_DATA since 4.7), EOVERFLOW (32-bit large-file page-count overflow), EPERM (PROT_EXEC on no-exec mount; file seal; unprivileged MAP_HUGETLB), ETXTBSY. Use of the mapping can raise SIGSEGV (write to read-only) or SIGBUS (past file end).

Flags and constants

prot: PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC (full PROT_* list under mprotect). flags values verified in installed glibc headers (bits/mman-linux.h, bits/mman-map-flags-generic.h):

FlagValueSince / note
MAP_SHARED0x01updates visible to other mappings and the file
MAP_PRIVATE0x02private copy-on-write
MAP_SHARED_VALIDATE0x034.15; unknown flags fail with EOPNOTSUPP
MAP_DROPPABLE0x08in headers; man page coverage gap
MAP_FIXED0x10enforce addr exactly; clobbers overlaps
MAP_ANONYMOUS (=MAP_ANON)0x20no file; fd ignored; shared anon since 2.4
MAP_GROWSDOWN0x00100stack-like, grows downward
MAP_LOCKED0x020002.5.37; weak mlock, never fails the mmap
MAP_NORESERVE0x04000skip swap reservation
MAP_POPULATE0x080002.5.46; prefault page tables
MAP_NONBLOCK0x100002.5.46; POPULATE no-op since 2.6.23
MAP_STACK0x200002.6.27; currently a no-op on Linux
MAP_HUGETLB0x400002.6.32; huge-page mapping
MAP_SYNC0x800004.15; DAX-only, needs MAP_SHARED_VALIDATE
MAP_FIXED_NOREPLACE0x1000004.17; EEXIST instead of clobbering
MAP_HUGE_* / MAP_HUGE_SHIFTbits 26-313.8; log2 page-size encoding

MAP_32BIT (x86-64 only) lives in the x86 glibc bits; MAP_UNINITIALIZED (2.6.33) is honored only with CONFIG_MMAP_ALLOW_UNINITIALIZED. Only MAP_FIXED is POSIX; the rest need _DEFAULT_SOURCE (glibc >= 2.19) or _BSD_SOURCE/_SVID_SOURCE earlier.

Security and notes

  • Numbering trap: i386 slot 90 is the old_mmap entry (sys_old_mmap / compat_sys_ia32_mmap, cached syscall_32.tbl); 32-bit programs actually use mmap2 (i386/arm 192). arm32 EABI has no mmap row (hub arm “-”); the old arm OABI table has slot 90 oabi mmap.
  • MAP_FIXED clobbers pre-existing mappings and is hazardous in multithreaded programs (man “Using MAP_FIXED safely”); since 4.17 MAP_FIXED_NOREPLACE is the atomic, EEXIST-returning alternative.
  • PROT_WRITE implies PROT_READ on some architectures (e.g. i386); whether PROT_READ implies PROT_EXEC is arch dependent.
  • Writes past file end in the trailing partial page stay in page cache (POSIX deviation, man BUGS); msync(2) before unmap may flush them, except on tmpfs. MAP_NORESERVE gives no OOM guarantee: the kernel may kill the process under pressure (man BUGS).

References

  • Cached man page: source-cache/man-pages-sparse/man2/mmap.2 (full).
  • Flag values: /usr/include/x86_64-linux-gnu/bits/mman-linux.h, bits/mman-map-flags-generic.h.
  • Numbers: cached syscall_64.tbl, syscall_32.tbl (old_mmap), syscall_generic.tbl, syscall_arm.tbl; hub overview; worklog Task 1-b verified i386 90 = old_mmap.