Home | History | Annotate | Download | only in profile
      1 /*
      2  * This code is derived from uClibc (original license follows).
      3  * https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c
      4  */
      5  /* mmap() replacement for Windows
      6  *
      7  * Author: Mike Frysinger <vapier (at) gentoo.org>
      8  * Placed into the public domain
      9  */
     10 
     11 /* References:
     12  * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
     13  * CloseHandle:       http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
     14  * MapViewOfFile:     http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
     15  * UnmapViewOfFile:   http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
     16  */
     17 
     18 #if defined(_WIN32)
     19 
     20 #include "WindowsMMap.h"
     21 #include "InstrProfiling.h"
     22 
     23 #ifdef __USE_FILE_OFFSET64
     24 # define DWORD_HI(x) (x >> 32)
     25 # define DWORD_LO(x) ((x) & 0xffffffff)
     26 #else
     27 # define DWORD_HI(x) (0)
     28 # define DWORD_LO(x) (x)
     29 #endif
     30 
     31 COMPILER_RT_VISIBILITY
     32 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
     33 {
     34   if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
     35     return MAP_FAILED;
     36   if (fd == -1) {
     37     if (!(flags & MAP_ANON) || offset)
     38       return MAP_FAILED;
     39   } else if (flags & MAP_ANON)
     40     return MAP_FAILED;
     41 
     42   DWORD flProtect;
     43   if (prot & PROT_WRITE) {
     44     if (prot & PROT_EXEC)
     45       flProtect = PAGE_EXECUTE_READWRITE;
     46     else
     47       flProtect = PAGE_READWRITE;
     48   } else if (prot & PROT_EXEC) {
     49     if (prot & PROT_READ)
     50       flProtect = PAGE_EXECUTE_READ;
     51     else if (prot & PROT_EXEC)
     52       flProtect = PAGE_EXECUTE;
     53   } else
     54     flProtect = PAGE_READONLY;
     55 
     56   off_t end = length + offset;
     57   HANDLE mmap_fd, h;
     58   if (fd == -1)
     59     mmap_fd = INVALID_HANDLE_VALUE;
     60   else
     61     mmap_fd = (HANDLE)_get_osfhandle(fd);
     62   h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
     63   if (h == NULL)
     64     return MAP_FAILED;
     65 
     66   DWORD dwDesiredAccess;
     67   if (prot & PROT_WRITE)
     68     dwDesiredAccess = FILE_MAP_WRITE;
     69   else
     70     dwDesiredAccess = FILE_MAP_READ;
     71   if (prot & PROT_EXEC)
     72     dwDesiredAccess |= FILE_MAP_EXECUTE;
     73   if (flags & MAP_PRIVATE)
     74     dwDesiredAccess |= FILE_MAP_COPY;
     75   void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
     76   if (ret == NULL) {
     77     CloseHandle(h);
     78     ret = MAP_FAILED;
     79   }
     80   return ret;
     81 }
     82 
     83 COMPILER_RT_VISIBILITY
     84 void munmap(void *addr, size_t length)
     85 {
     86   UnmapViewOfFile(addr);
     87   /* ruh-ro, we leaked handle from CreateFileMapping() ... */
     88 }
     89 
     90 COMPILER_RT_VISIBILITY
     91 int msync(void *addr, size_t length, int flags)
     92 {
     93   if (flags & MS_INVALIDATE)
     94     return -1; /* Not supported. */
     95 
     96   /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */
     97   switch (flags & (MS_ASYNC | MS_SYNC)) {
     98     case MS_SYNC:
     99     case MS_ASYNC:
    100       break;
    101     default:
    102       return -1;
    103   }
    104 
    105   if (!FlushViewOfFile(addr, length))
    106     return -1;
    107 
    108   if (flags & MS_SYNC) {
    109     /* FIXME: No longer have access to handle from CreateFileMapping(). */
    110     /*
    111      * if (!FlushFileBuffers(h))
    112      *   return -1;
    113      */
    114   }
    115 
    116   return 0;
    117 }
    118 
    119 COMPILER_RT_VISIBILITY
    120 int flock(int fd, int operation)
    121 {
    122   return -1; /* Not supported. */
    123 }
    124 
    125 #undef DWORD_HI
    126 #undef DWORD_LO
    127 
    128 #endif /* _WIN32 */
    129