re PR pch/13419 (Clarification of invoke.texi requested)
[gcc.git] / gcc / c-pch.c
1 /* Precompiled header implementation for the C languages.
2 Copyright (C) 2000, 2002, 2003, 2004 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 2, 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 COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
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 "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"
37
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'. */
41
42 static const struct c_pch_matching
43 {
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" }
49 };
50
51 enum {
52 MATCH_SIZE = ARRAY_SIZE (pch_matching)
53 };
54
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.
59
60 If you add or change entries before version_length, you should increase
61 the version number in get_ident().
62
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. */
65
66 struct c_pch_validity
67 {
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;
75 };
76
77 struct c_pch_header
78 {
79 unsigned long asm_size;
80 };
81
82 #define IDENT_LENGTH 8
83
84 /* The file we'll be writing the PCH to. */
85 static FILE *pch_outfile;
86
87 /* The position in the assembler output file when pch_init was called. */
88 static long asm_file_startpos;
89
90 /* The host and target machines. */
91 static const char host_machine[] = HOST_MACHINE;
92 static const char target_machine[] = TARGET_MACHINE;
93
94 static const char *get_ident (void);
95
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. */
100
101 static const char *
102 get_ident(void)
103 {
104 static char result[IDENT_LENGTH];
105 static const char template[IDENT_LENGTH] = "gpch.012";
106 static const char c_language_chars[] = "Co+O";
107
108 memcpy (result, template, IDENT_LENGTH);
109 result[4] = c_language_chars[c_language];
110
111 return result;
112 }
113
114 /* Prepare to write a PCH file. This is called at the start of
115 compilation. */
116
117 void
118 pch_init (void)
119 {
120 FILE *f;
121 struct c_pch_validity v;
122 void *target_validity;
123 static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
124
125 if (! pch_file)
126 return;
127
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;
132
133 if (strlen (host_machine) > 255 || strlen (target_machine) > 255
134 || strlen (version_string) > 255)
135 abort ();
136
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;
141 {
142 size_t i;
143 for (i = 0; i < MATCH_SIZE; i++)
144 {
145 v.match[i] = *pch_matching[i].flag_var;
146 if (v.match[i] != *pch_matching[i].flag_var)
147 abort ();
148 }
149 }
150 v.pch_init = &pch_init;
151 target_validity = targetm.get_pch_validity (&v.target_data_length);
152
153 if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
154 || fwrite (&v, sizeof (v), 1, f) != 1
155 || fwrite (host_machine, v.host_machine_length, 1, f) != 1
156 || fwrite (target_machine, v.target_machine_length, 1, f) != 1
157 || fwrite (version_string, v.version_length, 1, f) != 1
158 || fwrite (target_validity, v.target_data_length, 1, f) != 1)
159 fatal_error ("can't write to %s: %m", pch_file);
160
161 /* We need to be able to re-read the output. */
162 /* The driver always provides a valid -o option. */
163 if (asm_file_name == NULL
164 || strcmp (asm_file_name, "-") == 0)
165 fatal_error ("`%s' is not a valid output file", asm_file_name);
166
167 asm_file_startpos = ftell (asm_out_file);
168
169 /* Let the debugging format deal with the PCHness. */
170 (*debug_hooks->handle_pch) (0);
171
172 cpp_save_state (parse_in, f);
173 }
174
175 /* Write the PCH file. This is called at the end of a compilation which
176 will produce a PCH file. */
177
178 void
179 c_common_write_pch (void)
180 {
181 char *buf;
182 long asm_file_end;
183 long written;
184 struct c_pch_header h;
185
186 (*debug_hooks->handle_pch) (1);
187
188 cpp_write_pch_deps (parse_in, pch_outfile);
189
190 asm_file_end = ftell (asm_out_file);
191 h.asm_size = asm_file_end - asm_file_startpos;
192
193 if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
194 fatal_error ("can't write %s: %m", pch_file);
195
196 buf = xmalloc (16384);
197 fflush (asm_out_file);
198
199 if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
200 fatal_error ("can't seek in %s: %m", asm_file_name);
201
202 for (written = asm_file_startpos; written < asm_file_end; )
203 {
204 long size = asm_file_end - written;
205 if (size > 16384)
206 size = 16384;
207 if (fread (buf, size, 1, asm_out_file) != 1)
208 fatal_error ("can't read %s: %m", asm_file_name);
209 if (fwrite (buf, size, 1, pch_outfile) != 1)
210 fatal_error ("can't write %s: %m", pch_file);
211 written += size;
212 }
213 free (buf);
214 /* asm_out_file can be written afterwards, so must be flushed first. */
215 fflush (asm_out_file);
216
217 gt_pch_save (pch_outfile);
218 cpp_write_pch_state (parse_in, pch_outfile);
219
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);
223
224 fclose (pch_outfile);
225 }
226
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. */
231
232 int
233 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
234 {
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;
242
243 /* Perform a quick test of whether this is a valid
244 precompiled header for the current language. */
245
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;
251
252 pch_ident = get_ident();
253 if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
254 {
255 if (cpp_get_options (pfile)->warn_invalid_pch)
256 {
257 if (memcmp (ident, pch_ident, 5) == 0)
258 /* It's a PCH, for the right language, but has the wrong version.
259 */
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);
269 }
270 return 2;
271 }
272
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);
277
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)
284 {
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;
290 }
291 if (v.target_machine_length != strlen (target_machine)
292 || memcmp (target_machine, short_strings + v.host_machine_length,
293 strlen (target_machine)) != 0)
294 {
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;
301 }
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)
307 {
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;
316 }
317
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)
323 {
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;
330 }
331
332 /* Check flags that must match exactly. */
333 {
334 size_t i;
335 for (i = 0; i < MATCH_SIZE; i++)
336 if (*pch_matching[i].flag_var != v.match[i])
337 {
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;
343 }
344 }
345
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)
351 {
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;
356 }
357
358 /* Check the target-specific validity data. */
359 {
360 void *this_file_data = xmalloc (v.target_data_length);
361 const char *msg;
362
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)
369 {
370 if (cpp_get_options (pfile)->warn_invalid_pch)
371 cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
372 return 2;
373 }
374 }
375
376 /* Check the preprocessor macros are the same as when the PCH was
377 generated. */
378
379 result = cpp_valid_state (pfile, name, fd);
380 if (result == -1)
381 return 2;
382 else
383 return result == 0;
384 }
385
386 /* Load in the PCH file NAME, open on FD. It was originally searched for
387 by ORIG_NAME. */
388
389 void
390 c_common_read_pch (cpp_reader *pfile, const char *name,
391 int fd, const char *orig_name ATTRIBUTE_UNUSED)
392 {
393 FILE *f;
394 struct c_pch_header h;
395 char *buf;
396 unsigned long written;
397 struct save_macro_data *smd;
398
399 f = fdopen (fd, "rb");
400 if (f == NULL)
401 {
402 cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
403 return;
404 }
405
406 cpp_get_callbacks (parse_in)->valid_pch = NULL;
407
408 if (fread (&h, sizeof (h), 1, f) != 1)
409 {
410 cpp_errno (pfile, CPP_DL_ERROR, "reading");
411 return;
412 }
413
414 buf = xmalloc (16384);
415 for (written = 0; written < h.asm_size; )
416 {
417 long size = h.asm_size - written;
418 if (size > 16384)
419 size = 16384;
420 if (fread (buf, size, 1, f) != 1
421 || fwrite (buf, size, 1, asm_out_file) != 1)
422 cpp_errno (pfile, CPP_DL_ERROR, "reading");
423 written += size;
424 }
425 free (buf);
426
427 cpp_prepare_state (pfile, &smd);
428
429 gt_pch_restore (f);
430
431 if (cpp_read_state (pfile, name, f, smd) != 0)
432 return;
433
434 fclose (f);
435 }
436
437 /* Indicate that no more PCH files should be read. */
438
439 void
440 c_common_no_more_pch (void)
441 {
442 if (cpp_get_callbacks (parse_in)->valid_pch)
443 {
444 cpp_get_callbacks (parse_in)->valid_pch = NULL;
445 host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
446 }
447 }