This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch][plugins] Check the gcc version
With my previous patches already in trunk, it is probably better to
add this patch there. Attached is a port to current trunk. The only
big difference is that it is missing the testsuite bits. Is it OK?
2009-04-14 Rafael Avila de Espindola <espindola@google.com>
* 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.
Cheers,
--
Rafael Avila de Espindola
Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 3b748d4..2e6a110 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.
@@ -1153,6 +1153,7 @@ OBJS-common = \
params.o \
passes.o \
plugin.o \
+ plugin-version.o \
pointer-set.o \
postreload-gcse.o \
postreload.o \
@@ -2002,7 +2003,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)
@@ -2468,6 +2469,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 8627720..dd5f249 100644
--- a/gcc/gcc-plugin.h
+++ b/gcc/gcc-plugin.h
@@ -66,22 +66,42 @@ struct plugin_info
const char *version;
};
+/* 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 0000000..3be5417
--- /dev/null
+++ b/gcc/plugin-version.c
@@ -0,0 +1,15 @@
+#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 95297a7..4770ae7 100644
--- a/gcc/plugin.c
+++ b/gcc/plugin.c
@@ -98,6 +98,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
@@ -564,8 +565,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)
@@ -588,8 +591,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;
@@ -758,3 +765,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;
+}