This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]