]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR pch/10757 (Adding -fpic/-fPIC causes crash with PCH created without -fpic/...
authorGeoffrey Keating <geoffk@apple.com>
Fri, 24 Oct 2003 21:28:13 +0000 (21:28 +0000)
committerGeoffrey Keating <geoffk@gcc.gnu.org>
Fri, 24 Oct 2003 21:28:13 +0000 (21:28 +0000)
PR 10757
* c-pch.c: Include target.h.  Improve comments.
(struct c_pch_validity): Add target_data_length.
(pch_init): Add target's validity data.
(c_common_valid_pch): Check target's validity data.
* target-def.h (TARGET_GET_PCH_VALIDITY): New.
(TARGET_PCH_VALID_P): New.
(TARGET_INITIALIZER): Add new fields.
* target.h: Include tm.h.
(struct gcc_target): Add get_pch_validity, pch_valid_p.
* toplev.h (default_get_pch_validity): New prototype.
(default_pch_valid_p): New prototype.
* toplev.c (default_get_pch_validity): New routine.
(default_pch_valid_p): New routine.
* Makefile.in (TARGET_H): Add TM_H.  Replace all users of
target.h with $(TARGET_H).
(c-pch.o): Add TARGET_H.
* doc/tm.texi (PCH Target): New node.
(TARGET_GET_PCH_VALIDITY): Document.
(TARGET_PCH_VALID_P): Document.

From-SVN: r72909

gcc/ChangeLog
gcc/Makefile.in
gcc/c-pch.c
gcc/doc/tm.texi
gcc/target-def.h
gcc/target.h
gcc/toplev.c
gcc/toplev.h

index a392a2a42f9cb5d4dd9b628540a2b72f7b20a271..2fcdbce9952bd59df224e5ed6a6b52f17f5c2254 100644 (file)
@@ -1,3 +1,26 @@
+2003-10-24  Geoffrey Keating  <geoffk@apple.com>
+
+       PR 10757
+       * c-pch.c: Include target.h.  Improve comments.
+       (struct c_pch_validity): Add target_data_length.
+       (pch_init): Add target's validity data.
+       (c_common_valid_pch): Check target's validity data.
+       * target-def.h (TARGET_GET_PCH_VALIDITY): New.
+       (TARGET_PCH_VALID_P): New.
+       (TARGET_INITIALIZER): Add new fields.
+       * target.h: Include tm.h.
+       (struct gcc_target): Add get_pch_validity, pch_valid_p.
+       * toplev.h (default_get_pch_validity): New prototype.
+       (default_pch_valid_p): New prototype.
+       * toplev.c (default_get_pch_validity): New routine.
+       (default_pch_valid_p): New routine.
+       * Makefile.in (TARGET_H): Add TM_H.  Replace all users of
+       target.h with $(TARGET_H).
+       (c-pch.o): Add TARGET_H.
+       * doc/tm.texi (PCH Target): New node.
+       (TARGET_GET_PCH_VALIDITY): Document.
+       (TARGET_PCH_VALID_P): Document.
+
 2003-10-24  Kelley Cook  <kcook@gcc.gnu.org>
 
        * Makefile.in: Define a vpath for %.texi.  Remove explicit $(docdir)
index ef9ba4aa6f0800df9bbab9d55f83d1dfca860e68..6097e1feb0ae7e9533d0e66a3f665887feef897b 100644 (file)
@@ -640,7 +640,7 @@ TM_P_H    = tm_p.h    $(tm_p_file_list)
 GTM_H     = tm.h      $(tm_file_list)
 TM_H      = $(GTM_H) insn-constants.h insn-flags.h
 
-TARGET_H = target.h
+TARGET_H = $(TM_H) target.h
 HOOKS_H = hooks.h
 LANGHOOKS_DEF_H = langhooks-def.h $(HOOKS_H)
 TARGET_DEF_H = target-def.h $(HOOKS_H)
@@ -1371,7 +1371,7 @@ c-dump.o : c-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
 
 c-pch.o : c-pch.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) $(TREE_H) \
        $(C_COMMON_H) output.h toplev.h c-pragma.h $(GGC_H) debug.h \
-       langhooks.h flags.h hosthooks.h version.h
+       langhooks.h flags.h hosthooks.h version.h $(TARGET_H)
        $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
          -DHOST_MACHINE=\"$(host)\" -DTARGET_MACHINE=\"$(target)\" \
          $< $(OUTPUT_OPTION)
