+ if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created by a different GCC executable", name);
+ return 2;
+ }
+
+ /* At this point, we know it's a PCH file created by this
+ executable, 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);
+
+ /* 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
+ built for some kind of debug info but now none is in use. */
+ if (v.debug_info_type != write_symbols
+ && write_symbols != NO_DEBUG)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: created with -g%s, but used with -g%s", name,
+ debug_type_names[v.debug_info_type],
+ debug_type_names[write_symbols]);
+ return 2;
+ }
+
+ /* Check flags that must match exactly. */
+ {
+ size_t i;
+ for (i = 0; i < MATCH_SIZE; i++)
+ if (*pch_matching[i].flag_var != v.match[i])
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: settings for %s do not match", name,
+ pch_matching[i].flag_name);
+ return 2;
+ }
+ }
+
+ /* If the text segment was not loaded at the same address as it was
+ when the PCH file was created, function pointers loaded from the
+ PCH will not be valid. We could in theory remap all the function
+ pointers, but no support for that exists at present.
+ Since we have the same executable, it should only be necessary to
+ check one function. */
+ if (v.pch_init != &pch_init)
+ {
+ if (cpp_get_options (pfile)->warn_invalid_pch)
+ cpp_error (pfile, CPP_DL_WARNING,
+ "%s: had text segment at different address", name);
+ 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, CPP_DL_WARNING, "%s: %s", name, msg);
+ return 2;
+ }
+ }