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]

PR/15448: add a compiler timestamp to PCH files


While, this would be good, it isn't the fix to the problem you describe. The way to add better validation would be to add __TIME__ to the compiler and validate it across PCH usage. This way, if the compiler is ever rebuilt, we get a new timestamp, which then will kill all PCH files.

Unless I am misunderstanding you, we were speaking of the same solution.


Unluckily, getting the timestamp from the preprocessor is a sure recipe for a bootstrap comparison failure on the file where you put the timestamp. I even implemented it, having libcpp define an unsigned long __TIMESTAMP__ together with __DATE__ and __TIME__, but it fails bootstrap for that precise reason.

Thinking more about it, my patch would not have worked even in my case, because c-pch.c was not changed by my cvs update, and thus make would not have bootstrapped the compiler. So, the timestamp should be put into a file that is compiled to a different extension than .o, and the object file should be made dependent on every C file in a front-end; but, I wouldn't like adding more and more hacks to the GCC Makefile.

The executable path can be used on Linux to find the compiler timestamp (see the attached patch). A similar test is used in libjava, but I enhanced it by supporting the cache variable even in the cross-compilation case (Canadian in gcc's case), so that the test can be overridden.

Unlike Autoconf's AC_CHECK_FILES, an absolute path is expected and the leading / is accounted for when creating the name of the #define (so we have HAVE_PROC_SELF_EXE while Autoconf would yield HAVE__PROC_SELF_EXE).

To fix the problem you describe, the PCH building rules in libstdc++ should just always rebuild them. If they want to get crafty, they can check the timestamp on the compiler (cc1plus), and ensure that the PCH is rebuilt if the compiler is newer.

That's just a workaround (maybe a necessary one in GCC, where libstdc++-v3 also acts as a PCH testsuite). But it cannot be used outside GCC, even though the bug is present there for people who build their own GCC and are not developers. Non-bootstrapped, bootstrapped and profiledbootstrapped installations, for example, have the same version string but their PCH's are incompatible.


The attached patch was bootstrapped and regtested (C/C++ only) on i686-pc-linux-gnu, and I checked on powerpc-darwin that HAVE_PROC_SELF_EXE is not misdetected. Ok for mainline?

Paolo
2005-05-16  Paolo Bonzini  <bonzini@gnu.org>

	* aclocal.m4 (GCC_CHECK_FILE_CROSS): New.
	* configure.ac: Use it.
	* configure: Regenerate.
	* config.in: Regenerate.
	* c-pch.c (get_ident) [HAVE_PROC_SELF_EXE]: Add a fingerprint
	made from the compiler's size and modification time.

Index: configure.ac
===================================================================
RCS file: /cvs/gcc/gcc/gcc/configure.ac,v
retrieving revision 2.94
diff -u -p -r2.94 configure.ac
--- configure.ac	7 Feb 2005 23:10:54 -0000	2.94
+++ configure.ac	16 Feb 2005 10:58:09 -0000
@@ -878,6 +878,12 @@ AC_CHECK_HEADER(pthread.h, [have_pthread
 gcc_AC_C_CHAR_BIT
 AC_C_BIGENDIAN_CROSS
 
+# ------------------------------
+# Checks for other host features
+# ------------------------------
+
+GCC_CHECK_FILE_CROSS(/proc/self/exe, *-*-linux*)
+
 # --------
 # UNSORTED
 # --------
Index: aclocal.m4
===================================================================
RCS file: /cvs/gcc/gcc/gcc/aclocal.m4,v
retrieving revision 1.100
diff -u -p -r1.100 aclocal.m4
--- aclocal.m4	2 Dec 2004 11:04:01 -0000	1.100
+++ aclocal.m4	16 Feb 2005 10:58:17 -0000
@@ -657,3 +657,23 @@ AC_PREREQ([2.50])dnl
 # expand $ac_aux_dir to an absolute path
 am_aux_dir=`cd $ac_aux_dir && pwd`
 ])
+
+AC_DEFUN([GCC_CHECK_FILE_CROSS], [dnl
+m4_bmatch([$1], [^/.*], ,
+  [m4_fatal([GCC_CHECK_FILE_CROSS expects an absolute pathname])])
+AS_VAR_PUSHDEF([ac_File], [ac_cv_file_$1])dnl
+AC_CACHE_CHECK([for $1], ac_File,
+[if test "$cross_compiling" = yes; then
+  case $host in
+  $2) AS_VAR_SET(ac_File, yes) ;;
+  *) AS_VAR_SET(ac_File, no) ;;
+  esac
+elif test -r "$1"; then
+  AS_VAR_SET(ac_File, yes)
+else
+  AS_VAR_SET(ac_File, no) 
+fi])
+AS_IF([test AS_VAR_GET(ac_File) = yes],
+      [AC_DEFINE(HAVE[]AS_TR_CPP([$1]), 1, [Define if you have $1])])
+AS_VAR_POPDEF([ac_File])dnl
+])
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	16 Feb 2005 10:58:20 -0000
@@ -104,10 +104,23 @@ get_ident (void)
   static char result[IDENT_LENGTH];
   static const char template[IDENT_LENGTH] = "gpch.012";
   static const char c_language_chars[] = "Co+O";
+#ifdef HAVE_PROC_SELF_EXE
+  struct stat s;
+#endif
   
   memcpy (result, template, IDENT_LENGTH);
   result[4] = c_language_chars[c_language];
 
+#ifdef HAVE_PROC_SELF_EXE
+  if (stat ("/proc/self/exe", &s) != -1)
+    {
+      int fingerprint = (int) s.st_size ^ (int) (8087 * s.st_mtime);
+      result[5] = (fingerprint & 255);
+      result[6] = (fingerprint & 0xFF00) >> 8;
+      result[7] = (fingerprint & 0xFF0000) >> 16;
+    }
+#endif
+
   return result;
 }
 

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