@@ -1580,7 +1580,7 @@ explow.o : explow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_
 optabs.o : optabs.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
    flags.h insn-config.h $(EXPR_H) $(OPTABS_H) libfuncs.h $(RECOG_H) reload.h \
    toplev.h $(GGC_H) real.h $(TM_P_H) except.h gt-optabs.h $(BASIC_BLOCK_H) \
-   target.h
+   $(TARGET_H)
 dbxout.o : dbxout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) $(RTL_H) \
    flags.h $(REGS_H) debug.h $(TM_P_H) $(TARGET_H) function.h langhooks.h \
    insn-config.h reload.h gstab.h xcoffout.h output.h dbxout.h toplev.h \
@@ -1822,7 +1822,7 @@ regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h $(RECOG_H) function.h \
    resource.h $(OBSTACK_H) flags.h $(TM_P_H)
 ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
-   $(REGS_H) toplev.h flags.h insn-config.h function.h $(RECOG_H) target.h \
+   $(REGS_H) toplev.h flags.h insn-config.h function.h $(RECOG_H) $(TARGET_H) \
    $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) real.h $(OPTABS_H) \
    cfgloop.h
 params.o : params.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(PARAMS_H) toplev.h
index f7830b2ba279cb6ae864d454686f4f7a0d9c62da..2a29075d5a399b3bb355735e4c06e9bb84bbd49a 100644 (file)
@@ -33,6 +33,7 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "langhooks.h"
 #include "hosthooks.h"
+#include "target.h"
 
 /* This structure is read very early when validating the PCH, and
    might be read for a PCH which is for a completely different compiler
@@ -40,7 +41,10 @@ Boston, MA 02111-1307, USA.  */
    'unsigned char' entries, at least in the initial entries.  
 
    If you add or change entries before version_length, you should increase
-   the version number in get_ident().  */
+   the version number in get_ident().  
+
+   There are a bunch of fields named *_length; those are lengths of data that
+   follows this structure in the same order as the fields in the structure.  */
 
 struct c_pch_validity
 {
@@ -49,6 +53,7 @@ struct c_pch_validity
   unsigned char version_length;
   unsigned char debug_info_type;
   void (*pch_init) (void);
+  size_t target_data_length;
 };
 
 struct c_pch_header 
@@ -96,6 +101,7 @@ pch_init (void)
 {
   FILE *f;
   struct c_pch_validity v;
+  void *target_validity;
   
   if (! pch_file)
     return;
@@ -112,14 +118,16 @@ pch_init (void)
   v.host_machine_length = strlen (host_machine);
   v.target_machine_length = strlen (target_machine);
   v.version_length = strlen (version_string);
-  
   v.debug_info_type = write_symbols;
   v.pch_init = &pch_init;
+  target_validity = targetm.get_pch_validity (&v.target_data_length);
+  
   if (fwrite (get_ident(), IDENT_LENGTH, 1, f) != 1
       || fwrite (&v, sizeof (v), 1, f) != 1
       || fwrite (host_machine, v.host_machine_length, 1, f) != 1
       || fwrite (target_machine, v.target_machine_length, 1, f) != 1
-      || fwrite (version_string, v.version_length, 1, f) != 1)
+      || fwrite (version_string, v.version_length, 1, f) != 1
+      || 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.  */
@@ -184,8 +192,10 @@ c_common_write_pch (void)
   fclose (pch_outfile);
 }
 
-/* Check the PCH file called NAME, open on FD, to see if it can be used
-   in this compilation.  */
+/* Check the PCH file called NAME, open on FD, to see if it can be
+   used in this compilation.  Return 1 if valid, 0 if the file can't
+   be used now but might be if it's seen later in the compilation, and
+   2 if this file could never be used in the compilation.  */
 
 int
 c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
@@ -299,6 +309,24 @@ c_common_valid_pch (cpp_reader *pfile, const char *name, int fd)
       return 2;
     }
 
+  /* Check the target-specific validity data.  */
+  {
+    void *this_file_data = xmalloc (v.target_data_length);
+    const char *msg;
+    
+    if ((size_t) read (fd, this_file_data, v.target_data_length)
+       != v.target_data_length)
+      fatal_error ("can't read %s: %m", name);
+    msg = targetm.pch_valid_p (this_file_data, v.target_data_length);
+    free (this_file_data);
+    if (msg != NULL)
+      {
+       if (cpp_get_options (pfile)->warn_invalid_pch)
+         cpp_error (pfile, DL_WARNING, "%s: %s", name, msg);
+       return 2;
+      }
+  }
+
   /* Check the preprocessor macros are the same as when the PCH was
      generated.  */
   
