/* mingw32 host-specific hook definitions.
   Copyright (C) 2004-2021 Free Software Foundation, Inc.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 3, or (at your
   option) any later version.

   GCC is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
   License for more details.

   You should have received a copy of the GNU General Public License
   along with GCC; see the file COPYING3.  If not see
   <http://www.gnu.org/licenses/>.  */

#define IN_TARGET_CODE 1

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic.h"
#include "hosthooks.h"
#include "hosthooks-def.h"


#define WIN32_LEAN_AND_MEAN  /* Not so important if we have windows.h.gch.  */
#include <windows.h>
#include <stdlib.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*);

/* FIXME: Is this big enough?  */
static const size_t pch_VA_max_size  = 128 * 1024 * 1024;

/* Granularity for reserving address space.  */
static size_t va_granularity = 0x10000;

/* Print out the GetLastError() translation.  */ 
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);
}

/* Granularity for reserving address space.  */
static size_t
mingw32_gt_pch_alloc_granularity (void)
{
  SYSTEM_INFO si;

  GetSystemInfo (&si);
  va_granularity = (size_t) si.dwAllocationGranularity;

  return va_granularity;
}

/* Identify an address that's likely to be free in a subsequent invocation
   of the compiler.  The area should be able to hold SIZE bytes.  FD is an
   open file descriptor if the host would like to probe with mmap.  */

static void *
mingw32_gt_pch_get_address (size_t size, int)
{
  void* res;
  size = (size + va_granularity - 1) & ~(va_granularity - 1);
  if (size > pch_VA_max_size)
    return NULL;

  /* FIXME: We let system determine base by setting first arg to NULL.
     Allocating at top of available address space avoids unnecessary
     fragmentation of "ordinary" (malloc's)  address space but may not
     be safe  with delayed load of system dll's. Preferred addresses
     for NT system dlls is in 0x70000000 to 0x78000000 range.
     If we allocate at bottom we need to reserve the address as early
     as possible and at the same point in each invocation. */
 
  res = VirtualAlloc (NULL, pch_VA_max_size,
		      MEM_RESERVE | MEM_TOP_DOWN,
		      PAGE_NOACCESS);
  if (!res)
    w32_error (__FUNCTION__, __FILE__, __LINE__, "VirtualAlloc");
  else
    /* We do not need the address space for now, so free it.  */
    VirtualFree (res, 0, MEM_RELEASE);

  return res; 
}

/* ADDR is an address returned by gt_pch_get_address.  Attempt to allocate
   SIZE bytes at the same address and load it with the data from FD at 
   OFFSET.  Return -1 if we couldn't allocate memory at ADDR, return 0
   if the memory is allocated but the data not loaded, return 1 if done.  */

static int
mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
			    size_t offset)
{
  void * mmap_addr;
  HANDLE mmap_handle;
 
  /* Apparently, MS Vista puts unnamed file mapping objects into Global
     namespace when running an application in a Terminal Server
     session.  This causes failure since, by default, applications 
     don't get SeCreateGlobalPrivilege. We don't need global
     memory sharing so explicitly put object into Local namespace.

     If multiple concurrent GCC processes are using PCH functionality,
     MapViewOfFileEx returns "Access Denied" error.  So we ensure the
     session-wide mapping name is unique by appending process ID.  */

#define OBJECT_NAME_FMT "Local\\MinGWGCCPCH-"

  char* object_name = NULL;
  /* However, the documentation for CreateFileMapping says that on NT4
     and earlier, backslashes are invalid in object name.  So, we need
     to check if we are on Windows2000 or higher.  */
  OSVERSIONINFO version_info;
  int r;

  version_info.dwOSVersionInfoSize = sizeof (version_info);

  if (size == 0)
    return 0; 

  /* Offset must be also be a multiple of allocation granularity for
     this to work.  We can't change the offset. */ 
  if ((offset & (va_granularity - 1)) != 0 || size > pch_VA_max_size)
    return -1;


  /* Determine the version of Windows we are running on and use a
     uniquely-named local object if running > 4.  */
  GetVersionEx (&version_info);

  char local_object_name[sizeof (OBJECT_NAME_FMT) + sizeof (DWORD) * 2];
  if (version_info.dwMajorVersion > 4)
    {
      snprintf (local_object_name, sizeof (local_object_name),
		OBJECT_NAME_FMT "%lx", GetCurrentProcessId());
      object_name = local_object_name;
    }
  mmap_handle = CreateFileMappingA ((HANDLE) _get_osfhandle (fd), NULL,
				    PAGE_WRITECOPY | SEC_COMMIT, 0, 0,
				    object_name);

  if (mmap_handle == NULL)
    {
      w32_error (__FUNCTION__,  __FILE__, __LINE__, "CreateFileMapping");
      return -1; 
    }

  /* Retry five times, as here might occure a race with multiple gcc's
     instances at same time.  */
  for (r = 0; r < 5; r++)
   {
      mmap_addr = MapViewOfFileEx (mmap_handle, FILE_MAP_COPY, 0, offset,
				   size, addr);
      if (mmap_addr == addr)
	break;
      if (r != 4)
        Sleep (500);
   }
      
  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;
