2 * Copyright 2016 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <folly/portability/SysMman.h>
20 #include <folly/portability/Windows.h>
22 static bool mmap_to_page_protection(int prot, DWORD& ret) {
23 if (prot == PROT_NONE) {
25 } else if (prot == PROT_READ) {
27 } else if (prot == PROT_EXEC) {
29 } else if (prot == (PROT_READ | PROT_EXEC)) {
30 ret = PAGE_EXECUTE_READ;
31 } else if (prot == (PROT_READ | PROT_WRITE)) {
33 } else if (prot == (PROT_READ | PROT_WRITE | PROT_EXEC)) {
34 ret = PAGE_EXECUTE_READWRITE;
42 int madvise(const void* addr, size_t len, int advise) {
43 // We do nothing at all.
44 // Could probably implement dontneed via VirtualAlloc
45 // with the MEM_RESET and MEM_RESET_UNDO flags.
49 int mlock(const void* addr, size_t len) {
50 if (!VirtualLock((void*)addr, len)) {
56 void* mmap(void* addr, size_t length, int prot, int flags, int fd, off_t off) {
57 // Make sure it's something we support first.
60 if ((flags & (MAP_ANONYMOUS | MAP_SHARED)) == (MAP_ANONYMOUS | MAP_SHARED)) {
63 // No private copy on write.
64 if ((flags & MAP_PRIVATE) == MAP_PRIVATE && fd != -1) {
67 // Map isn't anon, must be file backed.
68 if (!(flags & MAP_ANONYMOUS) && fd == -1) {
73 if (!mmap_to_page_protection(prot, newProt)) {
78 if (!(flags & MAP_ANONYMOUS) || (flags & MAP_SHARED)) {
79 HANDLE h = INVALID_HANDLE_VALUE;
80 if (!(flags & MAP_ANONYMOUS)) {
81 h = (HANDLE)_get_osfhandle(fd);
84 HANDLE fmh = CreateFileMapping(
87 newProt | SEC_COMMIT | SEC_RESERVE,
88 (DWORD)((length >> 32) & 0xFFFFFFFF),
89 (DWORD)(length & 0xFFFFFFFF),
91 ret = MapViewOfFileEx(
94 (DWORD)((off >> 32) & 0xFFFFFFFF),
95 (DWORD)(off & 0xFFFFFFFF),
103 ret = VirtualAlloc(addr, length, MEM_COMMIT | MEM_RESERVE, newProt);
104 if (ret == nullptr) {
109 // TODO: Could technically implement MAP_POPULATE via PrefetchVirtualMemory
110 // Should also see about implementing MAP_NORESERVE
114 int mprotect(void* addr, size_t size, int prot) {
116 if (!mmap_to_page_protection(prot, newProt)) {
121 BOOL res = VirtualProtect(addr, size, newProt, &oldProt);
128 int munlock(const void* addr, size_t length) {
129 if (!VirtualUnlock((void*)addr, length)) {
135 int munmap(void* addr, size_t length) {
136 // Try to unmap it as a file, otherwise VirtualFree.
137 if (!UnmapViewOfFile(addr)) {
138 if (!VirtualFree(addr, length, MEM_RELEASE)) {