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