index 8a0ff9bbe63fbda90ca0064f07e54d82f1de18dd..09f8295e9ee4fdfab3f3b85b45534dd37bd4b3fc 100644 (file)
@@ -50,6 +50,7 @@ through the macros defined in the @file{.h} file.
 * Mode Switching::      Insertion of mode-switching instructions.
 * Target Attributes::   Defining target-specific uses of @code{__attribute__}.
 * MIPS Coprocessors::   MIPS coprocessor support and how to customize it.
+* PCH Target::          Validity checking for precompiled headers.
 * Misc::                Everything else.
 @end menu
 
@@ -8387,6 +8388,30 @@ alternate names of coprocessor registers.  The format of each entry should be
 Default: empty.
 @end defmac
 
+@node PCH Target
+@section Parameters for Precompiled Header Validity Checking
+@cindex parameters, precompiled headers
+
+@deftypefn {Target Hook} void * TARGET_GET_PCH_VALIDITY (size_t * @var{sz})
+Define this hook if your target needs to check a different collection
+of flags than the default, which is every flag defined by
+@code{TARGET_SWITCHES} and @code{TARGET_OPTIONS}.  It should return
+some data which will be saved in the PCH file and presented to
+@code{TARGET_PCH_VALID_P} later; it should set @code{SZ} to the size
+of the data.
+@end deftypefn
+
+@deftypefn {Target Hook} const char * TARGET_PCH_VALID_P (const void * @var{data}, size_t @var{sz})
+Define this hook if your target needs to check a different collection of
+flags than the default, which is every flag defined by @code{TARGET_SWITCHES}
+and @code{TARGET_OPTIONS}.  It is given data which came from
+@code{TARGET_GET_PCH_VALIDITY} (in this version of this compiler, so there
+is no need for extensive validity checking).  It returns @code{NULL} if
+it is safe to load a PCH file with this data, or a suitable error message
+if not.  The error message will be presented to the user, so it should
+be localised.
+@end deftypefn
+
 @node Misc
 @section Miscellaneous Parameters
 @cindex parameters, miscellaneous
index 3f35e2e90d80dc661ce4a3a7d9b6edbea1d410e9..5c7fcb0b9df025276593f954e3f8da9500df492e 100644 (file)
@@ -316,6 +316,9 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 #define TARGET_MACHINE_DEPENDENT_REORG 0
 
+#define TARGET_GET_PCH_VALIDITY default_get_pch_validity
+#define TARGET_PCH_VALID_P default_pch_valid_p
+
 #define TARGET_PROMOTE_FUNCTION_ARGS default_promote_function_args
 #define TARGET_PROMOTE_FUNCTION_RETURN default_promote_function_return
 #define TARGET_PROMOTE_PROTOTYPES default_promote_prototypes
@@ -358,7 +361,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   TARGET_INIT_LIBFUNCS,                                \
   TARGET_SECTION_TYPE_FLAGS,                   \
   TARGET_CANNOT_MODIFY_JUMPS_P,                        \
-  TARGET_BRANCH_TARGET_REGISTER_CLASS, \
+  TARGET_BRANCH_TARGET_REGISTER_CLASS,         \
   TARGET_BRANCH_TARGET_REGISTER_CALLEE_SAVED,  \
   TARGET_CANNOT_FORCE_CONST_MEM,               \
   TARGET_CANNOT_COPY_INSN_P,                   \
@@ -374,6 +377,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
   TARGET_ADDRESS_COST,                         \
   TARGET_DWARF_REGISTER_SPAN,                   \
   TARGET_MACHINE_DEPENDENT_REORG,              \
+  TARGET_GET_PCH_VALIDITY,                     \
+  TARGET_PCH_VALID_P,                          \
   TARGET_HAVE_NAMED_SECTIONS,                  \
   TARGET_HAVE_CTORS_DTORS,                     \
   TARGET_HAVE_TLS,                             \
index 8d77dfde2d058685e3121764643a414ed34f7aba..0b19445456aa4de01a7685249a7c2942acd49c12 100644 (file)
@@ -44,6 +44,8 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
    to gradually reduce the amount of conditional compilation that is
    scattered throughout GCC.  */
 
