Home | History | Annotate | Line # | Download | only in c-family
c-pch.cc revision 1.1
      1 /* Precompiled header implementation for the C languages.
      2    Copyright (C) 2000-2022 Free Software Foundation, Inc.
      3 
      4 This file is part of GCC.
      5 
      6 GCC is free software; you can redistribute it and/or modify
      7 it under the terms of the GNU General Public License as published by
      8 the Free Software Foundation; either version 3, or (at your option)
      9 any later version.
     10 
     11 GCC is distributed in the hope that it will be useful,
     12 but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 GNU General Public License for more details.
     15 
     16 You should have received a copy of the GNU General Public License
     17 along with GCC; see the file COPYING3.  If not see
     18 <http://www.gnu.org/licenses/>.  */
     19 
     20 #include "config.h"
     21 #include "system.h"
     22 #include "coretypes.h"
     23 #include "target.h"
     24 #include "c-common.h"
     25 #include "timevar.h"
     26 #include "flags.h"
     27 #include "debug.h"
     28 #include "c-pragma.h"
     29 #include "langhooks.h"
     30 #include "hosthooks.h"
     31 
     32 /* This is a list of flag variables that must match exactly, and their
     33    names for the error message.  The possible values for *flag_var must
     34    fit in a 'signed char'.  */
     35 
     36 static const struct c_pch_matching
     37 {
     38   int *flag_var;
     39   const char *flag_name;
     40 } pch_matching[] = {
     41   { &flag_exceptions, "-fexceptions" },
     42 };
     43 
     44 enum {
     45   MATCH_SIZE = ARRAY_SIZE (pch_matching)
     46 };
     47 
     48 /* Information about flags and suchlike that affect PCH validity.
     49 
     50    Before this structure is read, both an initial 8-character identification
     51    string, and a 16-byte checksum, have been read and validated.  */
     52 
     53 struct c_pch_validity
     54 {
     55   uint32_t pch_write_symbols;
     56   signed char match[MATCH_SIZE];
     57   size_t target_data_length;
     58 };
     59 
     60 #define IDENT_LENGTH 8
     61 
     62 /* The file we'll be writing the PCH to.  */
     63 static FILE *pch_outfile;
     64 
     65 static const char *get_ident (void);
     66 
     67 /* Compute an appropriate 8-byte magic number for the PCH file, so that
     68    utilities like file(1) can identify it, and so that GCC can quickly
     69    ignore non-PCH files and PCH files that are of a completely different
     70    format.  */
     71 
     72 static const char *
     73 get_ident (void)
     74 {
     75   static char result[IDENT_LENGTH];
     76   static const char templ[] = "gpch.014";
     77   static const char c_language_chars[] = "Co+O";
     78 
     79   memcpy (result, templ, IDENT_LENGTH);
     80   result[4] = c_language_chars[c_language];
     81 
     82   return result;
     83 }
     84 
     85 /* Whether preprocessor state should be saved by pch_init.  */
     86 
     87 static bool pch_ready_to_save_cpp_state = false;
     88 
     89 /* Prepare to write a PCH file, if one is being written.  This is
     90    called at the start of compilation.  */
     91 
     92 void
     93 pch_init (void)
     94 {
     95   FILE *f;
     96   struct c_pch_validity v;
     97   void *target_validity;
     98   static const char partial_pch[] = "gpcWrite";
     99 
    100   if (!pch_file)
    101     return;
    102 
    103   f = fopen (pch_file, "w+b");
    104   if (f == NULL)
    105     fatal_error (input_location, "cannot create precompiled header %s: %m",
    106 		 pch_file);
    107   pch_outfile = f;
    108 
    109   memset (&v, '\0', sizeof (v));
    110   v.pch_write_symbols = write_symbols;
    111   {
    112     size_t i;
    113     for (i = 0; i < MATCH_SIZE; i++)
    114       {
    115 	v.match[i] = *pch_matching[i].flag_var;
    116 	gcc_assert (v.match[i] == *pch_matching[i].flag_var);
    117       }
    118   }
    119   target_validity = targetm.get_pch_validity (&v.target_data_length);
    120 
    121   if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
    122       || fwrite (executable_checksum, 16, 1, f) != 1
    123       || fwrite (&v, sizeof (v), 1, f) != 1
    124       || fwrite (target_validity, v.target_data_length, 1, f) != 1)
    125     fatal_error (input_location, "cannot write to %s: %m", pch_file);
    126 
    127   /* Let the debugging format deal with the PCHness.  */
    128   (*debug_hooks->handle_pch) (0);
    129 
    130   if (pch_ready_to_save_cpp_state)
    131     pch_cpp_save_state ();
    132 
    133   XDELETE (target_validity);
    134 }
    135 
    136 /* Whether preprocessor state has been saved in a PCH file.  */
    137 
    138 static bool pch_cpp_state_saved = false;
    139 
    140 /* Save preprocessor state in a PCH file, after implicitly included
    141    headers have been read.  If the PCH file has not yet been opened,
    142    record that state should be saved when it is opened.  */
    143 
    144 void
    145 pch_cpp_save_state (void)
    146 {
    147   if (!pch_cpp_state_saved)
    148     {
    149       if (pch_outfile)
    150 	{
    151 	  cpp_save_state (parse_in, pch_outfile);
    152 	  pch_cpp_state_saved = true;
    153 	}
    154       else
    155 	pch_ready_to_save_cpp_state = true;
    156     }
    157 }
    158 
    159 /* Write the PCH file.  This is called at the end of a compilation which
    160    will produce a PCH file.  */
    161 
    162 void
    163 c_common_write_pch (void)
    164 {
    165   timevar_push (TV_PCH_SAVE);
    166 
    167   targetm.prepare_pch_save ();
    168 
    169   (*debug_hooks->handle_pch) (1);
    170 
    171   prepare_target_option_nodes_for_pch ();
    172 
    173   cpp_write_pch_deps (parse_in, pch_outfile);
    174 
    175   gt_pch_save (pch_outfile);
    176 
    177   timevar_push (TV_PCH_CPP_SAVE);
    178   cpp_write_pch_state (parse_in, pch_outfile);
    179   timevar_pop (TV_PCH_CPP_SAVE);
    180 
    181   if (fseek (pch_outfile, 0, SEEK_SET) != 0
    182       || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
    183     fatal_error (input_location, "cannot write %s: %m", pch_file);
    184 
    185   fclose (pch_outfile);
    186 
    187   timevar_pop (TV_PCH_SAVE);
    188 }
    189 
    190 /* Check the PCH file called NAME, open on FD, to see if it can be
    191    used in this compilation.  Return 1 if valid, 0 if the file can't
    192    be used now but might be if it's seen later in the compilation, and
    193    2 if this file could never be used in the compilation.  */
    194 
    195 int
    196 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
    197 {
    198   int sizeread;
    199   int result;
    200   char ident[IDENT_LENGTH + 16];
    201   const char *pch_ident;
    202   struct c_pch_validity v;
    203 
    204   /* Perform a quick test of whether this is a valid
    205      precompiled header for the current language.  */
    206 
    207   /* C++ modules and PCH don't play together.  */
    208   if (flag_modules)
    209     return 2;
    210 
    211   sizeread = read (fd, ident, IDENT_LENGTH + 16);
    212   if (sizeread == -1)
    213     fatal_error (input_location, "cannot read %s: %m", name);
    214   else if (sizeread != IDENT_LENGTH + 16)
    215     {
    216       cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: too short to be a PCH file",
    217 		   name);
    218       return 2;
    219     }
    220 
    221   pch_ident = get_ident();
    222   if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
    223     {
    224 	if (memcmp (ident, pch_ident, 5) == 0)
    225 	  /* It's a PCH, for the right language, but has the wrong version.  */
    226 	  cpp_warning (pfile, CPP_W_INVALID_PCH,
    227 		       "%s: not compatible with this GCC version", name);
    228 	else if (memcmp (ident, pch_ident, 4) == 0)
    229 	  /* It's a PCH for the wrong language.  */
    230 	  cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not for %s", name,
    231 		       lang_hooks.name);
    232 	else
    233 	  /* Not any kind of PCH.  */
    234 	  cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: not a PCH file", name);
    235       return 2;
    236     }
    237   if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
    238     {
    239       cpp_warning (pfile, CPP_W_INVALID_PCH,
    240 		   "%s: created by a different GCC executable", name);
    241       return 2;
    242     }
    243 
    244   /* At this point, we know it's a PCH file created by this
    245      executable, so it ought to be long enough that we can read a
    246      c_pch_validity structure.  */
    247   if (read (fd, &v, sizeof (v)) != sizeof (v))
    248     fatal_error (input_location, "cannot read %s: %m", name);
    249 
    250   /* The allowable debug info combinations are that either the PCH file
    251      was built with the same as is being used now, or the PCH file was
    252      built for some kind of debug info but now none is in use.  */
    253   if (v.pch_write_symbols != write_symbols
    254       && write_symbols != NO_DEBUG)
    255     {
    256       char *created_str = xstrdup (debug_set_names (v.pch_write_symbols));
    257       char *used_str = xstrdup (debug_set_names (write_symbols));
    258       cpp_warning (pfile, CPP_W_INVALID_PCH,
    259 		   "%s: created with '%s' debug info, but used with '%s'", name,
    260 		   created_str, used_str);
    261       free (created_str);
    262       free (used_str);
    263       return 2;
    264     }
    265 
    266   /* Check flags that must match exactly.  */
    267   {
    268     size_t i;
    269     for (i = 0; i < MATCH_SIZE; i++)
    270       if (*pch_matching[i].flag_var != v.match[i])
    271 	{
    272 	  cpp_warning (pfile, CPP_W_INVALID_PCH,
    273 		       "%s: settings for %s do not match", name,
    274 		       pch_matching[i].flag_name);
    275 	  return 2;
    276 	}
    277   }
    278 
    279   /* Check the target-specific validity data.  */
    280   {
    281     void *this_file_data = xmalloc (v.target_data_length);
    282     const char *msg;
    283 
    284     if ((size_t) read (fd, this_file_data, v.target_data_length)
    285 	!= v.target_data_length)
    286       fatal_error (input_location, "cannot read %s: %m", name);
    287     msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
    288     free (this_file_data);
    289     if (msg != NULL)
    290       {
    291 	cpp_warning (pfile, CPP_W_INVALID_PCH, "%s: %s", name, msg);
    292 	return 2;
    293       }
    294   }
    295 
    296   /* Check the preprocessor macros are the same as when the PCH was
    297      generated.  */
    298 
    299   result = cpp_valid_state (pfile, name, fd);
    300   if (result == -1)
    301     return 2;
    302   else
    303     return result == 0;
    304 }
    305 
    306 /* If non-NULL, this function is called after a precompile header file
    307    is loaded.  */
    308 void (*lang_post_pch_load) (void);
    309 
    310 /* Load in the PCH file NAME, open on FD.  It was originally searched for
    311    by ORIG_NAME.  */
    312 
    313 void
    314 c_common_read_pch (cpp_reader *pfile, const char *name,
    315 		   int fd, const char *orig_name ATTRIBUTE_UNUSED)
    316 {
    317   FILE *f;
    318   struct save_macro_data *smd;
    319   expanded_location saved_loc;
    320   bool saved_trace_includes;
    321 
    322   timevar_push (TV_PCH_RESTORE);
    323 
    324   f = fdopen (fd, "rb");
    325   if (f == NULL)
    326     {
    327       cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
    328       close (fd);
    329       goto end;
    330     }
    331 
    332   cpp_get_callbacks (parse_in)->valid_pch = NULL;
    333 
    334   /* Save the location and then restore it after reading the PCH.  */
    335   saved_loc = expand_location (line_table->highest_line);
    336   saved_trace_includes = line_table->trace_includes;
    337 
    338   timevar_push (TV_PCH_CPP_RESTORE);
    339   cpp_prepare_state (pfile, &smd);
    340   timevar_pop (TV_PCH_CPP_RESTORE);
    341 
    342   gt_pch_restore (f);
    343   cpp_set_line_map (pfile, line_table);
    344   rebuild_location_adhoc_htab (line_table);
    345   line_table->trace_includes = saved_trace_includes;
    346   linemap_add (line_table, LC_ENTER, 0, saved_loc.file, saved_loc.line);
    347 
    348   timevar_push (TV_PCH_CPP_RESTORE);
    349   if (cpp_read_state (pfile, name, f, smd) != 0)
    350     {
    351       fclose (f);
    352       timevar_pop (TV_PCH_CPP_RESTORE);
    353       goto end;
    354     }
    355   timevar_pop (TV_PCH_CPP_RESTORE);
    356 
    357 
    358   fclose (f);
    359 
    360   /* Give the front end a chance to take action after a PCH file has
    361      been loaded.  */
    362   if (lang_post_pch_load)
    363     (*lang_post_pch_load) ();
    364 
    365 end:
    366   timevar_pop (TV_PCH_RESTORE);
    367 }
    368 
    369 /* Indicate that no more PCH files should be read.  */
    370 
    371 void
    372 c_common_no_more_pch (void)
    373 {
    374   if (cpp_get_callbacks (parse_in)->valid_pch)
    375     {
    376       cpp_get_callbacks (parse_in)->valid_pch = NULL;
    377       void *addr = NULL;
    378       host_hooks.gt_pch_use_address (addr, 0, -1, 0);
    379     }
    380 }
    381 
    382 /* Handle #pragma GCC pch_preprocess, to load in the PCH file.  */
    383 
    384 void
    385 c_common_pch_pragma (cpp_reader *pfile, const char *name)
    386 {
    387   int fd;
    388 
    389   if (!cpp_get_options (pfile)->preprocessed)
    390     {
    391       error ("%<pch_preprocess%> pragma should only be used "
    392 	     "with %<-fpreprocessed%>");
    393       inform (input_location, "use %<#include%> instead");
    394       return;
    395     }
    396 
    397   fd = open (name, O_RDONLY | O_BINARY, 0666);
    398   if (fd == -1)
    399     fatal_error (input_location, "%s: couldn%'t open PCH file: %m", name);
    400 
    401   if (c_common_valid_pch (pfile, name, fd) != 1)
    402     {
    403       if (!cpp_get_options (pfile)->warn_invalid_pch)
    404 	inform (input_location, "use %<-Winvalid-pch%> for more information");
    405       fatal_error (input_location, "%s: PCH file was invalid", name);
    406     }
    407 
    408   c_common_read_pch (pfile, name, fd, name);
    409 
    410   close (fd);
    411 }
    412 
    413