c-pch.c revision 161651
1/* Precompiled header implementation for the C languages.
2   Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, 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   The flags_info field is used to verify that certain flags settings that
50   have to be the same during the compilation of the PCH and a compilation
51   using the PCH are indeed the same.  */
52
53struct c_pch_validity
54{
55  unsigned char host_machine_length;
56  unsigned char target_machine_length;
57  unsigned char version_length;
58  unsigned char debug_info_type;
59  unsigned int flags_info;
60  void (*pch_init) (void);
61  size_t target_data_length;
62};
63
64/* If -funit-at-a-time is set, we require that it was also set during the
65   compilation of the PCH we may be using.  */
66#define FLAG_UNIT_AT_A_TIME_SET 1 << 0
67
68struct c_pch_header
69{
70  unsigned long asm_size;
71};
72
73#define IDENT_LENGTH 8
74
75/* The file we'll be writing the PCH to.  */
76static FILE *pch_outfile;
77
78/* The position in the assembler output file when pch_init was called.  */
79static long asm_file_startpos;
80
81/* The host and target machines.  */
82static const char host_machine[] = HOST_MACHINE;
83static const char target_machine[] = TARGET_MACHINE;
84
85static const char *get_ident (void);
86
87/* Compute an appropriate 8-byte magic number for the PCH file, so that
88   utilities like file(1) can identify it, and so that GCC can quickly
89   ignore non-PCH files and PCH files that are of a completely different
90   format.  */
91
92static const char *
93get_ident(void)
94{
95  static char result[IDENT_LENGTH];
96  static const char template[IDENT_LENGTH] = "gpch.012";
97  static const char c_language_chars[] = "Co+O";
98
99  memcpy (result, template, IDENT_LENGTH);
100  result[4] = c_language_chars[c_language];
101
102  return result;
103}
104
105/* Prepare to write a PCH file.  This is called at the start of
106   compilation.  */
107
108void
109pch_init (void)
110{
111  FILE *f;
112  struct c_pch_validity v;
113  void *target_validity;
114  static const char partial_pch[IDENT_LENGTH] = "gpcWrite";
115  unsigned int current_flags_info = 0;
116
117  if (! pch_file)
118    return;
119
120  if (flag_unit_at_a_time)
121    current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
122
123  f = fopen (pch_file, "w+b");
124  if (f == NULL)
125    fatal_error ("can't create precompiled header %s: %m", pch_file);
126  pch_outfile = f;
127
128  if (strlen (host_machine) > 255 || strlen (target_machine) > 255
129      || strlen (version_string) > 255)
130    abort ();
131
132  v.host_machine_length = strlen (host_machine);
133  v.target_machine_length = strlen (target_machine);
134  v.version_length = strlen (version_string);
135  v.debug_info_type = write_symbols;
136  v.flags_info = current_flags_info;
137  v.pch_init = &pch_init;
138  target_validity = targetm.get_pch_validity (&v.target_data_length);
139
140  if (fwrite (partial_pch, IDENT_LENGTH, 1, f) != 1
141      || fwrite (&v, sizeof (v), 1, f) != 1
142      || fwrite (host_machine, v.host_machine_length, 1, f) != 1
143      || fwrite (target_machine, v.target_machine_length, 1, f) != 1
144      || fwrite (version_string, v.version_length, 1, f) != 1
145      || fwrite (target_validity, v.target_data_length, 1, f) != 1)
146    fatal_error ("can't write to %s: %m", pch_file);
147
148  /* We need to be able to re-read the output.  */
149  /* The driver always provides a valid -o option.  */
150  if (asm_file_name == NULL
151      || strcmp (asm_file_name, "-") == 0)
152    fatal_error ("`%s' is not a valid output file", asm_file_name);
153
154  asm_file_startpos = ftell (asm_out_file);
155
156  /* Let the debugging format deal with the PCHness.  */
157  (*debug_hooks->handle_pch) (0);
158
159  cpp_save_state (parse_in, f);
160}
161
162/* Write the PCH file.  This is called at the end of a compilation which
163   will produce a PCH file.  */
164
165void
166c_common_write_pch (void)
167{
168  char *buf;
169  long asm_file_end;
170  long written;
171  struct c_pch_header h;
172
173  (*debug_hooks->handle_pch) (1);
174
175  cpp_write_pch_deps (parse_in, pch_outfile);
176
177  asm_file_end = ftell (asm_out_file);
178  h.asm_size = asm_file_end - asm_file_startpos;
179
180  if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
181    fatal_error ("can't write %s: %m", pch_file);
182
183  buf = xmalloc (16384);
184  fflush (asm_out_file);
185
186  if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
187    fatal_error ("can't seek in %s: %m", asm_file_name);
188
189  for (written = asm_file_startpos; written < asm_file_end; )
190    {
191      long size = asm_file_end - written;
192      if (size > 16384)
193	size = 16384;
194      if (fread (buf, size, 1, asm_out_file) != 1)
195	fatal_error ("can't read %s: %m", asm_file_name);
196      if (fwrite (buf, size, 1, pch_outfile) != 1)
197	fatal_error ("can't write %s: %m", pch_file);
198      written += size;
199    }
200  free (buf);
201  /* asm_out_file can be written afterwards, so must be flushed first.  */
202  fflush (asm_out_file);
203
204  gt_pch_save (pch_outfile);
205  cpp_write_pch_state (parse_in, pch_outfile);
206
207  if (fseek (pch_outfile, 0, SEEK_SET) != 0
208      || fwrite (get_ident (), IDENT_LENGTH, 1, pch_outfile) != 1)
209    fatal_error ("can't write %s: %m", pch_file);
210
211  fclose (pch_outfile);
212}
213
214/* Check the PCH file called NAME, open on FD, to see if it can be
215   used in this compilation.  Return 1 if valid, 0 if the file can't
216   be used now but might be if it's seen later in the compilation, and
217   2 if this file could never be used in the compilation.  */
218
219int
220c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
221{
222  int sizeread;
223  int result;
224  char ident[IDENT_LENGTH];
225  char short_strings[256 * 3];
226  int strings_length;
227  const char *pch_ident;
228  struct c_pch_validity v;
229  unsigned int current_flags_info = 0;
230
231  if (flag_unit_at_a_time)
232    current_flags_info |= FLAG_UNIT_AT_A_TIME_SET;
233
234  /* Perform a quick test of whether this is a valid
235     precompiled header for the current language
236     and with the current flag settings.  */
237
238  sizeread = read (fd, ident, IDENT_LENGTH);
239  if (sizeread == -1)
240    fatal_error ("can't read %s: %m", name);
241  else if (sizeread != IDENT_LENGTH)
242    return 2;
243
244  pch_ident = get_ident();
245  if (memcmp (ident, pch_ident, IDENT_LENGTH) != 0)
246    {
247      if (cpp_get_options (pfile)->warn_invalid_pch)
248	{
249	  if (memcmp (ident, pch_ident, 5) == 0)
250	    /* It's a PCH, for the right language, but has the wrong version.
251	     */
252	    cpp_error (pfile, CPP_DL_WARNING,
253		       "%s: not compatible with this GCC version", name);
254	  else if (memcmp (ident, pch_ident, 4) == 0)
255	    /* It's a PCH for the wrong language.  */
256	    cpp_error (pfile, CPP_DL_WARNING, "%s: not for %s", name,
257		       lang_hooks.name);
258	  else
259	    /* Not any kind of PCH.  */
260	    cpp_error (pfile, CPP_DL_WARNING, "%s: not a PCH file", name);
261	}
262      return 2;
263    }
264
265  /* At this point, we know it's a PCH file, so it ought to be long enough
266     that we can read a c_pch_validity structure.  */
267  if (read (fd, &v, sizeof (v)) != sizeof (v))
268    fatal_error ("can't read %s: %m", name);
269
270  strings_length = (v.host_machine_length + v.target_machine_length
271		    + v.version_length);
272  if (read (fd, short_strings, strings_length) != strings_length)
273    fatal_error ("can't read %s: %m", name);
274  if (v.host_machine_length != strlen (host_machine)
275      || memcmp (host_machine, short_strings, strlen (host_machine)) != 0)
276    {
277      if (cpp_get_options (pfile)->warn_invalid_pch)
278	cpp_error (pfile, CPP_DL_WARNING,
279		   "%s: created on host `%.*s', but used on host `%s'", name,
280		   v.host_machine_length, short_strings, host_machine);
281      return 2;
282    }
283  if (v.target_machine_length != strlen (target_machine)
284      || memcmp (target_machine, short_strings + v.host_machine_length,
285		 strlen (target_machine)) != 0)
286    {
287      if (cpp_get_options (pfile)->warn_invalid_pch)
288	cpp_error (pfile, CPP_DL_WARNING,
289		   "%s: created for target `%.*s', but used for target `%s'",
290		   name, v.target_machine_length,
291		   short_strings + v.host_machine_length, target_machine);
292      return 2;
293    }
294  if (v.version_length != strlen (version_string)
295      || memcmp (version_string,
296		 (short_strings + v.host_machine_length
297		  + v.target_machine_length),
298		 v.version_length) != 0)
299    {
300      if (cpp_get_options (pfile)->warn_invalid_pch)
301	cpp_error (pfile, CPP_DL_WARNING,
302		   "%s: created by version `%.*s', but this is version `%s'",
303		   name, v.version_length,
304		   (short_strings + v.host_machine_length
305		    + v.target_machine_length),
306		   version_string);
307      return 2;
308    }
309  if (v.flags_info != current_flags_info)
310    {
311      if (cpp_get_options (pfile)->warn_invalid_pch)
312	cpp_error (pfile, CPP_DL_WARNING,
313		   "%s: created using different flags",
314		   name);
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  /* If the text segment was not loaded at the same address as it was
333     when the PCH file was created, function pointers loaded from the
334     PCH will not be valid.  We could in theory remap all the function
335     pointers, but no support for that exists at present.  */
336  if (v.pch_init != &pch_init)
337    {
338      if (cpp_get_options (pfile)->warn_invalid_pch)
339	cpp_error (pfile, CPP_DL_WARNING,
340		   "%s: had text segment at different address", name);
341      return 2;
342    }
343
344  /* Check the target-specific validity data.  */
345  {
346    void *this_file_data = xmalloc (v.target_data_length);
347    const char *msg;
348
349    if ((size_t) read (fd, this_file_data, v.target_data_length)
350	!= v.target_data_length)
351      fatal_error ("can't read %s: %m", name);
352    msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
353    free (this_file_data);
354    if (msg != NULL)
355      {
356	if (cpp_get_options (pfile)->warn_invalid_pch)
357	  cpp_error (pfile, CPP_DL_WARNING, "%s: %s", name, msg);
358	return 2;
359      }
360  }
361
362  /* Check the preprocessor macros are the same as when the PCH was
363     generated.  */
364
365  result = cpp_valid_state (pfile, name, fd);
366  if (result == -1)
367    return 2;
368  else
369    return result == 0;
370}
371
372/* Load in the PCH file NAME, open on FD.  It was originally searched for
373   by ORIG_NAME.  */
374
375void
376c_common_read_pch (cpp_reader *pfile, const char *name,
377		   int fd, const char *orig_name ATTRIBUTE_UNUSED)
378{
379  FILE *f;
380  struct c_pch_header h;
381  char *buf;
382  unsigned long written;
383  struct save_macro_data *smd;
384
385  f = fdopen (fd, "rb");
386  if (f == NULL)
387    {
388      cpp_errno (pfile, CPP_DL_ERROR, "calling fdopen");
389      return;
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      return;
398    }
399
400  buf = xmalloc (16384);
401  for (written = 0; written < h.asm_size; )
402    {
403      long size = h.asm_size - written;
404      if (size > 16384)
405	size = 16384;
406      if (fread (buf, size, 1, f) != 1
407	  || fwrite (buf, size, 1, asm_out_file) != 1)
408	cpp_errno (pfile, CPP_DL_ERROR, "reading");
409      written += size;
410    }
411  free (buf);
412
413  cpp_prepare_state (pfile, &smd);
414
415  gt_pch_restore (f);
416
417  if (cpp_read_state (pfile, name, f, smd) != 0)
418    return;
419
420  fclose (f);
421}
422
423/* Indicate that no more PCH files should be read.  */
424
425void
426c_common_no_more_pch (void)
427{
428  if (cpp_get_callbacks (parse_in)->valid_pch)
429    {
430      cpp_get_callbacks (parse_in)->valid_pch = NULL;
431      host_hooks.gt_pch_use_address (NULL, 0, -1, 0);
432    }
433}
434