OSDN Git Service

2010-04-28 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / c-pch.c
1 /* Precompiled header implementation for the C languages.
2    Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
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 #include "opts.h"
38 #include "timevar.h"
39
40 /* This is a list of flag variables that must match exactly, and their
41    names for the error message.  The possible values for *flag_var must
42    fit in a 'signed char'.  */
43
44 static const struct c_pch_matching
45 {
46   int *flag_var;
47   const char *flag_name;
48 } pch_matching[] = {
49   { &flag_exceptions, "-fexceptions" },
50 };
51
52 enum {
53   MATCH_SIZE = ARRAY_SIZE (pch_matching)
54 };
55
56 /* The value of the checksum in the dummy compiler that is actually
57    checksummed.  That compiler should never be run.  */
58 static const char no_checksum[16] = { 0 };
59
60 /* Information about flags and suchlike that affect PCH validity.
61
62    Before this structure is read, both an initial 8-character identification
63    string, and a 16-byte checksum, have been read and validated.  */
64
65 struct c_pch_validity
66 {
67   unsigned char debug_info_type;
68   signed char match[MATCH_SIZE];
69   void (*pch_init) (void);
70   size_t target_data_length;
71 };
72
73 struct c_pch_header
74 {
75   unsigned long asm_size;
76 };
77
78 #define IDENT_LENGTH 8
79
80 /* The file we'll be writing the PCH to.  */
81 static FILE *pch_outfile;
82
83 /* The position in the assembler output file when pch_init was called.  */
84 static long asm_file_startpos;
85
86 static const char *get_ident (void);
87
88 /* Compute an appropriate 8-byte magic number for the PCH file, so that
89    utilities like file(1) can identify it, and so that GCC can quickly
90    ignore non-PCH files and PCH files that are of a completely different
91    format.  */
92
93 static const char *
94 get_ident (void)
95 {
96   static char result[IDENT_LENGTH];
97   static const char templ[] = "gpch.013";
98   static const char c_language_chars[] = "Co+O";
99
100   memcpy (result, templ, IDENT_LENGTH);
101   result[4] = c_language_chars[c_language];
102
103   return result;
104 }
105
106 /* Prepare to write a PCH file, if one is being written.  This is
107    called at the start of compilation.
108
109    Also, print out the executable checksum if -fverbose-asm is in effect.  */
110
111 void
112 pch_init (void)
113 {
114   FILE *f;
115   struct c_pch_validity v;
116   void *target_validity;
117   static const char partial_pch[] = "gpcWrite";
118
119 #ifdef ASM_COMMENT_START
120   if (flag_verbose_asm)
121     {
122       fprintf (asm_out_file, "%s ", ASM_COMMENT_START);
123       c_common_print_pch_checksum (asm_out_file);
124       fputc ('\n', asm_out_file);
125     }
126 #endif
127
128   if (!pch_file)
129     return;
130
131   f = fopen (pch_file, "w+b");
132   if (f == NULL)
133     fatal_error ("can%'t create precompiled header %s: %m", pch_file);
134   pch_outfile = f;
135
136   gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
137
138   memset (&v, '\0', sizeof (v));
139   v.debug_info_type = write_symbols;
140   {
141     size_t i;
142     for (i = 0; i < MATCH_SIZE; i++)
143       {
144         v.match[i] = *pch_matching[i].flag_var;
145         gcc_assert (v.match[i] == *pch_matching[i].flag_var);
146       }
147   }
148   v.pch_init = &pch_init;
149   target_validity = targetm.get_pch_validity (&v.target_data_length);
150
151   if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
152       || fwrite (executable_checksum, 16, 1, f) != 1
153       || fwrite (&v, sizeof (v), 1, f) != 1
154       || fwrite (target_validity, v.target_data_length, 1, f) != 1)
155     fatal_error ("can%'t write to %s: %m", pch_file);
156
157   /* We need to be able to re-read the output.  */
158   /* The driver always provides a valid -o option.  */
159   if (asm_file_name == NULL
160       || strcmp (asm_file_name, "-") == 0)
161     fatal_error ("%qs is not a valid output file", asm_file_name);
162
163   asm_file_startpos = ftell (asm_out_file);
164
165   /* Let the debugging format deal with the PCHness.  */
166   (*debug_hooks->handle_pch) (0);
167
168   cpp_save_state (parse_in, f);
169 }
170
171 /* Write the PCH file.  This is called at the end of a compilation which
172    will produce a PCH file.  */
173
174 void
175 c_common_write_pch (void)
176 {
177   char *buf;
178   long asm_file_end;
179   long written;
180   struct c_pch_header h;
181
182   timevar_push (TV_PCH_SAVE);
183
184   (*debug_hooks->handle_pch) (1);
185
186   cpp_write_pch_deps (parse_in, pch_outfile);
187
188   asm_file_end = ftell (asm_out_file);
189   h.asm_size = asm_file_end - asm_file_startpos;
190
191   if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
192     fatal_error ("can%'t write %s: %m", pch_file);
193
194   buf = XNEWVEC (char, 16384);
195
196   if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
197     fatal_error ("can%'t seek in %s: %m", asm_file_name);
198
199   for (written = asm_file_startpos; written < asm_file_end; )
200     {
201       long size = asm_file_end - written;
202       if (size > 16384)
203         size = 16384;
204       if (fread (buf, size, 1, asm_out_file) != 1)
205         fatal_error ("can%'t read %s: %m", asm_file_name);
206       if (fwrite (buf, size, 1, pch_outfile) != 1)
207         fatal_error ("can%'t write %s: %m", pch_file);
208       written += size;
209     }
210   free (buf);
211   /* asm_out_file can be written afterwards, so fseek to clear
212      _IOREAD flag.  */
213   if (fseek (asm_out_file, 0, SEEK_END) != 0)
214     fatal_error ("can%'t seek in %s: %m", asm_file_name);
215
216   gt_pch_save (pch_outfile);
217
218   timevar_push (TV_PCH_CPP_SAVE);
219   cpp_write_pch_state (parse_in, pch_outfile);
220   timevar_pop (TV_PCH_CPP_SAVE);
221
222   if (fseek (pch_outfile, 0, SEEK_SET) != 0
223       || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
224     fatal_error ("can%'t write %s: %m", pch_file);
225
226   fclose (pch_outfile);
227
228   timevar_pop (TV_PCH_SAVE);
229 }
230
231 /* Check the PCH file called NAME, open on FD, to see if it can be
232    used in this compilation.  Return 1 if valid, 0 if the file can't
233    be used now but might be if it's seen later in the compilation, and
234    2 if this file could never be used in the compilation.  */
235
236 int
237 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
238 {
239   int sizeread;
240   int result;
241   char ident[IDENT_LENGTH + 16];
242   const char *pch_ident;
243   struct c_pch_validity v;
244
245   /* Perform a quick test of whether this is a valid
246      precompiled header for the current language.  */
247
248   gcc_assert (memcmp (executable_checksum, no_checksum, 16) != 0);
249
250   sizeread = read (fd, ident, IDENT_LENGTH + 16);
251   if (sizeread == -1)
252     fatal_error ("can%'t read %s: %m", name);
253   else if (sizeread != IDENT_LENGTH + 16)
254     {
255       if (cpp_get_options (pfile)->warn_invalid_pch)
256         cpp_error (pfile, CPP_DL_WARNING, "%s: too short to be a PCH file",
257                    name);
258       return 2;
259     }
260
261   pch_ident = get_ident();
262   if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
263     {
264       if (cpp_get_options (pfile)->warn_invalid_pch)
265         {
266           if (memcmp (ident, pch_ident, 5) == 0)
267             /* It's a PCH, for the right language, but has the wrong version.
268              */
269             cpp_error (pfile, CPP_DL_WARNING,
270                        "%s: not compatible with this GCC version", name);
271           else if (memcmp (ident, pch_ident, 4) == 0)
272             /* It's a PCH for the wrong language.  */
273             cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
274                        lang_hooks.name);
275           else
276             /* Not any kind of PCH.  */
277             cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
278         }
279       return 2;
280     }
281   if (memcmp (ident + IDENT_LENGTH, executable_checksum, 16) != 0)
282     {
283       if (cpp_get_options (pfile)->warn_invalid_pch)
284         cpp_error (pfile, CPP_DL_WARNING,
285                    "%s: created by a different GCC executable", name);
286       return 2;
287     }
288
289   /* At this point, we know it's a PCH file created by this
290      executable, so it ought to be long enough that we can read a
291      c_pch_validity structure.  */
292   if (read (fd, &v, sizeof (v)) != sizeof (v))
293     fatal_error ("can%'t read %s: %m", name);
294
295   /* The allowable debug info combinations are that either the PCH file
296      was built with the same as is being used now, or the PCH file was
297      built for some kind of debug info but now none is in use.  */
298   if (v.debug_info_type != write_symbols
299       && write_symbols != NO_DEBUG)
300     {
301       if (cpp_get_options (pfile)->warn_invalid_pch)
302         cpp_error (pfile, CPP_DL_WARNING,
303                    "%s: created with -g%s, but used with -g%s", name,
304                    debug_type_names[v.debug_info_type],
305                    debug_type_names[write_symbols]);
306       return 2;
307     }
308
309   /* Check flags that must match exactly.  */
310   {
311     size_t i;
312     for (i = 0; i < MATCH_SIZE; i++)
313       if (*pch_matching[i].flag_var != v.match[i])
314         {
315           if (cpp_get_options (pfile)->warn_invalid_pch)
316             cpp_error (pfile, CPP_DL_WARNING,
317                        "%s: settings for %s do not match", name,
318                        pch_matching[i].flag_name);
319           return 2;
320         }
321   }
322
323   /* If the text segment was not loaded at the same address as it was
324      when the PCH file was created, function pointers loaded from the
325      PCH will not be valid.  We could in theory remap all the function
326      pointers, but no support for that exists at present.
327      Since we have the same executable, it should only be necessary to
328      check one function.  */
329   if (v.pch_init != &pch_init)
330     {
331       if (cpp_get_options (pfile)->warn_invalid_pch)
332         cpp_error (pfile, CPP_DL_WARNING,
333                    "%s: had text segment at different address", name);
334       return 2;
335     }
336
337   /* Check the target-specific validity data.  */
338   {
339     void *this_file_data = xmalloc (v.target_data_length);
340     const char *msg;
341
342     if ((size_t) read (fd, this_file_data, v.target_data_length)
343         != v.target_data_length)
344       fatal_error ("can%'t read %s: %m", name);
345     msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
346     free (this_file_data);
347     if (msg != NULL)
348       {
349         if (cpp_get_options (pfile)->warn_invalid_pch)
350           cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
351         return 2;
352       }
353   }
354
355   /* Check the preprocessor macros are the same as when the PCH was
356      generated.  */
357
358   result = cpp_valid_state (pfile, name, fd);
359   if (result == -1)
360     return 2;
361   else
362     return result == 0;
363 }
364
365 /* If non-NULL, this function is called after a precompile header file
366    is loaded.  */
367 void (*lang_post_pch_load) (void);
368
369 /* Load in the PCH file NAME, open on FD.  It was originally searched for
370    by ORIG_NAME.  */
371
372 void
373 c_common_read_pch (cpp_reader *pfile, const char *name,
374                    int fd, const char *orig_name ATTRIBUTE_UNUSED)
375 {
376   FILE *f;
377   struct c_pch_header h;
378   struct save_macro_data *smd;
379   expanded_location saved_loc;
380   bool saved_trace_includes;
381
382   timevar_push (TV_PCH_RESTORE);
383
384   f = fdopen (fd, "rb");
385   if (f == NULL)
386     {
387       cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
388       close (fd);
389       goto end;
390     }
391
392   cpp_get_callbacks (parse_in)->valid_pch = NULL;
393
394   if (fread (&h, sizeof (h), 1, f) != 1)
395     {
396       cpp_errno (pfile, CPP_DL_ERROR, "reading");
397       fclose (f);
398       goto end;
399     }
400
401   if (!flag_preprocess_only)
402     {
403       unsigned long written;
404       char * buf = XNEWVEC (char, 16384);
405
406       for (written = 0; written < h.asm_size; )
407         {
408           long size = h.asm_size - written;
409           if (size > 16384)
410             size = 16384;
411           if (fread (buf, size, 1, f) != 1
412               || fwrite (buf, size, 1, asm_out_file) != 1)
413             cpp_errno (pfile, CPP_DL_ERROR, "reading");
414           written += size;
415         }
416       free (buf);
417     }
418   else
419     {
420       /* If we're preprocessing, don't write to a NULL
421          asm_out_file.  */
422       if (fseek (f, h.asm_size, SEEK_CUR) != 0)
423         cpp_errno (pfile, CPP_DL_ERROR, "seeking");
424     }
425
426   /* Save the location and then restore it after reading the PCH.  */
427   saved_loc = expand_location (line_table->highest_line);
428   saved_trace_includes = line_table->trace_includes;
429
430   timevar_push (TV_PCH_CPP_RESTORE);
431   cpp_prepare_state (pfile, &smd);
432   timevar_pop (TV_PCH_CPP_RESTORE);
433
434   gt_pch_restore (f);
435
436   timevar_push (TV_PCH_CPP_RESTORE);
437   if (cpp_read_state (pfile, name, f, smd) != 0)
438     {
439       fclose (f);
440       timevar_pop (TV_PCH_CPP_RESTORE);
441       goto end;
442     }
443   timevar_pop (TV_PCH_CPP_RESTORE);
444
445
446   fclose (f);
447
448   line_table->trace_includes = saved_trace_includes;
449   cpp_set_line_map (pfile, line_table);
450   linemap_add (line_table, LC_RENAME, 0, saved_loc.file, saved_loc.line);
451
452   /* Give the front end a chance to take action after a PCH file has
453      been loaded.  */
454   if (lang_post_pch_load)
455     (*lang_post_pch_load) ();
456
457 end:
458   timevar_pop (TV_PCH_RESTORE);
459 }
460
461 /* Indicate that no more PCH files should be read.  */
462
463 void
464 c_common_no_more_pch (void)
465 {
466   if (cpp_get_callbacks (parse_in)->valid_pch)
467     {
468       cpp_get_callbacks (parse_in)->valid_pch = NULL;
469       host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
470     }
471 }
472
473 /* Handle #pragma GCC pch_preprocess, to load in the PCH file.  */
474
475 #ifndef O_BINARY
476 # define O_BINARY 0
477 #endif
478
479 void
480 c_common_pch_pragma (cpp_reader *pfile, const char *name)
481 {
482   int fd;
483
484   if (!cpp_get_options (pfile)->preprocessed)
485     {
486       error ("pch_preprocess pragma should only be used with -fpreprocessed");
487       inform (input_location, "use #include instead");
488       return;
489     }
490
491   fd = open (name, O_RDONLY | O_BINARY, 0666);
492   if (fd == -1)
493     fatal_error ("%s: couldn%'t open PCH file: %m", name);
494
495   if (c_common_valid_pch (pfile, name, fd) != 1)
496     {
497       if (!cpp_get_options (pfile)->warn_invalid_pch)
498         inform (input_location, "use -Winvalid-pch for more information");
499       fatal_error ("%s: PCH file was invalid", name);
500     }
501
502   c_common_read_pch (pfile, name, fd, name);
503
504   close (fd);
505 }
506
507 /* Print out executable_checksum[].  */
508
509 void
510 c_common_print_pch_checksum (FILE *f)
511 {
512   int i;
513   fputs ("Compiler executable checksum: ", f);
514   for (i = 0; i < 16; i++)
515     fprintf (f, "%02x", executable_checksum[i]);
516   putc ('\n', f);
517 }