re PR pch/10757 (Adding -fpic/-fPIC causes crash with PCH created without -fpic/-fPIC)

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
This commit is contained in:
Geoffrey Keating 2003-10-24 21:28:13 +00:00 committed by Geoffrey Keating
parent eebf21ef99
commit 7bb1ad9314
8 changed files with 214 additions and 10 deletions

View 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)

View 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

View 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. */

View 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

View 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, \

View 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. */

View 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)

View 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;