OSDN Git Service

PR preprocessor/12847
[pf3gnuchains/gcc-fork.git] / gcc / c-pch.c
1 /* Precompiled header implementation for the C languages.
2    Copyright (C) 2000, 2002, 2003 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 structure is read very early when validating the PCH, and
39    might be read for a PCH which is for a completely different compiler
40    for a different operating system.  Thus, it should really only contain
41    'unsigned char' entries, at least in the initial entries.  
42
43    If you add or change entries before version_length, you should increase
44    the version number in get_ident().  
45
46    There are a bunch of fields named *_length; those are lengths of data that
47    follows this structure in the same order as the fields in the structure.  */
48
49 struct c_pch_validity
50 {
51   unsigned char host_machine_length;
52   unsigned char target_machine_length;
53   unsigned char version_length;
54   unsigned char debug_info_type;
55   void (*pch_init) (void);
56   size_t target_data_length;
57 };
58
59 struct c_pch_header 
60 {
61   unsigned long asm_size;
62 };
63
64 #define IDENT_LENGTH 8
65
66 /* The file we'll be writing the PCH to.  */
67 static FILE *pch_outfile;
68
69 /* The position in the assembler output file when pch_init was called.  */
70 static long asm_file_startpos;
71
72 /* The host and target machines.  */
73 static const char host_machine[] = HOST_MACHINE;
74 static const char target_machine[] = TARGET_MACHINE;
75
76 static const char *get_ident (void);
77
78 /* Compute an appropriate 8-byte magic number for the PCH file, so that
79    utilities like file(1) can identify it, and so that GCC can quickly
80    ignore non-PCH files and PCH files that are of a completely different
81    format.  */
82
83 static const char *
84 get_ident(void)
85 {
86   static char result[IDENT_LENGTH];
87   static const char template[IDENT_LENGTH] = "gpch.012";
88   static const char c_language_chars[] = "Co+O";
89   
90   memcpy (result, template, IDENT_LENGTH);
91   result[4] = c_language_chars[c_language];
92
93   return result;
94 }
95
96 /* Prepare to write a PCH file.  This is called at the start of 
97    compilation.  */
98
99 void
100 pch_init (void)
101 {
102   FILE *f;
103   struct c_pch_validity v;
104   void *target_validity;
105   
106   if (! pch_file)
107     return;
108   
109   f = fopen (pch_file, "w+b");
110   if (f == NULL)
111     fatal_error ("can't open %s: %m", pch_file);
112   pch_outfile = f;
113   
114   if (strlen (host_machine) > 255 || strlen (target_machine) > 255
115       || strlen (version_string) > 255)
116     abort ();
117   
118   v.host_machine_length = strlen (host_machine);
119   v.target_machine_length = strlen (target_machine);
120   v.version_length = strlen (version_string);
121   v.debug_info_type = write_symbols;
122   v.pch_init = &pch_init;
123   target_validity = targetm.get_pch_validity (&v.target_data_length);
124   
125   if (fwrite (get_ident(), IDENT_LENGTH, 1, f) != 1
126       || fwrite (&v, sizeof (v), 1, f) != 1
127       || fwrite (host_machine, v.host_machine_length, 1, f) != 1
128       || fwrite (target_machine, v.target_machine_length, 1, f) != 1
129       || fwrite (version_string, v.version_length, 1, f) != 1
130       || fwrite (target_validity, v.target_data_length, 1, f) != 1)
131     fatal_error ("can't write to %s: %m", pch_file);
132
133   /* We need to be able to re-read the output.  */
134   /* The driver always provides a valid -o option.  */
135   if (asm_file_name == NULL
136       || strcmp (asm_file_name, "-") == 0)
137     fatal_error ("`%s' is not a valid output file", asm_file_name);
138   
139   asm_file_startpos = ftell (asm_out_file);
140   
141   /* Let the debugging format deal with the PCHness.  */
142   (*debug_hooks->handle_pch) (0);
143   
144   cpp_save_state (parse_in, f);
145 }
146
147 /* Write the PCH file.  This is called at the end of a compilation which
148    will produce a PCH file.  */
149
150 void
151 c_common_write_pch (void)
152 {
153   char *buf;
154   long asm_file_end;
155   long written;
156   struct c_pch_header h;
157
158   (*debug_hooks->handle_pch) (1);
159
160   cpp_write_pch_deps (parse_in, pch_outfile);
161
162   asm_file_end = ftell (asm_out_file);
163   h.asm_size = asm_file_end - asm_file_startpos;
164   
165   if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
166     fatal_error ("can't write %s: %m", pch_file);
167   
168   buf = xmalloc (16384);
169   fflush (asm_out_file);
170
171   if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
172     fatal_error ("can't seek in %s: %m", asm_file_name);
173
174   for (written = asm_file_startpos; written < asm_file_end; )
175     {
176       long size = asm_file_end - written;
177       if (size > 16384)
178         size = 16384;
179       if (fread (buf, size, 1, asm_out_file) != 1)
180         fatal_error ("can't read %s: %m", asm_file_name);
181       if (fwrite (buf, size, 1, pch_outfile) != 1)
182         fatal_error ("can't write %s: %m", pch_file);
183       written += size;
184     }
185   free (buf);
186   /* asm_out_file can be written afterwards, so must be flushed first.  */
187   fflush (asm_out_file);
188
189   gt_pch_save (pch_outfile);
190   cpp_write_pch_state (parse_in, pch_outfile);
191
192   fclose (pch_outfile);
193 }
194
195 /* Check the PCH file called NAME, open on FD, to see if it can be
196    used in this compilation.  Return 1 if valid, 0 if the file can't
197    be used now but might be if it's seen later in the compilation, and
198    2 if this file could never be used in the compilation.  */
199
200 int
201 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
202 {
203   int sizeread;
204   int result;
205   char ident[IDENT_LENGTH];
206   char short_strings[256 * 3];
207   int strings_length;
208   const char *pch_ident;
209   struct c_pch_validity v;
210
211   /* Perform a quick test of whether this is a valid
212      precompiled header for the current language.  */
213
214   sizeread = read (fd, ident, IDENT_LENGTH);
215   if (sizeread == -1)
216     fatal_error ("can't read %s: %m", name);
217   else if (sizeread != IDENT_LENGTH)
218     return 2;
219   
220   pch_ident = get_ident();
221   if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
222     {
223       if (cpp_get_options (pfile)->warn_invalid_pch)
224         {
225           if (memcmp (ident, pch_ident, 5) == 0)
226             /* It's a PCH, for the right language, but has the wrong version.
227              */
228             cpp_error (pfile, CPP_DL_WARNING, 
229                        "%s: not compatible with this GCC version", name);
230           else if (memcmp (ident, pch_ident, 4) == 0)
231             /* It's a PCH for the wrong language.  */
232             cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
233                        lang_hooks.name);
234           else 
235             /* Not any kind of PCH.  */
236             cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
237         }
238       return 2;
239     }
240
241   /* At this point, we know it's a PCH file, so it ought to be long enough
242      that we can read a c_pch_validity structure.  */
243   if (read (fd, &v, sizeof (v)) != sizeof (v))
244     fatal_error ("can't read %s: %m", name);
245
246   strings_length = (v.host_machine_length + v.target_machine_length 
247                     + v.version_length);
248   if (read (fd, short_strings, strings_length) != strings_length)
249     fatal_error ("can't read %s: %m", name);
250   if (v.host_machine_length != strlen (host_machine)
251       || memcmp (host_machine, short_strings, strlen (host_machine)) != 0)
252     {
253       if (cpp_get_options (pfile)->warn_invalid_pch)
254         cpp_error (pfile, CPP_DL_WARNING, 
255                    "%s: created on host `%.*s', but used on host `%s'", name,
256                    v.host_machine_length, short_strings, host_machine);
257       return 2;
258     }
259   if (v.target_machine_length != strlen (target_machine)
260       || memcmp (target_machine, short_strings + v.host_machine_length,
261                  strlen (target_machine)) != 0)
262     {
263       if (cpp_get_options (pfile)->warn_invalid_pch)
264         cpp_error (pfile, CPP_DL_WARNING, 
265                    "%s: created for target `%.*s', but used for target `%s'", 
266                    name, v.target_machine_length, 
267                    short_strings + v.host_machine_length, target_machine);
268       return 2;
269     }
270   if (v.version_length != strlen (version_string)
271       || memcmp (version_string, 
272                  (short_strings + v.host_machine_length 
273                   + v.target_machine_length),
274                  v.version_length) != 0)
275     {
276       if (cpp_get_options (pfile)->warn_invalid_pch)
277         cpp_error (pfile, CPP_DL_WARNING,
278                    "%s: created by version `%.*s', but this is version `%s'", 
279                    name, v.version_length, 
280                    (short_strings + v.host_machine_length 
281                     + v.target_machine_length), 
282                    version_string);
283       return 2;
284     }
285
286   /* The allowable debug info combinations are that either the PCH file
287      was built with the same as is being used now, or the PCH file was
288      built for some kind of debug info but now none is in use.  */
289   if (v.debug_info_type != write_symbols
290       && write_symbols != NO_DEBUG)
291     {
292       if (cpp_get_options (pfile)->warn_invalid_pch)
293         cpp_error (pfile, CPP_DL_WARNING, 
294                    "%s: created with -g%s, but used with -g%s", name,
295                    debug_type_names[v.debug_info_type],
296                    debug_type_names[write_symbols]);
297       return 2;
298     }
299
300   /* If the text segment was not loaded at the same address as it was
301      when the PCH file was created, function pointers loaded from the
302      PCH will not be valid.  We could in theory remap all the function
303      pointers, but no support for that exists at present.  */
304   if (v.pch_init != &pch_init)
305     {
306       if (cpp_get_options (pfile)->warn_invalid_pch)
307         cpp_error (pfile, CPP_DL_WARNING, 
308                    "%s: had text segment at different address", name);
309       return 2;
310     }
311
312   /* Check the target-specific validity data.  */
313   {
314     void *this_file_data = xmalloc (v.target_data_length);
315     const char *msg;
316     
317     if ((size_t) read (fd, this_file_data, v.target_data_length)
318         != v.target_data_length)
319       fatal_error ("can't read %s: %m", name);
320     msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
321     free (this_file_data);
322     if (msg != NULL)
323       {
324         if (cpp_get_options (pfile)->warn_invalid_pch)
325           cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
326         return 2;
327       }
328   }
329
330   /* Check the preprocessor macros are the same as when the PCH was
331      generated.  */
332   
333   result = cpp_valid_state (pfile, name, fd);
334   if (result == -1)
335     return 2;
336   else
337     return result == 0;
338 }
339
340 /* Load in the PCH file NAME, open on FD.  It was originally searched for
341    by ORIG_NAME.  */
342
343 void
344 c_common_read_pch (cpp_reader *pfile, const char *name,
345                    int fd, const char *orig_name ATTRIBUTE_UNUSED)
346 {
347   FILE *f;
348   struct c_pch_header h;
349   char *buf;
350   unsigned long written;
351   struct save_macro_data *smd;
352   
353   f = fdopen (fd, "rb");
354   if (f == NULL)
355     {
356       cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
357       return;
358     }
359
360   cpp_get_callbacks (parse_in)->valid_pch = NULL;
361
362   if (fread (&h, sizeof (h), 1, f) != 1)
363     {
364       cpp_errno (pfile, CPP_DL_ERROR, "reading");
365       return;
366     }
367
368   buf = xmalloc (16384);
369   for (written = 0; written < h.asm_size; )
370     {
371       long size = h.asm_size - written;
372       if (size > 16384)
373         size = 16384;
374       if (fread (buf, size, 1, f) != 1
375           || fwrite (buf, size, 1, asm_out_file) != 1)
376         cpp_errno (pfile, CPP_DL_ERROR, "reading");
377       written += size;
378     }
379   free (buf);
380
381   cpp_prepare_state (pfile, &smd);
382
383   gt_pch_restore (f);
384
385   if (cpp_read_state (pfile, name, f, smd) != 0)
386     return;
387
388   fclose (f);
389 }
390
391 /* Indicate that no more PCH files should be read.  */
392
393 void
394 c_common_no_more_pch (void)
395 {
396   if (cpp_get_callbacks (parse_in)->valid_pch)
397     {
398       cpp_get_callbacks (parse_in)->valid_pch = NULL;
399       host_hooks.gt_pch_use_address (NULL, 0);
400     }
401 }