aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-pch.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-pch.c')
-rw-r--r--gcc/c-pch.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/gcc/c-pch.c b/gcc/c-pch.c
index f7830b2..2a29075 100644
--- a/gcc/c-pch.c
+++ b/gcc/c-pch.c
@@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA. */
#include "ggc.h"
#include "langhooks.h"
#include "hosthooks.h"
+#include "target.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
@@ -40,7 +41,10 @@ Boston, MA 02111-1307, USA. */
'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(). */
+ the version number in get_ident().
+
+ There are a bunch of fields named *_length; those are lengths of data that
+ follows this structure in the same order as the fields in the structure. */
struct c_pch_validity
{
@@ -49,6 +53,7 @@ struct c_pch_validity
unsigned char version_length;
unsigned char debug_info_type;
void (*pch_init) (void);
+ size_t target_data_length;
};
struct c_pch_header
@@ -96,6 +101,7 @@ pch_init (void)
{
FILE *f;
struct c_pch_validity v;
+ void *target_validity;
if (! pch_file)
return;
@@ -112,14 +118,16 @@ pch_init (void)
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;
v.pch_init = &pch_init;
+ target_validity = targetm.get_pch_validity (&v.target_data_length);
+
if (fwrite (get_ident(), IDENT_LENGTH, 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)
+ || fwrite (version_string, v.version_length, 1, f) != 1
+ || fwrite (target_validity, v.target_data_length, 1, f) != 1)
fatal_error ("can't write to %s: %m", pch_file);
/* We need to be able to re-read the output. */
@@ -184,8 +192,10 @@ c_common_write_pch (void)
fclose (pch_outfile);
}
-/* Check the PCH file called NAME, open on FD, to see if it can be used
- in this compilation. */
+/* Check the PCH file called NAME, open on FD, to see if it can be
+ used in this compilation. Return 1 if valid, 0 if the file can't
+ be used now but might be if it's seen later in the compilation, and
+ 2 if this file could never be used in the compilation. */
int
c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
@@ -299,6 +309,24 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
return 2;
}
+ /* Check the target-specific validity data. */
+ {
+ void *this_file_data = xmalloc (v.target_data_length);
+ const char *msg;
+
+ if ((size_t) read (fd, this_file_data, v.target_data_length)
+ != v.target_data_length)
+ fatal_error ("can't read %s: %m", name);
+ msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
+ free (this_file_data);
+ if (msg != NULL)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, DL_WARNING, "%s: %s", name, msg);
+ return 2;
+ }
+ }
+
/* Check the preprocessor macros are the same as when the PCH was
generated. */