2013-02-13 Jakub Jelinek PR pch/54117 Revert 2012-07-14 Steven Bosscher * toplev.c (init_asm_output): Open asm_out_file in 'w' mode. * c-pch.c (CHECK_NO_ASM_OUT_DURING_PCH): Do not define. Remove code conditional on it. 2012-07-01 Uros Bizjak * c-pch.c (c_common_write_pch): Remove unused variables. 2012-06-21 Steven Bosscher * c-common.h (c_common_print_pch_checksum): Remove. * c-pch.c: Do not include output.h. (CHECK_NO_ASM_OUT_DURING_PCH): Define and add FIXME. (asm_out_file): Define iff CHECK_NO_ASM_OUT_DURING_PCH isdefined. (asm_file_startpos): Define iff CHECK_NO_ASM_OUT_DURING_PCH is defined. (struct c_pch_header): Remove. (get_ident): Update gpch version. (pch_init): Do not print executable_checksum to asm_out_file. Do not fail if there is no asm_out_file to read back from. Set asm_file_startpos only if CHECK_NO_ASM_OUT_DURING_PCH is defined. (c_common_write_pch): Verify that nothing was written to asm_out_file since pch_init was called. Do not write a c_pch_header, and do not copy from asm_out_file to the PCH. (c_common_read_pch): Do not read a c_pch_header, and do not restore the content of asm_out_file from the PCH. (c_common_print_pch_checksum): Remove. * c-opts.c (c_common_init): Print out executable_checksum directly. --- gcc/toplev.c.jj 2013-02-13 09:29:16.197757222 +0100 +++ gcc/toplev.c 2013-02-13 11:34:38.855800182 +0100 @@ -912,7 +912,7 @@ init_asm_output (const char *name) if (!strcmp (asm_file_name, "-")) asm_out_file = stdout; else - asm_out_file = fopen (asm_file_name, "w"); + asm_out_file = fopen (asm_file_name, "w+b"); if (asm_out_file == 0) fatal_error ("can%'t open %s for writing: %m", asm_file_name); } --- gcc/c-family/c-pch.c.jj 2013-02-13 09:29:16.065757956 +0100 +++ gcc/c-family/c-pch.c 2013-02-13 11:34:45.552761549 +0100 @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. #include "tree.h" #include "flags.h" #include "c-common.h" +#include "output.h" /* for asm_out_file */ #include "debug.h" #include "c-pragma.h" #include "ggc.h" @@ -67,11 +68,19 @@ struct c_pch_validity size_t target_data_length; }; +struct c_pch_header +{ + unsigned long asm_size; +}; + #define IDENT_LENGTH 8 /* The file we'll be writing the PCH to. */ static FILE *pch_outfile; +/* The position in the assembler output file when pch_init was called. */ +static long asm_file_startpos; + static const char *get_ident (void); /* Compute an appropriate 8-byte magic number for the PCH file, so that @@ -83,7 +92,7 @@ static const char * get_ident (void) { static char result[IDENT_LENGTH]; - static const char templ[] = "gpch.014"; + static const char templ[] = "gpch.013"; static const char c_language_chars[] = "Co+O"; memcpy (result, templ, IDENT_LENGTH); @@ -97,7 +106,9 @@ get_ident (void) static bool pch_ready_to_save_cpp_state = false; /* Prepare to write a PCH file, if one is being written. This is - called at the start of compilation. */ + called at the start of compilation. + + Also, print out the executable checksum if -fverbose-asm is in effect. */ void pch_init (void) @@ -107,6 +118,15 @@ pch_init (void) void *target_validity; static const char partial_pch[] = "gpcWrite"; +#ifdef ASM_COMMENT_START + if (flag_verbose_asm) + { + fprintf (asm_out_file, "%s ", ASM_COMMENT_START); + c_common_print_pch_checksum (asm_out_file); + fputc ('\n', asm_out_file); + } +#endif + if (!pch_file) return; @@ -136,6 +156,14 @@ pch_init (void) || fwrite (target_validity, v.target_data_length, 1, f) != 1) fatal_error ("can%'t write to %s: %m", pch_file); + /* We need to be able to re-read the output. */ + /* The driver always provides a valid -o option. */ + if (asm_file_name == NULL + || strcmp (asm_file_name, "-") == 0) + fatal_error ("%qs is not a valid output file", asm_file_name); + + asm_file_startpos = ftell (asm_out_file); + /* Let the debugging format deal with the PCHness. */ (*debug_hooks->handle_pch) (0); @@ -172,6 +200,11 @@ pch_cpp_save_state (void) void c_common_write_pch (void) { + char *buf; + long asm_file_end; + long written; + struct c_pch_header h; + timevar_push (TV_PCH_SAVE); targetm.prepare_pch_save (); @@ -180,6 +213,34 @@ c_common_write_pch (void) cpp_write_pch_deps (parse_in, pch_outfile); + asm_file_end = ftell (asm_out_file); + h.asm_size = asm_file_end - asm_file_startpos; + + if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1) + fatal_error ("can%'t write %s: %m", pch_file); + + buf = XNEWVEC (char, 16384); + + if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0) + fatal_error ("can%'t seek in %s: %m", asm_file_name); + + for (written = asm_file_startpos; written < asm_file_end; ) + { + long size = asm_file_end - written; + if (size > 16384) + size = 16384; + if (fread (buf, size, 1, asm_out_file) != 1) + fatal_error ("can%'t read %s: %m", asm_file_name); + if (fwrite (buf, size, 1, pch_outfile) != 1) + fatal_error ("can%'t write %s: %m", pch_file); + written += size; + } + free (buf); + /* asm_out_file can be written afterwards, so fseek to clear + _IOREAD flag. */ + if (fseek (asm_out_file, 0, SEEK_END) != 0) + fatal_error ("can%'t seek in %s: %m", asm_file_name); + gt_pch_save (pch_outfile); timevar_push (TV_PCH_CPP_SAVE); @@ -341,6 +402,7 @@ c_common_read_pch (cpp_reader *pfile, co int fd, const char *orig_name ATTRIBUTE_UNUSED) { FILE *f; + struct c_pch_header h; struct save_macro_data *smd; expanded_location saved_loc; bool saved_trace_includes; @@ -357,6 +419,38 @@ c_common_read_pch (cpp_reader *pfile, co cpp_get_callbacks (parse_in)->valid_pch = NULL; + if (fread (&h, sizeof (h), 1, f) != 1) + { + cpp_errno (pfile, CPP_DL_ERROR, "reading"); + fclose (f); + goto end; + } + + if (!flag_preprocess_only) + { + unsigned long written; + char * buf = XNEWVEC (char, 16384); + + for (written = 0; written < h.asm_size; ) + { + long size = h.asm_size - written; + if (size > 16384) + size = 16384; + if (fread (buf, size, 1, f) != 1 + || fwrite (buf, size, 1, asm_out_file) != 1) + cpp_errno (pfile, CPP_DL_ERROR, "reading"); + written += size; + } + free (buf); + } + else + { + /* If we're preprocessing, don't write to a NULL + asm_out_file. */ + if (fseek (f, h.asm_size, SEEK_CUR) != 0) + cpp_errno (pfile, CPP_DL_ERROR, "seeking"); + } + /* Save the location and then restore it after reading the PCH. */ saved_loc = expand_location (line_table->highest_line); saved_trace_includes = line_table->trace_includes; @@ -435,3 +529,14 @@ c_common_pch_pragma (cpp_reader *pfile, close (fd); } +/* Print out executable_checksum[]. */ + +void +c_common_print_pch_checksum (FILE *f) +{ + int i; + fputs ("Compiler executable checksum: ", f); + for (i = 0; i < 16; i++) + fprintf (f, "%02x", executable_checksum[i]); + putc ('\n', f); +} --- gcc/c-family/c-opts.c.jj 2013-02-13 09:29:16.110757723 +0100 +++ gcc/c-family/c-opts.c 2013-02-13 11:34:45.551761562 +0100 @@ -999,13 +999,7 @@ c_common_init (void) cpp_init_iconv (parse_in); if (version_flag) - { - int i; - fputs ("Compiler executable checksum: ", stderr); - for (i = 0; i < 16; i++) - fprintf (stderr, "%02x", executable_checksum[i]); - putc ('\n', stderr); - } + c_common_print_pch_checksum (stderr); /* Has to wait until now so that cpplib has its hash table. */ init_pragma (); --- gcc/c-family/c-common.h.jj 2013-02-13 09:29:16.152757462 +0100 +++ gcc/c-family/c-common.h 2013-02-13 11:34:45.551761562 +0100 @@ -1011,6 +1011,7 @@ extern void c_common_read_pch (cpp_reade extern void c_common_write_pch (void); extern void c_common_no_more_pch (void); extern void c_common_pch_pragma (cpp_reader *pfile, const char *); +extern void c_common_print_pch_checksum (FILE *f); /* In *-checksum.c */ extern const unsigned char executable_checksum[16];