summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-24 21:28:13 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-24 21:28:13 +0000
commit7988d6e261f71ae9e293e727e7286c860d4ed8d2 (patch)
treed43094488963890ba2a849eb20c57b70ebe80264
parent262c6367352ee365cb78533d503308e0d2d64c6d (diff)
downloadgcc-7988d6e261f71ae9e293e727e7286c860d4ed8d2.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72909 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/Makefile.in8
-rw-r--r--gcc/c-pch.c38
-rw-r--r--gcc/doc/tm.texi25
-rw-r--r--gcc/target-def.h7
-rw-r--r--gcc/target.h11
-rw-r--r--gcc/toplev.c109
-rw-r--r--gcc/toplev.h3
8 files changed, 214 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a392a2a42f9..2fcdbce9952 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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)
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index ef9ba4aa6f0..6097e1feb0a 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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
diff --git a/gcc/c-pch.c b/gcc/c-pch.c
index f7830b2ba27..2a29075d5a3 100644
--- a/gcc/c-pch.c
+++ b/gcc/c-pch.c
@@ -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. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 8a0ff9bbe63..09f8295e9ee 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
diff --git a/gcc/target-def.h b/gcc/target-def.h
index 3f35e2e90d8..5c7fcb0b9df 100644
--- a/gcc/target-def.h
+++ b/gcc/target-def.h
@@ -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, \
diff --git a/gcc/target.h b/gcc/target.h
index 8d77dfde2d0..0b19445456a 100644
--- a/gcc/target.h
+++ b/gcc/target.h
@@ -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. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 41b27edd910..3e350bf08e3 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -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)
diff --git a/gcc/toplev.h b/gcc/toplev.h
index ae05f4b22ec..5a8b5813f09 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -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;