Path: blob/main/contrib/llvm-project/compiler-rt/lib/profile/WindowsMMap.c
35233 views
/*1* This code is derived from uClibc (original license follows).2* https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c3*/4/* mmap() replacement for Windows5*6* Author: Mike Frysinger <[email protected]>7* Placed into the public domain8*/910/* References:11* CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx12* CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx13* MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx14* UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx15*/1617#if defined(_WIN32)1819#include "WindowsMMap.h"2021#define WIN32_LEAN_AND_MEAN22#include <windows.h>2324#include "InstrProfiling.h"2526COMPILER_RT_VISIBILITY27void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)28{29if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))30return MAP_FAILED;31if (fd == -1) {32if (!(flags & MAP_ANON) || offset)33return MAP_FAILED;34} else if (flags & MAP_ANON)35return MAP_FAILED;3637DWORD flProtect;38if (prot & PROT_WRITE) {39if (prot & PROT_EXEC)40flProtect = PAGE_EXECUTE_READWRITE;41else42flProtect = PAGE_READWRITE;43} else if (prot & PROT_EXEC) {44if (prot & PROT_READ)45flProtect = PAGE_EXECUTE_READ;46else if (prot & PROT_EXEC)47flProtect = PAGE_EXECUTE;48} else49flProtect = PAGE_READONLY;5051off_t end = length + offset;52HANDLE mmap_fd, h;53if (fd == -1)54mmap_fd = INVALID_HANDLE_VALUE;55else56mmap_fd = (HANDLE)_get_osfhandle(fd);57h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);58if (h == NULL)59return MAP_FAILED;6061DWORD dwDesiredAccess;62if (prot & PROT_WRITE)63dwDesiredAccess = FILE_MAP_WRITE;64else65dwDesiredAccess = FILE_MAP_READ;66if (prot & PROT_EXEC)67dwDesiredAccess |= FILE_MAP_EXECUTE;68if (flags & MAP_PRIVATE)69dwDesiredAccess |= FILE_MAP_COPY;70void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);71if (ret == NULL) {72CloseHandle(h);73ret = MAP_FAILED;74}75return ret;76}7778COMPILER_RT_VISIBILITY79void munmap(void *addr, size_t length)80{81UnmapViewOfFile(addr);82/* ruh-ro, we leaked handle from CreateFileMapping() ... */83}8485COMPILER_RT_VISIBILITY86int msync(void *addr, size_t length, int flags)87{88if (flags & MS_INVALIDATE)89return -1; /* Not supported. */9091/* Exactly one of MS_ASYNC or MS_SYNC must be specified. */92switch (flags & (MS_ASYNC | MS_SYNC)) {93case MS_SYNC:94case MS_ASYNC:95break;96default:97return -1;98}99100if (!FlushViewOfFile(addr, length))101return -1;102103if (flags & MS_SYNC) {104/* FIXME: No longer have access to handle from CreateFileMapping(). */105/*106* if (!FlushFileBuffers(h))107* return -1;108*/109}110111return 0;112}113114COMPILER_RT_VISIBILITY115int madvise(void *addr, size_t length, int advice)116{117if (advice != MADV_DONTNEED)118return -1; /* Not supported. */119120if (!VirtualUnlock(addr, length))121return -1;122123return 0;124}125126static int lock(HANDLE handle, DWORD lockType, BOOL blocking) {127DWORD flags = lockType;128if (!blocking)129flags |= LOCKFILE_FAIL_IMMEDIATELY;130131OVERLAPPED overlapped;132ZeroMemory(&overlapped, sizeof(OVERLAPPED));133overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);134BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);135if (!result) {136DWORD dw = GetLastError();137138// In non-blocking mode, return an error if the file is locked.139if (!blocking && dw == ERROR_LOCK_VIOLATION)140return -1; // EWOULDBLOCK141142// If the error is ERROR_IO_PENDING, we need to wait until the operation143// finishes. Otherwise, we return an error.144if (dw != ERROR_IO_PENDING)145return -1;146147DWORD dwNumBytes;148if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))149return -1;150}151152return 0;153}154155COMPILER_RT_VISIBILITY156int flock(int fd, int operation) {157HANDLE handle = (HANDLE)_get_osfhandle(fd);158if (handle == INVALID_HANDLE_VALUE)159return -1;160161BOOL blocking = (operation & LOCK_NB) == 0;162int op = operation & ~LOCK_NB;163164switch (op) {165case LOCK_EX:166return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);167168case LOCK_SH:169return lock(handle, 0, blocking);170171case LOCK_UN:172if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))173return -1;174break;175176default:177return -1;178}179180return 0;181}182183#undef DWORD_HI184#undef DWORD_LO185186#endif /* _WIN32 */187188189