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