#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "hosthooks.h"
#include "hosthooks-def.h"
#include "toplev.h"
#include "diagnostic.h"
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static void * mingw32_gt_pch_get_address (size_t, int);
static int mingw32_gt_pch_use_address (void *, size_t, int, size_t);
static size_t mingw32_gt_pch_alloc_granularity (void);
#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
#define HOST_HOOKS_GT_PCH_GET_ADDRESS mingw32_gt_pch_get_address
#undef HOST_HOOKS_GT_PCH_USE_ADDRESS
#define HOST_HOOKS_GT_PCH_USE_ADDRESS mingw32_gt_pch_use_address
#undef HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY
#define HOST_HOOKS_GT_PCH_ALLOC_GRANULARITY mingw32_gt_pch_alloc_granularity
static inline void w32_error(const char*, const char*, int, const char*);
static const size_t pch_VA_max_size = 128 * 1024 * 1024;
static const size_t va_granularity = 0x10000;
static inline void
w32_error (const char* function, const char* file, int line,
const char* my_msg)
{
LPSTR w32_msgbuf;
FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS
| FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR) &w32_msgbuf, 0, NULL);
fprintf(stderr, "internal error in %s, at %s:%d: %s: %s\n",
function, trim_filename (file), line, my_msg, w32_msgbuf);
LocalFree ((HLOCAL)w32_msgbuf);
}
static size_t mingw32_gt_pch_alloc_granularity (void)
{
return va_granularity;
}
static void *
mingw32_gt_pch_get_address (size_t size, int fd ATTRIBUTE_UNUSED)
{
void* res;
size = (size + va_granularity - 1) & ~(va_granularity - 1);
if (size > pch_VA_max_size)
return NULL;
res = VirtualAlloc (NULL, pch_VA_max_size,
MEM_RESERVE | MEM_TOP_DOWN,
PAGE_NOACCESS);
if (!res)
w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc");
else
VirtualFree (res, 0, MEM_RELEASE);
return res;
}
static int
mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
size_t offset)
{
void * mmap_addr;
static HANDLE mmap_handle;
if (size == 0)
return 0;
if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
return -1;
mmap_handle = CreateFileMapping ((HANDLE) _get_osfhandle (fd),
NULL, PAGE_WRITECOPY | SEC_COMMIT,
0, 0, NULL);
if (mmap_handle == NULL)
{
w32_error (__FUNCTION__, __FILE__, __LINE__, "CreateFileMapping");
return -1;
}
mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
size, addr);
if (mmap_addr != addr)
{
w32_error (__FUNCTION__, __FILE__, __LINE__, "MapViewOfFileEx");
CloseHandle(mmap_handle);
return -1;
}
return 1;
}
const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;