Better initial PCH validity checking

Syd Polk spolk@apple.com
Tue Oct 21 23:35:00 GMT 2003


On Oct 21, 2003, at 4:27 PM, Geoffrey Keating wrote:

>
> This patch improves the PCH validity checking.  It puts in an initial
> check that the host, target, and GCC version number are consistent.
> It's a preliminary step towards fixing some of the other PCH validity
> checking issues (like -fpic on x86), plus the error messages are nicer
> than before.
>
> Some notes:
> - I didn't check the build system.  Maybe later, if anyone finds it's
>   a problem.
> - I believe that at least the first few bytes of the structure are the
>   same on every system on which GCC is hosted; if not, we should move
>   to an array of unsigned char.
> - The string that's checked is the canonical host or target name.
> - Really, the thing that should be checked is something like the
>   checksum of the actual cc1 or cc1plus binary.  This should be good
>   enough for the moment, though.

The problem with this approach is things like prebinding which touch 
the binaries. The check sum will have to ignore those sections that 
prebinding touches.

>
> Bootstrapped & dejagnu tested on powerpc-darwin.  I also checked
> proper functioning in a cross-compiler built to x86-darwin and if the
> version string is changed.  I haven't checked the 'build' part of the
> checking.
>
> -- 
> - Geoffrey Keating <geoffk@apple.com>
>
> ===File ~/patches/gcc-pchvalidtarget.patch==================
> 2003-10-21  Geoffrey Keating  <geoffk@apple.com>
>
> 	* c-pch.c: Add comments in various places.
> 	(struct c_pch_validity): Add the lengths of various strings.
> 	(host_machine): New static.
> 	(target_machine): New static.
> 	(get_ident): Bump version number.
> 	(pch_init): Write out version, host, target validity data.
> 	(c_common_valid_pch): Check version, host, target.
> 	* Makefile.in (c-pch.o): Add version.h; define HOST_MACHINE and
> 	TARGET_MACHINE.
>
> Index: Makefile.in
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
> retrieving revision 1.1175
> diff -u -p -u -p -r1.1175 Makefile.in
> --- Makefile.in	19 Oct 2003 21:37:30 -0000	1.1175
> +++ Makefile.in	21 Oct 2003 23:14:55 -0000
> @@ -1360,7 +1360,10 @@ c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM
>
>  c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) 
> $(TREE_H) \
>  	$(C_COMMON_H) output.h toplev.h c-pragma.h $(GGC_H) debug.h \
> -	langhooks.h flags.h hosthooks.h
> +	langhooks.h flags.h hosthooks.h version.h
> +	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
> +	  -DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \
> +	  $< $(OUTPUT_OPTION)
>
>  # Language-independent files.
>
> Index: c-pch.c
> ===================================================================
> RCS file: /cvs/gcc/gcc/gcc/c-pch.c,v
> retrieving revision 1.14
> diff -u -p -u -p -r1.14 c-pch.c
> --- c-pch.c	29 Jul 2003 23:36:46 -0000	1.14
> +++ c-pch.c	21 Oct 2003 23:14:55 -0000
> @@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
>  #include "config.h"
>  #include "system.h"
>  #include "coretypes.h"
> +#include "version.h"
>  #include "cpplib.h"
>  #include "tree.h"
>  #include "flags.h"
> @@ -33,8 +34,19 @@ Boston, MA 02111-1307, USA.  */
>  #include "langhooks.h"
>  #include "hosthooks.h"
>
> +/* This structure is read very early when validating the PCH, and
> +   might be read for a PCH which is for a completely different 
> compiler
> +   for a different operating system.  Thus, it should really only 
> contain
> +   'unsigned char' entries, at least in the initial entries.
> +
> +   If you add or change entries before version_length, you should 
> increase
> +   the version number in get_ident().  */
> +
>  struct c_pch_validity
>  {
> +  unsigned char host_machine_length;
> +  unsigned char target_machine_length;
> +  unsigned char version_length;
>    unsigned char debug_info_type;
>  };
>
> @@ -45,10 +57,16 @@ struct c_pch_header
>
>  #define IDENT_LENGTH 8
>
> +/* The file we'll be writing the PCH to.  */
>  static FILE *pch_outfile;
>
> +/* The position in the assembler output file when pch_init was 
> called.  */
>  static long asm_file_startpos;
>
> +/* The host and target machines.  */
> +static const char host_machine[] = HOST_MACHINE;
> +static const char target_machine[] = TARGET_MACHINE;
> +
>  static const char *get_ident (void);
>
>  /* Compute an appropriate 8-byte magic number for the PCH file, so 
> that
> @@ -60,7 +78,7 @@ static const char *
>  get_ident(void)
>  {
>    static char result[IDENT_LENGTH];
> -  static const char template[IDENT_LENGTH] = "gpch.011";
> +  static const char template[IDENT_LENGTH] = "gpch.012";
>    static const char c_language_chars[] = "Co+O";
>
>    memcpy (result, template, IDENT_LENGTH);
> @@ -86,9 +104,20 @@ pch_init (void)
>      fatal_error ("can't open %s: %m", pch_file);
>    pch_outfile = f;
>
> +  if (strlen (host_machine) > 255 || strlen (target_machine) > 255
> +      || strlen (version_string) > 255)
> +    abort ();
> +
> +  v.host_machine_length = strlen (host_machine);
> +  v.target_machine_length = strlen (target_machine);
> +  v.version_length = strlen (version_string);
> +
>    v.debug_info_type = write_symbols;
>    if (fwrite (get_ident(), IDENT_LENGTH, 1, f) != 1
> -      || fwrite (&v, sizeof (v), 1, f) != 1)
> +      || fwrite (&v, sizeof (v), 1, f) != 1
> +      || fwrite (host_machine, v.host_machine_length, 1, f) != 1
> +      || fwrite (target_machine, v.target_machine_length, 1, f) != 1
> +      || fwrite (version_string, v.version_length, 1, f) != 1)
>      fatal_error ("can't write to %s: %m", pch_file);
>
>    /* We need to be able to re-read the output.  */
> @@ -162,6 +191,8 @@ c_common_valid_pch (cpp_reader *pfile, c
>    int sizeread;
>    int result;
>    char ident[IDENT_LENGTH];
> +  char short_strings[256 * 3];
> +  int strings_length;
>    const char *pch_ident;
>    struct c_pch_validity v;
>
> @@ -195,8 +226,50 @@ c_common_valid_pch (cpp_reader *pfile, c
>        return 2;
>      }
>
> +  /* At this point, we know it's a PCH file, so it ought to be long 
> enough
> +     that we can read a c_pch_validity structure.  */
>    if (read (fd, &v, sizeof (v)) != sizeof (v))
>      fatal_error ("can't read %s: %m", name);
> +
> +  strings_length = (v.host_machine_length + v.target_machine_length
> +		    + v.version_length);
> +  if (read (fd, short_strings, strings_length) != strings_length)
> +    fatal_error ("can't read %s: %m", name);
> +  if (v.host_machine_length != strlen (host_machine)
> +      || memcmp (host_machine, short_strings, strlen (host_machine)) 
> != 0)
> +    {
> +      if (cpp_get_options (pfile)->warn_invalid_pch)
> +	cpp_error (pfile, DL_WARNING,
> +		   "%s: created on host `%.*s', but used on host `%s'", name,
> +		   v.host_machine_length, short_strings, host_machine);
> +      return 2;
> +    }
> +  if (v.target_machine_length != strlen (target_machine)
> +      || memcmp (target_machine, short_strings + 
> v.host_machine_length,
> +		 strlen (target_machine)) != 0)
> +    {
> +      if (cpp_get_options (pfile)->warn_invalid_pch)
> +	cpp_error (pfile, DL_WARNING,
> +		   "%s: created for target `%.*s', but used for target `%s'",
> +		   name, v.target_machine_length,
> +		   short_strings + v.host_machine_length, target_machine);
> +      return 2;
> +    }
> +  if (v.version_length != strlen (version_string)
> +      || memcmp (version_string,
> +		 (short_strings + v.host_machine_length
> +		  + v.target_machine_length),
> +		 v.version_length) != 0)
> +    {
> +      if (cpp_get_options (pfile)->warn_invalid_pch)
> +	cpp_error (pfile, DL_WARNING,
> +		   "%s: created by version `%.*s', but this is version `%s'",
> +		   name, v.version_length,
> +		   (short_strings + v.host_machine_length
> +		    + v.target_machine_length),
> +		   version_string);
> +      return 2;
> +    }
>
>    /* The allowable debug info combinations are that either the PCH 
> file
>       was built with the same as is being used now, or the PCH file was
> ============================================================
>
Syd Polk
Apple Computer
Technology EPM, Mac OS X Development Tools
+1 408 974-0577

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: text/enriched
Size: 8016 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20031021/03c3b8a6/attachment.bin>


More information about the Gcc-patches mailing list