155 lines
5.7 KiB
Diff
155 lines
5.7 KiB
Diff
From 22a67f6b18d2854bcdf740833cf4e1a0555c7295 Mon Sep 17 00:00:00 2001
|
|
From: Martin Richter <xricht17@stud.fit.vutbr.cz>
|
|
Date: Wed, 5 Aug 2015 23:36:25 +0100
|
|
Subject: [PATCH 10/15] Fix using large PCH
|
|
|
|
The following patch fixes segfault when gt_pch_use_address
|
|
fails (returns -1). fatal_error now correctly shows an error
|
|
message and terminates the program.
|
|
I have basicly only reordered reads, and placed them after
|
|
the file mapping itself. Global pointers are changed only
|
|
after gt_pch_use_address succeeds, so in case of failure
|
|
they still contain valid addresses.
|
|
|
|
This patch is meant for the master branch. However, it
|
|
should not be hard to modify it for others.
|
|
|
|
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14940
|
|
https://sourceforge.net/p/mingw-w64/bugs/382/
|
|
---
|
|
gcc/config/i386/host-mingw32.c | 10 ++-------
|
|
gcc/ggc-common.c | 51 +++++++++++++++++++++++++++++++++---------
|
|
2 files changed, 42 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/gcc/config/i386/host-mingw32.c b/gcc/config/i386/host-mingw32.c
|
|
index aa17378..631d9c4 100644
|
|
--- a/gcc/config/i386/host-mingw32.c
|
|
+++ b/gcc/config/i386/host-mingw32.c
|
|
@@ -42,9 +42,6 @@ static size_t mingw32_gt_pch_alloc_granularity (void);
|
|
|
|
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;
|
|
|
|
@@ -86,9 +83,6 @@ 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
|
|
@@ -98,7 +92,7 @@ mingw32_gt_pch_get_address (size_t size, int)
|
|
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,
|
|
+ res = VirtualAlloc (NULL, size,
|
|
MEM_RESERVE | MEM_TOP_DOWN,
|
|
PAGE_NOACCESS);
|
|
if (!res)
|
|
@@ -148,7 +142,7 @@ mingw32_gt_pch_use_address (void *addr, size_t size, int fd,
|
|
|
|
/* 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)
|
|
+ if ((offset & (va_granularity - 1)) != 0)
|
|
return -1;
|
|
|
|
|
|
diff --git a/gcc/ggc-common.c b/gcc/ggc-common.c
|
|
index 03fbe7d..3a5df8a 100644
|
|
--- a/gcc/ggc-common.c
|
|
+++ b/gcc/ggc-common.c
|
|
@@ -603,7 +603,9 @@ gt_pch_restore (FILE *f)
|
|
size_t i;
|
|
struct mmap_info mmi;
|
|
int result;
|
|
-
|
|
+ long pch_tabs_off;
|
|
+ long pch_data_off;
|
|
+
|
|
/* Delete any deletable objects. This makes ggc_pch_read much
|
|
faster, as it can be sure that no GCable objects remain other
|
|
than the ones just read in. */
|
|
@@ -611,20 +613,24 @@ gt_pch_restore (FILE *f)
|
|
for (rti = *rt; rti->base != NULL; rti++)
|
|
memset (rti->base, 0, rti->stride);
|
|
|
|
- /* Read in all the scalar variables. */
|
|
+ /* We need to read tables after mapping, or fatal_error will
|
|
+ segfault when gt_pch_use_address returns -1. Skip them for now. */
|
|
+ pch_tabs_off = ftell(f);
|
|
+
|
|
+ /* Skip all the scalar variables. */
|
|
for (rt = gt_pch_scalar_rtab; *rt; rt++)
|
|
for (rti = *rt; rti->base != NULL; rti++)
|
|
- if (fread (rti->base, rti->stride, 1, f) != 1)
|
|
- fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+ if (fseek (f, rti->stride, SEEK_CUR) != 0)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
|
|
- /* Read in all the global pointers, in 6 easy loops. */
|
|
+ /* Skip all the global pointers. */
|
|
for (rt = gt_ggc_rtab; *rt; rt++)
|
|
for (rti = *rt; rti->base != NULL; rti++)
|
|
for (i = 0; i < rti->nelt; i++)
|
|
- if (fread ((char *)rti->base + rti->stride * i,
|
|
- sizeof (void *), 1, f) != 1)
|
|
- fatal_error (input_location, "can%'t read PCH file: %m");
|
|
-
|
|
+ if (fseek (f, sizeof (void *), SEEK_CUR) != 0)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+
|
|
+ /* mmi still has to be read now. */
|
|
if (fread (&mmi, sizeof (mmi), 1, f) != 1)
|
|
fatal_error (input_location, "can%'t read PCH file: %m");
|
|
|
|
@@ -635,12 +641,35 @@ gt_pch_restore (FILE *f)
|
|
if (result == 0)
|
|
{
|
|
if (fseek (f, mmi.offset, SEEK_SET) != 0
|
|
- || fread (mmi.preferred_base, mmi.size, 1, f) != 1)
|
|
- fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+ || fread (mmi.preferred_base, mmi.size, 1, f) != 1)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
}
|
|
else if (fseek (f, mmi.offset + mmi.size, SEEK_SET) != 0)
|
|
fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+
|
|
+ /* File mapping done, read tables now. */
|
|
+ pch_data_off = ftell(f);
|
|
+
|
|
+ if (fseek (f, pch_tabs_off, SEEK_SET) != 0)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
|
|
+ /* Read in all the scalar variables. */
|
|
+ for (rt = gt_pch_scalar_rtab; *rt; rt++)
|
|
+ for (rti = *rt; rti->base != NULL; rti++)
|
|
+ if (fread (rti->base, rti->stride, 1, f) != 1)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+
|
|
+ /* Read in all the global pointers, in 6 easy loops. */
|
|
+ for (rt = gt_ggc_rtab; *rt; rt++)
|
|
+ for (rti = *rt; rti->base != NULL; rti++)
|
|
+ for (i = 0; i < rti->nelt; i++)
|
|
+ if (fread ((char *)rti->base + rti->stride * i,
|
|
+ sizeof (void *), 1, f) != 1)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+
|
|
+ if (fseek (f, pch_data_off, SEEK_SET) != 0)
|
|
+ fatal_error (input_location, "can%'t read PCH file: %m");
|
|
+
|
|
ggc_pch_read (f, mmi.preferred_base);
|
|
|
|
gt_pch_restore_stringpool ();
|
|
--
|
|
2.8.1
|
|
|