brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 9d7da83 Raw
188 lines · c
1/*2 * This code is derived from uClibc (original license follows).3 * https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c4 */5 /* mmap() replacement for Windows6 *7 * Author: Mike Frysinger <vapier@gentoo.org>8 * Placed into the public domain9 */10 11/* References:12 * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx13 * CloseHandle:       http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx14 * MapViewOfFile:     http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx15 * UnmapViewOfFile:   http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx16 */17 18#if defined(_WIN32)19 20#include "WindowsMMap.h"21 22#define WIN32_LEAN_AND_MEAN23#include <windows.h>24 25#include "InstrProfiling.h"26 27COMPILER_RT_VISIBILITY28void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)29{30  if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))31    return MAP_FAILED;32  if (fd == -1) {33    if (!(flags & MAP_ANON) || offset)34      return MAP_FAILED;35  } else if (flags & MAP_ANON)36    return MAP_FAILED;37 38  DWORD flProtect;39  if (prot & PROT_WRITE) {40    if (prot & PROT_EXEC)41      flProtect = PAGE_EXECUTE_READWRITE;42    else43      flProtect = PAGE_READWRITE;44  } else if (prot & PROT_EXEC) {45    if (prot & PROT_READ)46      flProtect = PAGE_EXECUTE_READ;47    else if (prot & PROT_EXEC)48      flProtect = PAGE_EXECUTE;49  } else50    flProtect = PAGE_READONLY;51 52  off_t end = length + offset;53  HANDLE mmap_fd, h;54  if (fd == -1)55    mmap_fd = INVALID_HANDLE_VALUE;56  else57    mmap_fd = (HANDLE)_get_osfhandle(fd);58  h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);59  if (h == NULL)60    return MAP_FAILED;61 62  DWORD dwDesiredAccess;63  if (prot & PROT_WRITE)64    dwDesiredAccess = FILE_MAP_WRITE;65  else66    dwDesiredAccess = FILE_MAP_READ;67  if (prot & PROT_EXEC)68    dwDesiredAccess |= FILE_MAP_EXECUTE;69  if (flags & MAP_PRIVATE)70    dwDesiredAccess |= FILE_MAP_COPY;71  void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);72  if (ret == NULL) {73    CloseHandle(h);74    ret = MAP_FAILED;75  }76  return ret;77}78 79COMPILER_RT_VISIBILITY80void munmap(void *addr, size_t length)81{82  UnmapViewOfFile(addr);83  /* ruh-ro, we leaked handle from CreateFileMapping() ... */84}85 86COMPILER_RT_VISIBILITY87int msync(void *addr, size_t length, int flags)88{89  if (flags & MS_INVALIDATE)90    return -1; /* Not supported. */91 92  /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */93  switch (flags & (MS_ASYNC | MS_SYNC)) {94    case MS_SYNC:95    case MS_ASYNC:96      break;97    default:98      return -1;99  }100 101  if (!FlushViewOfFile(addr, length))102    return -1;103 104  if (flags & MS_SYNC) {105    /* FIXME: No longer have access to handle from CreateFileMapping(). */106    /*107     * if (!FlushFileBuffers(h))108     *   return -1;109     */110  }111 112  return 0;113}114 115COMPILER_RT_VISIBILITY116int madvise(void *addr, size_t length, int advice)117{118  if (advice != MADV_DONTNEED)119    return -1; /* Not supported. */120 121  if (!VirtualUnlock(addr, length))122    return -1;123 124  return 0;125}126 127static int lock(HANDLE handle, DWORD lockType, BOOL blocking) {128  DWORD flags = lockType;129  if (!blocking)130    flags |= LOCKFILE_FAIL_IMMEDIATELY;131 132  OVERLAPPED overlapped;133  ZeroMemory(&overlapped, sizeof(OVERLAPPED));134  overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);135  BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);136  if (!result) {137    DWORD dw = GetLastError();138 139    // In non-blocking mode, return an error if the file is locked.140    if (!blocking && dw == ERROR_LOCK_VIOLATION)141      return -1; // EWOULDBLOCK142 143    // If the error is ERROR_IO_PENDING, we need to wait until the operation144    // finishes. Otherwise, we return an error.145    if (dw != ERROR_IO_PENDING)146      return -1;147 148    DWORD dwNumBytes;149    if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))150      return -1;151  }152 153  return 0;154}155 156COMPILER_RT_VISIBILITY157int flock(int fd, int operation) {158  HANDLE handle = (HANDLE)_get_osfhandle(fd);159  if (handle == INVALID_HANDLE_VALUE)160    return -1;161 162  BOOL blocking = (operation & LOCK_NB) == 0;163  int op = operation & ~LOCK_NB;164 165  switch (op) {166  case LOCK_EX:167    return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);168 169  case LOCK_SH:170    return lock(handle, 0, blocking);171 172  case LOCK_UN:173    if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))174      return -1;175    break;176 177  default:178    return -1;179  }180 181  return 0;182}183 184#undef DWORD_HI185#undef DWORD_LO186 187#endif /* _WIN32 */188