| 1 | 707 | jeremybenn | /* Precompiled header implementation for the C languages.
 | 
      
         | 2 |  |  |    Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
 | 
      
         | 3 |  |  |    Free Software Foundation, Inc.
 | 
      
         | 4 |  |  |  
 | 
      
         | 5 |  |  | This file is part of GCC.
 | 
      
         | 6 |  |  |  
 | 
      
         | 7 |  |  | GCC is free software; you can redistribute it and/or modify
 | 
      
         | 8 |  |  | it under the terms of the GNU General Public License as published by
 | 
      
         | 9 |  |  | the Free Software Foundation; either version 3, or (at your option)
 | 
      
         | 10 |  |  | any later version.
 | 
      
         | 11 |  |  |  
 | 
      
         | 12 |  |  | GCC is distributed in the hope that it will be useful,
 | 
      
         | 13 |  |  | but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
      
         | 14 |  |  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
      
         | 15 |  |  | GNU General Public License for more details.
 | 
      
         | 16 |  |  |  
 | 
      
         | 17 |  |  | You should have received a copy of the GNU General Public License
 | 
      
         | 18 |  |  | along with GCC; see the file COPYING3.  If not see
 | 
      
         | 19 |  |  | <http://www.gnu.org/licenses/>.  */
 | 
      
         | 20 |  |  |  
 | 
      
         | 21 |  |  | #include "config.h"
 | 
      
         | 22 |  |  | #include "system.h"
 | 
      
         | 23 |  |  | #include "coretypes.h"
 | 
      
         | 24 |  |  | #include "version.h"
 | 
      
         | 25 |  |  | #include "cpplib.h"
 | 
      
         | 26 |  |  | #include "tree.h"
 | 
      
         | 27 |  |  | #include "flags.h"
 | 
      
         | 28 |  |  | #include "c-common.h"
 | 
      
         | 29 |  |  | #include "output.h"
 | 
      
         | 30 |  |  | #include "debug.h"
 | 
      
         | 31 |  |  | #include "c-pragma.h"
 | 
      
         | 32 |  |  | #include "ggc.h"
 | 
      
         | 33 |  |  | #include "langhooks.h"
 | 
      
         | 34 |  |  | #include "hosthooks.h"
 | 
      
         | 35 |  |  | #include "target.h"
 | 
      
         | 36 |  |  | #include "opts.h"
 | 
      
         | 37 |  |  | #include "timevar.h"
 | 
      
         | 38 |  |  |  
 | 
      
         | 39 |  |  | /* This is a list of flag variables that must match exactly, and their
 | 
      
         | 40 |  |  |    names for the error message.  The possible values for *flag_var must
 | 
      
         | 41 |  |  |    fit in a 'signed char'.  */
 | 
      
         | 42 |  |  |  
 | 
      
         | 43 |  |  | static const struct c_pch_matching
 | 
      
         | 44 |  |  | {
 | 
      
         | 45 |  |  |   int *flag_var;
 | 
      
         | 46 |  |  |   const char *flag_name;
 | 
      
         | 47 |  |  | } pch_matching[] = {
 | 
      
         | 48 |  |  |   { &flag_exceptions, "-fexceptions" },
 | 
      
         | 49 |  |  | };
 | 
      
         | 50 |  |  |  
 | 
      
         | 51 |  |  | enum {
 | 
      
         | 52 |  |  |   MATCH_SIZE = ARRAY_SIZE (pch_matching)
 | 
      
         | 53 |  |  | };
 | 
      
         | 54 |  |  |  
 | 
      
         | 55 |  |  | /* The value of the checksum in the dummy compiler that is actually
 | 
      
         | 56 |  |  |    checksummed.  That compiler should never be run.  */
 | 
      
         | 57 |  |  | static const char no_checksum[16] = { 0 };
 | 
      
         | 58 |  |  |  
 | 
      
         | 59 |  |  | /* Information about flags and suchlike that affect PCH validity.
 | 
      
         | 60 |  |  |  
 | 
      
         | 61 |  |  |    Before this structure is read, both an initial 8-character identification
 | 
      
         | 62 |  |  |    string, and a 16-byte checksum, have been read and validated.  */
 | 
      
         | 63 |  |  |  
 | 
      
         | 64 |  |  | struct c_pch_validity
 | 
      
         | 65 |  |  | {
 | 
      
         | 66 |  |  |   unsigned char debug_info_type;
 | 
      
         | 67 |  |  |   signed char match[MATCH_SIZE];
 | 
      
         | 68 |  |  |   void (*pch_init) (void);
 | 
      
         | 69 |  |  |   size_t target_data_length;
 | 
      
         | 70 |  |  | };
 | 
      
         | 71 |  |  |  
 | 
      
         | 72 |  |  | struct c_pch_header
 | 
      
         | 73 |  |  | {
 | 
      
         | 74 |  |  |   unsigned long asm_size;
 | 
      
         | 75 |  |  | };
 | 
      
         | 76 |  |  |  
 | 
      
         | 77 |  |  | #define IDENT_LENGTH 8
 | 
      
         | 78 |  |  |  
 | 
      
         | 79 |  |  | /* The file we'll be writing the PCH to.  */
 | 
      
         | 80 |  |  | static FILE *pch_outfile;
 | 
      
         | 81 |  |  |  
 | 
      
         | 82 |  |  | /* The position in the assembler output file when pch_init was called.  */
 | 
      
         | 83 |  |  | static long asm_file_startpos;
 | 
      
         | 84 |  |  |  
 | 
      
         | 85 |  |  | static const char *get_ident (void);
 | 
      
         | 86 |  |  |  
 | 
      
         | 87 |  |  | /* Compute an appropriate 8-byte magic number for the PCH file, so that
 | 
      
         | 88 |  |  |    utilities like file(1) can identify it, and so that GCC can quickly
 | 
      
         | 89 |  |  |    ignore non-PCH files and PCH files that are of a completely different
 | 
      
         | 90 |  |  |    format.  */
 | 
      
         | 91 |  |  |  
 | 
      
         | 92 |  |  | static const char *
 | 
      
         | 93 |  |  | get_ident (void)
 | 
      
         | 94 |  |  | {
 | 
      
         | 95 |  |  |   static char result[IDENT_LENGTH];
 | 
      
         | 96 |  |  |   static const char templ[] = "gpch.013";
 | 
      
         | 97 |  |  |   static const char c_language_chars[] = "Co+O";
 | 
      
         | 98 |  |  |  
 | 
      
         | 99 |  |  |   memcpy (result, templ, IDENT_LENGTH);
 | 
      
         | 100 |  |  |   result[4] = c_language_chars[c_language];
 | 
      
         | 101 |  |  |  
 | 
      
         | 102 |  |  |   return result;
 | 
      
         | 103 |  |  | }
 | 
      
         | 104 |  |  |  
 | 
      
         | 105 |  |  | /* Prepare to write a PCH file, if one is being written.  This is
 | 
      
         | 106 |  |  |    called at the start of compilation.
 | 
      
         | 107 |  |  |  
 | 
      
         | 108 |  |  |    Also, print out the executable checksum if -fverbose-asm is in effect.  */
 | 
      
         | 109 |  |  |  
 | 
      
         | 110 |  |  | void
 | 
      
         | 111 |  |  | pch_init (void)
 | 
      
         | 112 |  |  | {
 | 
      
         | 113 |  |  |   FILE *f;
 | 
      
         | 114 |  |  |   struct c_pch_validity v;
 | 
      
         | 115 |  |  |   void *target_validity;
 | 
      
         | 116 |  |  |   static const char partial_pch[] = "gpcWrite";
 | 
      
         | 117 |  |  |  
 | 
      
         | 118 |  |  | #ifdef ASM_COMMENT_START
 | 
      
         | 119 |  |  |   if (flag_verbose_asm)
 | 
      
         | 120 |  |  |     {
 | 
      
         | 121 |  |  |       fprintf (asm_out_file, "%s ", ASM_COMMENT_START);
 | 
      
         | 122 |  |  |       c_common_print_pch_checksum (asm_out_file);
 | 
      
         | 123 |  |  |       fputc ('\n', asm_out_file);
 | 
      
         | 124 |  |  |     }
 | 
      
         | 125 |  |  | #endif
 | 
      
         | 126 |  |  |  
 | 
      
         | 127 |  |  |   if (!pch_file)
 | 
      
         | 128 |  |  |     return;
 | 
      
         | 129 |  |  |  
 | 
      
         | 130 |  |  |   f = fopen (pch_file, "w+b");
 | 
      
         | 131 |  |  |   if (f == NULL)
 | 
      
         | 132 |  |  |     fatal_error ("can%'t create precompiled header %s: %m", pch_file);
 | 
      
         | 133 |  |  |   pch_outfile = f;
 | 
      
         | 134 |  |  |  
 | 
      
         | 135 |  |  |   gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
 | 
      
         | 136 |  |  |  
 | 
      
         | 137 |  |  |   memset (&v, '\0', sizeof (v));
 | 
      
         | 138 |  |  |   v.debug_info_type = write_symbols;
 | 
      
         | 139 |  |  |   {
 | 
      
         | 140 |  |  |     size_t i;
 | 
      
         | 141 |  |  |     for (i = 0; i < MATCH_SIZE; i++)
 | 
      
         | 142 |  |  |       {
 | 
      
         | 143 |  |  |         v.match[i] = *pch_matching[i].flag_var;
 | 
      
         | 144 |  |  |         gcc_assert (v.match[i] == *pch_matching[i].flag_var);
 | 
      
         | 145 |  |  |       }
 | 
      
         | 146 |  |  |   }
 | 
      
         | 147 |  |  |   v.pch_init = &pch_init;
 | 
      
         | 148 |  |  |   target_validity = targetm.get_pch_validity (&v.target_data_length);
 | 
      
         | 149 |  |  |  
 | 
      
         | 150 |  |  |   if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
 | 
      
         | 151 |  |  |       || fwrite (executable_checksum, 16, 1, f) != 1
 | 
      
         | 152 |  |  |       || fwrite (&v, sizeof (v), 1, f) != 1
 | 
      
         | 153 |  |  |       || fwrite (target_validity, v.target_data_length, 1, f) != 1)
 | 
      
         | 154 |  |  |     fatal_error ("can%'t write to %s: %m", pch_file);
 | 
      
         | 155 |  |  |  
 | 
      
         | 156 |  |  |   /* We need to be able to re-read the output.  */
 | 
      
         | 157 |  |  |   /* The driver always provides a valid -o option.  */
 | 
      
         | 158 |  |  |   if (asm_file_name == NULL
 | 
      
         | 159 |  |  |       || strcmp (asm_file_name, "-") == 0)
 | 
      
         | 160 |  |  |     fatal_error ("%qs is not a valid output file", asm_file_name);
 | 
      
         | 161 |  |  |  
 | 
      
         | 162 |  |  |   asm_file_startpos = ftell (asm_out_file);
 | 
      
         | 163 |  |  |  
 | 
      
         | 164 |  |  |   /* Let the debugging format deal with the PCHness.  */
 | 
      
         | 165 |  |  |   (*debug_hooks->handle_pch) (0);
 | 
      
         | 166 |  |  |  
 | 
      
         | 167 |  |  |   cpp_save_state (parse_in, f);
 | 
      
         | 168 |  |  | }
 | 
      
         | 169 |  |  |  
 | 
      
         | 170 |  |  | /* Write the PCH file.  This is called at the end of a compilation which
 | 
      
         | 171 |  |  |    will produce a PCH file.  */
 | 
      
         | 172 |  |  |  
 | 
      
         | 173 |  |  | void
 | 
      
         | 174 |  |  | c_common_write_pch (void)
 | 
      
         | 175 |  |  | {
 | 
      
         | 176 |  |  |   char *buf;
 | 
      
         | 177 |  |  |   long asm_file_end;
 | 
      
         | 178 |  |  |   long written;
 | 
      
         | 179 |  |  |   struct c_pch_header h;
 | 
      
         | 180 |  |  |  
 | 
      
         | 181 |  |  |   timevar_push (TV_PCH_SAVE);
 | 
      
         | 182 |  |  |  
 | 
      
         | 183 |  |  |   targetm.prepare_pch_save ();
 | 
      
         | 184 |  |  |  
 | 
      
         | 185 |  |  |   (*debug_hooks->handle_pch) (1);
 | 
      
         | 186 |  |  |  
 | 
      
         | 187 |  |  |   cpp_write_pch_deps (parse_in, pch_outfile);
 | 
      
         | 188 |  |  |  
 | 
      
         | 189 |  |  |   asm_file_end = ftell (asm_out_file);
 | 
      
         | 190 |  |  |   h.asm_size = asm_file_end - asm_file_startpos;
 | 
      
         | 191 |  |  |  
 | 
      
         | 192 |  |  |   if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
 | 
      
         | 193 |  |  |     fatal_error ("can%'t write %s: %m", pch_file);
 | 
      
         | 194 |  |  |  
 | 
      
         | 195 |  |  |   buf = XNEWVEC (char, 16384);
 | 
      
         | 196 |  |  |  
 | 
      
         | 197 |  |  |   if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
 | 
      
         | 198 |  |  |     fatal_error ("can%'t seek in %s: %m", asm_file_name);
 | 
      
         | 199 |  |  |  
 | 
      
         | 200 |  |  |   for (written = asm_file_startpos; written < asm_file_end; )
 | 
      
         | 201 |  |  |     {
 | 
      
         | 202 |  |  |       long size = asm_file_end - written;
 | 
      
         | 203 |  |  |       if (size > 16384)
 | 
      
         | 204 |  |  |         size = 16384;
 | 
      
         | 205 |  |  |       if (fread (buf, size, 1, asm_out_file) != 1)
 | 
      
         | 206 |  |  |         fatal_error ("can%'t read %s: %m", asm_file_name);
 | 
      
         | 207 |  |  |       if (fwrite (buf, size, 1, pch_outfile) != 1)
 | 
      
         | 208 |  |  |         fatal_error ("can%'t write %s: %m", pch_file);
 | 
      
         | 209 |  |  |       written += size;
 | 
      
         | 210 |  |  |     }
 | 
      
         | 211 |  |  |   free (buf);
 | 
      
         | 212 |  |  |   /* asm_out_file can be written afterwards, so fseek to clear
 | 
      
         | 213 |  |  |      _IOREAD flag.  */
 | 
      
         | 214 |  |  |   if (fseek (asm_out_file, 0, SEEK_END) != 0)
 | 
      
         | 215 |  |  |     fatal_error ("can%'t seek in %s: %m", asm_file_name);
 | 
      
         | 216 |  |  |  
 | 
      
         | 217 |  |  |   gt_pch_save (pch_outfile);
 | 
      
         | 218 |  |  |  
 | 
      
         | 219 |  |  |   timevar_push (TV_PCH_CPP_SAVE);
 | 
      
         | 220 |  |  |   cpp_write_pch_state (parse_in, pch_outfile);
 | 
      
         | 221 |  |  |   timevar_pop (TV_PCH_CPP_SAVE);
 | 
      
         | 222 |  |  |  
 | 
      
         | 223 |  |  |   if (fseek (pch_outfile, 0, SEEK_SET) != 0
 | 
      
         | 224 |  |  |       || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
 | 
      
         | 225 |  |  |     fatal_error ("can%'t write %s: %m", pch_file);
 | 
      
         | 226 |  |  |  
 | 
      
         | 227 |  |  |   fclose (pch_outfile);
 | 
      
         | 228 |  |  |  
 | 
      
         | 229 |  |  |   timevar_pop (TV_PCH_SAVE);
 | 
      
         | 230 |  |  | }
 | 
      
         | 231 |  |  |  
 | 
      
         | 232 |  |  | /* Check the PCH file called NAME, open on FD, to see if it can be
 | 
      
         | 233 |  |  |    used in this compilation.  Return 1 if valid, 0 if the file can't
 | 
      
         | 234 |  |  |    be used now but might be if it's seen later in the compilation, and
 | 
      
         | 235 |  |  |    2 if this file could never be used in the compilation.  */
 | 
      
         | 236 |  |  |  
 | 
      
         | 237 |  |  | int
 | 
      
         | 238 |  |  | c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
 | 
      
         | 239 |  |  | {
 | 
      
         | 240 |  |  |   int sizeread;
 | 
      
         | 241 |  |  |   int result;
 | 
      
         | 242 |  |  |   char ident[IDENT_LENGTH + 16];
 | 
      
         | 243 |  |  |   const char *pch_ident;
 | 
      
         | 244 |  |  |   struct c_pch_validity v;
 | 
      
         | 245 |  |  |  
 | 
      
         | 246 |  |  |   /* Perform a quick test of whether this is a valid
 | 
      
         | 247 |  |  |      precompiled header for the current language.  */
 | 
      
         | 248 |  |  |  
 | 
      
         | 249 |  |  |   gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
 | 
      
         | 250 |  |  |  
 | 
      
         | 251 |  |  |   sizeread = read (fd, ident, IDENT_LENGTH + 16);
 | 
      
         | 252 |  |  |   if (sizeread == -1)
 | 
      
         | 253 |  |  |     fatal_error ("can%'t read %s: %m", name);
 | 
      
         | 254 |  |  |   else if (sizeread != IDENT_LENGTH + 16)
 | 
      
         | 255 |  |  |     {
 | 
      
         | 256 |  |  |       if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 257 |  |  |         cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file",
 | 
      
         | 258 |  |  |                    name);
 | 
      
         | 259 |  |  |       return 2;
 | 
      
         | 260 |  |  |     }
 | 
      
         | 261 |  |  |  
 | 
      
         | 262 |  |  |   pch_ident = get_ident();
 | 
      
         | 263 |  |  |   if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
 | 
      
         | 264 |  |  |     {
 | 
      
         | 265 |  |  |       if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 266 |  |  |         {
 | 
      
         | 267 |  |  |           if (memcmp (ident, pch_ident, 5) == 0)
 | 
      
         | 268 |  |  |             /* It's a PCH, for the right language, but has the wrong version.
 | 
      
         | 269 |  |  |              */
 | 
      
         | 270 |  |  |             cpp_error (pfile, CPP_DL_WARNING,
 | 
      
         | 271 |  |  |                        "%s: not compatible with this GCC version", name);
 | 
      
         | 272 |  |  |           else if (memcmp (ident, pch_ident, 4) == 0)
 | 
      
         | 273 |  |  |             /* It's a PCH for the wrong language.  */
 | 
      
         | 274 |  |  |             cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
 | 
      
         | 275 |  |  |                        lang_hooks.name);
 | 
      
         | 276 |  |  |           else
 | 
      
         | 277 |  |  |             /* Not any kind of PCH.  */
 | 
      
         | 278 |  |  |             cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
 | 
      
         | 279 |  |  |         }
 | 
      
         | 280 |  |  |       return 2;
 | 
      
         | 281 |  |  |     }
 | 
      
         | 282 |  |  |   if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
 | 
      
         | 283 |  |  |     {
 | 
      
         | 284 |  |  |       if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 285 |  |  |         cpp_error (pfile, CPP_DL_WARNING,
 | 
      
         | 286 |  |  |                    "%s: created by a different GCC executable", name);
 | 
      
         | 287 |  |  |       return 2;
 | 
      
         | 288 |  |  |     }
 | 
      
         | 289 |  |  |  
 | 
      
         | 290 |  |  |   /* At this point, we know it's a PCH file created by this
 | 
      
         | 291 |  |  |      executable, so it ought to be long enough that we can read a
 | 
      
         | 292 |  |  |      c_pch_validity structure.  */
 | 
      
         | 293 |  |  |   if (read (fd, &v, sizeof (v)) != sizeof (v))
 | 
      
         | 294 |  |  |     fatal_error ("can%'t read %s: %m", name);
 | 
      
         | 295 |  |  |  
 | 
      
         | 296 |  |  |   /* The allowable debug info combinations are that either the PCH file
 | 
      
         | 297 |  |  |      was built with the same as is being used now, or the PCH file was
 | 
      
         | 298 |  |  |      built for some kind of debug info but now none is in use.  */
 | 
      
         | 299 |  |  |   if (v.debug_info_type != write_symbols
 | 
      
         | 300 |  |  |       && write_symbols != NO_DEBUG)
 | 
      
         | 301 |  |  |     {
 | 
      
         | 302 |  |  |       if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 303 |  |  |         cpp_error (pfile, CPP_DL_WARNING,
 | 
      
         | 304 |  |  |                    "%s: created with -g%s, but used with -g%s", name,
 | 
      
         | 305 |  |  |                    debug_type_names[v.debug_info_type],
 | 
      
         | 306 |  |  |                    debug_type_names[write_symbols]);
 | 
      
         | 307 |  |  |       return 2;
 | 
      
         | 308 |  |  |     }
 | 
      
         | 309 |  |  |  
 | 
      
         | 310 |  |  |   /* Check flags that must match exactly.  */
 | 
      
         | 311 |  |  |   {
 | 
      
         | 312 |  |  |     size_t i;
 | 
      
         | 313 |  |  |     for (i = 0; i < MATCH_SIZE; i++)
 | 
      
         | 314 |  |  |       if (*pch_matching[i].flag_var != v.match[i])
 | 
      
         | 315 |  |  |         {
 | 
      
         | 316 |  |  |           if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 317 |  |  |             cpp_error (pfile, CPP_DL_WARNING,
 | 
      
         | 318 |  |  |                        "%s: settings for %s do not match", name,
 | 
      
         | 319 |  |  |                        pch_matching[i].flag_name);
 | 
      
         | 320 |  |  |           return 2;
 | 
      
         | 321 |  |  |         }
 | 
      
         | 322 |  |  |   }
 | 
      
         | 323 |  |  |  
 | 
      
         | 324 |  |  |   /* If the text segment was not loaded at the same address as it was
 | 
      
         | 325 |  |  |      when the PCH file was created, function pointers loaded from the
 | 
      
         | 326 |  |  |      PCH will not be valid.  We could in theory remap all the function
 | 
      
         | 327 |  |  |      pointers, but no support for that exists at present.
 | 
      
         | 328 |  |  |      Since we have the same executable, it should only be necessary to
 | 
      
         | 329 |  |  |      check one function.  */
 | 
      
         | 330 |  |  |   if (v.pch_init != &pch_init)
 | 
      
         | 331 |  |  |     {
 | 
      
         | 332 |  |  |       if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 333 |  |  |         cpp_error (pfile, CPP_DL_WARNING,
 | 
      
         | 334 |  |  |                    "%s: had text segment at different address", name);
 | 
      
         | 335 |  |  |       return 2;
 | 
      
         | 336 |  |  |     }
 | 
      
         | 337 |  |  |  
 | 
      
         | 338 |  |  |   /* Check the target-specific validity data.  */
 | 
      
         | 339 |  |  |   {
 | 
      
         | 340 |  |  |     void *this_file_data = xmalloc (v.target_data_length);
 | 
      
         | 341 |  |  |     const char *msg;
 | 
      
         | 342 |  |  |  
 | 
      
         | 343 |  |  |     if ((size_t) read (fd, this_file_data, v.target_data_length)
 | 
      
         | 344 |  |  |         != v.target_data_length)
 | 
      
         | 345 |  |  |       fatal_error ("can%'t read %s: %m", name);
 | 
      
         | 346 |  |  |     msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
 | 
      
         | 347 |  |  |     free (this_file_data);
 | 
      
         | 348 |  |  |     if (msg != NULL)
 | 
      
         | 349 |  |  |       {
 | 
      
         | 350 |  |  |         if (cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 351 |  |  |           cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
 | 
      
         | 352 |  |  |         return 2;
 | 
      
         | 353 |  |  |       }
 | 
      
         | 354 |  |  |   }
 | 
      
         | 355 |  |  |  
 | 
      
         | 356 |  |  |   /* Check the preprocessor macros are the same as when the PCH was
 | 
      
         | 357 |  |  |      generated.  */
 | 
      
         | 358 |  |  |  
 | 
      
         | 359 |  |  |   result = cpp_valid_state (pfile, name, fd);
 | 
      
         | 360 |  |  |   if (result == -1)
 | 
      
         | 361 |  |  |     return 2;
 | 
      
         | 362 |  |  |   else
 | 
      
         | 363 |  |  |     return result == 0;
 | 
      
         | 364 |  |  | }
 | 
      
         | 365 |  |  |  
 | 
      
         | 366 |  |  | /* If non-NULL, this function is called after a precompile header file
 | 
      
         | 367 |  |  |    is loaded.  */
 | 
      
         | 368 |  |  | void (*lang_post_pch_load) (void);
 | 
      
         | 369 |  |  |  
 | 
      
         | 370 |  |  | /* Load in the PCH file NAME, open on FD.  It was originally searched for
 | 
      
         | 371 |  |  |    by ORIG_NAME.  */
 | 
      
         | 372 |  |  |  
 | 
      
         | 373 |  |  | void
 | 
      
         | 374 |  |  | c_common_read_pch (cpp_reader *pfile, const char *name,
 | 
      
         | 375 |  |  |                    int fd, const char *orig_name ATTRIBUTE_UNUSED)
 | 
      
         | 376 |  |  | {
 | 
      
         | 377 |  |  |   FILE *f;
 | 
      
         | 378 |  |  |   struct c_pch_header h;
 | 
      
         | 379 |  |  |   struct save_macro_data *smd;
 | 
      
         | 380 |  |  |   expanded_location saved_loc;
 | 
      
         | 381 |  |  |   bool saved_trace_includes;
 | 
      
         | 382 |  |  |  
 | 
      
         | 383 |  |  |   timevar_push (TV_PCH_RESTORE);
 | 
      
         | 384 |  |  |  
 | 
      
         | 385 |  |  |   f = fdopen (fd, "rb");
 | 
      
         | 386 |  |  |   if (f == NULL)
 | 
      
         | 387 |  |  |     {
 | 
      
         | 388 |  |  |       cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
 | 
      
         | 389 |  |  |       close (fd);
 | 
      
         | 390 |  |  |       goto end;
 | 
      
         | 391 |  |  |     }
 | 
      
         | 392 |  |  |  
 | 
      
         | 393 |  |  |   cpp_get_callbacks (parse_in)->valid_pch = NULL;
 | 
      
         | 394 |  |  |  
 | 
      
         | 395 |  |  |   if (fread (&h, sizeof (h), 1, f) != 1)
 | 
      
         | 396 |  |  |     {
 | 
      
         | 397 |  |  |       cpp_errno (pfile, CPP_DL_ERROR, "reading");
 | 
      
         | 398 |  |  |       fclose (f);
 | 
      
         | 399 |  |  |       goto end;
 | 
      
         | 400 |  |  |     }
 | 
      
         | 401 |  |  |  
 | 
      
         | 402 |  |  |   if (!flag_preprocess_only)
 | 
      
         | 403 |  |  |     {
 | 
      
         | 404 |  |  |       unsigned long written;
 | 
      
         | 405 |  |  |       char * buf = XNEWVEC (char, 16384);
 | 
      
         | 406 |  |  |  
 | 
      
         | 407 |  |  |       for (written = 0; written < h.asm_size; )
 | 
      
         | 408 |  |  |         {
 | 
      
         | 409 |  |  |           long size = h.asm_size - written;
 | 
      
         | 410 |  |  |           if (size > 16384)
 | 
      
         | 411 |  |  |             size = 16384;
 | 
      
         | 412 |  |  |           if (fread (buf, size, 1, f) != 1
 | 
      
         | 413 |  |  |               || fwrite (buf, size, 1, asm_out_file) != 1)
 | 
      
         | 414 |  |  |             cpp_errno (pfile, CPP_DL_ERROR, "reading");
 | 
      
         | 415 |  |  |           written += size;
 | 
      
         | 416 |  |  |         }
 | 
      
         | 417 |  |  |       free (buf);
 | 
      
         | 418 |  |  |     }
 | 
      
         | 419 |  |  |   else
 | 
      
         | 420 |  |  |     {
 | 
      
         | 421 |  |  |       /* If we're preprocessing, don't write to a NULL
 | 
      
         | 422 |  |  |          asm_out_file.  */
 | 
      
         | 423 |  |  |       if (fseek (f, h.asm_size, SEEK_CUR) != 0)
 | 
      
         | 424 |  |  |         cpp_errno (pfile, CPP_DL_ERROR, "seeking");
 | 
      
         | 425 |  |  |     }
 | 
      
         | 426 |  |  |  
 | 
      
         | 427 |  |  |   /* Save the location and then restore it after reading the PCH.  */
 | 
      
         | 428 |  |  |   saved_loc = expand_location (line_table->highest_line);
 | 
      
         | 429 |  |  |   saved_trace_includes = line_table->trace_includes;
 | 
      
         | 430 |  |  |  
 | 
      
         | 431 |  |  |   timevar_push (TV_PCH_CPP_RESTORE);
 | 
      
         | 432 |  |  |   cpp_prepare_state (pfile, &smd);
 | 
      
         | 433 |  |  |   timevar_pop (TV_PCH_CPP_RESTORE);
 | 
      
         | 434 |  |  |  
 | 
      
         | 435 |  |  |   gt_pch_restore (f);
 | 
      
         | 436 |  |  |   cpp_set_line_map (pfile, line_table);
 | 
      
         | 437 |  |  |  
 | 
      
         | 438 |  |  |   timevar_push (TV_PCH_CPP_RESTORE);
 | 
      
         | 439 |  |  |   if (cpp_read_state (pfile, name, f, smd) != 0)
 | 
      
         | 440 |  |  |     {
 | 
      
         | 441 |  |  |       fclose (f);
 | 
      
         | 442 |  |  |       timevar_pop (TV_PCH_CPP_RESTORE);
 | 
      
         | 443 |  |  |       goto end;
 | 
      
         | 444 |  |  |     }
 | 
      
         | 445 |  |  |   timevar_pop (TV_PCH_CPP_RESTORE);
 | 
      
         | 446 |  |  |  
 | 
      
         | 447 |  |  |  
 | 
      
         | 448 |  |  |   fclose (f);
 | 
      
         | 449 |  |  |  
 | 
      
         | 450 |  |  |   line_table->trace_includes = saved_trace_includes;
 | 
      
         | 451 |  |  |   linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line);
 | 
      
         | 452 |  |  |  
 | 
      
         | 453 |  |  |   /* Give the front end a chance to take action after a PCH file has
 | 
      
         | 454 |  |  |      been loaded.  */
 | 
      
         | 455 |  |  |   if (lang_post_pch_load)
 | 
      
         | 456 |  |  |     (*lang_post_pch_load) ();
 | 
      
         | 457 |  |  |  
 | 
      
         | 458 |  |  | end:
 | 
      
         | 459 |  |  |   timevar_pop (TV_PCH_RESTORE);
 | 
      
         | 460 |  |  | }
 | 
      
         | 461 |  |  |  
 | 
      
         | 462 |  |  | /* Indicate that no more PCH files should be read.  */
 | 
      
         | 463 |  |  |  
 | 
      
         | 464 |  |  | void
 | 
      
         | 465 |  |  | c_common_no_more_pch (void)
 | 
      
         | 466 |  |  | {
 | 
      
         | 467 |  |  |   if (cpp_get_callbacks (parse_in)->valid_pch)
 | 
      
         | 468 |  |  |     {
 | 
      
         | 469 |  |  |       cpp_get_callbacks (parse_in)->valid_pch = NULL;
 | 
      
         | 470 |  |  |       host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
 | 
      
         | 471 |  |  |     }
 | 
      
         | 472 |  |  | }
 | 
      
         | 473 |  |  |  
 | 
      
         | 474 |  |  | /* Handle #pragma GCC pch_preprocess, to load in the PCH file.  */
 | 
      
         | 475 |  |  |  
 | 
      
         | 476 |  |  | void
 | 
      
         | 477 |  |  | c_common_pch_pragma (cpp_reader *pfile, const char *name)
 | 
      
         | 478 |  |  | {
 | 
      
         | 479 |  |  |   int fd;
 | 
      
         | 480 |  |  |  
 | 
      
         | 481 |  |  |   if (!cpp_get_options (pfile)->preprocessed)
 | 
      
         | 482 |  |  |     {
 | 
      
         | 483 |  |  |       error ("pch_preprocess pragma should only be used with -fpreprocessed");
 | 
      
         | 484 |  |  |       inform (input_location, "use #include instead");
 | 
      
         | 485 |  |  |       return;
 | 
      
         | 486 |  |  |     }
 | 
      
         | 487 |  |  |  
 | 
      
         | 488 |  |  |   fd = open (name, O_RDONLY | O_BINARY, 0666);
 | 
      
         | 489 |  |  |   if (fd == -1)
 | 
      
         | 490 |  |  |     fatal_error ("%s: couldn%'t open PCH file: %m", name);
 | 
      
         | 491 |  |  |  
 | 
      
         | 492 |  |  |   if (c_common_valid_pch (pfile, name, fd) != 1)
 | 
      
         | 493 |  |  |     {
 | 
      
         | 494 |  |  |       if (!cpp_get_options (pfile)->warn_invalid_pch)
 | 
      
         | 495 |  |  |         inform (input_location, "use -Winvalid-pch for more information");
 | 
      
         | 496 |  |  |       fatal_error ("%s: PCH file was invalid", name);
 | 
      
         | 497 |  |  |     }
 | 
      
         | 498 |  |  |  
 | 
      
         | 499 |  |  |   c_common_read_pch (pfile, name, fd, name);
 | 
      
         | 500 |  |  |  
 | 
      
         | 501 |  |  |   close (fd);
 | 
      
         | 502 |  |  | }
 | 
      
         | 503 |  |  |  
 | 
      
         | 504 |  |  | /* Print out executable_checksum[].  */
 | 
      
         | 505 |  |  |  
 | 
      
         | 506 |  |  | void
 | 
      
         | 507 |  |  | c_common_print_pch_checksum (FILE *f)
 | 
      
         | 508 |  |  | {
 | 
      
         | 509 |  |  |   int i;
 | 
      
         | 510 |  |  |   fputs ("Compiler executable checksum: ", f);
 | 
      
         | 511 |  |  |   for (i = 0; i < 16; i++)
 | 
      
         | 512 |  |  |     fprintf (f, "%02x", executable_checksum[i]);
 | 
      
         | 513 |  |  |   putc ('\n', f);
 | 
      
         | 514 |  |  | }
 |