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