2004-10-07 J"orn Rennecke <joern.rennecke@st.com>
[official-gcc.git] / gcc / c-pch.c
blob8b2123580874b50780fa7534f20e413bd5e1d212
1 /* Precompiled header implementation for the C languages.
2 Copyright (C) 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
4 This file is part of GCC.
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 2, or (at your option)
9 any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
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 "toplev.h"
31 #include "debug.h"
32 #include "c-pragma.h"
33 #include "ggc.h"
34 #include "langhooks.h"
35 #include "hosthooks.h"
36 #include "target.h"
38 /* This is a list of flag variables that must match exactly, and their
39 names for the error message. The possible values for *flag_var must
40 fit in a 'signed char'. */
42 static const struct c_pch_matching
44 int *flag_var;
45 const char *flag_name;
46 } pch_matching[] = {
47 { &flag_exceptions, "-fexceptions" },
48 { &flag_unit_at_a_time, "-funit-at-a-time" }
51 enum {
52 MATCH_SIZE = ARRAY_SIZE (pch_matching)
55 /* This structure is read very early when validating the PCH, and
56 might be read for a PCH which is for a completely different compiler
57 for a different operating system. Thus, it should really only contain
58 'unsigned char' entries, at least in the initial entries.
60 If you add or change entries before version_length, you should increase
61 the version number in get_ident().
63 There are a bunch of fields named *_length; those are lengths of data that
64 follows this structure in the same order as the fields in the structure. */
66 struct c_pch_validity
68 unsigned char host_machine_length;
69 unsigned char target_machine_length;
70 unsigned char version_length;
71 unsigned char debug_info_type;
72 signed char match[MATCH_SIZE];
73 void (*pch_init) (void);
74 size_t target_data_length;
77 struct c_pch_header
79 unsigned long asm_size;
82 #define IDENT_LENGTH 8
84 /* The file we'll be writing the PCH to. */
85 static FILE *pch_outfile;
87 /* The position in the assembler output file when pch_init was called. */
88 static long asm_file_startpos;
90 /* The host and target machines. */
91 static const char host_machine[] = HOST_MACHINE;
92 static const char target_machine[] = TARGET_MACHINE;
94 static const char *get_ident (void);
96 /* Compute an appropriate 8-byte magic number for the PCH file, so that
97 utilities like file(1) can identify it, and so that GCC can quickly
98 ignore non-PCH files and PCH files that are of a completely different
99 format. */
101 static const char *
102 get_ident (void)
104 static char result[IDENT_LENGTH];
105 static const char template[IDENT_LENGTH] = "gpch.012";
106 static const char c_language_chars[] = "Co+O";
108 memcpy (result, template, IDENT_LENGTH);
109 result[4] = c_language_chars[c_language];
111 return result;
114 /* Prepare to write a PCH file. This is called at the start of
115 compilation. */
117 void
118 pch_init (void)
120 FILE *f;
121 struct c_pch_validity v;
122 void *target_validity;
123 static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
125 if (!pch_file)
126 return;
128 f = fopen (pch_file, "w+b");
129 if (f == NULL)
130 fatal_error ("can't create precompiled header %s: %m", pch_file);
131 pch_outfile = f;
133 gcc_assert (strlen (host_machine) < 256
134 && strlen (target_machine) < 256
135 && strlen (version_string) < 256);
137 v.host_machine_length = strlen (host_machine);
138 v.target_machine_length = strlen (target_machine);
139 v.version_length = strlen (version_string);
140 v.debug_info_type = write_symbols;
142 size_t i;
143 for (i = 0; i < MATCH_SIZE; i++)
145 v.match[i] = *pch_matching[i].flag_var;
146 gcc_assert (v.match[i] == *pch_matching[i].flag_var);
149 v.pch_init = &pch_init;
150 target_validity = targetm.get_pch_validity (&v.target_data_length);
152 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
153 || fwrite (&v, sizeof (v), 1, f) != 1
154 || fwrite (host_machine, v.host_machine_length, 1, f) != 1
155 || fwrite (target_machine, v.target_machine_length, 1, f) != 1
156 || fwrite (version_string, v.version_length, 1, f) != 1
157 || fwrite (target_validity, v.target_data_length, 1, f) != 1)
158 fatal_error ("can't write to %s: %m", pch_file);
160 /* We need to be able to re-read the output. */
161 /* The driver always provides a valid -o option. */
162 if (asm_file_name == NULL
163 || strcmp (asm_file_name, "-") == 0)
164 fatal_error ("%qs is not a valid output file", asm_file_name);
166 asm_file_startpos = ftell (asm_out_file);
168 /* Let the debugging format deal with the PCHness. */
169 (*debug_hooks->handle_pch) (0);
171 cpp_save_state (parse_in, f);
174 /* Write the PCH file. This is called at the end of a compilation which
175 will produce a PCH file. */
177 void
178 c_common_write_pch (void)
180 char *buf;
181 long asm_file_end;
182 long written;
183 struct c_pch_header h;
185 (*debug_hooks->handle_pch) (1);
187 cpp_write_pch_deps (parse_in, pch_outfile);
189 asm_file_end = ftell (asm_out_file);
190 h.asm_size = asm_file_end - asm_file_startpos;
192 if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
193 fatal_error ("can't write %s: %m", pch_file);
195 buf = xmalloc (16384);
197 if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
198 fatal_error ("can't seek in %s: %m", asm_file_name);
200 for (written = asm_file_startpos; written < asm_file_end; )
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;
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);
217 gt_pch_save (pch_outfile);
218 cpp_write_pch_state (parse_in, pch_outfile);
220 if (fseek (pch_outfile, 0, SEEK_SET) != 0
221 || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
222 fatal_error ("can't write %s: %m", pch_file);
224 fclose (pch_outfile);
227 /* Check the PCH file called NAME, open on FD, to see if it can be
228 used in this compilation. Return 1 if valid, 0 if the file can't
229 be used now but might be if it's seen later in the compilation, and
230 2 if this file could never be used in the compilation. */
233 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
235 int sizeread;
236 int result;
237 char ident[IDENT_LENGTH];
238 char short_strings[256 * 3];
239 int strings_length;
240 const char *pch_ident;
241 struct c_pch_validity v;
243 /* Perform a quick test of whether this is a valid
244 precompiled header for the current language. */
246 sizeread = read (fd, ident, IDENT_LENGTH);
247 if (sizeread == -1)
248 fatal_error ("can't read %s: %m", name);
249 else if (sizeread != IDENT_LENGTH)
250 return 2;
252 pch_ident = get_ident();
253 if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
255 if (cpp_get_options (pfile)->warn_invalid_pch)
257 if (memcmp (ident, pch_ident, 5) == 0)
258 /* It's a PCH, for the right language, but has the wrong version.
260 cpp_error (pfile, CPP_DL_WARNING,
261 "%s: not compatible with this GCC version", name);
262 else if (memcmp (ident, pch_ident, 4) == 0)
263 /* It's a PCH for the wrong language. */
264 cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
265 lang_hooks.name);
266 else
267 /* Not any kind of PCH. */
268 cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
270 return 2;
273 /* At this point, we know it's a PCH file, so it ought to be long enough
274 that we can read a c_pch_validity structure. */
275 if (read (fd, &v, sizeof (v)) != sizeof (v))
276 fatal_error ("can't read %s: %m", name);
278 strings_length = (v.host_machine_length + v.target_machine_length
279 + v.version_length);
280 if (read (fd, short_strings, strings_length) != strings_length)
281 fatal_error ("can't read %s: %m", name);
282 if (v.host_machine_length != strlen (host_machine)
283 || memcmp (host_machine, short_strings, strlen (host_machine)) != 0)
285 if (cpp_get_options (pfile)->warn_invalid_pch)
286 cpp_error (pfile, CPP_DL_WARNING,
287 "%s: created on host '%.*s', but used on host '%s'", name,
288 v.host_machine_length, short_strings, host_machine);
289 return 2;
291 if (v.target_machine_length != strlen (target_machine)
292 || memcmp (target_machine, short_strings + v.host_machine_length,
293 strlen (target_machine)) != 0)
295 if (cpp_get_options (pfile)->warn_invalid_pch)
296 cpp_error (pfile, CPP_DL_WARNING,
297 "%s: created for target '%.*s', but used for target '%s'",
298 name, v.target_machine_length,
299 short_strings + v.host_machine_length, target_machine);
300 return 2;
302 if (v.version_length != strlen (version_string)
303 || memcmp (version_string,
304 (short_strings + v.host_machine_length
305 + v.target_machine_length),
306 v.version_length) != 0)
308 if (cpp_get_options (pfile)->warn_invalid_pch)
309 cpp_error (pfile, CPP_DL_WARNING,
310 "%s: created by version '%.*s', but this is version '%s'",
311 name, v.version_length,
312 (short_strings + v.host_machine_length
313 + v.target_machine_length),
314 version_string);
315 return 2;
318 /* The allowable debug info combinations are that either the PCH file
319 was built with the same as is being used now, or the PCH file was
320 built for some kind of debug info but now none is in use. */
321 if (v.debug_info_type != write_symbols
322 && write_symbols != NO_DEBUG)
324 if (cpp_get_options (pfile)->warn_invalid_pch)
325 cpp_error (pfile, CPP_DL_WARNING,
326 "%s: created with -g%s, but used with -g%s", name,
327 debug_type_names[v.debug_info_type],
328 debug_type_names[write_symbols]);
329 return 2;
332 /* Check flags that must match exactly. */
334 size_t i;
335 for (i = 0; i < MATCH_SIZE; i++)
336 if (*pch_matching[i].flag_var != v.match[i])
338 if (cpp_get_options (pfile)->warn_invalid_pch)
339 cpp_error (pfile, CPP_DL_WARNING,
340 "%s: settings for %s do not match", name,
341 pch_matching[i].flag_name);
342 return 2;
346 /* If the text segment was not loaded at the same address as it was
347 when the PCH file was created, function pointers loaded from the
348 PCH will not be valid. We could in theory remap all the function
349 pointers, but no support for that exists at present. */
350 if (v.pch_init != &pch_init)
352 if (cpp_get_options (pfile)->warn_invalid_pch)
353 cpp_error (pfile, CPP_DL_WARNING,
354 "%s: had text segment at different address", name);
355 return 2;
358 /* Check the target-specific validity data. */
360 void *this_file_data = xmalloc (v.target_data_length);
361 const char *msg;
363 if ((size_t) read (fd, this_file_data, v.target_data_length)
364 != v.target_data_length)
365 fatal_error ("can't read %s: %m", name);
366 msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
367 free (this_file_data);
368 if (msg != NULL)
370 if (cpp_get_options (pfile)->warn_invalid_pch)
371 cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
372 return 2;
376 /* Check the preprocessor macros are the same as when the PCH was
377 generated. */
379 result = cpp_valid_state (pfile, name, fd);
380 if (result == -1)
381 return 2;
382 else
383 return result == 0;
386 /* If non-NULL, this function is called after a precompile header file
387 is loaded. */
388 void (*lang_post_pch_load) (void);
390 /* Load in the PCH file NAME, open on FD. It was originally searched for
391 by ORIG_NAME. */
393 void
394 c_common_read_pch (cpp_reader *pfile, const char *name,
395 int fd, const char *orig_name ATTRIBUTE_UNUSED)
397 FILE *f;
398 struct c_pch_header h;
399 struct save_macro_data *smd;
401 f = fdopen (fd, "rb");
402 if (f == NULL)
404 cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
405 return;
408 cpp_get_callbacks (parse_in)->valid_pch = NULL;
410 if (fread (&h, sizeof (h), 1, f) != 1)
412 cpp_errno (pfile, CPP_DL_ERROR, "reading");
413 return;
416 if (!flag_preprocess_only)
418 unsigned long written;
419 char * buf = xmalloc (16384);
421 for (written = 0; written < h.asm_size; )
423 long size = h.asm_size - written;
424 if (size > 16384)
425 size = 16384;
426 if (fread (buf, size, 1, f) != 1
427 || fwrite (buf, size, 1, asm_out_file) != 1)
428 cpp_errno (pfile, CPP_DL_ERROR, "reading");
429 written += size;
431 free (buf);
433 else
435 /* If we're preprocessing, don't write to a NULL
436 asm_out_file. */
437 if (fseek (f, h.asm_size, SEEK_CUR) != 0)
438 cpp_errno (pfile, CPP_DL_ERROR, "seeking");
441 cpp_prepare_state (pfile, &smd);
443 gt_pch_restore (f);
445 if (cpp_read_state (pfile, name, f, smd) != 0)
446 return;
448 fclose (f);
450 /* Give the front end a chance to take action after a PCH file has
451 been loaded. */
452 if (lang_post_pch_load)
453 (*lang_post_pch_load) ();
456 /* Indicate that no more PCH files should be read. */
458 void
459 c_common_no_more_pch (void)
461 if (cpp_get_callbacks (parse_in)->valid_pch)
463 cpp_get_callbacks (parse_in)->valid_pch = NULL;
464 host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
468 /* Handle #pragma GCC pch_preprocess, to load in the PCH file. */
470 #ifndef O_BINARY
471 # define O_BINARY 0
472 #endif
474 void
475 c_common_pch_pragma (cpp_reader *pfile)
477 tree name_t;
478 const char *name;
479 int fd;
481 if (c_lex (&name_t) != CPP_STRING)
483 error ("malformed #pragma GCC pch_preprocess, ignored");
484 return;
487 if (!cpp_get_options (pfile)->preprocessed)
489 error ("pch_preprocess pragma should only be used with -fpreprocessed");
490 inform ("use #include instead");
491 return;
494 name = TREE_STRING_POINTER (name_t);
496 fd = open (name, O_RDONLY | O_BINARY, 0666);
497 if (fd == -1)
498 fatal_error ("%s: couldn't open PCH file: %m\n", name);
500 if (c_common_valid_pch (pfile, name, fd) != 1)
502 if (!cpp_get_options (pfile)->warn_invalid_pch)
503 inform ("use -Winvalid-pch for more information");
504 fatal_error ("%s: PCH file was invalid", name);
507 c_common_read_pch (pfile, name, fd, name);
509 close (fd);