This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PR/15448: add a compiler timestamp to PCH files (take 3)
If there is a way to do it at c_common_valid_pch time, that would be best.
Like the attached patch?
Bootstrapped C/C++, ran the PCH tests, other tests in progress. Ok for
mainline?
Paolo
2005-02-18 Paolo Bonzini <bonzini@gnu.org>
* ggc.h (gt_save_validity_data, gt_check_validity): New.
* ggc-common.c (read_pch_globals, write_rti_validity_data,
check_rti_validity, gt_save_validity_data, gt_check_validity): New.
(gt_pch_restore): Use read_pch_globals.
* c-pch.c (pch_init): Use gt_save_validity_data.
(c_common_valid_pch): Use gt_check_validity.
Index: c-pch.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-pch.c,v
retrieving revision 1.30
diff -u -p -r1.30 c-pch.c
--- c-pch.c 9 Nov 2004 10:12:15 -0000 1.30
+++ c-pch.c 18 Feb 2005 13:37:08 -0000
@@ -163,6 +163,8 @@ pch_init (void)
|| strcmp (asm_file_name, "-") == 0)
fatal_error ("%qs is not a valid output file", asm_file_name);
+ gt_pch_save_validity_data (f);
+
asm_file_startpos = ftell (asm_out_file);
/* Let the debugging format deal with the PCHness. */
@@ -373,6 +375,15 @@ c_common_valid_pch (cpp_reader *pfile, c
}
}
+ if (!gt_pch_check_validity (fd))
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "data layout mismatch: have you rebuilt the compiler "
+ "after building the PCH?");
+ return 2;
+ }
+
/* Check the preprocessor macros are the same as when the PCH was
generated. */
Index: ggc.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc.h,v
retrieving revision 1.69
diff -u -p -r1.69 ggc.h
--- ggc.h 2 Sep 2004 18:32:49 -0000 1.69
+++ ggc.h 18 Feb 2005 13:37:12 -0000
@@ -283,8 +283,15 @@ extern size_t ggc_get_size (const void *
/* Write out all GCed objects to F. */
extern void gt_pch_save (FILE *f);
+/* Write out the addresses of GCed objects to F. */
+extern void gt_pch_save_validity_data (FILE *f);
+
/* Read objects previously saved with gt_pch_save from F. */
extern void gt_pch_restore (FILE *f);
+
+/* Read in the addresses of GCed objects from F, and check that they match. */
+extern bool gt_pch_check_validity (int fd);
+
/* Statistics. */
Index: ggc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ggc-common.c,v
retrieving revision 1.91
diff -u -p -r1.91 ggc-common.c
--- ggc-common.c 12 Sep 2004 20:14:23 -0000 1.91
+++ ggc-common.c 18 Feb 2005 13:37:21 -0000
@@ -78,6 +78,11 @@ static int compare_ptr_data (const void
static void relocate_ptrs (void *, void *);
static void write_pch_globals (const struct ggc_root_tab * const *tab,
struct traversal_state *state);
+static void read_pch_globals (const struct ggc_root_tab *const *tab,
+ FILE *f);
+static void write_rti_validity_data (const struct ggc_root_tab *const *tab,
+ FILE *f);
+static bool check_rti_validity (const struct ggc_root_tab *const *tab, int fd);
static double ggc_rlimit_bound (double);
/* Maintain global roots that are preserved during GC. */
@@ -392,8 +397,7 @@ write_pch_globals (const struct ggc_root
struct ptr_data *new_ptr;
if (ptr == NULL || ptr == (void *)1)
{
- if (fwrite (&ptr, sizeof (void *), 1, state->f)
- != 1)
+ if (fwrite (&ptr, sizeof (void *), 1, state->f) != 1)
fatal_error ("can't write PCH file: %m");
}
else
@@ -525,6 +529,22 @@ gt_pch_save (FILE *f)
htab_delete (saving_htab);
}
+/* Read in the global pointers, in 3 easy loops. */
+void
+read_pch_globals (const struct ggc_root_tab *const *tab, FILE *f)
+{
+ const struct ggc_root_tab *const *rt;
+ const struct ggc_root_tab *rti;
+ size_t i;
+
+ for (rt = tab; *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 ("can't read PCH file: %m");
+}
+
/* Read the state of the compiler back in from F. */
void
@@ -532,7 +552,6 @@ gt_pch_restore (FILE *f)
{
const struct ggc_root_tab *const *rt;
const struct ggc_root_tab *rti;
- size_t i;
struct mmap_info mmi;
int result;
@@ -549,20 +568,8 @@ gt_pch_restore (FILE *f)
if (fread (rti->base, rti->stride, 1, f) != 1)
fatal_error ("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 ("can't read PCH file: %m");
-
- for (rt = gt_pch_cache_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 ("can't read PCH file: %m");
+ read_pch_globals (gt_ggc_rtab, f);
+ read_pch_globals (gt_pch_cache_rtab, f);
if (fread (&mmi, sizeof (mmi), 1, f) != 1)
fatal_error ("can't read PCH file: %m");
@@ -584,6 +591,54 @@ gt_pch_restore (FILE *f)
gt_pch_restore_stringpool ();
}
+
+static inline void
+write_rti_validity_data (const struct ggc_root_tab *const *tab, FILE *f)
+{
+ const struct ggc_root_tab *const *rt;
+ const struct ggc_root_tab *rti;
+
+ /* Write out all the scalar variables. */
+ for (rt = tab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ if (fwrite (&rti->base, sizeof (void *), 1, f) != 1)
+ fatal_error ("can't write PCH file: %m");
+}
+
+static inline bool
+check_rti_validity (const struct ggc_root_tab *const *tab, int fd)
+{
+ const struct ggc_root_tab *const *rt;
+ const struct ggc_root_tab *rti;
+
+ for (rt = tab; *rt; rt++)
+ for (rti = *rt; rti->base != NULL; rti++)
+ {
+ void *pch_rti_base;
+ if (read (fd, &pch_rti_base, sizeof (void *)) != sizeof (void *))
+ fatal_error ("can't read PCH file: %m");
+ if (pch_rti_base != rti->base)
+ return false;
+ }
+
+ return true;
+}
+
+void
+gt_pch_save_validity_data (FILE *f)
+{
+ write_rti_validity_data (gt_pch_scalar_rtab, f);
+ write_rti_validity_data (gt_ggc_rtab, f);
+ write_rti_validity_data (gt_pch_cache_rtab, f);
+}
+
+bool
+gt_pch_check_validity (int fd)
+{
+ return check_rti_validity (gt_pch_scalar_rtab, fd)
+ && check_rti_validity (gt_ggc_rtab, fd)
+ && check_rti_validity (gt_pch_cache_rtab, fd);
+}
/* Default version of HOST_HOOKS_GT_PCH_GET_ADDRESS when mmap is not present.
Select no address whatsoever, and let gt_pch_save choose what it will with