xref: /netbsd-src/external/gpl3/gcc/dist/gcc/c-family/c-pch.cc (revision 0a3071956a3a9fdebdbf7f338cf2d439b45fc728)
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 *
get_ident(void)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
pch_init(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
pch_cpp_save_state(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
c_common_write_pch(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
c_common_valid_pch(cpp_reader * pfile,const char * name,int fd)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
c_common_read_pch(cpp_reader * pfile,const char * name,int fd,const char * orig_name ATTRIBUTE_UNUSED)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
c_common_no_more_pch(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
c_common_pch_pragma(cpp_reader * pfile,const char * name)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