diff options
Diffstat (limited to 'PATCHES/0010-Fix-using-large-PCH.patch')
-rw-r--r-- | PATCHES/0010-Fix-using-large-PCH.patch | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/PATCHES/0010-Fix-using-large-PCH.patch b/PATCHES/0010-Fix-using-large-PCH.patch new file mode 100644 index 0000000..af8ebec --- /dev/null +++ b/PATCHES/0010-Fix-using-large-PCH.patch @@ -0,0 +1,154 @@ +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 + |