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: Better initial PCH validity checking



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


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