mmap(2) System Calls Manual mmap(2) mmap, munmap - , LIBRARY Standard C library (libc, -lc) #include void *mmap(void addr[.length], size_t length, int prot, int flags, int fd, off_t offset); int munmap(void addr[.length], size_t length); . mmap() . addr. length ( 0). addr NULL, ( ), ; . addr NULL, ; Linux ( , /proc/sys/vm/mmap_min_addr) . , , . . ( ; MAP_ANONYMOUS ) ( ), fd, length , offset. offset ( sysconf(_SC_PAGE_SIZE)) . mmap() fd . prot ( ). PROT_NONE (OR) : PROT_EXEC . PROT_READ . PROT_WRITE . PROT_NONE . flags , , . flags : MAP_SHARED . , ( ) ( msync(2)). MAP_SHARED_VALIDATE ( Linux 4.15) , MAP_SHARED, MAP_SHARED flags. MAP_SHARED_VALIDATE, , EOPNOTSUPP, . (, MAP_SYNC). MAP_PRIVATE . , , . , , mmap(). MAP_SHARED MAP_PRIVATE POSIX.1-2001 POSIX.1-2008. MAP_SHARED_VALIDATE Linux. flags ( ): MAP_32BIT ( Linux 2.4.20, 2.6) 2 . x86-64 64- . 2 , 64- . x86-64 , . , MAP_FIXED. MAP_ANON Synonym for MAP_ANONYMOUS; provided for compatibility with other implementations. MAP_ANONYMOUS The mapping is not backed by any file; its contents are initialized to zero. The fd argument is ignored; however, some implementations require fd to be -1 if MAP_ANONYMOUS (or MAP_ANON) is specified, and portable applications should ensure this. The offset argument should be zero. Support for MAP_ANONYMOUS in conjunction with MAP_SHARED was added in Linux 2.4. MAP_DENYWRITE This flag is ignored. (Long ago--Linux 2.0 and earlier--it signaled that attempts to write to the underlying file should fail with ETXTBSY. But this was a source of denial-of-service attacks.) MAP_EXECUTABLE . MAP_FILE , . MAP_FIXED addr : . addr : ; . , addr length, , . , mmap() . Software that aspires to be portable should use the MAP_FIXED flag with care, keeping in mind that the exact layout of a process's memory mappings is allowed to change significantly between Linux versions, C library versions, and operating system releases. Carefully read the discussion of this flag in NOTES! MAP_FIXED_NOREPLACE ( Linux 4.17) MAP_FIXED addr, , MAP_FIXED_NOREPLACE . , EEXIST. ( ) : ; . Note that older kernels which do not recognize the MAP_FIXED_NOREPLACE flag will typically (upon detecting a collision with a preexisting mapping) fall back to a "non-MAP_FIXED" type of behavior: they will return an address that is different from the requested address. Therefore, backward-compatible software should check the returned address against the requested address. MAP_GROWSDOWN . , . , . <<>> . , , <<>> SIGSEGV. MAP_HUGETLB ( Linux 2.6.32) << >>. Linux Documentation/admin-guide/mm/hugetlbpage.rst, . MAP_HUGE_2MB MAP_HUGE_1GB (since Linux 3.8) MAP_HUGETLB hugetlb (2 1 , ), . , 2 MAP_HUGE_SHIFT ( ; Hugepagesize /proc/meminfo). : #define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT) #define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT) , /sys/kernel/mm/hugepages. MAP_LOCKED ( Linux 2.5.37) mlock(2). () , mmap() ENOMEM, . . mlock(2). mmap() mlock(2), . MAP_LOCKED . MAP_NONBLOCK ( Linux 2.5.46) MAP_POPULATE. : , . Linux 2.6.23 , MAP_POPULATE . - MAP_POPULATE MAP_NONBLOCK . MAP_NORESERVE Do not reserve swap space for this mapping. When swap space is reserved, one has the guarantee that it is possible to modify the mapping. When swap space is not reserved one might get SIGSEGV upon a write if no physical memory is available. See also the discussion of the file /proc/sys/vm/overcommit_memory in proc(5). Before Linux 2.6, this flag had effect only for private writable mappings. MAP_POPULATE ( Linux 2.5.46) Populate (prefault) page tables for a mapping. For a file mapping, this causes read-ahead on the file. This will help to reduce blocking on page faults later. The mmap() call doesn't fail if the mapping cannot be populated (for example, due to limitations on the number of mapped huge pages when using MAP_HUGETLB). Support for MAP_POPULATE in conjunction with private mappings was added in Linux 2.6.23. MAP_STACK ( Linux 2.6.27) Allocate the mapping at an address suitable for a process or thread stack. This flag is currently a no-op on Linux. However, by employing this flag, applications can ensure that they transparently obtain support if the flag is implemented in the future. Thus, it is used in the glibc threading implementation to allow for the fact that some architectures may (later) require special treatment for stack allocations. A further reason to employ this flag is portability: MAP_STACK exists (and has an effect) on some other systems (e.g., some of the BSDs). MAP_SYNC ( Linux 4.15) MAP_SHARED_VALIDATE; MAP_SHARED . DAX ( ). , EOPNOTSUPP. , , . . MAP_UNINITIALIZED ( Linux 2.6.33) . . , CONFIG_MMAP_ALLOW_UNINITIALIZED. , ( , , ). , , POSIX.1-2001 POSIX.1-2008 MAP_FIXED. , MAP_ANONYMOUS ( MAP_ANON). munmap() munmap() , . . , . addr ( length ). , , SIGSEGV. , - . On success, mmap() returns a pointer to the mapped area. On error, the value MAP_FAILED (that is, (void *) -1) is returned, and errno is set to indicate the error. On success, munmap() returns 0. On failure, it returns -1, and errno is set to indicate the error (probably to EINVAL). EACCES . (mapping), fd . MAP_SHARED PROT_WRITE, fd / (O_RDWR). PROT_WRITE, . EAGAIN , ( setrlimit(2)). EBADF fd ( MAP_ANONYMOUS ). EEXIST flags MAP_FIXED_NOREPLACE , addr length, . EINVAL addr, length offset (, , ). EINVAL ( Linux 2.6.12) length 0. EINVAL flags MAP_PRIVATE, MAP_SHARED MAP_SHARED_VALIDATE. ENFILE . ENODEV . ENOMEM . ENOMEM . munmap() , . ENOMEM ( Linux 4.7) RLIMIT_DATA, getrlimit(2). ENOMEM We don't like addr, because it exceeds the virtual address space of the CPU. EOVERFLOW 32- (.., 64- off_t): , length , offset unsigned long (32 ). EPERM prot PROT_EXEC, , no-exec. EPERM (file seal); fcntl(2). EPERM The MAP_HUGETLB flag was specified, but the caller was not privileged (did not have the CAP_IPC_LOCK capability) and is not a member of the sysctl_hugetlb_shm_group group; see the description of /proc/sys/vm/sysctl_hugetlb_shm_group in proc_sys(5). ETXTBSY MAP_DENYWRITE, , fd, . : SIGSEGV , . SIGBUS Attempted access to a page of the buffer that lies beyond the end of the mapped file. For an explanation of the treatment of the bytes in the page that corresponds to the end of a mapped file that is not a multiple of the page size, see NOTES. attributes(7). +----------------------------+----------------------------------------------------------+--------------------------+ | | | | +----------------------------+----------------------------------------------------------+--------------------------+ |mmap(), munmap() | | MT-Safe | +----------------------------+----------------------------------------------------------+--------------------------+ (, i386), PROT_WRITE PROT_READ. PROT_READ PROT_EXEC . PROT_EXEC, , . : addr 0 (NULL) MAP_FIXED flags. , ; , , 0. MAP_FIXED addr 0 (NULL), 0 (NULL). flags , (, ): _DEFAULT_SOURCE glibc 2.19 ; _BSD_SOURCE _SVID_SOURCE glibc 2.19 ( _GNU_SOURCE , , Linux). , : MAP_32BIT, MAP_ANONYMOUS ( MAP_ANON), MAP_DENYWRITE, MAP_EXECUTABLE, MAP_FILE, MAP_GROWSDOWN, MAP_HUGETLB, MAP_LOCKED, MAP_NONBLOCK, MAP_NORESERVE, MAP_POPULATE MAP_STACK. C This page describes the interface provided by the glibc mmap() wrapper function. Originally, this function invoked a system call of the same name. Since Linux 2.4, that system call has been superseded by mmap2(2), and nowadays the glibc mmap() wrapper function invokes mmap2(2) with a suitably adjusted value for offset. POSIX.1-2008. POSIX.1-2001, SVr4, 4.4BSD. POSIX, mmap(), msync(2) munmap(), _POSIX_MAPPED_FILES, , 0 ( sysconf(3)). , mmap(), fork(2) . A file is mapped in multiples of the page size. For a file that is not a multiple of the page size, the remaining bytes in the partial page at the end of the mapping are zeroed when mapped, and modifications to that region are not written out to the file. The effect of changing the size of the underlying file of a mapping on the pages that correspond to added or removed regions of the file is unspecified. / mincore(2). MAP_FIXED MAP_FIXED , addr length, ; MAP_FIXED , , . For example, suppose that thread A looks through /proc/pid/maps in order to locate an unused address range that it can map using MAP_FIXED, while thread B simultaneously acquires part or all of that same address range. When thread A subsequently employs mmap(MAP_FIXED), it will effectively clobber the mapping that thread B created. In this scenario, thread B need not create a mapping directly; simply making a library call that, internally, uses dlopen(3) to load some other shared library, will suffice. The dlopen(3) call will map the library into the process's address space. Furthermore, almost any library call may be implemented in a way that adds memory mappings to the address space, either with this technique, or by simply allocating memory. Examples include brk(2), malloc(3), pthread_create(3), and the PAM libraries . Linux 4.17, MAP_FIXED_NOREPLACE , , , , , . st_atime mmap() ; , . st_ctime st_mtime PROT_WRITE MAP_SHARED msync(2) MS_SYNC MS_ASYNC, . (Huge TLB) , , mmap() munmap() , . mmap(), offset . length . munmap(), addr length . Linux MAP_NORESERVE, . , , . Before Linux 2.6.7, the MAP_POPULATE flag has effect only if prot is specified as PROT_NONE. SUSv3 specifies that mmap() should fail if length is 0. However, before Linux 2.6.12, mmap() succeeded in this case: no mapping was created and the call returned addr. Since Linux 2.6.12, mmap() fails with the error EINVAL for this case. POSIX , . Linux, , , . msync(2) ; tmpfs(5) (, POSIX, shm_overview(7)). , , . . write(2) . #include #include #include #include #include #include #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { int fd; char *addr; off_t offset, pa_offset; size_t length; ssize_t s; struct stat sb; if (argc < 3 || argc > 4) { fprintf(stderr, "%s file offset [length]\n", argv[0]); exit(EXIT_FAILURE); } fd = open(argv[1], O_RDONLY); if (fd == -1) handle_error("open"); if (fstat(fd, &sb) == -1) /* To obtain file size */ handle_error("fstat"); offset = atoi(argv[2]); pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1); /* offset for mmap() must be page aligned */ if (offset >= sb.st_size) { fprintf(stderr, "offset is past end of file\n"); exit(EXIT_FAILURE); } if (argc == 4) { length = atoi(argv[3]); if (offset + length > sb.st_size) length = sb.st_size - offset; /* Can't display bytes past end of file */ } else { /* No length arg ==> display to end of file */ length = sb.st_size - offset; } addr = mmap(NULL, length + offset - pa_offset, PROT_READ, MAP_PRIVATE, fd, pa_offset); if (addr == MAP_FAILED) handle_error("mmap"); s = write(STDOUT_FILENO, addr + offset - pa_offset, length); if (s != length) { if (s == -1) handle_error("write"); fprintf(stderr, "partial write"); exit(EXIT_FAILURE); } munmap(addr, length + offset - pa_offset); close(fd); exit(EXIT_SUCCESS); } . ftruncate(2), getpagesize(2), memfd_create(2), mincore(2), mlock(2), mmap2(2), mprotect(2), mremap(2), msync(2), remap_file_pages(2), setrlimit(2), shmat(2), userfaultfd(2), shm_open(3), shm_overview(7) The descriptions of the following files in proc(5): /proc/pid/maps, /proc/pid/map_files, and /proc/pid/smaps. B.O. Gallmeister, POSIX.4, O'Reilly, pp. 128-129 and 389-391. aereiae , Alexey , Azamat Hackimov , Dmitriy S. Seregin , Dmitry Bolkhovskikh , ITriskTI , Max Is , Yuri Kozlov , ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . mmap(2)