https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56926

--- Comment #17 from asmwarrior <asmwarrior at gmail dot com> ---
Good news, I can definitely confirm that enlarge the value: pch_VA_max_size can
solve the crash issue.

Luckily, the value is defined in host-mingw32.c is a const value:
static const size_t pch_VA_max_size  = 128 * 1024 * 1024;
And there are only three references in the host-mingw32.c.

Since I don't have the ability to build the gcc under windows myself, today, I
try to edit the cc1plus.exe in a binary editor.
That is: find the three references instructions in the cc1plus.exe, and edit
the instructions, so that I changed the pch_VA_max_size value from 128M to
512M.
128 * 1024 * 1024 = 128M = 08 00 00 00 (Hex)
512M = 20 00 00 00 (Hex)

To find the places where those three instructions locates, there is a trick.

I use the tool named "ollydbg" version 1.1 which is a debugger and also a
disassembler. 
Open the file cc1plus.exe, and let ollydbg show a table containing all the
calls to external modules. 


Two references is located in the function body:
--------
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;

  /* 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; 
}
--------
Then, you can search the calling table by "VirtualAlloc" from the table, you
will find only one match, then go the address of the calling instruction, you
can easily find the two instructions which has "00000008" in the instructions.
Then, change the last byte to "20", note that "00000020" is in fact 20 00 00 00
which is 512M because x86 cpu uses little endian.

The third place can be found in the function body:
--------
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);
--------
Now, search for the function call of "GetVersionEx", you can easily find and
change the instruction.


The total changes can be listed in the patch window of ollydbg, see the screen
shot
http://imagizer.imageshack.us/v2/689x223q90/673/xL8rmw.png
(The cc1plus.exe I used to modify is the one I tested in comment 11)
Then, you can save the modified cc1plus.exe, and now, it can handle larger pch
file up to 512M.

Good luck.

Reply via email to