diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b09ac21ab4..a269b1c558d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2009-04-17 Rafael Avila de Espindola + + * Makefile.in (REVISION_s): Always include quotes. Change ifdef to use + REVISION_c. + (OBJS-common): Add plugin-version.o. + (plugin-version.o): New. + * gcc-plugin.h (plugin_gcc_version): New. + (plugin_default_version_check): New. + (plugin_init_func, plugin_init): Add version argument. + * plugin-version.c: New. + * plugin.c (str_plugin_gcc_version_name): New. + (try_init_one_plugin): Read plugin_gcc_version from the plugin and + pass it to the init function. + (plugin_default_version_check): New. + 2009-04-17 Richard Guenther * tree-ssa-alias.c (refs_may_alias_p_1): Do not use TBAA diff --git a/gcc/Makefile.in b/gcc/Makefile.in index f534684480f..9236f1408c8 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -780,7 +780,7 @@ BUGURL_TEXI := @REPORT_BUGS_TEXI@ ifdef REVISION_c REVISION_s := "\"$(if $(DEVPHASE_c), $(REVISION_c))\"" else -REVISION_s := +REVISION_s := "\"\"" endif # Shorthand variables for dependency lists. @@ -1154,6 +1154,7 @@ OBJS-common = \ params.o \ passes.o \ plugin.o \ + plugin-version.o \ pointer-set.o \ postreload-gcse.o \ postreload.o \ @@ -2003,7 +2004,7 @@ gcc-options.o: options.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) opts.h intl dumpvers: dumpvers.c -ifdef REVISION_s +ifdef REVISION_c version.o: version.c version.h $(REVISION) $(DATESTAMP) $(BASEVER) $(DEVPHASE) else version.o: version.c version.h $(DATESTAMP) $(BASEVER) $(DEVPHASE) @@ -2473,6 +2474,12 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \ errors.h $(TOPLEV_H) $(TREE_H) $(TREE_PASS_H) intl.h +plugin-version.o : plugin-version.c $(SYSTEM_H) gcc-plugin.h configargs.h + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) \ + -DBASEVER=$(BASEVER_s) -DDATESTAMP=$(DATESTAMP_s) \ + -DREVISION=$(REVISION_s) -DDEVPHASE=$(DEVPHASE_s) -c \ + -DPLUGIN $(srcdir)/plugin-version.c $(OUTPUT_OPTION) + main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) host-default.o : host-default.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ diff --git a/gcc/gcc-plugin.h b/gcc/gcc-plugin.h index 6865566472f..543dc933742 100644 --- a/gcc/gcc-plugin.h +++ b/gcc/gcc-plugin.h @@ -67,22 +67,42 @@ struct plugin_info const char *help; }; +/* Represents the gcc version. Used to avoid using an incompatible plugin. */ + +struct plugin_gcc_version +{ + const char *basever; + const char *datestamp; + const char *devphase; + const char *revision; + const char *configuration_arguments; +}; + +extern struct plugin_gcc_version plugin_gcc_version; + +/* The default version check. Compares every field in VERSION. */ + +extern bool plugin_default_version_check(struct plugin_gcc_version *version); + /* Function type for the plugin initialization routine. Each plugin module should define this as an externally-visible function with name "plugin_init." PLUGIN_NAME - name of the plugin (useful for error reporting) + VERSION - the plugin_gcc_version symbol of the plugin itself. ARGC - the size of the ARGV array ARGV - an array of key-value argument pair Returns 0 if initialization finishes successfully. */ typedef int (*plugin_init_func) (const char *plugin_name, + struct plugin_gcc_version *version, int argc, struct plugin_argument *argv); /* Declaration for "plugin_init" function so that it doesn't need to be duplicated in every plugin. */ -extern int plugin_init (const char *, int, struct plugin_argument *); +extern int plugin_init (const char *, struct plugin_gcc_version *version, + int, struct plugin_argument *); /* Function type for a plugin callback routine. diff --git a/gcc/plugin-version.c b/gcc/plugin-version.c new file mode 100644 index 00000000000..b6f35a9d18f --- /dev/null +++ b/gcc/plugin-version.c @@ -0,0 +1,36 @@ +/* Version information for plugins. + Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#include "system.h" +#include "gcc-plugin.h" +#include "configargs.h" + +static char basever[] = BASEVER; +static char datestamp[] = DATESTAMP; +static char devphase[] = DEVPHASE; +static char revision[] = REVISION; + +/* FIXME plugins: We should make the version information more precise. + One way to do is to add a checksum. */ + +struct plugin_gcc_version plugin_gcc_version = {basever, datestamp, devphase, + revision, + configuration_arguments}; diff --git a/gcc/plugin.c b/gcc/plugin.c index 4d4addd3bd8..c406c38b5f3 100644 --- a/gcc/plugin.c +++ b/gcc/plugin.c @@ -99,6 +99,7 @@ static struct pass_list_node *prev_added_pass_node; /* Each plugin should define an initialization function with exactly this name. */ static const char *str_plugin_init_func_name = "plugin_init"; +static const char *str_plugin_gcc_version_name = "plugin_gcc_version"; #endif /* Helper function for the hash table that compares the base_name of the @@ -566,8 +567,10 @@ try_init_one_plugin (struct plugin_name_args *plugin) { void *dl_handle; plugin_init_func plugin_init; + struct plugin_gcc_version *version; char *err; PTR_UNION_TYPE (plugin_init_func) plugin_init_union; + PTR_UNION_TYPE (struct plugin_gcc_version*) version_union; dl_handle = dlopen (plugin->full_name, RTLD_NOW); if (!dl_handle) @@ -590,8 +593,12 @@ try_init_one_plugin (struct plugin_name_args *plugin) return false; } + PTR_UNION_AS_VOID_PTR (version_union) = + dlsym (dl_handle, str_plugin_gcc_version_name); + version = PTR_UNION_AS_CAST_PTR (version_union); + /* Call the plugin-provided initialization routine with the arguments. */ - if ((*plugin_init) (plugin->base_name, plugin->argc, plugin->argv)) + if ((*plugin_init) (plugin->base_name, version, plugin->argc, plugin->argv)) { error ("Fail to initialize plugin %s", plugin->full_name); return false; @@ -805,3 +812,26 @@ debug_active_plugins (void) { dump_active_plugins (stderr); } + +/* The default version check. Compares every field in VERSION. */ + +bool +plugin_default_version_check(struct plugin_gcc_version *version) +{ + /* version is NULL if the plugin was not linked with plugin-version.o */ + if (!version) + return false; + + if (strcmp (version->basever, plugin_gcc_version.basever)) + return false; + if (strcmp (version->datestamp, plugin_gcc_version.datestamp)) + return false; + if (strcmp (version->devphase, plugin_gcc_version.devphase)) + return false; + if (strcmp (version->revision, plugin_gcc_version.revision)) + return false; + if (strcmp (version->configuration_arguments, + plugin_gcc_version.configuration_arguments)) + return false; + return true; +}