+#include "tm.h"
+
 struct gcc_target
 {
   /* Functions that output assembler for the target.  */
@@ -380,6 +382,15 @@ struct gcc_target
      delayed-branch scheduling.  */
   void (* machine_dependent_reorg) (void);
 
+  /* Validity-checking routines for PCH files, target-specific.
+     get_pch_validity returns a pointer to the data to be stored,
+     and stores the size in its argument.  pch_valid_p gets the same
+     information back and returns NULL if the PCH is valid,
+     or an error message if not.
+  */
+  void * (* get_pch_validity) (size_t *);
+  const char * (* pch_valid_p) (const void *, size_t);
+
   /* Leave the boolean fields at the end.  */
 
   /* True if arbitrary sections are supported.  */
index 41b27edd910295cfa19facf1c5a4b0ccad2d9bab..3e350bf08e3d9e91a323a0f16fc8a253c0482539 100644 (file)
@@ -4099,6 +4099,115 @@ init_asm_output (const char *name)
     }
 }
 
+/* Default version of get_pch_validity.
+   By default, every flag difference is fatal; that will be mostly right for
+   most targets, but completely right for very few.  */
+
+void *
+default_get_pch_validity (size_t *len)
+{
+  size_t i;
+  char *result, *r;
+  
+  *len = sizeof (target_flags) + 2;
+  for (i = 0; i < ARRAY_SIZE (target_options); i++)
+    {
+      *len += 1;
+      if (*target_options[i].variable)
+       *len += strlen (*target_options[i].variable);
+    }
+
+  result = r = xmalloc (*len);
+  r[0] = flag_pic;
+  r[1] = flag_pie;
+  r += 2;
+  memcpy (r, &target_flags, sizeof (target_flags));
+  r += sizeof (target_flags);
+  
+  for (i = 0; i < ARRAY_SIZE (target_options); i++)
+    {
+      const char *str = *target_options[i].variable;
+      size_t l;
+      if (! str)
+       str = "";
+      l = strlen (str) + 1;
+      memcpy (r, str, l);
+      r += l;
+    }
+
+  return result;
+}
+
+/* Default version of pch_valid_p.  */
+
+const char *
+default_pch_valid_p (const void *data_p, size_t len)
+{
+  const char *data = (const char *)data_p;
+  const char *flag_that_differs = NULL;
+  size_t i;
+  
+  /* -fpic and -fpie also usually make a PCH invalid.  */
+  if (data[0] != flag_pic)
+    return _("created and used with different settings of -fpic");
+  if (data[1] != flag_pie)
+    return _("created and used with different settings of -fpie");
+  data += 2;
+
+  /* Check target_flags.  */
+  if (memcmp (data, &target_flags, sizeof (target_flags)) != 0)
+    {
+      for (i = 0; i < ARRAY_SIZE (target_switches); i++)
+       {
+         int bits;
+         int tf;
+
+         memcpy (&tf, data, sizeof (target_flags));
+
+         bits = target_switches[i].value;
+         if (bits < 0)
+           bits = -bits;
+         if ((target_flags & bits) != (tf & bits))
+           {
+             flag_that_differs = target_switches[i].name;
+             goto make_message;
+           }
+       }
+      abort ();
+    }
+  data += sizeof (target_flags);
+  len -= sizeof (target_flags);
+  
+  /* Check string options.  */
+  for (i = 0; i < ARRAY_SIZE (target_options); i++)
+    {
+      const char *str = *target_options[i].variable;
+      size_t l;
+      if (! str)
+       str = "";
+      l = strlen (str) + 1;
+      if (len < l || memcmp (data, str, l) != 0)
+       {
+         flag_that_differs = target_options[i].prefix;
+         goto make_message;
+       }
+      data += l;
+      len -= l;
+    }
+
+  return NULL;
+  
+ make_message:
+  {
+    char *r;
+    asprintf (&r, _("created and used with differing settings of `-m%s'"),
+                 flag_that_differs);
+    if (r == NULL)
+      r = _("out of memory");
+    return r;
+  }
+}
+
 /* Default tree printer.   Handles declarations only.  */
 static bool
 default_tree_printer (pretty_printer * pp, text_info *text)
index ae05f4b22ec0b5ef40a380d41db3591bc87ef813..5a8b5813f09c1bedfcac7fd3489d32a0a2f7ca42 100644 (file)
@@ -124,9 +124,12 @@ extern int flag_ssa_dce;
 extern int time_report;
 extern int flag_new_regalloc;
 
+/* Things to do with target switches.  */
 extern void display_target_options (void);
 extern void print_version (FILE *, const char *);
 extern void set_target_switch (const char *);
+extern void * default_get_pch_validity (size_t *);
+extern const char * default_pch_valid_p (const void *, size_t);
 
 /* The hashtable, so that the C front ends can pass it to cpplib.  */
 extern struct ht *ident_hash;