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