OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [gcc/] [c-pch.c] - Blame information for rev 826

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.