This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
+}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]