00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "coretypes.h"
00024 #include "hosthooks.h"
00025 #include "hosthooks-def.h"
00026 #include "toplev.h"
00027 #include "diagnostic.h"
00028
00029
00030 #define WIN32_LEAN_AND_MEAN
00031 #include <windows.h>
00032
00033 static void * mingw32_gt_pch_get_address (size_t, int);
00034 static int mingw32_gt_pch_use_address (void *, size_t, int, size_t);
00035 static size_t mingw32_gt_pch_alloc_granularity (void);
00036
00037 #undef HOST_HOOKS_GT_PCH_GET_ADDRESS
00038 #define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address
00039 #undef HOST_HOOKS_GT_PCH_USE_ADDRESS
00040 #define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address
00041 #undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY
00042 #define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity
00043
00044 static inline void w32_error(const char*, const char*, int, const char*);
00045
00046
00047 static const size_t pch_VA_max_size = 128 * 1024 * 1024;
00048
00049
00050 static const size_t va_granularity = 0x10000;
00051
00052
00053 static inline void
00054 w32_error (const char* function, const char* file, int line,
00055 const char* my_msg)
00056 {
00057 LPSTR w32_msgbuf;
00058 FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER
00059 | FORMAT_MESSAGE_FROM_SYSTEM
00060 | FORMAT_MESSAGE_IGNORE_INSERTS
00061 | FORMAT_MESSAGE_MAX_WIDTH_MASK,
00062 NULL, GetLastError(),
00063 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00064 (LPSTR) &w32_msgbuf, 0, NULL);
00065 fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n",
00066 function, trim_filename (file), line, my_msg, w32_msgbuf);
00067 LocalFree ((HLOCAL)w32_msgbuf);
00068 }
00069
00070
00071 static size_t mingw32_gt_pch_alloc_granularity (void)
00072 {
00073 return va_granularity;
00074 }
00075
00076
00077
00078
00079
00080 static void *
00081 mingw32_gt_pch_get_address (size_t size, int fd ATTRIBUTE_UNUSED)
00082 {
00083 void* res;
00084 size = (size + va_granularity - 1) & ~(va_granularity - 1);
00085 if (size > pch_VA_max_size)
00086 return NULL;
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 res = VirtualAlloc (NULL, pch_VA_max_size,
00097 MEM_RESERVE | MEM_TOP_DOWN,
00098 PAGE_NOACCESS);
00099 if (!res)
00100 w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc");
00101 else
00102
00103 VirtualFree (res, 0, MEM_RELEASE);
00104
00105 return res;
00106 }
00107
00108
00109
00110
00111
00112
00113 static int
00114 mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
00115 size_t offset)
00116 {
00117 void * mmap_addr;
00118 static HANDLE mmap_handle;
00119
00120 if (size == 0)
00121 return 0;
00122
00123
00124
00125 if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
00126 return -1;
00127
00128 mmap_handle = CreateFileMapping ((HANDLE) _get_osfhandle (fd),
00129 NULL, PAGE_WRITECOPY | SEC_COMMIT,
00130 0, 0, NULL);
00131 if (mmap_handle == NULL)
00132 {
00133 w32_error (__FUNCTION__, __FILE__, __LINE__, "CreateFileMapping");
00134 return -1;
00135 }
00136 mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
00137 size, addr);
00138 if (mmap_addr != addr)
00139 {
00140 w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx");
00141 CloseHandle(mmap_handle);
00142 return -1;
00143 }
00144
00145 return 1;
00146 }
00147
00148 const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;